struct _node_data {
gchar *name;
node_type_t type;
+ guint32 isin;
};
/* Node type */
} 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 },
{ "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 }
};
{ "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 },
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;
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 */
/* 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);
+
}
/********************************************************************/
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);
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);
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)
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
}
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
{
g_print("Removing old OSM POIs...\n");
sqlite3_step(sql.delete_osm_poi);
+sqlite3_step(sql.delete_place);
}
void
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;
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:
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) {
_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:
{
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
{
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);
}
/************************************************************************/
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();