summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormdankov <mdankov@ffa7fe5e-494d-0410-b361-a75ebd5db220>2013-05-10 15:10:18 +0000
committermdankov <mdankov@ffa7fe5e-494d-0410-b361-a75ebd5db220>2013-05-10 15:10:18 +0000
commitd33634c7a256ae17e486d834137bbb865d2e7511 (patch)
treec3d184eae2751505ab3f3ac902c9fd697089d93e
parenta5d44df590f5335364274c58f50f8fde289d3571 (diff)
downloadnavit-d33634c7a256ae17e486d834137bbb865d2e7511.tar.gz
Add:maptool:Support associatedStreet relations in maps built with "experimental" option.
git-svn-id: https://navit.svn.sourceforge.net/svnroot/navit/trunk@5491 ffa7fe5e-494d-0410-b361-a75ebd5db220
-rw-r--r--navit/navit/maptool/maptool.c33
-rw-r--r--navit/navit/maptool/maptool.h2
-rw-r--r--navit/navit/maptool/osm.c104
-rw-r--r--navit/navit/maptool/osm_relations.c49
4 files changed, 175 insertions, 13 deletions
diff --git a/navit/navit/maptool/maptool.c b/navit/navit/maptool/maptool.c
index 0a40e3b28..232660da2 100644
--- a/navit/navit/maptool/maptool.c
+++ b/navit/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/navit/maptool/maptool.h b/navit/navit/maptool/maptool.h
index a65db39ba..fda04c8e7 100644
--- a/navit/navit/maptool/maptool.h
+++ b/navit/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/navit/maptool/osm.c b/navit/navit/maptool/osm.c
index efb5e70e9..1c07f9a73 100644
--- a/navit/navit/maptool/osm.c
+++ b/navit/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/navit/maptool/osm_relations.c b/navit/navit/maptool/osm_relations.c
index b14165bf6..909367e1f 100644
--- a/navit/navit/maptool/osm_relations.c
+++ b/navit/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);
}
}
}