diff options
-rw-r--r-- | navit/maptool/boundaries.c | 54 | ||||
-rw-r--r-- | navit/maptool/maptool.c | 20 | ||||
-rw-r--r-- | navit/maptool/maptool.h | 22 | ||||
-rw-r--r-- | navit/maptool/osm.c | 147 |
4 files changed, 190 insertions, 53 deletions
diff --git a/navit/maptool/boundaries.c b/navit/maptool/boundaries.c index e83fb4ea9..54f1b0e94 100644 --- a/navit/maptool/boundaries.c +++ b/navit/maptool/boundaries.c @@ -20,13 +20,6 @@ #include <string.h> #include "maptool.h" -struct boundary { - struct item_bin *ib; - GList *segments,*sorted_segments; - GList *children; - struct rect r; -}; - struct boundary_member { long long wayid; enum geom_poly_segment_type role; @@ -51,16 +44,23 @@ boundary_member_equal(gconstpointer a, gconstpointer b) GHashTable *member_hash; static char * -osm_tag_name(struct item_bin *ib) +osm_tag_value(struct item_bin *ib, char *key) { char *tag=NULL; + int len=strlen(key); while ((tag=item_bin_get_attr(ib, attr_osm_tag, tag))) { - if (!strncmp(tag,"name=",5)) - return tag+5; + if (!strncmp(tag,key,len) && tag[len] == '=') + return tag+len+1; } return NULL; } +static char * +osm_tag_name(struct item_bin *ib) +{ + return osm_tag_value(ib, "name"); +} + static GList * build_boundaries(FILE *boundaries) { @@ -70,6 +70,17 @@ build_boundaries(FILE *boundaries) while ((ib=read_item(boundaries))) { char *member=NULL; struct boundary *boundary=g_new0(struct boundary, 1); + char *admin_level=osm_tag_value(ib, "admin_level"); + char *iso=osm_tag_value(ib, "ISO3166-1"); + if (admin_level && !strcmp(admin_level, "2")) { + if (iso) { + struct country_table *country=country_from_iso2(iso); + if (!country) + osm_warning("relation",item_bin_get_relationid(ib),0,"Country Boundary contains unknown ISO3166-1 value '%s'\n",iso); + boundary->country=country; + } else + osm_warning("relation",item_bin_get_relationid(ib),0,"Country Boundary doesn't contain an ISO3166-1 tag\n"); + } while ((member=item_bin_get_attr(ib, attr_osm_member, member))) { long long wayid; int read=0; @@ -98,19 +109,20 @@ build_boundaries(FILE *boundaries) return boundaries_list; } -static void -find_matches(GList *l, struct coord *c) +GList * +boundary_find_matches(GList *l, struct coord *c) { + GList *ret=NULL; while (l) { struct boundary *boundary=l->data; if (bbox_contains_coord(&boundary->r, c)) { - struct item_bin *ib=boundary->ib; if (geom_poly_segments_point_inside(boundary->sorted_segments,c)) - printf("%s,",osm_tag_name(ib)); - find_matches(boundary->children, c); + ret=g_list_prepend(ret, boundary); + ret=g_list_concat(ret,boundary_find_matches(boundary->children, c)); } l=g_list_next(l); } + return ret; } static void @@ -123,7 +135,7 @@ test(GList *boundaries_list) struct coord *c=(struct coord *)(ib+1); char *name=item_bin_get_attr(ib, attr_town_name, NULL); printf("%s:",name); - find_matches(boundaries_list, c); + boundary_find_matches(boundaries_list, c); printf("\n"); } fclose(f); @@ -158,7 +170,7 @@ boundary_bbox_compare(gconstpointer a, gconstpointer b) return 0; } -int +GList * process_boundaries(FILE *boundaries, FILE *ways) { struct item_bin *ib; @@ -201,7 +213,9 @@ process_boundaries(FILE *boundaries, FILE *ways) l=g_list_next(l); } +#if 0 printf("hierarchy\n"); +#endif boundaries_list=g_list_sort(boundaries_list, boundary_bbox_compare); l=boundaries_list; while (l) { @@ -212,16 +226,20 @@ process_boundaries(FILE *boundaries, FILE *ways) if (bbox_contains_bbox(&boundary2->r, &boundary->r)) { boundaries_list=g_list_remove(boundaries_list, boundary); boundary2->children=g_list_append(boundary2->children, boundary); +#if 0 printf("found\n"); +#endif break; } l2=g_list_next(l2); } l=ln; } +#if 0 printf("hierarchy done\n"); dump_hierarchy(boundaries_list,""); printf("test\n"); test(boundaries_list); - return 1; +#endif + return boundaries_list; } diff --git a/navit/maptool/maptool.c b/navit/maptool/maptool.c index 859334b21..622d78ce9 100644 --- a/navit/maptool/maptool.c +++ b/navit/maptool/maptool.c @@ -53,6 +53,7 @@ int slices; int unknown_country; int doway2poi=1; char ch_suffix[] ="r"; /* Used to make compiler happy due to Bug 35903 in gcc */ +int experimental; struct buffer node_buffer = { 64*1024*1024, @@ -124,6 +125,7 @@ usage(FILE *f) fprintf(f,"-d (--db) <conn. string> : get osm data out of a postgresql database with osm simple scheme and given connect string\n"); #endif fprintf(f,"-e (--end) <phase> : end at specified phase\n"); + fprintf(f,"-E (--experimental) : Enable experimental features\n"); fprintf(f,"-i (--input-file) <file> : specify the input file name (OSM), overrules default stdin\n"); fprintf(f,"-k (--keep-tmpfiles) : do not delete tmp files after processing. useful to reuse them\n\n"); fprintf(f,"-M (--o5m) : input file os o5m\n"); @@ -200,6 +202,7 @@ parse_option(struct maptool_params *p, char **argv, int argc, int *option_index) {"dump", 0, 0, 'D'}, {"dump-coordinates", 0, 0, 'c'}, {"end", 1, 0, 'e'}, + {"experimental", 0, 0, 'E'}, {"help", 0, 0, 'h'}, {"keep-tmpfiles", 0, 0, 'k'}, {"nodes-only", 0, 0, 'N'}, @@ -218,7 +221,7 @@ parse_option(struct maptool_params *p, char **argv, int argc, int *option_index) {"unknown-country", 0, 0, 'U'}, {0, 0, 0, 0} }; - c = getopt_long (argc, argv, "5:6B:DMNO:PS:Wa:bc" + c = getopt_long (argc, argv, "5:6B:DEMNO:PS:Wa:bc" #ifdef HAVE_POSTGRESQL "d:" #endif @@ -238,6 +241,9 @@ parse_option(struct maptool_params *p, char **argv, int argc, int *option_index) case 'D': p->output=1; break; + case 'E': + experimental=1; + break; case 'M': p->o5m=1; break; @@ -810,9 +816,17 @@ int main(int argc, char **argv) } phase++; if (p.start <= phase && p.end >= phase) { - FILE *towns=tempfile(suffix,"towns",0); + FILE *towns=tempfile(suffix,"towns",0),*boundaries=NULL,*ways=NULL; + if (experimental) { + boundaries=tempfile(suffix,"boundaries",0); + ways=tempfile(suffix,"ways_split",0); + } fprintf(stderr,"PROGRESS: Phase %d: assinging towns to countries\n",phase); - osm_process_towns(towns); + osm_process_towns(towns,boundaries,ways); + if (experimental) { + fclose(ways); + fclose(boundaries); + } fclose(towns); if(!p.keep_tmpfiles) tempfile_unlink(suffix,"towns"); diff --git a/navit/maptool/maptool.h b/navit/maptool/maptool.h index 0886dde03..a487b4333 100644 --- a/navit/maptool/maptool.h +++ b/navit/maptool/maptool.h @@ -102,9 +102,21 @@ struct item_bin_sink { struct zip_info; +struct country_table; + /* boundaries.c */ -int process_boundaries(FILE *boundaries, FILE *ways); +struct boundary { + struct item_bin *ib; + struct country_table *country; + GList *segments,*sorted_segments; + GList *children; + struct rect r; +}; + +GList *process_boundaries(FILE *boundaries, FILE *ways); + +GList *boundary_find_matches(GList *bl, struct coord *c); /* buffer.c */ struct buffer { @@ -211,6 +223,7 @@ extern struct item_bin *item_bin; extern int bytes_read; extern int overlap; extern int unknown_country; +extern int experimental; void sig_alrm(int sig); void sig_alrm_end(void); @@ -245,6 +258,7 @@ struct maptool_osm { FILE *towns; }; +void osm_warning(char *type, long long id, int cont, char *fmt, ...); void osm_add_tag(char *k, char *v); void osm_add_node(osmid id, double lat, double lon); void osm_add_way(osmid id); @@ -261,13 +275,17 @@ void process_turn_restrictions(FILE *in, FILE *coords, FILE *ways, FILE *ways_in void clear_node_item_buffer(void); void ref_ways(FILE *in); void resolve_ways(FILE *in, FILE *out); +long long item_bin_get_nodeid(struct item_bin *ib); +long long item_bin_get_wayid(struct item_bin *ib); +long long item_bin_get_relationid(struct item_bin *ib); FILE *resolve_ways_file(FILE *in, char *suffix, char *filename); void process_way2poi(FILE *in, FILE *out, int type); int map_find_intersections(FILE *in, FILE *out, FILE *out_index, FILE *out_graph, FILE *out_coastline, int final); void write_countrydir(struct zip_info *zip_info); -void osm_process_towns(FILE *in); +void osm_process_towns(FILE *in, FILE *boundaries, FILE *ways); void load_countries(void); void remove_countryfiles(void); +struct country_table * country_from_iso2(char *iso); void osm_init(FILE*); /* osm_o5m.c */ diff --git a/navit/maptool/osm.c b/navit/maptool/osm.c index 7d11df0f9..045342e26 100644 --- a/navit/maptool/osm.c +++ b/navit/maptool/osm.c @@ -23,6 +23,7 @@ #include "maptool.h" #include "debug.h" #include "linguistics.h" +#include "country.h" #include "file.h" extern int doway2poi; @@ -822,7 +823,8 @@ build_countrytable(void) } } } -static void + +void osm_warning(char *type, long long id, int cont, char *fmt, ...) { char str[4096]; @@ -848,7 +850,7 @@ attr_strings_save(enum attr_strings id, char *str) attr_strings_buffer_len+=strlen(str)+1; } -static long long +long long item_bin_get_nodeid(struct item_bin *ib) { long long *ret=item_bin_get_attr(ib, attr_osm_nodeid, NULL); @@ -857,7 +859,7 @@ item_bin_get_nodeid(struct item_bin *ib) return 0; } -static long long +long long item_bin_get_wayid(struct item_bin *ib) { long long *ret=item_bin_get_attr(ib, attr_osm_wayid, NULL); @@ -866,7 +868,7 @@ item_bin_get_wayid(struct item_bin *ib) return 0; } -static long long +long long item_bin_get_relationid(struct item_bin *ib) { long long *ret=item_bin_get_attr(ib, attr_osm_relationid, NULL); @@ -1436,6 +1438,43 @@ osm_add_relation(osmid id) item_bin_add_attr_longlong(item_bin, attr_osm_relationid, current_id); } +static int +country_id_from_iso2(char *iso) +{ + int ret=0; + if (iso) { + struct country_search *search; + struct attr country_iso2,country_id; + struct item *item; + country_iso2.type=attr_country_iso2; + country_iso2.u.str=iso; + search=country_search_new(&country_iso2,0); + if ((item=country_search_get_item(search)) && item_attr_get(item, attr_country_id, &country_id)) + ret=country_id.u.num; + + country_search_destroy(search); + } + return ret; +} + +static struct country_table * +country_from_countryid(int id) +{ + int i; + for (i = 0 ; i < sizeof(country_table)/sizeof(struct country_table) ; i++) { + if (country_table[i].countryid == id) + return &country_table[i]; + } + return NULL; +} + +struct country_table * +country_from_iso2(char *iso) +{ + return country_from_countryid(country_id_from_iso2(iso)); +} + + void osm_end_relation(struct maptool_osm *osm) { @@ -1500,13 +1539,13 @@ relation_add_tag(char *k, char *v) } else if (!strcmp(k,"ISO3166-1")) { strcpy(iso_code, v); } -#if 0 - if (add_tag) { - char tag[strlen(k)+strlen(v)+2]; - sprintf(tag,"%s=%s",k,v); - item_bin_add_attr_string(item_bin, attr_osm_tag, tag); + if (experimental) { + if (add_tag) { + char tag[strlen(k)+strlen(v)+2]; + sprintf(tag,"%s=%s",k,v); + item_bin_add_attr_string(item_bin, attr_osm_tag, tag); + } } -#endif } @@ -1685,30 +1724,77 @@ osm_end_node(struct maptool_osm *osm) attr_longest_match_clear(); } +static struct country_table * +osm_process_town_unknown_country(void) +{ + static struct country_table *unknown; + if (!unknown) + unknown=country_from_countryid(999); + + return unknown; +} + +static struct country_table * +osm_process_town_by_is_in(char *is_in) +{ + struct country_table *result=NULL, *lookup; + char *tok,*dup=g_strdup(is_in),*buf=dup; + int conflict; + + while ((tok=strtok(buf, ",;"))) { + while (*tok==' ') + tok++; + lookup=g_hash_table_lookup(country_table_hash,tok); + if (lookup) { + if (result && result->countryid != lookup->countryid) { + osm_warning("node",nodeid,0,"conflict for %s %s country %d vs %d\n", attr_strings[attr_string_label], debug_attr_buffer, lookup->countryid, result->countryid); + conflict=1; + } + result=lookup; + } + buf=NULL; + } + g_free(dup); + return result; +} + +static struct country_table * +osm_process_town_by_boundary(GList *bl, struct coord *c) +{ + GList *l,*matches=boundary_find_matches(bl, c); + struct country_table *match=NULL; + + l=matches; + while (l) { + struct boundary *b=l->data; + if (b->country) { + if (match) + printf("conflict %d vs %d\n",b->country->countryid,match->countryid); + match=b->country; + } + l=g_list_next(l); + } + return match; +} + void -osm_process_towns(FILE *in) +osm_process_towns(FILE *in, FILE *boundaries, FILE *ways) { struct item_bin *ib; + GList *bl=NULL; + if (experimental) + bl=process_boundaries(boundaries, ways); while ((ib=read_item(in))) { - struct country_table *result=NULL, *lookup; - char *tok,*is_in=item_bin_get_attr(ib, attr_osm_is_in, NULL), *buf=g_strdup(is_in); - int conflict; - if (!buf && unknown_country) - buf=g_strdup("Unknown"); - while ((tok=strtok(buf, ",;"))) { - while (*tok==' ') - tok++; - lookup=g_hash_table_lookup(country_table_hash,tok); - if (lookup) { - if (result && result->countryid != lookup->countryid) { - osm_warning("node",nodeid,0,"conflict for %s %s country %d vs %d\n", attr_strings[attr_string_label], debug_attr_buffer, lookup->countryid, result->countryid); - conflict=1; - } - result=lookup; - } - buf=NULL; - } + struct coord *c=(struct coord *)(ib+1); + struct country_table *result=NULL; + char *is_in=item_bin_get_attr(ib, attr_osm_is_in, NULL); + if (experimental) + result=osm_process_town_by_boundary(bl, c); + if (!result) + result=osm_process_town_by_is_in(is_in); + if (!result && unknown_country) + result=osm_process_town_unknown_country(); if (result) { if (!result->file) { char *name=g_strdup_printf("country_%d.unsorted.tmp", result->countryid); @@ -1721,7 +1807,6 @@ osm_process_towns(FILE *in) item_bin_write_match(ib, attr_town_name, attr_town_name_match, result->file); } } - g_free(buf); } } @@ -2006,6 +2091,7 @@ process_turn_restrictions(FILE *in, FILE *coords, FILE *ways, FILE *ways_index, } } +#if 0 static void process_countries(FILE *way, FILE *ways_index) { @@ -2056,6 +2142,7 @@ process_countries(FILE *way, FILE *ways_index) fclose(tmp); fclose(in); } +#endif static void node_ref_way(osmid node) |