/[zanavi_public1]/navit/navit/maptool/boundaries.c
ZANavi

Contents of /navit/navit/maptool/boundaries.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 57 - (show annotations) (download)
Sun Mar 19 16:46:08 2017 UTC (7 years, 1 month ago) by zoff99
File MIME type: text/plain
File size: 26305 byte(s)
updates
1 /**
2 * ZANavi, Zoff Android Navigation system.
3 * Copyright (C) 2011-2013 Zoff <zoff@zoff.cc>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 /**
21 * Navit, a modular navigation system.
22 * Copyright (C) 2005-2011 Navit Team
23 *
24 * This program is free software; you can redistribute it and/or
25 * modify it under the terms of the GNU General Public License
26 * version 2 as published by the Free Software Foundation.
27 *
28 * This program is distributed in the hope that it will be useful,
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 * GNU General Public License for more details.
32 *
33 * You should have received a copy of the GNU General Public License
34 * along with this program; if not, write to the
35 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
36 * Boston, MA 02110-1301, USA.
37 */
38 #include <stdio.h>
39 #include <string.h>
40 #include <ctype.h>
41 #include <dirent.h>
42
43 #include <locale.h>
44 #include <stdlib.h>
45
46 #include "maptool.h"
47
48 char *
49 osm_tag_value(struct item_bin *ib, char *key)
50 {
51 char *tag = NULL;
52 int len = strlen(key);
53 while ((tag = item_bin_get_attr(ib, attr_osm_tag, tag)))
54 {
55 if (!strncmp(tag, key, len) && tag[len] == '=')
56 return tag + len + 1;
57 }
58 return NULL;
59 }
60
61 static char *
62 osm_tag_name(struct item_bin *ib)
63 {
64 return osm_tag_value(ib, "name");
65 }
66
67 long long *
68 boundary_relid(struct boundary *b)
69 {
70 long long *id;
71 if (!b)
72 return 0;
73 if (!b->ib)
74 return 0;
75 id = item_bin_get_attr(b->ib, attr_osm_relationid, NULL);
76 if (id)
77 return *id;
78 return 0;
79 }
80
81 static void process_boundaries_member(void *func_priv, void *relation_priv, struct item_bin *member, void *member_priv)
82 {
83 //fprintf(stderr,"process_boundaries_member:001\n");
84
85 struct boundary *b = relation_priv;
86 enum geom_poly_segment_type role = (long) member_priv;
87
88
89
90 int *dup;
91 dup=item_bin_get_attr(member,attr_duplicate_way,NULL);
92
93 // only add way to boundary if this way is not already added
94 if(!dup || *dup == 0)
95 {
96 b->segments = g_list_prepend(b->segments, item_bin_to_poly_segment(member, role));
97 // fprintf(stderr, "process_boundaries_member: dupdup wayid=%lld %p\n", item_bin_get_wayid(member), dup);
98 }
99 else
100 {
101 // fprintf(stderr, "process_boundaries_member: dup=true wayid=%lld\n", item_bin_get_wayid(member));
102 }
103
104 //fprintf(stderr,"process_boundaries_member:099\n");
105 }
106
107 static GList *
108 process_boundaries_setup(FILE *boundaries, struct relations *relations)
109 {
110 struct item_bin *ib;
111 GList *boundaries_list = NULL;
112 struct relations_func *relations_func;
113 long long b_counter_1 = 0;
114 // long long b_counter_2 = 0;
115
116 //fprintf(stderr,"process_boundaries_setup:001\n");
117
118 relations_func = relations_func_new(process_boundaries_member, NULL);
119 while ((ib = read_item(boundaries, 0)))
120 {
121
122 //fprintf(stderr,"********DUMP b ***********\n");
123 //dump_itembin(ib);
124 //fprintf(stderr,"********DUMP b ***********\n");
125
126
127 char *member = NULL;
128 struct boundary *boundary=g_new0(struct boundary, 1);
129 char *admin_level = osm_tag_value(ib, "admin_level");
130 char *iso = osm_tag_value(ib, "ISO3166-1");
131
132 b_counter_1++;
133 if ((b_counter_1 % 500) == 0)
134 {
135 fprintf_(stderr,"boundaries:B:%lld\n", b_counter_1);
136 }
137
138 //fprintf(stderr,"process_boundaries_setup:002\n");
139 //fprintf(stderr,"== b:%s %s ==\n", iso, admin_level);
140
141 /* disable spain for now since it creates a too large index */
142 // if (admin_level && !strcmp(admin_level, "2") && (!iso || strcasecmp(iso, "es")))
143 if (admin_level && !strcmp(admin_level, "2"))
144 {
145 if (iso)
146 {
147 struct country_table *country = country_from_iso2(iso);
148 if (!country)
149 {
150 osm_warning("relation", item_bin_get_relationid(ib), 0, "Country Boundary contains unknown ISO3166-1 value '%s'\n", iso);
151 }
152 else
153 {
154 boundary->iso2 = g_strdup(iso);
155 osm_info("relation", item_bin_get_relationid(ib), 0, "Country Boundary for '%s'\n", iso);
156 }
157 boundary->country = country;
158 }
159 else
160 {
161 osm_warning("relation", item_bin_get_relationid(ib), 0, "Country Boundary doesn't contain an ISO3166-1 tag\n");
162 }
163 }
164
165 //b_counter_2 = 0;
166 while ((member = item_bin_get_attr(ib, attr_osm_member, member)))
167 {
168 //fprintf(stderr,"process_boundaries_setup:005\n");
169 //fprintf(stderr,"********DUMP b ***********\n");
170 //dump_itembin(ib);
171 //fprintf(stderr,"********DUMP b ***********\n");
172
173 //b_counter_2++;
174 //fprintf(stderr,"boundaries:M:%lld\n", b_counter_2);
175
176 long long wayid;
177 int read = 0;
178 if (sscanf(member, "2:%Ld:%n", &wayid, &read) >= 1)
179 {
180 char *rolestr = member + read;
181 enum geom_poly_segment_type role;
182 if (!strcmp(rolestr, "outer") || !strcmp(rolestr, "exclave"))
183 {
184 role = geom_poly_segment_type_way_outer;
185 }
186 else if (!strcmp(rolestr, "inner") || !strcmp(rolestr, "enclave"))
187 {
188 role = geom_poly_segment_type_way_inner;
189 }
190 else if (!strcmp(rolestr, ""))
191 {
192 role = geom_poly_segment_type_way_unknown;
193 }
194 else
195 {
196 osm_warning("relation", item_bin_get_relationid(ib), 0, "Unknown role %s in member ", rolestr);
197 osm_warning("way", wayid, 1, "\n");
198 role = geom_poly_segment_type_none;
199 }
200
201 //fprintf(stderr,"process_boundaries_setup:006 %s %Ld\n", rolestr,wayid);
202
203 relations_add_func(relations, relations_func, boundary, (gpointer) role, 2, wayid);
204 }
205 }
206
207 boundary->ib = item_bin_dup(ib);
208 boundaries_list = g_list_append(boundaries_list, boundary);
209 }
210
211 return boundaries_list;
212 }
213
214 GList *
215 boundary_find_matches(GList *l, struct coord *c)
216 {
217 GList *ret = NULL;
218 //fprintf(stderr,"boundary_find_matches:001\n");
219 while (l)
220 {
221 //fprintf(stderr,"boundary_find_matches:002\n");
222
223 struct boundary *boundary = l->data;
224 if (bbox_contains_coord(&boundary->r, c))
225 {
226 //fprintf(stderr,"boundary_find_matches:003 id=%lld name=%s\n", item_bin_get_relationid(boundary->ib), osm_tag_name(boundary->ib));
227 if (geom_poly_segments_point_inside(boundary->sorted_segments, c) > 0)
228 {
229 //fprintf(stderr,"boundary_find_matches:004\n");
230 ret = g_list_prepend(ret, boundary);
231 }
232 // children stuff disabled!!
233 // ret = g_list_concat(ret, boundary_find_matches(boundary->children, c));
234 // children stuff disabled!!
235 }
236 l = g_list_next(l);
237 }
238
239 //fprintf(stderr,"boundary_find_matches:099\n");
240
241 return ret;
242 }
243
244 GList *
245 boundary_find_matches_level(GList *l, struct coord *c, int min_admin_level, int max_admin_level)
246 {
247 GList *ret = NULL;
248 char *al;
249 int admin_level;
250 struct boundary *boundary = NULL;
251
252 while (l)
253 {
254 boundary = l->data;
255 al = osm_tag_value(boundary->ib, "admin_level");
256 if (!al)
257 {
258 admin_level = 9999;
259 }
260 else
261 {
262 admin_level = atoi(al);
263 }
264
265 if (admin_level < 2)
266 {
267 admin_level = 9999;
268 }
269
270 //fprintf(stderr, "matches 001:this:%d min:%d max:%d\n", admin_level, min_admin_level, max_admin_level);
271
272 if ((admin_level >= min_admin_level) && (admin_level <= max_admin_level))
273 {
274 //fprintf(stderr, "matches 002:level\n");
275 if (bbox_contains_coord(&boundary->r, c))
276 {
277 //fprintf(stderr, "matches 003:bbox\n");
278 if (geom_poly_segments_point_inside(boundary->sorted_segments, c) > 0)
279 {
280 //fprintf(stderr, "matches 004:**found**\n");
281 ret = g_list_prepend(ret, boundary);
282 }
283 }
284 }
285 l = g_list_next(l);
286 }
287
288 return ret;
289 }
290
291
292 GList *
293 boundary_find_matches_single(GList *l, struct coord *c)
294 {
295 GList *ret = NULL;
296
297 if (l)
298 {
299 //fprintf(stderr, "bbox:001\n");
300 struct boundary *boundary = l->data;
301 //fprintf(stderr, "bbox:%d %d %d %d\n", boundary->r.l.x, boundary->r.l.y, boundary->r.h.x, boundary->r.h.y);
302 //fprintf(stderr, "c:%d %d\n", c->x, c->y);
303 if (bbox_contains_coord(&boundary->r, c))
304 {
305 //fprintf(stderr, "inside bbox\n");
306 if (geom_poly_segments_point_inside(boundary->sorted_segments, c) > 0)
307 {
308 //fprintf(stderr, "bbox:002\n");
309 ret = g_list_prepend(ret, boundary);
310 }
311 }
312 }
313
314 return ret;
315 }
316
317
318 static void dump_hierarchy(GList *l, char *prefix)
319 {
320 char *newprefix = g_alloca(sizeof(char) * (strlen(prefix) + 2));
321 strcpy(newprefix, prefix);
322 strcat(newprefix, " ");
323 while (l)
324 {
325 struct boundary *boundary = l->data;
326 fprintf(stderr, "%s:childs:%d:%lld:%s\n", prefix, g_list_length(boundary->children), item_bin_get_relationid(boundary->ib), osm_tag_name(boundary->ib));
327 dump_hierarchy(boundary->children, newprefix);
328 l = g_list_next(l);
329 }
330 }
331
332 static gint boundary_bbox_compare(gconstpointer a, gconstpointer b)
333 {
334 const struct boundary *boundarya = a;
335 const struct boundary *boundaryb = b;
336 long long areaa = bbox_area(&boundarya->r);
337 long long areab = bbox_area(&boundaryb->r);
338 if (areaa > areab)
339 return 1;
340 if (areaa < areab)
341 return -1;
342 return 0;
343 }
344
345 static GList *
346 process_boundaries_insert(GList *list, struct boundary *boundary)
347 {
348 // children stuff is totally broken, so it is disabled now!!
349 /*
350 GList *l = list;
351 while (l)
352 {
353 struct boundary *b = l->data;
354 if (bbox_contains_bbox(&boundary->r, &b->r))
355 {
356 list = g_list_remove(list, b);
357 boundary->children = g_list_prepend(boundary->children, b);
358 l = list;
359 }
360 else if (bbox_contains_bbox(&b->r, &boundary->r))
361 {
362 b->children = process_boundaries_insert(b->children, boundary);
363 return list;
364 }
365 else
366 {
367 l = g_list_next(l);
368 }
369 }
370 */
371 // children stuff is totally broken, so it is disabled now!!
372
373 return g_list_prepend(list, boundary);
374 }
375
376 static GList *
377 process_boundaries_finish(GList *boundaries_list)
378 {
379 //fprintf(stderr,"process_boundaries_finish:001\n");
380
381 GList *l = NULL, *sl = NULL, *l2 = NULL, *ln = NULL;
382 GList *ret = NULL;
383 l = boundaries_list;
384 char *f1_name = NULL;
385 char *f2_name = NULL;
386 long long b_counter_1 = 0;
387 long long nodes_counter_ = 0;
388 long long ways_counter_ = 0;
389
390 while (l)
391 {
392 struct boundary *boundary = l->data;
393 int first = 1;
394 FILE *f = NULL, *fu = NULL;
395
396 b_counter_1++;
397 if ((b_counter_1 % 500) == 0)
398 {
399 fprintf_(stderr,"boundaries_f1:B:%lld\n", b_counter_1);
400 }
401
402 //fprintf(stderr,"process_boundaries_finish:002\n");
403
404 // only uppercase country code
405 if (boundary->iso2)
406 {
407 int i99;
408 for (i99 = 0; boundary->iso2[i99]; i99++)
409 {
410 boundary->iso2[i99] = toupper(boundary->iso2[i99]);
411 }
412 }
413 // only uppercase country code
414
415 if (boundary->country)
416 {
417 //fprintf(stderr,"process_boundaries_finish:003\n");
418
419 char *name = g_strdup_printf("country_%s_poly", boundary->iso2);
420 f1_name = g_strdup_printf("country_%s_poly", boundary->iso2);
421 f = tempfile("", name, 1);
422 g_free(name);
423 }
424
425
426
427 // calc bounding box
428 first = 1;
429 nodes_counter_ = 0;
430 ways_counter_ = 0;
431 sl = boundary->segments;
432 while (sl)
433 {
434 struct geom_poly_segment *gs = sl->data;
435 struct coord *c = gs->first;
436 while (c <= gs->last)
437 {
438 if (first)
439 {
440 boundary->r.l = *c;
441 boundary->r.h = *c;
442 first = 0;
443 }
444 else
445 {
446 bbox_extend(c, &boundary->r);
447 }
448 c++;
449 nodes_counter_++;
450 }
451 sl = g_list_next(sl);
452 ways_counter_++;
453 }
454
455 //fprintf(stderr, "relid:%lld\n", item_bin_get_relationid(boundary->ib));
456 //fprintf(stderr, "ways:%lld nodes:%lld\n", ways_counter_, nodes_counter_);
457
458 boundary->sorted_segments = geom_poly_segments_sort(boundary->segments, geom_poly_segment_type_way_right_side);
459 sl = boundary->sorted_segments;
460
461 first = 1;
462 while (sl)
463 {
464 //fprintf(stderr,"process_boundaries_finish:004.1\n");
465
466 struct geom_poly_segment *gs = sl->data;
467 struct coord *c = gs->first;
468
469 /*
470 while (c <= gs->last)
471 {
472 if (first)
473 {
474 boundary->r.l = *c;
475 boundary->r.h = *c;
476 first = 0;
477 }
478 else
479 {
480 bbox_extend(c, &boundary->r);
481 }
482 c++;
483
484 //fprintf(stderr,"process_boundaries_finish:004.2 lx=%d ly=%d hx=%d hy=%d\n",boundary->r.l.x,boundary->r.l.y,boundary->r.h.x,boundary->r.h.y);
485
486 }
487 */
488
489 if (f)
490 {
491 struct item_bin *ib = item_bin_2;
492 item_bin_init(ib, type_selected_line);
493 item_bin_add_coord(ib, gs->first, gs->last - gs->first + 1);
494 item_bin_write(ib, f);
495 }
496
497 if (boundary->country)
498 {
499 if (!coord_is_equal(*gs->first, *gs->last))
500 {
501 if (!fu)
502 {
503 char *name = g_strdup_printf("country_%s_broken", boundary->iso2);
504 f2_name = g_strdup_printf("country_%s_broken", boundary->iso2);
505 fprintf(stderr, "*BROKEN*(1) country_%s_broken relid=%lld\n", boundary->iso2, item_bin_get_relationid(boundary->ib));
506 fu = tempfile("", name, 1);
507 g_free(name);
508 }
509 struct item_bin *ib = item_bin_2;
510 item_bin_init(ib, type_selected_point);
511 item_bin_add_coord(ib, gs->first, 1);
512 item_bin_write(ib, fu);
513
514 item_bin_init(ib, type_selected_point);
515 item_bin_add_coord(ib, gs->last, 1);
516 item_bin_write(ib, fu);
517 }
518 }
519 sl = g_list_next(sl);
520
521 if (f2_name)
522 {
523 tempfile_unlink("", f2_name);
524 g_free(f2_name);
525 f2_name = NULL;
526 }
527 }
528
529 ret = process_boundaries_insert(ret, boundary);
530 l = g_list_next(l);
531
532 if (f)
533 {
534 fclose(f);
535 }
536
537 if (fu)
538 {
539 if (boundary->country)
540 {
541 //osm_warning("relation", item_bin_get_relationid(boundary->ib), 0, "Broken country polygon '%s'\n", boundary->iso2);
542 fprintf_(stderr, "*BROKEN*(2) country polygon '%s' relid=%lld\n", boundary->iso2, item_bin_get_relationid(boundary->ib));
543 }
544 fclose(fu);
545 }
546
547 if (f1_name)
548 {
549 tempfile_unlink("", f1_name);
550 g_free(f1_name);
551 f1_name = NULL;
552 }
553 }
554 #if 0
555 printf("hierarchy\n");
556 #endif
557
558 // boundaries_list = g_list_sort(boundaries_list, boundary_bbox_compare); // disable sorting, does not seem to do any good
559
560 // children stuff totally broken!!!
561 #if 0
562 b_counter_1 = 0;
563 l = boundaries_list;
564 while (l)
565 {
566 b_counter_1++;
567 if ((b_counter_1 % 500) == 0)
568 {
569 fprintf(stderr,"boundaries_f2:B:%lld\n", b_counter_1);
570 }
571
572 struct boundary *boundary = l->data;
573 ln = l2 = g_list_next(l);
574 while (l2)
575 {
576 struct boundary *boundary2 = l2->data;
577 if (bbox_contains_bbox(&boundary2->r, &boundary->r))
578 {
579 boundaries_list = g_list_remove(boundaries_list, boundary);
580 boundary2->children = g_list_append(boundary2->children, boundary);
581 break;
582 }
583 l2 = g_list_next(l2);
584 }
585 l = ln;
586 }
587 #endif
588 // children stuff totally broken!!!
589
590 // -- DEBUG --
591 // -- DEBUG --
592 // -- DEBUG --
593 // dump_hierarchy(boundaries_list,""); // --> prints huge amounts of data!! be careful
594 // -- DEBUG --
595 // -- DEBUG --
596 // -- DEBUG --
597
598 return boundaries_list;
599 }
600
601
602 void free_boundaries(GList *l)
603 {
604 while (l)
605 {
606 struct boundary *boundary=l->data;
607 GList *s=boundary->segments;
608
609 while (s)
610 {
611 struct geom_poly_segment *seg=s->data;
612
613 g_free(seg->first);
614 g_free(seg);
615 s=g_list_next(s);
616 }
617
618 s=boundary->sorted_segments;
619
620 while (s)
621 {
622 struct geom_poly_segment *seg=s->data;
623
624 g_free(seg->first);
625 g_free(seg);
626 s=g_list_next(s);
627 }
628
629 g_list_free(boundary->segments);
630 g_list_free(boundary->sorted_segments);
631 g_free(boundary->ib);
632
633 free_boundaries(boundary->children);
634
635 g_free(boundary);
636
637 l=g_list_next(l);
638 }
639 }
640
641
642 GList *
643 process_boundaries(FILE *boundaries, FILE *coords, FILE *ways)
644 {
645 GList *boundaries_list = NULL;
646 struct relations *relations = relations_new();
647
648 //fprintf(stderr,"process_boundaries:001\n");
649 boundaries_list = process_boundaries_setup(boundaries, relations);
650 //fprintf(stderr,"process_boundaries:001.rp1\n");
651 relations_process(relations, NULL, ways, NULL);
652 //fprintf(stderr,"process_boundaries:001.rp2\n");
653 relations_destroy(relations);
654 return process_boundaries_finish(boundaries_list);
655 }
656
657 static char* only_ascii(char *instr)
658 {
659 char *outstr;
660 int i;
661 int j;
662
663 if (!instr)
664 {
665 return NULL;
666 }
667
668 outstr = g_strdup(instr);
669
670 j = 0;
671 for (i = 0; i<strlen(instr); i++)
672 {
673 if ((instr[i] >= 'a')&&(instr[i] <= 'z'))
674 {
675 outstr[j] = instr[i];
676 j++;
677 }
678 else if ((instr[i] >= 'A')&&(instr[i] <= 'Z'))
679 {
680 outstr[j] = instr[i];
681 j++;
682 }
683 else
684 {
685 // non ascii char encountered -> ingore it
686 }
687 }
688
689 if (j == 0)
690 {
691 if (outstr)
692 {
693 g_free(outstr);
694 }
695 return NULL;
696 }
697 else
698 {
699 outstr[j] = '\0';
700 }
701
702 return outstr;
703 }
704
705 void save_manual_country_borders(GList *borders)
706 {
707 struct country_table2
708 {
709 int countryid;
710 char *names;
711 char *admin_levels;
712 FILE *file;
713 int size;
714 struct rect r;
715 };
716
717 struct boundary *b;
718 struct country_table2 *country;
719 int i;
720 FILE *fp;
721 char filename[300];
722 int admin_l_boundary;
723 int num;
724 char broken_string[100];
725 char *broken_str = broken_string[0];
726 char *country_name = NULL;
727
728 GList *l = borders;
729 while (l)
730 {
731 if (l)
732 {
733
734 b = l->data;
735 if (b)
736 {
737 //if (item_bin_is_closed_poly(b->ib) == 1)
738 {
739 char *admin_l_boundary_str = osm_tag_value(b->ib, "admin_level");
740 if (!admin_l_boundary_str)
741 {
742 admin_l_boundary = 9999;
743 }
744 else
745 {
746 admin_l_boundary = atoi(admin_l_boundary_str);
747 }
748
749 if (admin_l_boundary < 2)
750 {
751 admin_l_boundary = 9999;
752 }
753
754 country = b->country;
755 if (country)
756 {
757 if (admin_l_boundary < 3)
758 {
759 fprintf_(stderr, "adminlevel=%d countryid=%d name=%s\n", admin_l_boundary, country->countryid, country->names);
760 num = 0;
761
762 GList *sl=b->sorted_segments;
763 while (sl)
764 {
765
766 //fprintf(stderr, "sorted segs\n");
767
768 struct geom_poly_segment *gs = sl->data;
769 struct coord *c2 = gs->first;
770 broken_str = "";
771
772 if ((gs->first == NULL)||(gs->last == NULL))
773 {
774 // only 1 coord in poly
775 broken_str = "._BROKEN1_";
776 }
777 else if (gs->first == gs->last)
778 {
779 // only 1 coord in poly
780 broken_str = "._BROKEN2_";
781 }
782 else if (!coord_is_equal(*gs->first, *gs->last))
783 {
784 // first coord not equal to last coord -> poly is not closed
785 broken_str = "._BROKEN3_";
786 }
787
788 if (country->names)
789 {
790 char *converted_to_ascii = only_ascii(country->names);
791 if (converted_to_ascii)
792 {
793 country_name = g_strdup_printf("%s_", converted_to_ascii);
794 g_free(converted_to_ascii);
795 }
796 else
797 {
798 country_name = g_strdup_printf("");
799 }
800 }
801 else
802 {
803 country_name = g_strdup_printf("");
804 }
805
806 num++;
807
808 if (gs->type == geom_poly_segment_type_none)
809 {
810 sprintf(filename, "XXman_country_poly.%s%d.%d%s.%s.txt", country_name, country->countryid, num, broken_str, "none");
811 }
812 else if (gs->type == geom_poly_segment_type_way_inner)
813 {
814 sprintf(filename, "XXman_country_poly.%s%d.%d%s.%s.txt", country_name, country->countryid, num, broken_str, "inner");
815 }
816 else if (gs->type == geom_poly_segment_type_way_outer)
817 {
818 sprintf(filename, "XXman_country_poly.%s%d.%d%s.%s.txt", country_name, country->countryid, num, broken_str, "outer");
819 }
820 else if (gs->type == geom_poly_segment_type_way_left_side)
821 {
822 sprintf(filename, "XXman_country_poly.%s%d.%d%s.%s.txt", country_name, country->countryid, num, broken_str, "left");
823 }
824 else if (gs->type == geom_poly_segment_type_way_right_side)
825 {
826 sprintf(filename, "XXman_country_poly.%s%d.%d%s.%s.txt", country_name, country->countryid, num, broken_str, "right");
827 }
828 else if (gs->type == geom_poly_segment_type_way_unknown)
829 {
830 sprintf(filename, "XXman_country_poly.%s%d.%d%s.%s.txt", country_name, country->countryid, num, broken_str, "unknown");
831 }
832
833 if (!global_less_verbose)
834 {
835 fp = fopen(filename,"wb");
836 if (fp)
837 {
838 fprintf(fp, "%d\n", country->countryid); // country id
839 fprintf(fp, "1\n"); // poly num -> here always 1
840
841 while (c2 <= gs->last)
842 {
843 // fprintf(stderr, "%d,%d\n", c2[0].x, c2[0].y);
844 fprintf(fp, " %lf %lf\n", transform_to_geo_lon(c2[0].x), transform_to_geo_lat(c2[0].y));
845 c2++;
846 }
847
848 fprintf(fp, "END\n"); // poly END marker
849 fprintf(fp, "END\n"); // file END marker
850 }
851 fclose(fp);
852 }
853
854 sl = g_list_next(sl);
855
856 if (country_name)
857 {
858 g_free(country_name);
859 country_name = NULL;
860 }
861 }
862 }
863
864 }
865
866 }
867 }
868
869 l = g_list_next(l);
870 }
871 }
872 }
873
874 GList* load_manual_country_borders()
875 {
876 struct country_table
877 {
878 int countryid;
879 char *names;
880 char *admin_levels;
881 FILE *file;
882 int size;
883 struct rect r;
884 };
885
886 DIR* dirp;
887 struct dirent *dp;
888 FILE * fp;
889 char *line = NULL;
890 size_t len = 0;
891 ssize_t read;
892 GList *ret = NULL;
893 int linecounter = 0;
894 char *iso = NULL;
895 int c_id = 999; // set to unkown country
896 int faktor;
897 struct coord *c;
898 struct coord *cur_coord;
899 int coord_count;
900 struct rect *boundary_bbox;
901 double lat;
902 double lon;
903 char lat_str[200];
904 char lon_str[200];
905 char *saved_locale;
906 char *endptr;
907 char *full_file_name = NULL;
908 int inner_polygon;
909 struct boundary_manual *boundary;
910
911 saved_locale = setlocale(LC_NUMERIC, "C");
912
913 // initialise inner manual border list
914 GList *boundary_list_inner_manual = NULL;
915
916 dirp = opendir(manual_country_border_dir);
917 // "man_country_poly.<ISO num>.txt"
918 while ((dp = readdir(dirp)) != NULL)
919 {
920 //fprintf(stderr, "consider:%s\n", dp->d_name);
921
922 if ((strlen(dp->d_name) > 20) && (!strncmp(dp->d_name, "man_country_poly.", 17)))
923 {
924 if (strcasestr(dp->d_name, ".inner.") == NULL)
925 {
926 // NOT an inner polygon
927 inner_polygon = 0;
928 }
929 else
930 {
931 inner_polygon = 1;
932 }
933
934 full_file_name = g_strdup_printf("%s/%s", manual_country_border_dir, dp->d_name);
935
936 fp = fopen(full_file_name, "rb");
937 // fprintf(stderr, "fopen=%s\n", dp->d_name);
938
939 if (fp != NULL)
940 {
941 // fprintf(stderr, "fopen:OK\n");
942 coord_count = 0;
943 while ((read = getline(&line, &len, fp)) != -1)
944 {
945 if (strlen(line) > 1)
946 {
947 if ((strlen(line) > 2)&&(!strncmp(line, "END", 3)))
948 {
949 // IGNORE "END" lines
950 //fprintf(stderr, "load_manual_country_borders:ignore END line\n");
951 }
952 else
953 {
954 coord_count++;
955 }
956 }
957 else
958 {
959 fprintf_(stderr, "load_manual_country_borders:ignore empty line\n");
960 }
961 }
962 coord_count = coord_count - 2; // subtract header to get number of coords
963 c = (struct coord*) malloc(sizeof(struct coord) * coord_count);
964 cur_coord = c;
965
966 fseeko(fp, 0L, SEEK_SET);
967 // rewind(fp);
968
969 linecounter = 0;
970
971 while ((read = getline(&line, &len, fp)) != -1)
972 {
973 if (linecounter == 0)
974 {
975 if (inner_polygon == 1)
976 {
977 boundary=g_new0(struct boundary_manual, 1);
978 }
979 else
980 {
981 // first line has the ISO code of the country
982 boundary=g_new0(struct boundary_manual, 1);
983 }
984
985 c_id = atoi(line);
986
987 struct country_table *country = country_from_countryid(c_id);
988 if (!country)
989 {
990 // problem with this file -> skip it
991 fprintf(stderr, "load_manual_country_borders:PROBLEM WITH THIS FILE:%s cid=%d\n", dp->d_name, c_id);
992 g_free(boundary);
993 boundary = NULL;
994
995 break;
996 }
997 else
998 {
999 // boundary->iso2 = g_strdup("XXX");
1000 boundary->country = country;
1001 boundary->c = c;
1002 boundary->coord_count = coord_count;
1003 boundary->countryid = c_id;
1004 if (country->names)
1005 {
1006 //fprintf(stderr, "load_manual_country_borders:country %d:name=%s\n", c_id, country->names);
1007 }
1008 else
1009 {
1010 //fprintf(stderr, "load_manual_country_borders:country %d:name=\n", c_id);
1011 }
1012 }
1013 }
1014 else if (linecounter == 1)
1015 {
1016 // faktor = atoi(line);
1017 //
1018 // unsused anymore, line 2 ist just the polygon number, usually 1 in our case! so just ignore
1019 faktor = 1;
1020 //fprintf(stderr, "faktor1: %d\n", faktor);
1021 }
1022 else
1023 {
1024 if (strlen(line) > 1)
1025 {
1026 if ((strlen(line) > 2)&&(!strncmp(line, "END", 3)))
1027 {
1028 // IGNORE "END" lines
1029 //fprintf(stderr, "load_manual_country_borders:ignore END line\n");
1030 }
1031 else
1032 {
1033 // fprintf(stderr, "found1: line=%s", line);
1034 // fprintf(stderr, "faktor2: %d\n", faktor);
1035
1036 // line format:LON LAT
1037 lat_str[0] = '\0';
1038 lon_str[0] = '\0';
1039 // sscanf(line, " %lf %lf\n", &lon, &lat);
1040 sscanf(line, "%s%s", lon_str, lat_str);
1041 lon = strtod(lon_str, &endptr);
1042 lat = strtod(lat_str, &endptr);
1043
1044 // fprintf(stderr, "found2: lat_str=%s lon_str=%s\n", lat_str, lon_str);
1045 // 7.566702E+00 4.805764E+01
1046
1047 lat = lat * faktor;
1048 lon = lon * faktor;
1049 // fprintf(stderr, "found4: lat=%lf lon=%lf\n", lat, lon);
1050 cur_coord->x = transform_from_geo_lon(lon);
1051 cur_coord->y = transform_from_geo_lat(lat);
1052 cur_coord++;
1053 }
1054 }
1055 else
1056 {
1057 fprintf_(stderr, "load_manual_country_borders:ignore empty line\n");
1058 }
1059
1060 }
1061 linecounter++;
1062 }
1063
1064 if (line)
1065 {
1066 free(line);
1067 line = NULL;
1068 }
1069
1070 // add country boundary to result list
1071 if (boundary != NULL)
1072 {
1073 bbox(boundary->c, boundary->coord_count, &boundary->r);
1074 if (inner_polygon == 1)
1075 {
1076 fprintf_(stderr, "load_manual_country_borders:add inner poly\n");
1077 boundary_list_inner_manual = g_list_append(boundary_list_inner_manual, boundary);
1078 }
1079 else
1080 {
1081 //fprintf(stderr, "load_manual_country_borders:add normal poly\n");
1082 ret = g_list_append(ret, boundary);
1083 }
1084 }
1085
1086 fclose(fp);
1087 }
1088
1089 if (full_file_name)
1090 {
1091 g_free(full_file_name);
1092 full_file_name = NULL;
1093 }
1094
1095 }
1096 }
1097
1098 closedir(dirp);
1099
1100 setlocale(LC_NUMERIC, saved_locale);
1101
1102 // return result list
1103 return ret;
1104 }
1105
1106
1107

   
Visit the ZANavi Wiki