summaryrefslogtreecommitdiff
path: root/navit/maptool/osm_relations.c
diff options
context:
space:
mode:
authormartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>2011-07-11 12:35:45 +0000
committermartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>2011-07-11 12:35:45 +0000
commit215de8777a5ac45dc6fe53cf4b223dd7f2cb56ad (patch)
tree3c871ddb32c30ad02b7c80269a4460ac4da1e0ed /navit/maptool/osm_relations.c
parentba25fca0bb7b39cc5dc71e76a2642e8a6cb525e9 (diff)
downloadnavit-svn-215de8777a5ac45dc6fe53cf4b223dd7f2cb56ad.tar.gz
Add:maptool:Better resolving strategy for relations
git-svn-id: http://svn.code.sf.net/p/navit/code/trunk/navit@4623 ffa7fe5e-494d-0410-b361-a75ebd5db220
Diffstat (limited to 'navit/maptool/osm_relations.c')
-rw-r--r--navit/maptool/osm_relations.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/navit/maptool/osm_relations.c b/navit/maptool/osm_relations.c
new file mode 100644
index 00000000..d6f63a11
--- /dev/null
+++ b/navit/maptool/osm_relations.c
@@ -0,0 +1,122 @@
+/**
+ * Navit, a modular navigation system.
+ * Copyright (C) 2005-2011 Navit Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#include <stdio.h>
+#include <string.h>
+#include "maptool.h"
+#include "attr.h"
+
+struct relations {
+ GHashTable *member_hash[3];
+};
+
+struct relations_func {
+ void (*func)(void *func_priv, void *relation_priv, struct item_bin *member, void *member_priv);
+ void *func_priv;
+};
+
+struct relations_member {
+ osmid memberid;
+ void *relation_priv,*member_priv;
+ struct relations_func *func;
+};
+
+static guint
+relations_member_hash(gconstpointer key)
+{
+ const struct relations_member *memb=key;
+ return (memb->memberid >> 32)^(memb->memberid & 0xffffffff);
+}
+
+static gboolean
+relations_member_equal(gconstpointer a, gconstpointer b)
+{
+ const struct relations_member *memba=a;
+ const struct relations_member *membb=b;
+ return (memba->memberid == membb->memberid);
+}
+
+struct relations *
+relations_new(void)
+{
+ struct relations *ret=g_new(struct relations, 1);
+ int i;
+
+ for (i = 0 ; i < 3 ; i++)
+ ret->member_hash[i]=g_hash_table_new_full(relations_member_hash, relations_member_equal, NULL, NULL);
+ return ret;
+}
+
+struct relations_func *
+relations_func_new(void (*func)(void *func_priv, void *relation_priv, struct item_bin *member, void *member_priv), void *func_priv)
+{
+ struct relations_func *relations_func=g_new(struct relations_func, 1);
+ relations_func->func=func;
+ relations_func->func_priv=func_priv;
+ return relations_func;
+}
+
+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));
+}
+
+void
+relations_process(struct relations *rel, FILE *nodes, FILE *ways, FILE *relations)
+{
+ char buffer[128];
+ struct item_bin *ib=(struct item_bin *)buffer;
+ long long *id;
+ struct coord *c=(struct coord *)(ib+1),cn={0,0};
+ 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);
+ 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);
+ }
+ }
+ }
+}