diff options
author | Wildemann Stefan <stefan.wildemann@corpuls.com> | 2019-09-05 12:56:16 +0200 |
---|---|---|
committer | Stefan Wildemann <wildemann@CORPLIN1008.corpuls.local> | 2019-10-02 16:54:29 +0200 |
commit | e7d09bcc41d5d51fee186dff30627f86f9c4fd0d (patch) | |
tree | 0be9f9604632121ccc606093eaaadf953c2fc3bf | |
parent | 02e1d583204ec27f1fd4f6b08e24be87060d8194 (diff) | |
download | navit-e7d09bcc41d5d51fee186dff30627f86f9c4fd0d.tar.gz |
Avoid iterating input multiple times after thread processing
-rw-r--r-- | navit/maptool/maptool.h | 1 | ||||
-rw-r--r-- | navit/maptool/osm.c | 15 | ||||
-rw-r--r-- | navit/maptool/osm_relations.c | 61 |
3 files changed, 71 insertions, 6 deletions
diff --git a/navit/maptool/maptool.h b/navit/maptool/maptool.h index f0aee6fdf..5a97c8186 100644 --- a/navit/maptool/maptool.h +++ b/navit/maptool/maptool.h @@ -345,6 +345,7 @@ void relations_add_relation_member_entry(struct relations *rel, struct relations void *member_priv, enum relation_member_type type, osmid id); void relations_add_relation_default_entry(struct relations *rel, struct relations_func *func); void relations_process(struct relations *rel, FILE *nodes, FILE *ways); +void relations_process_multi(struct relations **rel, int count, FILE *nodes, FILE *ways); void relations_destroy(struct relations *rel); diff --git a/navit/maptool/osm.c b/navit/maptool/osm.c index 61f8f15fa..97ae5d1cf 100644 --- a/navit/maptool/osm.c +++ b/navit/maptool/osm.c @@ -3261,6 +3261,8 @@ void process_multipolygons(FILE *in, FILE *coords, FILE *ways, FILE *ways_index, if(ways) fseek(ways, 0,SEEK_SET); fprintf(stderr,"process_multipolygons:process (thread %d)\n", i); + /* we could use relations_process_multi here as well, but this would + * use way more memory. */ relations_process(relations[i], coords, ways); fprintf(stderr,"process_multipolygons:finish (thread %d)\n", i); process_multipolygons_finish(multipolygons[i], out); @@ -3609,13 +3611,14 @@ void process_turn_restrictions(FILE *in, FILE *coords, FILE *ways, FILE *ways_in processed_relations=0; processed_ways=0; sig_alrm(0); + if(coords) + fseek(coords, 0,SEEK_SET); + if(ways) + fseek(ways, 0,SEEK_SET); + fprintf(stderr,"process_multipolygons:process (thread %d)\n", i); + relations_process_multi(relations, thread_count, coords, ways); for( i=0; i < thread_count; i ++) { - if(coords) - fseek(coords, 0,SEEK_SET); - if(ways) - fseek(ways, 0,SEEK_SET); - fprintf(stderr,"process_turn_restrictions:process (thread %d)\n", i); - relations_process(relations[i], coords, ways); + fprintf(stderr,"process_turn_restrictions:finish (thread %d)\n", i); process_turn_restrictions_finish(turn_restrictions[i], out); relations_destroy(relations[i]); diff --git a/navit/maptool/osm_relations.c b/navit/maptool/osm_relations.c index b3c3c01a8..3d05caab7 100644 --- a/navit/maptool/osm_relations.c +++ b/navit/maptool/osm_relations.c @@ -164,6 +164,67 @@ void relations_process(struct relations *rel, FILE *nodes, FILE *ways) { } } +/* + * @brief The actual relations processing: Loop through raw data and process any relations members. + * This function reads through all nodes and ways passed in, and looks up each item in the + * relations collection. For each relation member found, its processing function is called. + * @param in rel relations collection storing pre-processed relations. Built using relations_add_relation_member_entry. + * @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. + */ +void relations_process_multi(struct relations **rel, int count, FILE *nodes, FILE *ways) { + char buffer[128]; + struct item_bin *ib=(struct item_bin *)buffer; + osmid *id; + struct coord *c=(struct coord *)(ib+1),cn= {0,0}; + struct node_item *ni; + GList *l; + + if(count <= 0) + return; + + if (nodes) { + item_bin_init(ib, type_point_unkn); + item_bin_add_coord(ib, &cn, 1); + item_bin_add_attr_longlong(ib, attr_osm_nodeid, 0); + id=item_bin_get_attr(ib, attr_osm_nodeid, NULL); + while ((ni=read_node_item(nodes))) { + int i; + *id=ni->nd_id; + *c=ni->c; + for(i=0; i < count; i ++) { + l=g_hash_table_lookup(rel[i]->member_hash[0], 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); + } + } + } + } + if (ways) { + while ((ib=read_item(ways))) { + int i; + for(i=0; i < count; i ++) { + l=NULL; + if(NULL!=(id=item_bin_get_attr(ib, attr_osm_nodeid, NULL))) + l=g_hash_table_lookup(rel[i]->member_hash[0], id); + else if(NULL!=(id=item_bin_get_attr(ib, attr_osm_wayid, NULL))) + l=g_hash_table_lookup(rel[i]->member_hash[1], id); + else if(NULL!=(id=item_bin_get_attr(ib, attr_osm_relationid, NULL))) + l=g_hash_table_lookup(rel[i]->member_hash[2], id); + if(!l) + l=rel[i]->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); + } + } + } + } +} + static void relations_destroy_func(void *key, GList *l, void *data) { GList *ll=l; while (ll) { |