]> mj.ucw.cz Git - leo.git/blobdiff - osm.c
Introduced multiple data sources
[leo.git] / osm.c
diff --git a/osm.c b/osm.c
index 12529f60154f7224da17cd54a93a06e8f11332fb..325b592322287858a064f46faa10bd538b5fac96 100644 (file)
--- a/osm.c
+++ b/osm.c
@@ -17,7 +17,7 @@
 #include "leo.h"
 #include "osm.h"
 
-static struct mempool *osm_pool;
+struct osm *osm_this;
 
 /*** Generic objects ***/
 
@@ -26,8 +26,6 @@ struct osm_id_to_obj {
   struct osm_object *o;
 };
 
-clist osm_obj_list[OSM_TYPE_MAX];
-
 #define P(x) [OSM_TYPE_##x] = #x,
 const char * const osm_obj_type_names[OSM_TYPE_MAX] = {
   [OSM_TYPE_INVALID] = "Invalid",
@@ -44,13 +42,12 @@ const char * const osm_obj_type_names[OSM_TYPE_MAX] = {
 #define HASH_ATOMIC_TYPE osm_id_t
 #define HASH_WANT_FIND
 #define HASH_WANT_LOOKUP
-#define HASH_USE_POOL osm_pool
+#define HASH_TABLE_VARS struct mempool *pool;
+#define HASH_USE_POOL table->pool
 #define HASH_ZERO_FILL
 #define HASH_TABLE_DYNAMIC
 #include <ucw/hashtable.h>
 
-static struct osm_id_hash_table osm_id_hash[OSM_TYPE_MAX];
-
 osm_id_t osm_parse_id(const char *str)
 {
   uintmax_t id;
@@ -64,19 +61,19 @@ osm_id_t osm_parse_id(const char *str)
 struct osm_object *osm_obj_find_by_id(enum osm_object_type type, osm_id_t id)
 {
   ASSERT(type != OSM_TYPE_INVALID && type < OSM_TYPE_MAX);
-  struct osm_id_to_obj *ii = osm_id_hash_find(&osm_id_hash[type], id);
+  struct osm_id_to_obj *ii = osm_id_hash_find(osm_this->id_hash[type], id);
   return ii ? ii->o : NULL;
 }
 
 static void *osm_obj_new(enum osm_object_type type, osm_id_t id, uns size)
 {
   ASSERT(type != OSM_TYPE_INVALID && type < OSM_TYPE_MAX);
-  struct osm_id_to_obj *ii = osm_id_hash_lookup(&osm_id_hash[type], id);
+  struct osm_id_to_obj *ii = osm_id_hash_lookup(osm_this->id_hash[type], id);
   if (ii->o)
     die("Id %ju for type %s defined twice", (uintmax_t) id, osm_obj_type_names[type]);
 
-  struct osm_object *o = mp_alloc_zero(osm_pool, size);
-  clist_add_tail(&osm_obj_list[type], &o->n);
+  struct osm_object *o = mp_alloc_zero(osm_this->pool, size);
+  clist_add_tail(&osm_this->obj_list[type], &o->n);
   o->type = type;
   o->id = id;
   clist_init(&o->tags);
@@ -89,12 +86,12 @@ void osm_ref_add(struct osm_object *parent, clist *list, struct osm_object *son,
 {
   ASSERT(parent != son);
 
-  struct osm_ref *ref = mp_alloc(osm_pool, sizeof(*ref));
+  struct osm_ref *ref = mp_alloc(osm_this->pool, sizeof(*ref));
   ref->o = son;
   ref->role = role;
   clist_add_tail(list, &ref->n);
 
-  struct osm_ref *backref = mp_alloc(osm_pool, sizeof(*ref));
+  struct osm_ref *backref = mp_alloc(osm_this->pool, sizeof(*ref));
   backref->o = parent;
   backref->role = 0;
   clist_add_tail(&son->backrefs, &backref->n);
@@ -135,7 +132,7 @@ struct dict osm_key_dict, osm_value_dict;
 
 void osm_obj_add_tag_raw(struct osm_object *o, osm_key_t key, osm_val_t val)
 {
-  struct osm_tag *t = mp_alloc(osm_pool, sizeof(*t));
+  struct osm_tag *t = mp_alloc(osm_this->pool, sizeof(*t));
   t->key = key;
   t->val = val;
   clist_add_tail(&o->tags, &t->n);
@@ -199,7 +196,7 @@ void osm_node_dump(struct osm_node *n)
 void osm_node_dump_all(void)
 {
   printf("Known nodes:\n");
-  CLIST_FOR_EACH(struct osm_node *, n, osm_obj_list[OSM_TYPE_NODE])
+  CLIST_FOR_EACH(struct osm_node *, n, osm_this->obj_list[OSM_TYPE_NODE])
     osm_node_dump(n);
   putchar('\n');
 }
@@ -233,7 +230,7 @@ void osm_way_dump(struct osm_way *w)
 void osm_way_dump_all(void)
 {
   printf("Known ways:\n");
-  CLIST_FOR_EACH(struct osm_way *, w, osm_obj_list[OSM_TYPE_WAY])
+  CLIST_FOR_EACH(struct osm_way *, w, osm_this->obj_list[OSM_TYPE_WAY])
     osm_way_dump(w);
   putchar('\n');
 }
@@ -273,7 +270,7 @@ void osm_relation_dump(struct osm_relation *r)
 void osm_relation_dump_all(void)
 {
   printf("Known relations:\n");
-  CLIST_FOR_EACH(struct osm_relation *, r, osm_obj_list[OSM_TYPE_RELATION])
+  CLIST_FOR_EACH(struct osm_relation *, r, osm_this->obj_list[OSM_TYPE_RELATION])
     osm_relation_dump(r);
   putchar('\n');
 }
@@ -296,7 +293,7 @@ void osm_multipolygon_dump(struct osm_multipolygon *m)
 void osm_multipolygon_dump_all(void)
 {
   printf("Known multipolygons:\n");
-  CLIST_FOR_EACH(struct osm_multipolygon *, r, osm_obj_list[OSM_TYPE_MULTIPOLYGON])
+  CLIST_FOR_EACH(struct osm_multipolygon *, r, osm_this->obj_list[OSM_TYPE_MULTIPOLYGON])
     osm_multipolygon_dump(r);
   putchar('\n');
 }
@@ -378,7 +375,7 @@ static void mpg_walk_boundary(struct osm_multipolygon *m, bool inner)
     {
       if (!v->visited)
        {
-         struct osm_mpg_boundary *b = mp_alloc(osm_pool, sizeof(*b));
+         struct osm_mpg_boundary *b = mp_alloc(osm_this->pool, sizeof(*b));
          clist_add_tail(&m->boundaries, &b->n);
          b->inner = inner;
          clist_init(&b->nodes);
@@ -387,7 +384,7 @@ static void mpg_walk_boundary(struct osm_multipolygon *m, bool inner)
          while (!w->visited)
            {
              w->visited = 1;
-             struct osm_ref *f = mp_alloc(osm_pool, sizeof(*f));
+             struct osm_ref *f = mp_alloc(osm_this->pool, sizeof(*f));
              clist_add_tail(&b->nodes, &f->n);
              f->o = w->o;
              f->role = 0;
@@ -417,7 +414,7 @@ static void mpg_walk_boundary(struct osm_multipolygon *m, bool inner)
          if (w != v)
            osm_obj_warn(&mpg_current->o, "Boundary not closed at node %ju", (uintmax_t) w->o->id);
 
-         struct osm_ref *f = mp_alloc(osm_pool, sizeof(*f));
+         struct osm_ref *f = mp_alloc(osm_this->pool, sizeof(*f));
          clist_add_tail(&b->nodes, &f->n);
          f->o = v->o;
          f->role = 0;
@@ -470,7 +467,7 @@ void osm_make_multipolygons(void)
 {
   uns mpg_cnt = 0;
 
-  CLIST_FOR_EACH(struct osm_relation *, r, osm_obj_list[OSM_TYPE_RELATION])
+  CLIST_FOR_EACH(struct osm_relation *, r, osm_this->obj_list[OSM_TYPE_RELATION])
     if (osm_obj_find_tag(&r->o, KEY_TYPE) == VALUE_MULTIPOLYGON)
       {
        osm_multipolygon_make(r);
@@ -489,7 +486,7 @@ void osm_project(const char *spec)
   if (!osm_pj)
     die("Unable to initialize projection %s", spec);
 
-  CLIST_FOR_EACH(struct osm_node *, n, osm_obj_list[OSM_TYPE_NODE])
+  CLIST_FOR_EACH(struct osm_node *, n, osm_this->obj_list[OSM_TYPE_NODE])
     {
       projUV p;
       p.u = n->x * DEG_TO_RAD;
@@ -561,15 +558,24 @@ bool osm_obj_center(struct osm_object *o, double *xp, double *yp)
 
 /*** Globals ***/
 
-void osm_init(void)
+struct osm *osm_init(void)
 {
-  osm_pool = mp_new(65536);
+  struct mempool *mp = mp_new(65536);
+  struct osm *osm = mp_alloc_zero(mp, sizeof(*osm));
+  osm->pool = mp;
+
   for (int i=0; i<OSM_TYPE_MAX; i++)
     {
-      clist_init(&osm_obj_list[i]);
-      osm_id_hash_init(&osm_id_hash[i]);
+      clist_init(&osm->obj_list[i]);
+      osm->id_hash[i] = mp_alloc(mp, sizeof(struct osm_id_hash_table));
+      osm->id_hash[i]->pool = mp;
+      osm_id_hash_init(osm->id_hash[i]);
     }
-  osm_tag_init();
+
+  if (!osm_this)
+    osm_tag_init();
+  osm_this = osm;
+  return osm;
 }
 
 void osm_dump(void)