]> err.no Git - mapper/commitdiff
Add place (city, town, etc) search
authorKaj-Michael Lang <milang@onion.tal.org>
Tue, 19 Feb 2008 14:20:34 +0000 (16:20 +0200)
committerKaj-Michael Lang <milang@onion.tal.org>
Tue, 19 Feb 2008 14:20:34 +0000 (16:20 +0200)
src/osm-db.c
src/osm-db.h
src/search.c

index 9b9be2efc887193e93038cfadf9a232a0536e261..be9080824ab8a6150f2d3de2e1b4118fad158ac5 100644 (file)
@@ -61,7 +61,8 @@ struct sql_select_stmt {
        sqlite3_stmt *select_way_name_search;
        sqlite3_stmt *select_way_ref;
        sqlite3_stmt *select_place;
-       sqlite3_stmt *select_near_place;
+       sqlite3_stmt *select_place_near;
+       sqlite3_stmt *select_place_search;
 
        sqlite3_stmt *select_node_next;
        sqlite3_stmt *select_node_prev;
@@ -147,24 +148,33 @@ gboolean
 osm_db_prepare(sqlite3 *db)
 {
 /* Select nearest place inside lat,lon+-range */
-if (sqlite3_prepare_v2(db, "select name,(($LAT-ilat)*($LAT-ilat))+(($LON-ilon)*($LON-ilon)) as dist,"
+if (sqlite3_prepare_v2(db, "select name,(($LAT-ilat)*($LAT-ilat))+(($LON-ilon)*($LON-ilon)) as d,"
                                        " ilat,ilon,places.nid,isin_p,isin_c "
                                        " from places,nodes where type=$TYPE "
                                        " and nodes.nid=places.nid "
                                        " and ilat between $LAT-$RANGE and $LAT+$RANGE"
-                                       " and ilon between $LON-$RANGE and $LON+$RANGE order by dist limit 1",
-                   -1, &sql.select_near_place, NULL)!=SQLITE_OK)
+                                       " and ilon between $LON-$RANGE and $LON+$RANGE order by d limit 1",
+                   -1, &sql.select_place_near, NULL)!=SQLITE_OK)
        return FALSE;
 
 /* Select place name, distance, location, parent-place and type with given ID */
-if (sqlite3_prepare_v2(db, "select name,(($LAT-ilat)*($LAT-ilat))+(($LON-ilon)*($LON-ilon)) as dist,"
+if (sqlite3_prepare_v2(db, "select name,(($LAT-ilat)*($LAT-ilat))+(($LON-ilon)*($LON-ilon)) as d,"
                                        " ilat,ilon,type,isin_p,isin_c "
                                        " from places,nodes where "
                                        " nodes.nid=places.nid "
-                                       " and places.nid=$NID order by dist limit 1",
+                                       " and places.nid=$NID order by d limit 1",
                    -1, &sql.select_place, NULL)!=SQLITE_OK)
        return FALSE;
 
+/* Search */
+if (sqlite3_prepare_v2(db, "select places.nid,name,(($LAT-ilat)*($LAT-ilat))+(($LON-ilon)*($LON-ilon)) as d,"
+                                       " rlat,rlon,type,isin_p,isin_c "
+                                       " from places,nodes where "
+                                       " nodes.nid=places.nid "
+                                       " and name like $NAME order by d limit 200",
+                   -1, &sql.select_place_search, NULL)!=SQLITE_OK)
+       return FALSE;
+
 /* Ways */
 /* Select nearest ways inside lat,lon+-range */
 if (sqlite3_prepare_v2(db, "select w.wid,type,nodes,flags,"
@@ -191,7 +201,7 @@ if (sqlite3_prepare_v2(db, "select w.wid,w.name as name,"
                                        " ww.type between $WTS and $WTY and w.wid=ww.wid and n.name like $NAME "
                                        " and ww.lat between $LAT-$RANGE and $LAT+$RANGE "
                                        " and ww.lon between $LON-$RANGE and $LON+$RANGE "
-                                       " order by name limit 100",
+                                       " order by name limit 200",
                        -1, &sql.select_way_name_search, NULL)!=SQLITE_OK)
        return FALSE;
 
@@ -243,8 +253,8 @@ if (osmdb) {
                sqlite3_finalize(sql.select_way2);
        if (sql.select_place)
                sqlite3_finalize(sql.select_place);
-       if (sql.select_near_place)
-               sqlite3_finalize(sql.select_near_place);
+       if (sql.select_place_near)
+               sqlite3_finalize(sql.select_place_near);
        if (sql.select_node_next)
                sqlite3_finalize(sql.select_node_next);
        if (sql.select_node_prev)
@@ -479,32 +489,32 @@ switch (type) {
        break;
 }
 
-sqlite3_clear_bindings(sql.select_near_place);
-sqlite3_reset(sql.select_near_place);
+sqlite3_clear_bindings(sql.select_place_near);
+sqlite3_reset(sql.select_place_near);
 
-if (SQLITE_OK != sqlite3_bind_int(sql.select_near_place, 1, lat) ||
-    SQLITE_OK != sqlite3_bind_int(sql.select_near_place, 2, lon) ||
-    SQLITE_OK != sqlite3_bind_int(sql.select_near_place, 3, type) ||
-    SQLITE_OK != sqlite3_bind_int(sql.select_near_place, 4, range)) {
+if (SQLITE_OK != sqlite3_bind_int(sql.select_place_near, 1, lat) ||
+    SQLITE_OK != sqlite3_bind_int(sql.select_place_near, 2, lon) ||
+    SQLITE_OK != sqlite3_bind_int(sql.select_place_near, 3, type) ||
+    SQLITE_OK != sqlite3_bind_int(sql.select_place_near, 4, range)) {
        g_printerr("Failed to bind values for near place\n");
        return FALSE;
 }
 
 n=osm_place_new();
 n->isin_p=n->lat=n->lon=n->dist=0;
-if (SQLITE_ROW == sqlite3_step(sql.select_near_place)) {
+if (SQLITE_ROW == sqlite3_step(sql.select_place_near)) {
        const gchar *place;
        guint32 dist;
 
-       place=sqlite3_column_text(sql.select_near_place, 0);
+       place=sqlite3_column_text(sql.select_place_near, 0);
        n->name=g_strdup(place);
-       dist=sqlite3_column_int(sql.select_near_place, 1);
+       dist=sqlite3_column_int(sql.select_place_near, 1);
        n->dist=sqrt((double)dist);
-       n->lat=sqlite3_column_int(sql.select_near_place, 2);
-       n->lon=sqlite3_column_int(sql.select_near_place, 3);
-       n->id=sqlite3_column_int(sql.select_near_place, 4);
-       n->isin_p=sqlite3_column_int(sql.select_near_place, 5);
-/*     n->isin_c=sqlite3_column_int(sql.select_near_place, 6); */
+       n->lat=sqlite3_column_int(sql.select_place_near, 2);
+       n->lon=sqlite3_column_int(sql.select_place_near, 3);
+       n->id=sqlite3_column_int(sql.select_place_near, 4);
+       n->isin_p=sqlite3_column_int(sql.select_place_near, 5);
+/*     n->isin_c=sqlite3_column_int(sql.select_place_near, 6); */
        n->type=type;
 
        osm_place_cache_add(n);
@@ -685,10 +695,8 @@ for (iter=w; iter!=NULL; iter=iter->next) {
        osm_way_node *wnp;
        osm_way *way=(osm_way*)iter->data;
 
-#ifdef DEBUG_OSM
-       g_printf("Way: %d (%d) has %d nodes, nearest is %d,%d\n", 
+       g_debug("Way: %d (%d) has %d nodes, nearest is %d,%d",
                way->id, way->type, way->nodecnt, way->f, way->t);
-#endif
 
        way->node_t=NULL;
 
@@ -701,7 +709,7 @@ for (iter=w; iter!=NULL; iter=iter->next) {
                cw=way;
                way->distance=dist_n;
                way->node_t=wnn;
-               g_printf("#1 distance: %f (%f)\n", dist_n, pdist);
+               g_debug("#1 distance: %f (%f)", dist_n, pdist);
        }
 
        wnp=osm_way_get_prev_node(way);
@@ -716,12 +724,10 @@ for (iter=w; iter!=NULL; iter=iter->next) {
                        osm_way_node_free(wnn);
                }
                way->node_t=wnp;
-               g_printf("#2 distance: %f (%f)\n", dist_p, pdist);
+               g_debug("#2 distance: %f (%f)", dist_p, pdist);
        }
 
-#ifdef DEBUG_OSM
-       g_printf("Found close way, distance: %f %f (%f)\n", dist_n, dist_p, pdist);
-#endif
+       g_debug("Found close way, distance: %f %f (%f)", dist_n, dist_p, pdist);
 
        if (!cw) {
                osm_way_free(way);
@@ -740,16 +746,9 @@ 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("\tType: %d Flags: %d Nodes: %d Dist: %f\n", 
-       cw->type, cw->flags, cw->nodecnt, cw->dist);
-g_printf("\tNF: %d NT: %d Distance: %f\n", 
-       cw->f, 
-       cw->t, 
-       cw->distance);
-#endif
+g_debug("Found way: (ID: %d): [%s]:[%s][%s]", cw->id, cw->name, cw->ref, cw->int_ref);
+g_debug("T: %d F: %d N#: %d D: %f", cw->type, cw->flags, cw->nodecnt, cw->dist);
+g_debug("\tNF#: %d NT#: %d (D: %f)", cw->f, cw->t, cw->distance);
 
 return cw;
 }
@@ -1025,6 +1024,74 @@ if (check_place==TRUE && d>way_dist_range*4) {
 return map_loc->street ? TRUE : FALSE;
 }
 
+/**
+ * osm_place_search
+ */
+gboolean
+osm_place_search(gdouble lat, gdouble lon, gchar *text, GtkListStore **store)
+{
+GtkTreeIter iter;
+gchar *ltext=NULL;
+guint rows=0;
+gchar tmp1[16], tmp2[16];
+gdouble range=6;
+
+ltext=g_strdup_printf("%s%%", text);
+
+if (SQLITE_OK != sqlite3_bind_double(sql.select_place_search, 1, lat) ||
+    SQLITE_OK != sqlite3_bind_double(sql.select_place_search, 2, lon) ||
+       SQLITE_OK != sqlite3_bind_text(sql.select_place_search,   3, ltext, -1, SQLITE_TRANSIENT)) {
+               g_printerr("Failed to bind values for sql.select_place_search\n");
+               sqlite3_clear_bindings(sql.select_place_search);
+               g_free(ltext);
+               return FALSE;
+}
+
+if (ltext)
+       g_free(ltext);
+
+*store = gtk_list_store_new(ITEM_NUM_COLUMNS, 
+                               G_TYPE_INT,             /* ID */
+                               G_TYPE_INT,             /*  */
+                               G_TYPE_DOUBLE,  /* Latitude */
+                               G_TYPE_DOUBLE,  /* Longitude */
+                               G_TYPE_DOUBLE,  /* Distance */
+                               G_TYPE_STRING,  /* Lat/Lon */
+                               G_TYPE_STRING,  /* Label */
+                               G_TYPE_STRING,  /* Desc. */
+                               G_TYPE_STRING,  /* Category */
+                               G_TYPE_STRING,  /* Dummy */
+                               G_TYPE_STRING); /* Dummy */
+
+while (SQLITE_ROW == sqlite3_step(sql.select_place_search)) {
+       gdouble rlat, rlon, dist;
+
+       rlat=sqlite3_column_double(sql.select_place_search, 3);
+       rlon=sqlite3_column_double(sql.select_place_search, 4);
+       lat_format(_degformat, rlat, tmp1);
+       lon_format(_degformat, rlon, tmp2);
+       dist=calculate_distance(lat, lon, rlat, rlon) * UNITS_CONVERT[_units];
+
+       gtk_list_store_append(*store, &iter);
+       gtk_list_store_set(*store, &iter,
+               ITEM_ID, sqlite3_column_int(sql.select_place_search, 0),
+               ITEM_LAT, rlat,
+               ITEM_LON, rlon,
+               ITEM_DIST, dist,
+               ITEM_LATLON, g_strdup_printf("%s, %s", tmp1, tmp2),
+               ITEM_LABEL, sqlite3_column_text(sql.select_place_search, 1),
+               -1);
+       rows++;
+}
+
+g_printf("Found: %d places\n", rows);
+
+sqlite3_reset(sql.select_place_search);
+sqlite3_clear_bindings(sql.select_place_search);
+
+return TRUE;
+}
+
 /**
  * osm_way_search
  *
index a83662229da6b61ec325ac49df51d5fe70cb8a38..6da5f702542d755d8465263e0f455109dab3a48a 100644 (file)
@@ -54,6 +54,7 @@ gboolean osm_find_nearest_place(node_type_t type, gint lat, gint lon, osm_place
 osm_way *osm_find_nearest_way(gint lat, gint lon);
 gboolean osm_way_distance(gint lat, gint lon, osm_way_node *f, osm_way_node *t, gdouble *d);
 
+gboolean osm_place_search(gdouble lat, gdouble lon, gchar *text, GtkListStore **store);
 gboolean osm_place_get(guint32 id, gint lat, gint lon, osm_place **nr);
 
 gboolean osm_get_location_data(gint lat, gint lon, gfloat heading, osm_location *map_loc);
index 5c688eaafd7a305daec9292612dc2e2a050f9011..59ae62dbf3f177bac3418948873b753775ae7dbd 100644 (file)
@@ -113,8 +113,7 @@ switch (s->stype) {
                sres=osm_way_search(s->lat, s->lon, st, &s->store);
        break;
        case SEARCH_TYPE_PLACE:
-               popup_error(s->dialog, "Not yet implemented");
-               sres=FALSE;
+               sres=osm_place_search(s->lat, s->lon, st, &s->store);
        break;
 }