From 18f4b666de24e19adb23c6955b10008eae3ef3fd Mon Sep 17 00:00:00 2001 From: Kaj-Michael Lang Date: Sun, 22 Jul 2007 18:07:04 +0300 Subject: [PATCH] Handle more node types (aiport, cafe, tourism, etc) Start to handle isin tag, we now try to find the parent of a place and poi using the isin tag. --- src/osm.c | 237 +++++++++++++++++++++++++++++++++++++++++++++--------- src/osm.h | 19 ++++- 2 files changed, 219 insertions(+), 37 deletions(-) diff --git a/src/osm.c b/src/osm.c index 805ef51..6e5f268 100644 --- a/src/osm.c +++ b/src/osm.c @@ -32,6 +32,7 @@ typedef struct _node_data node_data; struct _node_data { gchar *name; node_type_t type; + guint32 isin; }; /* Node type */ @@ -96,6 +97,10 @@ struct _nodeinfo { } nodeinfo[] = { { "amenity", "fuel", NODE_AMENITY_FUEL }, { "amenity", "pub", NODE_AMENITY_PUB }, + { "amenity", "biergarten", NODE_AMENITY_PUB }, + { "amenity", "cafe", NODE_AMENITY_CAFE }, + { "amenity", "telephone", NODE_AMENITY_TELEPHONE }, + { "amenity", "toilets", NODE_AMENITY_WC }, { "amenity", "fast_food", NODE_AMENITY_FOOD }, { "amenity", "restaurant", NODE_AMENITY_FOOD }, { "amenity", "parking", NODE_AMENITY_PARKING }, @@ -116,16 +121,34 @@ struct _nodeinfo { { "amenity", "school",NODE_AMENITY_SCHOOL }, { "amenity", "college",NODE_AMENITY_COLLEGE }, { "amenity", "university",NODE_AMENITY_COLLEGE }, + + { "tourism", "information",NODE_AMENITY_TOURISM_INFO }, + { "tourism", "camp_site",NODE_AMENITY_CAMP_SITE }, + { "tourism", "caravan_site",NODE_AMENITY_CARAVAN_SITE }, + { "tourism", "picnic_site",NODE_AMENITY_PICNIC_SITE }, + { "tourism", "theme_park",NODE_AMENITY_THEME_PARK }, + { "tourism", "hotel",NODE_AMENITY_HOTEL }, + { "tourism", "motel",NODE_AMENITY_MOTEL }, + { "tourism", "hostel",NODE_AMENITY_HOSTEL }, + { "tourism", "attraction",NODE_AMENITY_ATTRACTION }, + { "railway", "station", NODE_AMENITY_RAILWAY_STATION }, { "railway", "halt", NODE_AMENITY_RAILWAY_HALT }, + + { "aeroway", "terminal", NODE_AMENITY_AIRPORT }, + { "place", "city", NODE_PLACE_CITY }, { "place", "town", NODE_PLACE_TOWN }, { "place", "village", NODE_PLACE_VILLAGE }, { "place", "hamlet", NODE_PLACE_HAMLET }, { "place", "suburb", NODE_PLACE_SUBURB }, + { "place", "island", NODE_PLACE_ISLAND }, { "highway", "traffic_signals", NODE_TRAFFIC_SIGNALS }, + { "highway", "services", NODE_AMENITY_PARKING }, + { "highway", "toll_booth", NODE_TOLLBOOTH }, + { "highway", "gate", NODE_GATE }, { NULL, NULL, NODE_PLAIN } }; @@ -150,9 +173,14 @@ struct _wayinfo { { "highway", "service",WAY_SERVICE, FALSE, FALSE, FALSE }, { "highway", "track",WAY_TRACK, FALSE, FALSE, FALSE }, { "highway", "unsurfaced",WAY_TRACK, FALSE, FALSE, FALSE }, + { "highway", "pedestrian",WAY_FOOTWAY, FALSE, FALSE, FALSE }, { "highway", "footway",WAY_FOOTWAY, FALSE, FALSE, FALSE }, + { "highway", "steps",WAY_FOOTWAY, FALSE, FALSE, FALSE }, + { "highway", "bridleway",WAY_FOOTWAY, FALSE, FALSE, FALSE }, { "highway", "cycleway",WAY_CYCLEWAY, FALSE, FALSE, FALSE }, { "railway", "rail",WAY_RAIL, FALSE, FALSE, FALSE }, + { "aeroway", "runway",WAY_RUNWAY, FALSE, FALSE, FALSE }, + { "aeroway", "taxiway",WAY_TAXIWAY, FALSE, FALSE, FALSE }, { "natural", "water",WAY_WATER, FALSE, FALSE, TRUE }, { "waterway", "river",WAY_WATER, FALSE, FALSE, FALSE }, { "waterway", "canal",WAY_WATER, FALSE, FALSE, FALSE }, @@ -163,10 +191,18 @@ struct _wayinfo { static sqlite3 *db; tag_parent_t tag_parent=IS_NONE; -static GHashTable *osm_nodes=NULL; -static GHashTable *osm_segments=NULL; -static GSList *osm_ways=NULL; -static GSList *osm_poi=NULL; +static GHashTable *osm_nodes; +static GHashTable *osm_node_tags; +static GHashTable *osm_segments; +static GSList *osm_ways; +static GSList *osm_poi; + +static GHashTable *osm_place_country; +static GHashTable *osm_place_region; +static GHashTable *osm_place_city; +static GHashTable *osm_place_suburb; +static GHashTable *osm_place_village; +static GHashTable *osm_node_isin; static node *cnode=NULL; static way *cway=NULL; @@ -231,8 +267,8 @@ sqlite3_prepare_v2(db, "insert into places (nid,type,name,isin) values (?, ?, ?, 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, priority)" - " values (?, ?, ?, ?, ?, ?, 1, ?)", -1, &sql.insert_poi, NULL); +sqlite3_prepare_v2(db, "insert 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 */ @@ -259,6 +295,9 @@ sqlite3_prepare_v2(db, "delete from way_ref", -1, /* Turn of syncing to speed up data import */ sqlite3_exec(db, "PRAGMA synchronous = OFF;", NULL, NULL, NULL); +/* Use more cache memory */ +sqlite3_exec(db, "PRAGMA cache_size = 8000;", NULL, NULL, NULL); + } /********************************************************************/ @@ -284,14 +323,13 @@ gboolean db_insert_place(node *n) { if (!n->data) - return; + return FALSE; if (!n->data->name) - return; + return FALSE; sqlite3_bind_int(sql.insert_place, 1, n->id); sqlite3_bind_int(sql.insert_place, 2, n->data->type); sqlite3_bind_text(sql.insert_place, 3, n->data->name, -1, SQLITE_TRANSIENT); -/* Until we care enough, just use 0 */ -sqlite3_bind_int(sql.insert_place, 4, 0); +sqlite3_bind_int(sql.insert_place, 4, n->data->isin); sqlite3_step(sql.insert_place); sqlite3_reset(sql.insert_place); sqlite3_clear_bindings(sql.insert_place); @@ -314,6 +352,7 @@ if (n->data->desc) sqlite3_bind_int(sql.insert_poi, 6, n->data->type); sqlite3_bind_int(sql.insert_poi, 7, n->data->type/100); +sqlite3_bind_int(sql.insert_poi, 8, n->data->isin); sqlite3_step(sql.insert_poi); sqlite3_reset(sql.insert_poi); @@ -446,9 +485,10 @@ char **d; d=p; while (*d!=NULL) { - printf("[%s]", *d); + g_printf("[%s]", *d); d++; } +g_print("\n"); } gchar *get_attr_key_value(const gchar **p, gchar *key) @@ -646,6 +686,72 @@ w->nodes=g_slist_prepend(w->nodes, s); w->ncnt++; } +/** + * Search the place hash table for the location of the node. + * + */ +guint32 +osm_find_node_place(node *n) +{ +node *t; +node *r; +gchar **isin; +gchar **place; +gfloat dist; + +if (!n->data) + return 0; + +isin=g_hash_table_lookup(osm_node_isin, n->id); + +if (isin==NULL) + return 0; + +place=isin; +while (*place!=NULL) { + gchar *ps; + ps=g_strstrip(*place); + g_printf("Checking (%d) [%s] in [%s]\n",n->data->type, n->data->name, ps); + switch (n->data->type) { + case NODE_PLACE_CITY: + case NODE_PLACE_TOWN: + case NODE_PLACE_VILLAGE: + 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; + case NODE_PLACE_ISLAND: + default: + return 0; + break; + } + place++; +} + +return 0; +} + +guint32 +osm_find_way_place(way *w) +{ +return 0; +} + /***********************************************************************/ void @@ -658,25 +764,26 @@ if (dbnode_cnt % 26214==0) } void -osm_node_save_poi(node *value, gpointer user_data) +osm_node_save_poi(node *n, gpointer user_data) { -if (!value) { +if (!n) { g_printf("ERROR: null poi\n"); return; } -if (!value->data) +if (!n->data) return; -if (value->data->type>NODE_POI_START && value->data->typedata->type>NODE_PLACE_START && value->data->typedata->isin=osm_find_node_place(n); + +if (n->data->type>NODE_POI_START && n->data->typedata->type>NODE_PLACE_START && n->data->typedata==NULL) - osm_new_node_data(cnode); - - if (strcasecmp(k, "name")==0) - cnode->data->name=g_strdup(v); - else if (cnode->data->type==NODE_PLAIN) { - for (i=0; nodeinfo[i].k; i++) { - if (strcasecmp (nodeinfo[i].k, k)==0 && strcasecmp (v, nodeinfo[i].v)==0) { - cnode->data->type=nodeinfo[i].type; - break; - } - } - } + g_hash_table_insert(osm_node_tags, g_strdup(k), g_strdup(v)); } break; case IS_WAY: @@ -853,6 +949,7 @@ switch (t) { cway->flags|=W_ROUNDABOUT; cway->flags|=W_ONEWAY; } else if ((strcasecmp(k, "junction")==0) && (strcasecmp(v, "mini_roundabout")==0)) { + /* Just in case */ cway->flags|=W_ROUNDABOUT; cway->flags|=W_ONEWAY; } else if (cway->type==WAY_UNWAYED) { @@ -892,17 +989,68 @@ static void _osm_tag_end(void *userData, const char *name) { tag_state_t t; +gchar *v; +guint i; 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); } - if (cnode->data && cnode->data->type==NODE_PLAIN) { + + osm_new_node_data(cnode); + + for (i=0; nodeinfo[i].k; i++) { + v=g_hash_table_lookup(osm_node_tags, nodeinfo[i].k); + if (!v) + continue; + if (strcasecmp (v, nodeinfo[i].v)==0) { + cnode->data->type=nodeinfo[i].type; + break; + } + } + + if (cnode->data->type!=NODE_PLAIN) { + cnode->data->name=NULL; + v=g_hash_table_lookup(osm_node_tags, "name"); + if (v) + cnode->data->name=g_strdup(v); + } + + cnode->data->isin=0; + v=g_hash_table_lookup(osm_node_tags, "is_in"); + if (v) { + gchar **isin; + isin=g_strsplit(v, ",", 10); + g_hash_table_insert(osm_node_isin, GINT_TO_POINTER(cnode->id), isin); + } + + if (cnode->data->type==NODE_PLAIN) { osm_free_node_data(cnode); - } else if (cnode->data) { + } else { osm_poi=g_slist_prepend(osm_poi, cnode); + switch (cnode->data->type) { + case NODE_PLACE_COUNTRY: + g_hash_table_insert(osm_place_country, cnode->data->name, cnode); + break; + case NODE_PLACE_CITY: + case NODE_PLACE_TOWN: + g_hash_table_insert(osm_place_city, cnode->data->name, cnode); + break; + case NODE_PLACE_SUBURB: + g_hash_table_insert(osm_place_suburb, cnode->data->name, cnode); + break; + case NODE_PLACE_VILLAGE: + case NODE_PLACE_HAMLET: + g_hash_table_insert(osm_place_village, cnode->data->name, cnode); + break; + case NODE_PLACE_ISLAND: + /* Ignore for now */ + break; + default:; + } } + g_hash_table_destroy(osm_node_tags); cnode=NULL; break; case IN_WAY_TAG: @@ -984,6 +1132,13 @@ storage_init(void) { osm_nodes=g_hash_table_new(g_direct_hash, g_direct_equal); osm_segments=g_hash_table_new(g_direct_hash, g_direct_equal); + +osm_place_country=g_hash_table_new(g_str_hash, g_str_equal); +osm_place_city=g_hash_table_new(g_str_hash, g_str_equal); +osm_place_suburb=g_hash_table_new(g_str_hash, g_str_equal); +osm_place_village=g_hash_table_new(g_str_hash, g_str_equal); +osm_place_region=g_hash_table_new(g_str_hash, g_str_equal); +osm_node_isin=g_hash_table_new(g_direct_hash, g_direct_equal); } static void @@ -991,6 +1146,13 @@ storage_free(void) { g_hash_table_unref(osm_nodes); g_hash_table_unref(osm_segments); + +g_hash_table_unref(osm_place_country); +g_hash_table_unref(osm_place_city); +g_hash_table_unref(osm_place_suburb); +g_hash_table_unref(osm_place_village); +g_hash_table_unref(osm_place_region); +g_hash_table_unref(osm_node_isin); } /************************************************************************/ @@ -1015,6 +1177,9 @@ osm_planet_parse_file(argv[1]); g_printf("Planet loaded.\nTotal nodes %d, POIs: %d, Segments %d and Ways %d.\n", node_cnt, noded_cnt, seg_cnt, way_cnt); +g_printf("Cities/Towns: %d\n", g_hash_table_size(osm_place_city)); +g_printf("Villages/Hamlets: %d\n", g_hash_table_size(osm_place_village)); +g_printf("Suburbs: %d\n", g_hash_table_size(osm_place_suburb)); osm_planet_save_to_db(); diff --git a/src/osm.h b/src/osm.h index a51afe0..a1cff5c 100644 --- a/src/osm.h +++ b/src/osm.h @@ -29,24 +29,34 @@ typedef enum { NODE_AMENITY_POLICE=130, NODE_AMENITY_HOTEL=200, NODE_AMENITY_HOSTEL=201, + NODE_AMENITY_MOTEL=202, NODE_AMENITY_ATM=205, NODE_AMENITY_BANK=206, NODE_AMENITY_POST=210, NODE_AMENITY_POST_BOX=211, + NODE_AMENITY_TOURISM_INFO=219, NODE_AMENITY_TAXI=220, NODE_AMENITY_RAILWAY_STATION=230, NODE_AMENITY_RAILWAY_HALT=231, NODE_AMENITY_BUS_STATION=236, NODE_AMENITY_BOAT=240, NODE_AMENITY_AIRPORT=250, + NODE_AMENITY_CAMP_SITE=280, + NODE_AMENITY_CARAVAN_SITE=281, + NODE_AMENITY_PICNIC_SITE=282, NODE_AMENITY_FOOD=301, NODE_AMENITY_PUB=302, NODE_AMENITY_CINEMA=303, NODE_AMENITY_THEATRE=304, NODE_AMENITY_SHOP=305, + NODE_AMENITY_CAFE=306, + NODE_AMENITY_TELEPHONE=307, + NODE_AMENITY_WC=308, + NODE_AMENITY_THEME_PARK=309, NODE_AMENITY_POW=310, NODE_AMENITY_COLLEGE=320, NODE_AMENITY_SCHOOL=321, + NODE_AMENITY_ATTRACTION=330, NODE_AMENITY_GENERIC=900, /* */ NODE_POI_END=999, @@ -55,12 +65,17 @@ typedef enum { NODE_PLACE_SUBURB=1001, NODE_PLACE_HAMLET=1049, NODE_PLACE_VILLAGE=1050, + NODE_PLACE_ISLAND=1051, NODE_PLACE_TOWN=1099, NODE_PLACE_CITY=1100, + NODE_PLACE_AREA=1200, + NODE_PLACE_COUNTRY=1490, NODE_PLACE_END=1500, /* Other */ NODE_TRAFFIC_SIGNALS=2000, + NODE_GATE=2001, + NODE_TOLLBOOTH=2002, NODE_TYPE_MAX=9000 } node_type_t; @@ -80,6 +95,8 @@ typedef enum { WAY_CYCLEWAY, WAY_RAIL, + WAY_RUNWAY, + WAY_TAXIWAY, WAY_WATER, WAY_WATER_RIVER, @@ -95,7 +112,7 @@ struct _osm_place { gchar *name; gint lat; gint lon; - gint dist; + gdouble dist; guint32 isin; }; -- 2.39.5