]> err.no Git - mapper/commitdiff
Handle access=private tag
authorKaj-Michael Lang <milang@angel.tal.org>
Tue, 24 Jul 2007 20:37:36 +0000 (23:37 +0300)
committerKaj-Michael Lang <milang@angel.tal.org>
Tue, 24 Jul 2007 20:37:36 +0000 (23:37 +0300)
Handle maxspeed/speedlimit tag
Don't waste memory on segments outside requested area.

src/osm.c

index eaf60f761da8aef457bc1e6f297626efe7618b07..0238f003dbc9e1af5cd1829590d831c12d8872e3 100644 (file)
--- a/src/osm.c
+++ b/src/osm.c
@@ -20,6 +20,7 @@
 #define OSM_DB_FILE "osm-planet.db"
 
 static gint node_cnt=0;
+static gint node_skip_cnt=0;
 static gint noded_cnt=0;
 static gint way_cnt=0;
 static gint seg_cnt=0;
@@ -57,7 +58,8 @@ struct _way_data {
        gchar *name;
        gchar *ref;
        gchar *int_ref;
-       gchar *is_in;
+       guint32 isin;
+       gint speed;
        gint8 layer;
 };
 
@@ -203,6 +205,7 @@ static GHashTable *osm_place_city;
 static GHashTable *osm_place_suburb;
 static GHashTable *osm_place_village;
 static GHashTable *osm_node_isin;
+static GHashTable *osm_way_isin;
 
 static node *cnode=NULL;
 static way *cway=NULL;
@@ -222,6 +225,7 @@ struct sql_stmt {
        sqlite3_stmt *insert_way_seg;
        sqlite3_stmt *delete_way;
        sqlite3_stmt *delete_way_seg;
+       sqlite3_stmt *delete_way_seg_wsid;
        sqlite3_stmt *delete_way_name;
        sqlite3_stmt *delete_way_ref;
 
@@ -241,7 +245,7 @@ gboolean use_bbox;
 
 gint wsegcnt;
 
-node *osm_find_node(gint nid);
+node *osm_find_node(guint32 nid);
 void osm_free_way_data(way *w);
 void print_way(way *w);
 
@@ -263,7 +267,7 @@ void
 db_prepare(void)
 {
 /* Way nodes */
-sqlite3_prepare_v2(db, "insert into nodes (nid,lat,lon,l) values (?, ?, ?, 0)",
+sqlite3_prepare_v2(db, "insert or replace into nodes (nid,lat,lon,l) values (?, ?, ?, 0)",
                    -1, &sql.insert_node, NULL);
 sqlite3_prepare_v2(db, "select lat,lon,l from nodes where nid=?",
                    -1, &sql.select_node, NULL);
@@ -271,17 +275,17 @@ sqlite3_prepare_v2(db, "delete from nodes", -1, &sql.delete_nodes, NULL);
 sqlite3_prepare_v2(db, "update nodes set l=l+1 where nid=?", -1, &sql.update_node, NULL);
 
 /* Places */
-sqlite3_prepare_v2(db, "insert into places (nid,type,name,isin) values (?, ?, ?, ?)",
+sqlite3_prepare_v2(db, "insert or replace into places (nid,type,name,isin) values (?, ?, ?, ?)",
                    -1, &sql.insert_place, NULL);
 sqlite3_prepare_v2(db, "delete from places", -1, &sql.delete_place, NULL);
 
 /* POI nodes */
-sqlite3_prepare_v2(db, "insert into poi (osm_id, lat, lon, label, desc, cat_id, public, source, priority, isin)"
+sqlite3_prepare_v2(db, "insert or replace into poi (osm_id, lat, lon, label, desc, cat_id, public, source, priority, isin)"
                     " values (?, ?, ?, ?, ?, ?, 1, 1, ?, ?)", -1, &sql.insert_poi, NULL);
 sqlite3_prepare_v2(db, "delete from poi where osm_id>0", -1, &sql.delete_osm_poi, NULL);
 
 /* Ways */
-sqlite3_prepare_v2(db, "insert into way (wid,nodes,type,flags) values (?, ?, ?, ?)", 
+sqlite3_prepare_v2(db, "insert or replace into way (wid,nodes,type,flags,speed,isin) values (?, ?, ?, ?, ?, ?)", 
                    -1, &sql.insert_way_data, NULL);
 sqlite3_prepare_v2(db, "delete from way", -1, 
        &sql.delete_way, NULL);
@@ -290,13 +294,15 @@ sqlite3_prepare_v2(db, "insert into way_seg (wsid,num,node) values (?, ?, ?)",
                    -1, &sql.insert_way_seg, NULL);
 sqlite3_prepare_v2(db, "delete from way_seg", -1, 
        &sql.delete_way_seg, NULL);
+sqlite3_prepare_v2(db, "delete from way_seg where wsid=?", -1, 
+       &sql.delete_way_seg_wsid, NULL);
 
-sqlite3_prepare_v2(db, "insert into way_names (wid,name) values (?, ?)", 
+sqlite3_prepare_v2(db, "insert or replace into way_names (wid,name) values (?, ?)", 
                    -1, &sql.insert_way_name, NULL);
 sqlite3_prepare_v2(db, "delete from way_names", -1, 
        &sql.delete_way_name, NULL);
 
-sqlite3_prepare_v2(db, "insert into way_ref (rid,ref,int_ref) values (?, ?, ?)", 
+sqlite3_prepare_v2(db, "insert or replace into way_ref (rid,ref,int_ref) values (?, ?, ?)", 
                    -1, &sql.insert_way_ref, NULL);
 sqlite3_prepare_v2(db, "delete from way_ref", -1, 
        &sql.delete_way_ref, NULL);
@@ -306,7 +312,6 @@ sqlite3_exec(db, "PRAGMA synchronous = OFF;", NULL, NULL, NULL);
 
 /* Use more cache memory */
 sqlite3_exec(db, "PRAGMA cache_size = 8000;", NULL, NULL, NULL);
-
 }
 
 /********************************************************************/
@@ -430,6 +435,16 @@ sqlite3_reset(sql.insert_way_name);
 sqlite3_clear_bindings(sql.insert_way_name);
 }
 
+void
+db_delete_way_segments(way *w)
+{
+sqlite3_bind_int(sql.delete_way_seg_wsid, 1, w->id);
+
+sqlite3_step(sql.delete_way_seg_wsid);
+sqlite3_reset(sql.delete_way_seg_wsid);
+sqlite3_clear_bindings(sql.delete_way_seg_wsid);
+}
+
 gboolean
 db_insert_way_segments(segment *s, way *w)
 {
@@ -437,12 +452,16 @@ node *f;
 node *t;
 
 if (!s) {
-       g_printf("ERROR: null segment!\n");
+#ifdef VERBOSE
+       g_printerr("ERROR: null segment!\n");
+#endif
        return FALSE;
 }
 
 if (!w) {
-       g_printf("ERROR: null way!\n");
+#ifdef VERBOSE
+       g_printerr("ERROR: null way!\n");
+#endif
        return FALSE;
 }
 
@@ -483,6 +502,10 @@ sqlite3_bind_int(sql.insert_way_data, 1, w->id);
 sqlite3_bind_int(sql.insert_way_data, 2, w->ncnt);
 sqlite3_bind_int(sql.insert_way_data, 3, w->type);
 sqlite3_bind_int(sql.insert_way_data, 4, w->flags);
+if (w->data) {
+       sqlite3_bind_int(sql.insert_way_data, 5, w->data->speed);
+       sqlite3_bind_int(sql.insert_way_data, 6, w->data->isin);
+}
 
 sqlite3_step(sql.insert_way_data);
 sqlite3_reset(sql.insert_way_data);
@@ -491,7 +514,6 @@ sqlite3_clear_bindings(sql.insert_way_data);
 db_insert_way_ref(w);
 db_insert_way_names(w);
 
-
 osm_free_way_data(w);
 return TRUE;
 }
@@ -555,6 +577,14 @@ if (n->data) {
 
 }
 
+inline gboolean
+osm_node_check_box(gdouble nlat, gdouble nlon)
+{
+if (use_bbox==FALSE)
+       return TRUE;
+return (nlat > bbox.lat_min && nlat < bbox.lat_max && nlon > bbox.lon_min && nlon < bbox.lon_max) ? TRUE : FALSE;
+}
+
 void
 osm_new_node_data(node *n)
 {
@@ -619,30 +649,30 @@ g_slist_foreach(w->nodes, _print_segment_helper, NULL);
 #endif
 }
 
-segment *
-osm_get_segment_for_way(gint sid)
+inline segment *
+osm_get_segment_for_way(guint32 sid)
 {
 segment *s;
 s=g_hash_table_lookup(osm_segments, GINT_TO_POINTER(sid));
-if (!s)
-       g_printf("ERROR: Segment %d not found!\n", sid);
+if (!s && use_bbox==FALSE)
+       g_printerr("ERROR: Segment %d not found!\n", sid);
 return s;
 }
 
-node *
-osm_find_node(gint nid)
+inline node *
+osm_find_node(guint32 nid)
 {
 node *n;
 n=g_hash_table_lookup(osm_nodes, GINT_TO_POINTER(nid));
 #if 0
 if (!n)
-       g_printf("ERROR: Node %d not found!\n", nid);
+       g_printerr("ERROR: Node %d not found!\n", nid);
 #endif
 return n;
 }
 
 void
-osm_new_segment(gint id, gint from, gint to)
+osm_new_segment(guint32 id, guint32 from, guint32 to)
 {
 segment *s;
 
@@ -663,6 +693,7 @@ w->data->name=NULL;
 w->data->ref=NULL;
 w->data->int_ref=NULL;
 w->data->layer=0;
+w->data->speed=0;
 }
 
 void
@@ -715,24 +746,24 @@ guint32
 osm_find_node_place(node *n)
 {
 node *t;
-node *r;
 gchar **isin;
 gchar **place;
-gdouble dist;
 
 if (!n->data)
        return 0;
 
 isin=g_hash_table_lookup(osm_node_isin, n->id);
 
-if (isin==NULL)
+if (!isin)
        return 0;
 
 place=isin;
 while (*place!=NULL) {
        gchar *ps;
        ps=g_strstrip(*place);
+#ifdef VERBOSE
        g_printf("Checking (%d) [%s] in [%s]\n",n->data->type, n->data->name, ps);
+#endif
        switch (n->data->type) {
        case NODE_PLACE_CITY:
        case NODE_PLACE_TOWN:
@@ -740,19 +771,16 @@ while (*place!=NULL) {
        case NODE_PLACE_HAMLET:
                t=g_hash_table_lookup(osm_place_region, ps);
                if (t) {
-                       print_node(t);
                        return t->id;
                }
                t=g_hash_table_lookup(osm_place_country, ps);
                if (t) {
-                       print_node(t);
                        return t->id;
                }
        break;
        case NODE_PLACE_SUBURB:
                t=g_hash_table_lookup(osm_place_city, ps);
                if (t) {
-                       print_node(t);
                        return t->id;
                }
        break;
@@ -770,6 +798,26 @@ return 0;
 guint32
 osm_find_way_place(way *w)
 {
+way *t;
+gchar **isin;
+gchar **place;
+
+isin=g_hash_table_lookup(osm_way_isin, w->id);
+if (!isin)
+       return 0;
+
+place=isin;
+while (*place!=NULL) {
+       gchar *ps;
+       ps=g_strstrip(*place);
+
+       t=g_hash_table_lookup(osm_place_city, ps);
+       if (t) {
+               print_way(t);
+               return t->id;
+       }
+}
+
 return 0;
 }
 
@@ -788,7 +836,7 @@ void
 osm_node_save_poi(node *n, gpointer user_data)
 {
 if (!n) {
-       g_printf("ERROR: null poi\n");
+       g_printerr("ERROR: null poi\n");
        return;
 }
 
@@ -888,8 +936,8 @@ _osm_tag_start(void *userData, const char *name, const char **atts)
 {
 tag_state_t t;
 gchar *k, *v;
-guint32 id;
-gfloat nlat, nlon;
+guint32 id, idf, idt;
+gdouble nlat, nlon;
 
 t=check_tag(name);
 switch (t) {
@@ -901,18 +949,15 @@ switch (t) {
                node_cnt++;
 
                id=atoi(get_attr_key_value(atts, "id"));
-
-               osm_node_tags=NULL;
                nlat=atof(get_attr_key_value(atts, "lat"));
                nlon=atof(get_attr_key_value(atts, "lon"));
-               if (use_bbox==TRUE) {
-                       if (nlat > bbox.lat_min && nlat < bbox.lat_max && nlon > bbox.lon_min && nlon < bbox.lon_max) {
-                               cnode=osm_new_node(id, nlat, nlon);
-                               osm_node_tags=g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
-                       }
-               } else {
+
+               if (osm_node_check_box(nlat, nlon)==TRUE) {
                        cnode=osm_new_node(id, nlat, nlon);
                        osm_node_tags=g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+               } else {
+                       osm_node_tags=NULL;
+                       node_skip_cnt++;
                }
        break;
        case IN_SEGMENT_TAG:
@@ -920,10 +965,16 @@ switch (t) {
                seg_cnt++;
 
                id=atoi(get_attr_key_value(atts, "id"));
-
-               osm_new_segment(id,
-                       atoi(get_attr_key_value(atts, "from")),
-                       atoi(get_attr_key_value(atts, "to")));
+               idf=atoi(get_attr_key_value(atts, "from"));
+               idt=atoi(get_attr_key_value(atts, "to"));
+               /* XXX: Check that nodes exist only if using bbox */
+               if (use_bbox==TRUE) {
+                       if (osm_find_node(idf)==NULL)
+                               return;
+                       if (osm_find_node(idt)==NULL)
+                               return;
+               }
+               osm_new_segment(id, idf, idt);
        break;
        case IN_WAY_TAG:
                tag_parent=IS_WAY;
@@ -978,9 +1029,15 @@ switch (t) {
                                cway->flags|=W_NOEXIT;
                        else if (strcasecmp(k, "layer")==0)
                                cway->data->layer=atoi(v);
+                       else if (strcasecmp(k, "speedlimit")==0)
+                               cway->data->speed=atoi(v);
+                       else if (strcasecmp(k, "maxspeed")==0)
+                               cway->data->speed=atoi(v);
                        else if ((strcasecmp(k, "junction")==0) && (strcasecmp(v, "roundabout")==0)) {
                                cway->flags|=W_ROUNDABOUT;
                                cway->flags|=W_ONEWAY;
+                       } else if ((strcasecmp(k, "access")==0) && (strcasecmp(v, "private")==0)) {
+                               cway->flags|=W_NOACCESS;
                        } else if ((strcasecmp(k, "junction")==0) && (strcasecmp(v, "mini_roundabout")==0)) {
                                /* Just in case */
                                cway->flags|=W_ROUNDABOUT;
@@ -1028,7 +1085,7 @@ t=check_tag(name);
 switch (t) {
        case IN_NODE_TAG:
                if (node_cnt % 262140==0) {
-                       g_printf("Nodes: %d/%d\n", node_cnt, noded_cnt);
+                       g_printf("Nodes: %d, POIs: %d, Outside box: %d\n", node_cnt, noded_cnt, node_skip_cnt);
                }
 
                if (!osm_node_tags)
@@ -1129,7 +1186,7 @@ XML_SetElementHandler(xp, _osm_tag_start, _osm_tag_end);
 do {
        r=read(f, buffer, FILE_BUFFER);
        if (XML_Parse(xp, buffer, r, r>0 ? 0:1) == XML_STATUS_ERROR) {
-               g_printf("Parse error at line %d:\n%s\n",
+               g_printerr("Parse error at line %d:\n%s\n",
                XML_GetCurrentLineNumber(xp),
                XML_ErrorString(XML_GetErrorCode(xp)));
                res=2;
@@ -1148,7 +1205,7 @@ return res;
 static gint
 print_fail(const gchar *msg, gint ret)
 {
-g_printf("ERROR: %s\n", msg);
+g_printerr("ERROR: %s\n", msg);
 return ret;
 }
 
@@ -1157,10 +1214,12 @@ return ret;
 static void
 print_memory_usage(void)
 {
-g_print("Memory usage:\n");
-g_printf("Node size: %d\n", sizeof(node));
-g_printf("Seg  size: %d\n", sizeof(segment));
-g_printf("Way  size: %d\n", sizeof(way));
+g_print("Memory usage per item:\n");
+g_printf("Node  size: %d\n", sizeof(node));
+g_printf("NodeD size: %d\n", sizeof(node_data));
+g_printf("Seg   size: %d\n", sizeof(segment));
+g_printf("Way   size: %d\n", sizeof(way));
+g_printf("WayD  size: %d\n", sizeof(way_data));
 }
 
 static void
@@ -1211,6 +1270,7 @@ if (argc==6) {
        g_printf("Skipping data outside of box: %f,%f - %f,%f\n",
                bbox.lat_min, bbox.lon_min,
                bbox.lat_max, bbox.lon_max);
+       g_print("Note: missing nodes and segments can't be reported.\n");
 } else use_bbox=FALSE;
 
 if (db_open()!=TRUE)