From: Kaj-Michael Lang Date: Tue, 24 Jul 2007 20:37:36 +0000 (+0300) Subject: Handle access=private tag X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7bfaca2573da36d9d209192f44579ad6e367f5c0;p=mapper Handle access=private tag Handle maxspeed/speedlimit tag Don't waste memory on segments outside requested area. --- diff --git a/src/osm.c b/src/osm.c index eaf60f7..0238f00 100644 --- 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)