From b5b49b1576a135a3ab5731af3aa557434a9b882c Mon Sep 17 00:00:00 2001 From: Kaj-Michael Lang Date: Fri, 27 Jul 2007 11:49:21 +0300 Subject: [PATCH] Make place cache work. Use dynamic place variables in map.c --- src/map.c | 57 +++++++++++++------------- src/osm-db.c | 110 ++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 110 insertions(+), 57 deletions(-) diff --git a/src/map.c b/src/map.c index 800c13d..48fb991 100644 --- a/src/map.c +++ b/src/map.c @@ -82,8 +82,8 @@ static void map_update_location(gint x, gint y); gboolean get_next_pui(gpointer key, gpointer value, ProgressUpdateInfo ** data) { - *data = key; - return TRUE; +*data = key; +return TRUE; } gboolean curl_download_timeout() @@ -1388,30 +1388,30 @@ map_set_place_information(osm_way *s, osm_place *mp, osm_place *sp, PoiInfo *p) { gchar buffer[256]; +/* oh, fun */ snprintf(buffer, sizeof(buffer), "On %s%s%s%s%s%s%s%s%s%s%s", - s ? s->name ? s->name : "unknown" : "?", + s ? s->name ? s->name : _("unknown") : "?", s ? s->ref ? ", " : "" : "", s ? s->ref ? s->ref : "" : "", s ? s->int_ref ? ", " : "" : "", s ? s->int_ref ? s->int_ref : "" : "", (p && p->label) ? " near " : "", (p && p->label) ? p->label : "", - sp->name ? " in " : "", - sp->name ? sp->name : "", - mp->name ? " in " : "", - mp->name ? mp->name : ""); + (sp && sp->name) ? " in " : "", + (sp && sp->name) ? sp->name : "", + (mp && mp->name) ? " in " : "", + (mp && mp->name) ? mp->name : ""); gtk_label_set_label(GTK_LABEL(_info_banner), buffer); } -/* XXX: */ +/* XXX: Move this to osm-db.c */ static void map_update_location(gint x, gint y) { gint ilat, ilon; gdouble lat,lon, dist; -osm_place mplace; -osm_place splace; PoiInfo *p; +gboolean fs, fm; unit2latlon(x, y, lat, lon); @@ -1429,40 +1429,37 @@ if (map_loc.street && osm_way_distance(ilat, ilon, map_loc.street->node_f, map_l map_loc.street=osm_find_nearest_way(ilat, ilon); } -mplace.name=NULL; -splace.name=NULL; - p=poi_find_nearest(lat, lon); -osm_find_nearest_place(NODE_PLACE_SUBURB, ilat, ilon, &splace); - -if (splace.isin!=0) { - if (osm_place_get(splace.isin, ilat, ilon, &mplace)==FALSE) { - if (osm_find_nearest_place(NODE_PLACE_CITY, ilat, ilon, &mplace)==TRUE) - g_printf("Near city: %s\n", mplace.name); - else if (osm_find_nearest_place(NODE_PLACE_TOWN, ilat, ilon, &mplace)==TRUE) - g_printf("Near town: %s\n", mplace.name); +fs=osm_find_nearest_place(NODE_PLACE_SUBURB, ilat, ilon, &map_loc.secondary); + +if (fs==TRUE && map_loc.secondary && map_loc.secondary->isin!=0) { + if (osm_place_get(map_loc.secondary->isin, ilat, ilon, &map_loc.primary)==FALSE) { + if (osm_find_nearest_place(NODE_PLACE_CITY, ilat, ilon, &map_loc.primary)==TRUE) + g_printf("Near city: %s\n", map_loc.primary->name); + else if (osm_find_nearest_place(NODE_PLACE_TOWN, ilat, ilon, &map_loc.primary)==TRUE) + g_printf("Near town: %s\n", map_loc.primary->name); else g_printf("Unknown\n"); } else { - g_printf("In %s\n", mplace.name); + g_printf("In: %s\n", map_loc.primary ? map_loc.primary->name : "?"); } } else if (map_loc.street && map_loc.street->isin!=0) { - if (osm_place_get(map_loc.street->isin, ilat, ilon, &mplace)==FALSE) { - + if (osm_place_get(map_loc.street->isin, ilat, ilon, &map_loc.primary)==FALSE) { + g_printf("Street location not know.\n"); } else { - g_printf("In %s\n", mplace.name); + g_printf("Street is in: %s\n", map_loc.primary ? map_loc.primary->name : "?"); } } else { - if (osm_find_nearest_place(NODE_PLACE_CITY, ilat, ilon, &mplace)==TRUE) - g_printf("Near city: %s\n", mplace.name); - else if (osm_find_nearest_place(NODE_PLACE_TOWN, ilat, ilon, &mplace)==TRUE) - g_printf("Near town: %s\n", mplace.name); + if (osm_find_nearest_place(NODE_PLACE_CITY, ilat, ilon, &map_loc.primary)==TRUE) + g_printf("Near city: %s\n", map_loc.primary->name); + else if (osm_find_nearest_place(NODE_PLACE_TOWN, ilat, ilon, &map_loc.primary)==TRUE) + g_printf("Near town: %s\n", map_loc.primary->name); else g_printf("Unknown\n"); } -map_set_place_information(map_loc.street, &mplace, &splace, p); +map_set_place_information(map_loc.street, map_loc.primary, map_loc.secondary, p); } gboolean map_cb_scroll_event(GtkWidget * widget, GdkEventScroll * event) diff --git a/src/osm-db.c b/src/osm-db.c index 1c03dcc..5b4ae8f 100644 --- a/src/osm-db.c +++ b/src/osm-db.c @@ -16,6 +16,9 @@ #include "osm.h" #include "latlon.h" +/* #define DEBUG_OSM */ +#define OSM_PLACE_CACHE_MAX_ITEMS 40 + struct sql_select_stmt { sqlite3_stmt *select_way; sqlite3_stmt *select_way_nodes; @@ -102,27 +105,6 @@ g_hash_table_destroy(_place_cache); /*****************************************************************************/ -static osm_place * -osm_place_cache_lookup(guint32 id) -{ -return g_hash_table_lookup(_place_cache, GINT_TO_POINTER(id)); -} - -static void -osm_place_cache_add(guint32 id, osm_place *p) -{ -if (osm_place_cache_lookup(id)==NULL) - g_hash_table_insert(_place_cache, GINT_TO_POINTER(id), p); -} - -static void -osm_place_cache_gc(void) -{ -g_hash_table_foreach_remove(_place_cache, g_free, NULL); -} - -/*****************************************************************************/ - /** * Free way nodes list */ @@ -158,12 +140,80 @@ if (w->int_ref) g_slice_free(osm_way, w); } +/*****************************************************************************/ + +static void +osm_place_free(osm_place *p) +{ +if (p->name) + g_free(p->name); +g_slice_free(osm_place, p); +} + +static gboolean +osm_place_remove(gpointer k, gpointer v, gpointer ud) +{ +osm_place_free((osm_place *)v); +return TRUE; +} + +static osm_place * +osm_place_new(void) +{ +return g_slice_new0(osm_place); +} + +static osm_place * +osm_place_cache_lookup(guint32 id) +{ +return g_hash_table_lookup(_place_cache, GINT_TO_POINTER(id)); +} + +static void +osm_place_cache_add(osm_place *p) +{ +if (osm_place_cache_lookup(p->id)==NULL) + g_hash_table_insert(_place_cache, GINT_TO_POINTER(p->id), p); +} + +static void +osm_place_cache_gc(void) +{ +gint r; +g_printf("*** Clearing place cache\n"); +r=g_hash_table_foreach_remove(_place_cache, osm_place_remove, NULL); +g_printf("*** Removed %d items\n", r); +} + +static void +osm_place_update_distance(osm_place *p, gint lat, gint lon) +{ +gdouble lam, lom; + +lam=(gdouble)((lat-p->lat)*(lat-p->lat)); +lom=(gdouble)((lon-p->lon)*(lon-p->lon)); + +p->dist=sqrt(lam+lom); +} + /** * Get place with given id and distance to current location */ gboolean osm_place_get(guint32 id, gint lat, gint lon, osm_place *n) { +n=osm_place_cache_lookup(id); +if (n) { + g_printf("*** Place cache hit!\n"); + osm_place_update_distance(n, lat, lon); + return TRUE; +} +n=NULL; + +/* XXX: better place for this */ +if (g_hash_table_size(_place_cache)>OSM_PLACE_CACHE_MAX_ITEMS) + osm_place_cache_gc(); + sqlite3_clear_bindings(sql.select_place); sqlite3_reset(sql.select_place); @@ -178,6 +228,7 @@ if (SQLITE_ROW == sqlite3_step(sql.select_place)) { const gchar *place; guint32 dist; + n=osm_place_new(); place=sqlite3_column_text(sql.select_place, 0); n->name=g_strdup(place); dist=sqlite3_column_int(sql.select_place, 1); @@ -195,9 +246,10 @@ return FALSE; * Search for the nearest place, type */ gboolean -osm_find_nearest_place(node_type_t type, gint lat, gint lon, osm_place *n) +osm_find_nearest_place(node_type_t type, gint lat, gint lon, osm_place **nr) { gint range; +osm_place *n=NULL; switch (type) { case NODE_PLACE_SUBURB: @@ -227,10 +279,7 @@ if (SQLITE_OK != sqlite3_bind_int(sql.select_near_place, 1, lat) || return FALSE; } -if (n->name) { - g_free(n->name); - n->name=NULL; -} +n=osm_place_new(); n->isin=n->lat=n->lon=n->dist=0; if (SQLITE_ROW == sqlite3_step(sql.select_near_place)) { const gchar *place; @@ -246,8 +295,12 @@ if (SQLITE_ROW == sqlite3_step(sql.select_near_place)) { n->isin=sqlite3_column_int(sql.select_near_place, 5); n->type=type; + osm_place_cache_add(n); + + *nr=n; return TRUE; } +*nr=n; return FALSE; } @@ -363,8 +416,10 @@ switch (g_list_length(w)) { osm_way *way=(osm_way*)iter->data; +#ifdef DEBUG_OSM g_printf("WAY %d (%d) HAS %d NODES, nearest is %d\n", way->id, way->type, way->nodecnt, way->node_num); +#endif if (osm_way_get_nodes(way)==FALSE) continue; @@ -405,7 +460,6 @@ switch (g_list_length(w)) { way->distance=pndist; cw=way; } else { - g_printf("Way is not closer, freeing\n"); osm_way_free(way); way=NULL; } @@ -425,6 +479,7 @@ if (cw->type==WAY_MOTORWAY || cw->type==WAY_TRUNK || osm_way_get_ref(cw); } +#ifdef DEBUG_OSM g_printf("BEST WAY(%d): %s (%s,%s)\n", cw->id, cw->name, cw->ref, cw->int_ref); g_printf("\tT: %d F: %d N: %d D: %f\n", @@ -432,6 +487,7 @@ g_printf("\tT: %d F: %d N: %d D: %f\n", g_printf("\tNF: %d NT: %d DT %f\n", cw->node_f->num, cw->node_t->num, cw->distance); +#endif return cw; } -- 2.39.5