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

Diff of /navit/navit/maptool/boundaries.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 56 Revision 57
1/** 1/**
2 * ZANavi, Zoff Android Navigation system. 2 * ZANavi, Zoff Android Navigation system.
3 * Copyright (C) 2011-2012 Zoff <zoff@zoff.cc> 3 * Copyright (C) 2011-2013 Zoff <zoff@zoff.cc>
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License 6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation. 7 * version 2 as published by the Free Software Foundation.
8 * 8 *
36 * Boston, MA 02110-1301, USA. 36 * Boston, MA 02110-1301, USA.
37 */ 37 */
38#include <stdio.h> 38#include <stdio.h>
39#include <string.h> 39#include <string.h>
40#include <ctype.h> 40#include <ctype.h>
41#include <dirent.h>
42
43#include <locale.h>
44#include <stdlib.h>
45
41#include "maptool.h" 46#include "maptool.h"
42 47
43char * 48char *
44osm_tag_value(struct item_bin *ib, char *key) 49osm_tag_value(struct item_bin *ib, char *key)
45{ 50{
125 char *iso = osm_tag_value(ib, "ISO3166-1"); 130 char *iso = osm_tag_value(ib, "ISO3166-1");
126 131
127 b_counter_1++; 132 b_counter_1++;
128 if ((b_counter_1 % 500) == 0) 133 if ((b_counter_1 % 500) == 0)
129 { 134 {
130 fprintf(stderr,"boundaries:B:%lld\n", b_counter_1); 135 fprintf_(stderr,"boundaries:B:%lld\n", b_counter_1);
131 } 136 }
132 137
133 //fprintf(stderr,"process_boundaries_setup:002\n"); 138 //fprintf(stderr,"process_boundaries_setup:002\n");
134 //fprintf(stderr,"== b:%s %s ==\n", iso, admin_level); 139 //fprintf(stderr,"== b:%s %s ==\n", iso, admin_level);
135 140
136 /* disable spain for now since it creates a too large index */ 141 /* disable spain for now since it creates a too large index */
137 if (admin_level && !strcmp(admin_level, "2") && (!iso || strcasecmp(iso, "es"))) 142 // if (admin_level && !strcmp(admin_level, "2") && (!iso || strcasecmp(iso, "es")))
143 if (admin_level && !strcmp(admin_level, "2"))
138 { 144 {
139 if (iso) 145 if (iso)
140 { 146 {
141 struct country_table *country = country_from_iso2(iso); 147 struct country_table *country = country_from_iso2(iso);
142 if (!country) 148 if (!country)
172 if (sscanf(member, "2:%Ld:%n", &wayid, &read) >= 1) 178 if (sscanf(member, "2:%Ld:%n", &wayid, &read) >= 1)
173 { 179 {
174 char *rolestr = member + read; 180 char *rolestr = member + read;
175 enum geom_poly_segment_type role; 181 enum geom_poly_segment_type role;
176 if (!strcmp(rolestr, "outer") || !strcmp(rolestr, "exclave")) 182 if (!strcmp(rolestr, "outer") || !strcmp(rolestr, "exclave"))
183 {
177 role = geom_poly_segment_type_way_outer; 184 role = geom_poly_segment_type_way_outer;
185 }
178 else if (!strcmp(rolestr, "inner") || !strcmp(rolestr, "enclave")) 186 else if (!strcmp(rolestr, "inner") || !strcmp(rolestr, "enclave"))
187 {
179 role = geom_poly_segment_type_way_inner; 188 role = geom_poly_segment_type_way_inner;
189 }
180 else if (!strcmp(rolestr, "")) 190 else if (!strcmp(rolestr, ""))
191 {
181 role = geom_poly_segment_type_way_unknown; 192 role = geom_poly_segment_type_way_unknown;
193 }
182 else 194 else
183 { 195 {
184 osm_warning("relation", item_bin_get_relationid(ib), 0, "Unknown role %s in member ", rolestr); 196 osm_warning("relation", item_bin_get_relationid(ib), 0, "Unknown role %s in member ", rolestr);
185 osm_warning("way", wayid, 1, "\n"); 197 osm_warning("way", wayid, 1, "\n");
186 role = geom_poly_segment_type_none; 198 role = geom_poly_segment_type_none;
364static GList * 376static GList *
365process_boundaries_finish(GList *boundaries_list) 377process_boundaries_finish(GList *boundaries_list)
366{ 378{
367 //fprintf(stderr,"process_boundaries_finish:001\n"); 379 //fprintf(stderr,"process_boundaries_finish:001\n");
368 380
369 GList *l, *sl, *l2, *ln; 381 GList *l = NULL, *sl = NULL, *l2 = NULL, *ln = NULL;
370 GList *ret = NULL; 382 GList *ret = NULL;
371 l = boundaries_list; 383 l = boundaries_list;
372 char *f1_name = NULL; 384 char *f1_name = NULL;
373 char *f2_name = NULL; 385 char *f2_name = NULL;
374 long long b_counter_1 = 0; 386 long long b_counter_1 = 0;
382 FILE *f = NULL, *fu = NULL; 394 FILE *f = NULL, *fu = NULL;
383 395
384 b_counter_1++; 396 b_counter_1++;
385 if ((b_counter_1 % 500) == 0) 397 if ((b_counter_1 % 500) == 0)
386 { 398 {
387 fprintf(stderr,"boundaries_f1:B:%lld\n", b_counter_1); 399 fprintf_(stderr,"boundaries_f1:B:%lld\n", b_counter_1);
388 } 400 }
389 401
390 //fprintf(stderr,"process_boundaries_finish:002\n"); 402 //fprintf(stderr,"process_boundaries_finish:002\n");
391 403
392 // only lowercase country code 404 // only uppercase country code
393 if (boundary->iso2) 405 if (boundary->iso2)
394 { 406 {
395 int i99; 407 int i99;
396 for (i99 = 0; boundary->iso2[i99]; i99++) 408 for (i99 = 0; boundary->iso2[i99]; i99++)
397 { 409 {
398 boundary->iso2[i99] = tolower(boundary->iso2[i99]); 410 boundary->iso2[i99] = toupper(boundary->iso2[i99]);
399 }
400 } 411 }
412 }
401 // only lowercase country code 413 // only uppercase country code
402 414
403 if (boundary->country) 415 if (boundary->country)
404 { 416 {
405 //fprintf(stderr,"process_boundaries_finish:003\n"); 417 //fprintf(stderr,"process_boundaries_finish:003\n");
406 418
488 { 500 {
489 if (!fu) 501 if (!fu)
490 { 502 {
491 char *name = g_strdup_printf("country_%s_broken", boundary->iso2); 503 char *name = g_strdup_printf("country_%s_broken", boundary->iso2);
492 f2_name = g_strdup_printf("country_%s_broken", boundary->iso2); 504 f2_name = g_strdup_printf("country_%s_broken", boundary->iso2);
493 fprintf(stderr, "*BROKEN* country_%s_broken\n", boundary->iso2); 505 fprintf(stderr, "*BROKEN*(1) country_%s_broken relid=%lld\n", boundary->iso2, item_bin_get_relationid(boundary->ib));
494 fu = tempfile("", name, 1); 506 fu = tempfile("", name, 1);
495 g_free(name); 507 g_free(name);
496 } 508 }
497 struct item_bin *ib = item_bin_2; 509 struct item_bin *ib = item_bin_2;
498 item_bin_init(ib, type_selected_point); 510 item_bin_init(ib, type_selected_point);
525 if (fu) 537 if (fu)
526 { 538 {
527 if (boundary->country) 539 if (boundary->country)
528 { 540 {
529 //osm_warning("relation", item_bin_get_relationid(boundary->ib), 0, "Broken country polygon '%s'\n", boundary->iso2); 541 //osm_warning("relation", item_bin_get_relationid(boundary->ib), 0, "Broken country polygon '%s'\n", boundary->iso2);
530 fprintf(stderr, "*BROKEN* country polygon '%s' relid=%lld\n", boundary->iso2, item_bin_get_relationid(boundary->ib)); 542 fprintf_(stderr, "*BROKEN*(2) country polygon '%s' relid=%lld\n", boundary->iso2, item_bin_get_relationid(boundary->ib));
531 } 543 }
532 fclose(fu); 544 fclose(fu);
533 } 545 }
534 546
535 if (f1_name) 547 if (f1_name)
584 // -- DEBUG -- 596 // -- DEBUG --
585 597
586 return boundaries_list; 598 return boundaries_list;
587} 599}
588 600
601
602void 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
589GList * 642GList *
590process_boundaries(FILE *boundaries, FILE *coords, FILE *ways) 643process_boundaries(FILE *boundaries, FILE *coords, FILE *ways)
591{ 644{
592 GList *boundaries_list; 645 GList *boundaries_list = NULL;
593 struct relations *relations = relations_new(); 646 struct relations *relations = relations_new();
594 647
595 //fprintf(stderr,"process_boundaries:001\n"); 648 //fprintf(stderr,"process_boundaries:001\n");
596 boundaries_list = process_boundaries_setup(boundaries, relations); 649 boundaries_list = process_boundaries_setup(boundaries, relations);
597 //fprintf(stderr,"process_boundaries:001.rp1\n"); 650 //fprintf(stderr,"process_boundaries:001.rp1\n");
598 relations_process(relations, NULL, ways, NULL); 651 relations_process(relations, NULL, ways, NULL);
599 //fprintf(stderr,"process_boundaries:001.rp2\n"); 652 //fprintf(stderr,"process_boundaries:001.rp2\n");
653 relations_destroy(relations);
600 return process_boundaries_finish(boundaries_list); 654 return process_boundaries_finish(boundaries_list);
601} 655}
602 656
657static 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
705void 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
874GList* 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

Legend:
Removed from v.56  
changed lines
  Added in v.57

   
Visit the ZANavi Wiki