#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;
gchar *name;
gchar *ref;
gchar *int_ref;
- gchar *is_in;
+ guint32 isin;
+ gint speed;
gint8 layer;
};
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;
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;
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);
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);
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);
-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);
/* Use more cache memory */
sqlite3_exec(db, "PRAGMA cache_size = 8000;", NULL, NULL, NULL);
-
}
/********************************************************************/
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)
{
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;
}
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);
db_insert_way_ref(w);
db_insert_way_names(w);
-
osm_free_way_data(w);
return TRUE;
}
}
+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)
{
#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;
w->data->ref=NULL;
w->data->int_ref=NULL;
w->data->layer=0;
+w->data->speed=0;
}
void
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:
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;
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;
}
osm_node_save_poi(node *n, gpointer user_data)
{
if (!n) {
- g_printf("ERROR: null poi\n");
+ g_printerr("ERROR: null poi\n");
return;
}
{
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) {
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:
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;
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;
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)
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;
static gint
print_fail(const gchar *msg, gint ret)
{
-g_printf("ERROR: %s\n", msg);
+g_printerr("ERROR: %s\n", msg);
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
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)