]> err.no Git - mapper/commitdiff
Handle more node types (aiport, cafe, tourism, etc)
authorKaj-Michael Lang <milang@angel.tal.org>
Sun, 22 Jul 2007 15:07:04 +0000 (18:07 +0300)
committerKaj-Michael Lang <milang@angel.tal.org>
Sun, 22 Jul 2007 15:07:04 +0000 (18:07 +0300)
Start to handle isin tag, we now try to find the parent of a place and poi using the isin tag.

src/osm.c
src/osm.h

index 805ef51e666f94a16cd94bf8a70d624aa16fb217..6e5f268b58d4f3fe0239b5861377afd2a934b59c 100644 (file)
--- 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->type<NODE_POI_END) {
-       db_insert_poi(value);
-} else if (value->data->type>NODE_PLACE_START && value->data->type<NODE_PLACE_END) {
-       db_insert_place(value);
+n->data->isin=osm_find_node_place(n);
+
+if (n->data->type>NODE_POI_START && n->data->type<NODE_POI_END) {
+       db_insert_poi(n);
+} else if (n->data->type>NODE_PLACE_START && n->data->type<NODE_PLACE_END) {
+       db_insert_place(n);
 }
 
 /* Free the extra info, we don't need it anymore */
-osm_free_node_data(value);
-
+osm_free_node_data(n);
 }
 
 void
@@ -684,6 +791,7 @@ osm_planet_poi_clear_nodes(void)
 {
 g_print("Removing old OSM POIs...\n");
 sqlite3_step(sql.delete_osm_poi);
+sqlite3_step(sql.delete_place);
 }
 
 void
@@ -775,6 +883,7 @@ switch (t) {
                cnode=osm_new_node(id,
                        atof(get_attr_key_value(atts, "lat")),
                        atof(get_attr_key_value(atts, "lon")));
+               osm_node_tags=g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
        break;
        case IN_SEGMENT_TAG:
                tag_parent=IS_SEGMENT;
@@ -812,20 +921,7 @@ switch (t) {
                                g_printf("In node tags but current node is NULL\n");
                                return;
                        }       
-
-                       if (cnode->data==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();
 
index a51afe03f68da8c57fbbb4e085224dbad1a78738..a1cff5c198b4880ae7e9e0ccd62dd80909e2ecd8 100644 (file)
--- 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;
 };