summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--navit/maptool/boundaries.c93
-rw-r--r--navit/maptool/osm_relations.c40
2 files changed, 58 insertions, 75 deletions
diff --git a/navit/maptool/boundaries.c b/navit/maptool/boundaries.c
index 54f1b0e94..bc10cd59b 100644
--- a/navit/maptool/boundaries.c
+++ b/navit/maptool/boundaries.c
@@ -20,29 +20,6 @@
#include <string.h>
#include "maptool.h"
-struct boundary_member {
- long long wayid;
- enum geom_poly_segment_type role;
- struct boundary *boundary;
-};
-
-static guint
-boundary_member_hash(gconstpointer key)
-{
- const struct boundary_member *memb=key;
- return (memb->wayid >> 32)^(memb->wayid & 0xffffffff);
-}
-
-static gboolean
-boundary_member_equal(gconstpointer a, gconstpointer b)
-{
- const struct boundary_member *memba=a;
- const struct boundary_member *membb=b;
- return (memba->wayid == membb->wayid);
-}
-
-GHashTable *member_hash;
-
static char *
osm_tag_value(struct item_bin *ib, char *key)
{
@@ -61,12 +38,22 @@ osm_tag_name(struct item_bin *ib)
return osm_tag_value(ib, "name");
}
+static void
+process_boundaries_member(void *func_priv, void *relation_priv, struct item_bin *member, void *member_priv)
+{
+ struct boundary *b=relation_priv;
+ enum geom_poly_segment_type role=(long)member_priv;
+ b->segments=g_list_prepend(b->segments,item_bin_to_poly_segment(member, role));
+}
+
static GList *
-build_boundaries(FILE *boundaries)
+process_boundaries_setup(FILE *boundaries, struct relations *relations)
{
struct item_bin *ib;
GList *boundaries_list=NULL;
+ struct relations_func *relations_func;
+ relations_func=relations_func_new(process_boundaries_member, NULL);
while ((ib=read_item(boundaries))) {
char *member=NULL;
struct boundary *boundary=g_new0(struct boundary, 1);
@@ -85,22 +72,19 @@ build_boundaries(FILE *boundaries)
long long wayid;
int read=0;
if (sscanf(member,"2:%Ld:%n",&wayid,&read) >= 1) {
- struct boundary_member *memb=g_new(struct boundary_member, 1);
- char *role=member+read;
- memb->wayid=wayid;
- memb->boundary=boundary;
- if (!strcmp(role,"outer"))
- memb->role=geom_poly_segment_type_way_outer;
- else if (!strcmp(role,"inner"))
- memb->role=geom_poly_segment_type_way_inner;
- else if (!strcmp(role,""))
- memb->role=geom_poly_segment_type_way_unknown;
+ char *rolestr=member+read;
+ enum geom_poly_segment_type role;
+ if (!strcmp(rolestr,"outer"))
+ role=geom_poly_segment_type_way_outer;
+ else if (!strcmp(rolestr,"inner"))
+ role=geom_poly_segment_type_way_inner;
+ else if (!strcmp(rolestr,""))
+ role=geom_poly_segment_type_way_unknown;
else {
- printf("Unknown role %s\n",role);
- memb->role=geom_poly_segment_type_none;
+ printf("Unknown role %s\n",rolestr);
+ role=geom_poly_segment_type_none;
}
- g_hash_table_insert(member_hash, memb, g_list_append(g_hash_table_lookup(member_hash, memb), memb));
-
+ relations_add_func(relations, relations_func, boundary, (gpointer)role, 2, wayid);
}
}
boundary->ib=item_bin_dup(ib);
@@ -170,26 +154,10 @@ boundary_bbox_compare(gconstpointer a, gconstpointer b)
return 0;
}
-GList *
-process_boundaries(FILE *boundaries, FILE *ways)
+static GList *
+process_boundaries_finish(GList *boundaries_list)
{
- struct item_bin *ib;
- GList *boundaries_list,*l,*sl,*l2,*ln;
-
- member_hash=g_hash_table_new_full(boundary_member_hash, boundary_member_equal, NULL, NULL);
- boundaries_list=build_boundaries(boundaries);
- while ((ib=read_item(ways))) {
- long long *wayid=item_bin_get_attr(ib, attr_osm_wayid, NULL);
- if (wayid) {
- GList *l=g_hash_table_lookup(member_hash, wayid);
- while (l) {
- struct boundary_member *memb=l->data;
- memb->boundary->segments=g_list_prepend(memb->boundary->segments,item_bin_to_poly_segment(ib, memb->role));
-
- l=g_list_next(l);
- }
- }
- }
+ GList *l,*sl,*l2,*ln;
l=boundaries_list;
while (l) {
struct boundary *boundary=l->data;
@@ -243,3 +211,14 @@ process_boundaries(FILE *boundaries, FILE *ways)
#endif
return boundaries_list;
}
+
+GList *
+process_boundaries(FILE *boundaries, FILE *ways)
+{
+ GList *boundaries_list;
+ struct relations *relations=relations_new();
+
+ boundaries_list=process_boundaries_setup(boundaries, relations);
+ relations_process(relations, NULL, ways, NULL);
+ return process_boundaries_finish(boundaries_list);
+}
diff --git a/navit/maptool/osm_relations.c b/navit/maptool/osm_relations.c
index d6f63a110..b14165bf6 100644
--- a/navit/maptool/osm_relations.c
+++ b/navit/maptool/osm_relations.c
@@ -94,24 +94,15 @@ relations_process(struct relations *rel, FILE *nodes, FILE *ways, FILE *relation
struct node_item *ni;
GList *l;
- 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))) {
- *id=ni->id;
- *c=ni->c;
- l=g_hash_table_lookup(rel->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);
- }
- }
- while ((ib=read_item(ways))) {
- id=item_bin_get_attr(ib, attr_osm_wayid, NULL);
- if (id) {
- l=g_hash_table_lookup(rel->member_hash[1], id);
+ 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))) {
+ *id=ni->id;
+ *c=ni->c;
+ l=g_hash_table_lookup(rel->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);
@@ -119,4 +110,17 @@ 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=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);
+ }
+ }
+ }
+ }
}