/[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 - (hide annotations) (download)
Sun Mar 19 16:46:08 2017 UTC (7 years ago) by zoff99
File MIME type: text/plain
File size: 26305 byte(s)
updates
1 zoff99 8 /**
2 zoff99 37 * ZANavi, Zoff Android Navigation system.
3 zoff99 57 * Copyright (C) 2011-2013 Zoff <zoff@zoff.cc>
4 zoff99 37 *
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 zoff99 8 * 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 zoff99 36 #include <ctype.h>
41 zoff99 57 #include <dirent.h>
42    
43     #include <locale.h>
44     #include <stdlib.h>
45    
46 zoff99 8 #include "maptool.h"
47    
48 zoff99 36 char *
49     osm_tag_value(struct item_bin *ib, char *key)
50     {
51 zoff99 37 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 zoff99 36 }
58     return NULL;
59     }
60 zoff99 34
61 zoff99 36 static char *
62     osm_tag_name(struct item_bin *ib)
63 zoff99 8 {
64 zoff99 36 return osm_tag_value(ib, "name");
65 zoff99 8 }
66    
67 zoff99 36 long long *
68     boundary_relid(struct boundary *b)
69 zoff99 8 {
70 zoff99 36 long long *id;
71     if (!b)
72     return 0;
73     if (!b->ib)
74     return 0;
75 zoff99 37 id = item_bin_get_attr(b->ib, attr_osm_relationid, NULL);
76 zoff99 36 if (id)
77     return *id;
78     return 0;
79 zoff99 8 }
80    
81 zoff99 37 static void process_boundaries_member(void *func_priv, void *relation_priv, struct item_bin *member, void *member_priv)
82 zoff99 31 {
83 zoff99 37 //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 zoff99 8 }
106    
107     static GList *
108 zoff99 36 process_boundaries_setup(FILE *boundaries, struct relations *relations)
109 zoff99 8 {
110     struct item_bin *ib;
111 zoff99 37 GList *boundaries_list = NULL;
112 zoff99 36 struct relations_func *relations_func;
113 zoff99 37 long long b_counter_1 = 0;
114     // long long b_counter_2 = 0;
115 zoff99 8
116 zoff99 37 //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 zoff99 8 struct boundary *boundary=g_new0(struct boundary, 1);
129 zoff99 37 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 zoff99 57 fprintf_(stderr,"boundaries:B:%lld\n", b_counter_1);
136 zoff99 37 }
137    
138     //fprintf(stderr,"process_boundaries_setup:002\n");
139     //fprintf(stderr,"== b:%s %s ==\n", iso, admin_level);
140    
141 zoff99 36 /* disable spain for now since it creates a too large index */
142 zoff99 57 // if (admin_level && !strcmp(admin_level, "2") && (!iso || strcasecmp(iso, "es")))
143     if (admin_level && !strcmp(admin_level, "2"))
144 zoff99 37 {
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 zoff99 36 }
152 zoff99 37 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 zoff99 36 }
164 zoff99 37
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 zoff99 8 long long wayid;
177 zoff99 37 int read = 0;
178     if (sscanf(member, "2:%Ld:%n", &wayid, &read) >= 1)
179     {
180     char *rolestr = member + read;
181 zoff99 36 enum geom_poly_segment_type role;
182 zoff99 37 if (!strcmp(rolestr, "outer") || !strcmp(rolestr, "exclave"))
183 zoff99 57 {
184 zoff99 37 role = geom_poly_segment_type_way_outer;
185 zoff99 57 }
186 zoff99 37 else if (!strcmp(rolestr, "inner") || !strcmp(rolestr, "enclave"))
187 zoff99 57 {
188 zoff99 37 role = geom_poly_segment_type_way_inner;
189 zoff99 57 }
190 zoff99 37 else if (!strcmp(rolestr, ""))
191 zoff99 57 {
192 zoff99 37 role = geom_poly_segment_type_way_unknown;
193 zoff99 57 }
194 zoff99 37 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 zoff99 8 }
200 zoff99 37
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 zoff99 8 }
205     }
206 zoff99 37
207     boundary->ib = item_bin_dup(ib);
208     boundaries_list = g_list_append(boundaries_list, boundary);
209 zoff99 8 }
210 zoff99 37
211 zoff99 8 return boundaries_list;
212     }
213    
214 zoff99 36 GList *
215     boundary_find_matches(GList *l, struct coord *c)
216 zoff99 8 {
217 zoff99 37 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 zoff99 8 }
236 zoff99 37 l = g_list_next(l);
237 zoff99 8 }
238 zoff99 37
239     //fprintf(stderr,"boundary_find_matches:099\n");
240    
241 zoff99 36 return ret;
242 zoff99 8 }
243    
244 zoff99 37 GList *
245     boundary_find_matches_level(GList *l, struct coord *c, int min_admin_level, int max_admin_level)
246 zoff99 8 {
247 zoff99 37 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 zoff99 8 }
287 zoff99 37
288     return ret;
289 zoff99 8 }
290    
291 zoff99 37
292     GList *
293     boundary_find_matches_single(GList *l, struct coord *c)
294 zoff99 8 {
295 zoff99 37 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 zoff99 8 strcpy(newprefix, prefix);
322 zoff99 37 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 zoff99 8 dump_hierarchy(boundary->children, newprefix);
328 zoff99 37 l = g_list_next(l);
329 zoff99 8 }
330     }
331    
332 zoff99 37 static gint boundary_bbox_compare(gconstpointer a, gconstpointer b)
333 zoff99 8 {
334 zoff99 37 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 zoff99 8 if (areaa > areab)
339     return 1;
340     if (areaa < areab)
341     return -1;
342     return 0;
343     }
344    
345 zoff99 36 static GList *
346     process_boundaries_insert(GList *list, struct boundary *boundary)
347 zoff99 8 {
348 zoff99 37 // 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 zoff99 36 return list;
364 zoff99 37 }
365     else
366     {
367     l = g_list_next(l);
368     }
369 zoff99 36 }
370 zoff99 37 */
371     // children stuff is totally broken, so it is disabled now!!
372    
373 zoff99 36 return g_list_prepend(list, boundary);
374     }
375 zoff99 8
376 zoff99 36 static GList *
377     process_boundaries_finish(GList *boundaries_list)
378     {
379 zoff99 37 //fprintf(stderr,"process_boundaries_finish:001\n");
380    
381 zoff99 57 GList *l = NULL, *sl = NULL, *l2 = NULL, *ln = NULL;
382 zoff99 37 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 zoff99 36 while (l)
391     {
392 zoff99 37 struct boundary *boundary = l->data;
393     int first = 1;
394     FILE *f = NULL, *fu = NULL;
395 zoff99 36
396 zoff99 37 b_counter_1++;
397     if ((b_counter_1 % 500) == 0)
398     {
399 zoff99 57 fprintf_(stderr,"boundaries_f1:B:%lld\n", b_counter_1);
400 zoff99 37 }
401    
402     //fprintf(stderr,"process_boundaries_finish:002\n");
403    
404 zoff99 57 // only uppercase country code
405 zoff99 36 if (boundary->iso2)
406     {
407     int i99;
408     for (i99 = 0; boundary->iso2[i99]; i99++)
409     {
410 zoff99 57 boundary->iso2[i99] = toupper(boundary->iso2[i99]);
411 zoff99 36 }
412     }
413 zoff99 57 // only uppercase country code
414 zoff99 36
415 zoff99 37 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 zoff99 36 g_free(name);
423     }
424 zoff99 37
425    
426    
427     // calc bounding box
428     first = 1;
429     nodes_counter_ = 0;
430     ways_counter_ = 0;
431     sl = boundary->segments;
432 zoff99 36 while (sl)
433     {
434 zoff99 37 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 zoff99 8 bbox_extend(c, &boundary->r);
447 zoff99 37 }
448 zoff99 8 c++;
449 zoff99 37 nodes_counter_++;
450 zoff99 8 }
451 zoff99 37 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 zoff99 36 item_bin_init(ib, type_selected_line);
493 zoff99 37 item_bin_add_coord(ib, gs->first, gs->last - gs->first + 1);
494 zoff99 36 item_bin_write(ib, f);
495     }
496 zoff99 37
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 zoff99 57 fprintf(stderr, "*BROKEN*(1) country_%s_broken relid=%lld\n", boundary->iso2, item_bin_get_relationid(boundary->ib));
506 zoff99 37 fu = tempfile("", name, 1);
507 zoff99 36 g_free(name);
508     }
509 zoff99 37 struct item_bin *ib = item_bin_2;
510 zoff99 36 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 zoff99 37 sl = g_list_next(sl);
520 zoff99 36
521     if (f2_name)
522     {
523 zoff99 37 tempfile_unlink("", f2_name);
524 zoff99 36 g_free(f2_name);
525 zoff99 37 f2_name = NULL;
526 zoff99 36 }
527 zoff99 37 }
528    
529     ret = process_boundaries_insert(ret, boundary);
530     l = g_list_next(l);
531    
532     if (f)
533     {
534 zoff99 36 fclose(f);
535 zoff99 37 }
536    
537     if (fu)
538     {
539 zoff99 36 if (boundary->country)
540 zoff99 37 {
541     //osm_warning("relation", item_bin_get_relationid(boundary->ib), 0, "Broken country polygon '%s'\n", boundary->iso2);
542 zoff99 57 fprintf_(stderr, "*BROKEN*(2) country polygon '%s' relid=%lld\n", boundary->iso2, item_bin_get_relationid(boundary->ib));
543 zoff99 37 }
544 zoff99 36 fclose(fu);
545     }
546    
547     if (f1_name)
548     {
549 zoff99 37 tempfile_unlink("", f1_name);
550 zoff99 36 g_free(f1_name);
551 zoff99 37 f1_name = NULL;
552 zoff99 36 }
553 zoff99 8 }
554 zoff99 36 #if 0
555 zoff99 8 printf("hierarchy\n");
556 zoff99 36 #endif
557 zoff99 37
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 zoff99 36 #if 0
562 zoff99 37 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 zoff99 8 break;
582     }
583 zoff99 37 l2 = g_list_next(l2);
584 zoff99 8 }
585 zoff99 37 l = ln;
586 zoff99 8 }
587 zoff99 36 #endif
588 zoff99 37 // 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 zoff99 36 return boundaries_list;
599 zoff99 8 }
600 zoff99 36
601 zoff99 57
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 zoff99 36 GList *
643 zoff99 37 process_boundaries(FILE *boundaries, FILE *coords, FILE *ways)
644 zoff99 36 {
645 zoff99 57 GList *boundaries_list = NULL;
646 zoff99 37 struct relations *relations = relations_new();
647 zoff99 36
648 zoff99 37 //fprintf(stderr,"process_boundaries:001\n");
649     boundaries_list = process_boundaries_setup(boundaries, relations);
650     //fprintf(stderr,"process_boundaries:001.rp1\n");
651 zoff99 36 relations_process(relations, NULL, ways, NULL);
652 zoff99 37 //fprintf(stderr,"process_boundaries:001.rp2\n");
653 zoff99 57 relations_destroy(relations);
654 zoff99 36 return process_boundaries_finish(boundaries_list);
655     }
656    
657 zoff99 57 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