diff options
author | mdankov <mdankov@ffa7fe5e-494d-0410-b361-a75ebd5db220> | 2013-05-10 15:10:18 +0000 |
---|---|---|
committer | mdankov <mdankov@ffa7fe5e-494d-0410-b361-a75ebd5db220> | 2013-05-10 15:10:18 +0000 |
commit | c724caf6c1b2789803fdd2a5d1b1b9463d923aee (patch) | |
tree | f906c57304cfdef7f931bfdb1167fca99f24f6f2 /navit/maptool | |
parent | afc0742d0fdf0e5f3e7190d735f076d2418fa6a5 (diff) | |
download | navit-svn-c724caf6c1b2789803fdd2a5d1b1b9463d923aee.tar.gz |
Add:maptool:Support associatedStreet relations in maps built with "experimental" option.
git-svn-id: http://svn.code.sf.net/p/navit/code/trunk/navit@5491 ffa7fe5e-494d-0410-b361-a75ebd5db220
Diffstat (limited to 'navit/maptool')
-rw-r--r-- | navit/maptool/maptool.c | 33 | ||||
-rw-r--r-- | navit/maptool/maptool.h | 2 | ||||
-rw-r--r-- | navit/maptool/osm.c | 104 | ||||
-rw-r--r-- | navit/maptool/osm_relations.c | 49 |
4 files changed, 175 insertions, 13 deletions
diff --git a/navit/maptool/maptool.c b/navit/maptool/maptool.c index 0a40e3b2..232660da 100644 --- a/navit/maptool/maptool.c +++ b/navit/maptool/maptool.c @@ -437,8 +437,11 @@ osm_collect_data(struct maptool_params *p, char *suffix) p->osm.poly2poi=tempfile(suffix,"poly2poi",1); } } - if (p->process_relations) + if (p->process_relations) { p->osm.boundaries=tempfile(suffix,"boundaries",1); + if(experimental) + p->osm.associated_streets=tempfile(suffix,"associated_streets",1); + } #ifdef HAVE_POSTGRESQL if (p->dbstr) map_collect_data_osm_db(p->dbstr,&p->osm); @@ -476,6 +479,8 @@ osm_collect_data(struct maptool_params *p, char *suffix) fclose(p->osm.nodes); if (p->osm.turn_restrictions) fclose(p->osm.turn_restrictions); + if (p->osm.associated_streets) + fclose(p->osm.associated_streets); if (p->osm.boundaries) fclose(p->osm.boundaries); if (p->osm.poly2poi) @@ -833,7 +838,7 @@ int main(int argc, char **argv) exit(0); } } -#if 1 +#if 0 if (experimental) { fprintf(stderr,"No experimental features available\n"); exit(0); @@ -863,6 +868,30 @@ int main(int argc, char **argv) osm_collect_data(&p, suffix); p.node_table_loaded=1; } + if (experimental && p.process_relations && p.process_ways && p.process_nodes && start_phase(&p,"processing associated street relations")) { + FILE *ways_in=tempfile(suffix,"ways",0); + FILE *ways_out=tempfile(suffix,"ways_as",1); + FILE *nodes_in=tempfile(suffix,"nodes",0); + FILE *nodes_out=tempfile(suffix,"nodes_as",1); + + p.osm.associated_streets=tempfile(suffix,"associated_streets",0); + + process_associated_street(p.osm.associated_streets, ways_in, ways_out, nodes_in, nodes_out); + fclose(ways_in); + fclose(nodes_in); + fclose(ways_out); + fclose(nodes_out); + fclose(p.osm.associated_streets); + tempfile_rename(suffix,"ways","ways_pre_as"); + tempfile_rename(suffix,"nodes","nodes_pre_as"); + tempfile_rename(suffix,"ways_as","ways"); + tempfile_rename(suffix,"nodes_as","nodes"); + if(!p.keep_tmpfiles) { + tempfile_unlink(suffix,"ways_pre_as"); + tempfile_unlink(suffix,"nodes_pre_as"); + tempfile_unlink(suffix,"associated_streets"); + } + } if (start_phase(&p, "counting references and resolving ways")) { maptool_load_node_table(&p,1); osm_count_references(&p, suffix, p.start == phase); diff --git a/navit/maptool/maptool.h b/navit/maptool/maptool.h index a65db39b..fda04c8e 100644 --- a/navit/maptool/maptool.h +++ b/navit/maptool/maptool.h @@ -237,6 +237,7 @@ void cat(FILE *in, FILE *out); struct maptool_osm { FILE *boundaries; FILE *turn_restrictions; + FILE *associated_streets; FILE *nodes; FILE *ways; FILE *line2poi; @@ -258,6 +259,7 @@ void osm_add_nd(osmid ref); long long item_bin_get_id(struct item_bin *ib); void flush_nodes(int final); void sort_countries(int keep_tmpfiles); +void process_associated_street(FILE *in, FILE *ways_in, FILE *ways_out, FILE *nodes_in, FILE *nodes_out); void process_turn_restrictions(FILE *in, FILE *coords, FILE *ways, FILE *ways_index, FILE *out); void process_turn_restrictions_old(FILE *in, FILE *coords, FILE *ways, FILE *ways_index, FILE *out); void clear_node_item_buffer(void); diff --git a/navit/maptool/osm.c b/navit/maptool/osm.c index efb5e70e..1c07f9a7 100644 --- a/navit/maptool/osm.c +++ b/navit/maptool/osm.c @@ -1575,6 +1575,9 @@ osm_end_relation(struct maptool_osm *osm) if (!strcmp(relation_type, "restriction") && (item_bin->type == type_street_turn_restriction_no || item_bin->type == type_street_turn_restriction_only)) item_bin_write(item_bin, osm->turn_restrictions); + + if (experimental && !strcmp(relation_type, "associatedStreet") ) + item_bin_write(item_bin, osm->associated_streets); attr_longest_match_clear(); } @@ -2231,6 +2234,107 @@ get_way(FILE *way, FILE *ways_index, struct coord *c, long long wayid, struct it return NULL; } +struct associated_street { + osmid relid; + char *name; +}; + +static void +process_associated_street_member(void *func_priv, void *relation_priv, struct item_bin *member, void *member_priv) +{ + FILE *out=*(FILE **)func_priv; + struct associated_street *rel=relation_priv; + if(!out) { + /* Pass 1, fill associated street names in relation_priv */ + char *name; + if(!rel->name && item_is_street(*member) && (name=item_bin_get_attr(member,attr_street_name,NULL))!=NULL ) { + rel->name=g_strdup(name); + } + } else { + /* Pass 2, add associated street names to relation members which do not have street name attr defined but + have house number defined or are streets */ + if(rel->name && !item_bin_get_attr(member,attr_street_name,NULL) && (item_bin_get_attr(member,attr_house_number,NULL) || item_is_street(*member))) + item_bin_add_attr_string(member, attr_street_name, rel->name); + item_bin_write(member,out); + } +} + +static void +relation_func_writethrough(void *func_priv, void *relation_priv, struct item_bin *member, void *member_priv) +{ + FILE *out=*(FILE **)func_priv; + if(out) + item_bin_write(member,out); +} + + +static void +process_associated_street_setup(FILE *in, struct relations *relations, FILE **out) +{ + struct relation_member relm; + long long relid; + struct item_bin *ib; + struct relations_func *relations_func; + int min_count; + + fseek(in, 0, SEEK_SET); + relations_func=relations_func_new(process_associated_street_member, out); + while ((ib=read_item(in))) { + struct associated_street *rel=g_new0(struct associated_street, 1); + relid=item_bin_get_relationid(ib); + rel->relid=relid; + rel->name=g_strdup(osm_tag_value(ib, "name")); + dbg(0,"name=%s\n",rel->name); + min_count=0; + while(search_relation_member(ib, "street",&relm,&min_count)) { + if(relm.type==2) + relations_add_func(relations, relations_func, rel, NULL, relm.type, relm.id); + dbg(0,"street type=%d(should be 2) id=%lld\n",relm.type,relm.id); + + } + min_count=0; + while(search_relation_member(ib, "house",&relm,&min_count)) { + dbg(0,"house type=%d id=%lld\n",relm.type,relm.id); + relations_add_func(relations, relations_func, rel, NULL, relm.type, relm.id); + } + min_count=0; + while(search_relation_member(ib, "addr:houselink",&relm,&min_count)) { + dbg(0,"houselink type=%d id=%lld\n",relm.type,relm.id); + relations_add_func(relations, relations_func, rel, NULL, relm.type, relm.id); + } + min_count=0; + while(search_relation_member(ib, "address",&relm,&min_count)) { + dbg(0,"address type=%d id=%lld\n",relm.type,relm.id); + relations_add_func(relations, relations_func, rel, NULL, relm.type, relm.id); + } + } + relations_func=relations_func_new(relation_func_writethrough, out); + relations_add_func(relations, relations_func, NULL, NULL, -1, 0); +} + +void +process_associated_street(FILE *in, FILE *ways_in, FILE *ways_out, FILE *nodes_in, FILE *nodes_out) +{ + struct relations *relations=relations_new(); + FILE *out=NULL; + fseek(in, 0, SEEK_SET); + process_associated_street_setup(in, relations, &out); + + /* Set noname relations names from their street members */ + fseek(ways_in, 0, SEEK_SET); + relations_process(relations, NULL, ways_in, NULL); + + /* Set street names on all members */ + out=ways_out; + fseek(ways_in, 0, SEEK_SET); + relations_process(relations, NULL, ways_in, NULL); + + out=nodes_out; + fseek(nodes_in, 0, SEEK_SET); + relations_process(relations, NULL, nodes_in, NULL); +} + + struct turn_restriction { osmid relid; enum item_type type; diff --git a/navit/maptool/osm_relations.c b/navit/maptool/osm_relations.c index b14165bf..909367e1 100644 --- a/navit/maptool/osm_relations.c +++ b/navit/maptool/osm_relations.c @@ -23,6 +23,7 @@ struct relations { GHashTable *member_hash[3]; + GList *default_members; }; struct relations_func { @@ -54,7 +55,7 @@ relations_member_equal(gconstpointer a, gconstpointer b) struct relations * relations_new(void) { - struct relations *ret=g_new(struct relations, 1); + struct relations *ret=g_new0(struct relations, 1); int i; for (i = 0 ; i < 3 ; i++) @@ -71,19 +72,40 @@ relations_func_new(void (*func)(void *func_priv, void *relation_priv, struct ite return relations_func; } +/* + * @brief Add a relation member to relations collection. + * @param in rel relations collection to add the new member to. + * @param in funct structure defining function to call when this member is read + * @param in relation_priv parameter describing relation. Will be passed to funct function + * @param in member_priv parameter describing member function. Will be passed to funct function + * @param in type This member type: 1 - node, 2 - way, 3 - relation. + * Set to -1 to add a default member action which matches any item of any type which is not a member of any relation. + * @param in osmid This member id + * @param unused relations + */ void relations_add_func(struct relations *rel, struct relations_func *func, void *relation_priv, void *member_priv, int type, osmid id) { - GHashTable *member_hash=rel->member_hash[type-1]; struct relations_member *memb=g_new(struct relations_member, 1); - + memb->memberid=id; memb->relation_priv=relation_priv; memb->member_priv=member_priv; memb->func=func; - g_hash_table_insert(member_hash, memb, g_list_append(g_hash_table_lookup(member_hash, memb), memb)); + if(type>0) { + GHashTable *member_hash=rel->member_hash[type-1]; + g_hash_table_insert(member_hash, memb, g_list_append(g_hash_table_lookup(member_hash, memb), memb)); + } else + rel->default_members=g_list_append(rel->default_members, memb); } +/* + * @brief Process relations members from the file. + * @param in rel struct relations storing pre-processed relations info + * @param in nodes file containing nodes in "coords.tmp" format + * @param in ways file containing items in item_bin format. This file may contain both nodes, ways, and relations in that format. + * @param unused relations + */ void relations_process(struct relations *rel, FILE *nodes, FILE *ways, FILE *relations) { @@ -112,14 +134,19 @@ relations_process(struct relations *rel, FILE *nodes, FILE *ways, FILE *relation } if (ways) { while ((ib=read_item(ways))) { - id=item_bin_get_attr(ib, attr_osm_wayid, NULL); - if (id) { + l=NULL; + if(NULL!=(id=item_bin_get_attr(ib, attr_osm_nodeid, NULL))) + l=g_hash_table_lookup(rel->member_hash[0], id); + else if(NULL!=(id=item_bin_get_attr(ib, attr_osm_wayid, NULL))) l=g_hash_table_lookup(rel->member_hash[1], id); - while (l) { - struct relations_member *memb=l->data; - memb->func->func(memb->func->func_priv, memb->relation_priv, ib, memb->member_priv); - l=g_list_next(l); - } + else if(NULL!=(id=item_bin_get_attr(ib, attr_osm_relationid, NULL))) + l=g_hash_table_lookup(rel->member_hash[2], id); + if(!l) + l=rel->default_members; + while (l) { + struct relations_member *memb=l->data; + memb->func->func(memb->func->func_priv, memb->relation_priv, ib, memb->member_priv); + l=g_list_next(l); } } } |