2 * This file is part of mapper
4 * Copyright (C) 2007 Kaj-Michael Lang
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include <sys/types.h>
28 #include <glib/gstdio.h>
29 #include <glib/gi18n.h>
38 /* #define DEBUG_OSM */
39 /* #define DEBUG_OSM_TIME */
40 #define OSM_PLACE_CACHE_MAX_ITEMS (64)
42 #define OSM_DB_PROGRESS_NUM (15000)
44 /* Node search ranges */
45 #define OSM_RANGE_START (16384)
46 #define OSM_RANGE_STEP (8192)
47 #define OSM_RANGE_STOP (65535)
49 static sqlite3 *osmdb;
50 static gboolean osm_db_ok;
52 struct sql_select_stmt {
53 sqlite3_stmt *select_way;
54 sqlite3_stmt *select_way2;
55 sqlite3_stmt *select_way_next_seg;
56 sqlite3_stmt *select_way_prev_seg;
58 sqlite3_stmt *select_way_nodes;
59 sqlite3_stmt *select_way_name;
60 sqlite3_stmt *select_way_name_nls;
61 sqlite3_stmt *select_way_name_search;
62 sqlite3_stmt *select_way_ref;
63 sqlite3_stmt *select_place;
64 sqlite3_stmt *select_place_near;
65 sqlite3_stmt *select_place_search;
67 sqlite3_stmt *select_node_next;
68 sqlite3_stmt *select_node_prev;
70 static struct sql_select_stmt sql;
72 static GtkProgressBar *dbpw=NULL;
74 /* Cache hash tables */
75 struct osm_place_cache {
80 static struct osm_place_cache pcache;
82 static guint way_dist_range=OSM_RANGE_WAY;
85 osm_way_node *osm_way_get_prev_node(osm_way *w);
86 osm_way_node *osm_way_get_next_node(osm_way *w);
88 /*****************************************************************************/
91 osm_set_way_range(guint sr)
97 osm_set_way_range_from_speed(gfloat speed)
100 way_dist_range=OSM_RANGE_WAY;
102 way_dist_range=OSM_RANGE_WAY-lrint((speed/4)*1000);
105 /*****************************************************************************/
108 osm_progress_pulse(void)
112 gtk_progress_bar_pulse(dbpw);
117 osm_progress(void *ud)
119 g_debug("SQL: Running gtk mainloop");
121 while (gtk_events_pending())
122 gtk_main_iteration();
124 gtk_main_iteration_do(FALSE);
130 osm_progress_hide(sqlite3 *db)
134 gtk_progress_bar_set_text(dbpw, "");
135 gtk_progress_bar_set_fraction(dbpw, 0.0);
139 osm_progress_show(sqlite3 *db)
143 gtk_progress_bar_set_text(dbpw, _("Searching..."));
144 gtk_progress_bar_pulse(dbpw);
145 gtk_main_iteration_do(FALSE);
149 osm_progress_set_widget(sqlite3 *db, GtkProgressBar *w)
151 if (dbpw!=NULL && w==NULL) {
152 osm_progress_hide(db);
154 g_source_remove(sid);
161 osm_progress_show(db);
162 sid=g_timeout_add(200, osm_progress_pulse, NULL);
166 /*****************************************************************************/
169 osm_db_prepare(sqlite3 *db)
171 /* Select nearest place inside lat,lon+-range */
172 if (sqlite3_prepare_v2(db, "select name,(($LAT-ilat)*($LAT-ilat))+(($LON-ilon)*($LON-ilon)) as d,"
173 " ilat,ilon,places.nid,isin_p,isin_c "
174 " from places,nodes where type=$TYPE "
175 " and nodes.nid=places.nid "
176 " and ilat between $LAT-$RANGE and $LAT+$RANGE"
177 " and ilon between $LON-$RANGE and $LON+$RANGE order by d limit 1",
178 -1, &sql.select_place_near, NULL)!=SQLITE_OK)
181 /* Select place name, distance, location, parent-place and type with given ID */
182 if (sqlite3_prepare_v2(db, "select name,(($LAT-ilat)*($LAT-ilat))+(($LON-ilon)*($LON-ilon)) as d,"
183 " ilat,ilon,type,isin_p,isin_c "
184 " from places,nodes where "
185 " nodes.nid=places.nid "
186 " and places.nid=$NID order by d limit 1",
187 -1, &sql.select_place, NULL)!=SQLITE_OK)
191 if (sqlite3_prepare_v2(db, "select places.nid,name,(($LAT-ilat)*($LAT-ilat))+(($LON-ilon)*($LON-ilon)) as d,"
192 " rlat,rlon,type,isin_p,isin_c "
193 " from places,nodes where "
194 " nodes.nid=places.nid "
195 " and name like $NAME order by d limit 200",
196 -1, &sql.select_place_search, NULL)!=SQLITE_OK)
200 /* Select nearest ways inside lat,lon+-range */
201 if (sqlite3_prepare_v2(db, "select w.wid,type,nodes,flags,"
202 "(($LAT-n.ilat)*($LAT-n.ilat))+(($LON-n.ilon)*($LON-n.ilon)) as d,wn.f,wn.t,n.ilat,n.ilon "
203 " from way as w,way_n2n as wn,nodes as n "
204 " where w.wid=wn.wid and wn.f=n.nid "
205 " and n.ilat between $LAT-$RANGE and $LAT+$RANGE "
206 " and n.ilon between $LON-$RANGE and $LON+$RANGE "
207 " and w.type between $WTS and $WTY "
209 -1, &sql.select_way2, NULL)!=SQLITE_OK)
212 if (sqlite3_prepare_v2(db, "select w.wid,w.name as name,"
213 "(($LAT-ww.lat)*($LAT-ww.lat))+(($LON-ww.lon)*($LON-ww.lon)) as d,ww.lat,ww.lon "
214 " from way_names as w,way as ww where "
215 " ww.type between $WTS and $WTY and w.wid=ww.wid and w.name like $NAME "
216 " and ww.lat between $LAT-$RANGE and $LAT+$RANGE "
217 " and ww.lon between $LON-$RANGE and $LON+$RANGE "
219 " select w.wid,n.name as name,"
220 "(($LAT-ww.lat)*($LAT-ww.lat))+(($LON-ww.lon)*($LON-ww.lon)) as d,ww.lat,ww.lon "
221 " from way_names as w, way as ww,way_names_nls as n on w.wid=n.wid where "
222 " ww.type between $WTS and $WTY and w.wid=ww.wid and n.name like $NAME "
223 " and ww.lat between $LAT-$RANGE and $LAT+$RANGE "
224 " and ww.lon between $LON-$RANGE and $LON+$RANGE "
225 " order by name limit 200",
226 -1, &sql.select_way_name_search, NULL)!=SQLITE_OK)
229 if (sqlite3_prepare_v2(db, "select wn.t,ilat,ilon from way_n2n as wn,nodes where wid=? and wn.f=? and wn.t=nodes.nid limit 1",
230 -1, &sql.select_way_next_seg, NULL)!=SQLITE_OK)
233 if (sqlite3_prepare_v2(db, "select wn.f,ilat,ilon from way_n2n as wn,nodes where wid=? and wn.t=? and wn.f=nodes.nid limit 1",
234 -1, &sql.select_way_prev_seg, NULL)!=SQLITE_OK)
238 if (sqlite3_prepare_v2(db, "select name from way_names where wid=?", -1, &sql.select_way_name, NULL)!=SQLITE_OK)
241 /* Way ref and int_ref */
242 if (sqlite3_prepare_v2(db, "select ref,int_ref from way_ref where rid=?", -1, &sql.select_way_ref, NULL)!=SQLITE_OK)
245 /* Get next, prev node + way information. For routing. */
246 if (sqlite3_prepare_v2(db, "select w.wid,w.type,w.flags,w.speed,n.nid,n.rlat,n.rlon,nn.f,nn.t,n.f,n.l "
247 "from way as w, nodes as n, way_n2n as nn where w.wid=nn.wid and nn.f=n.nid and nn.f=?",
248 -1, &sql.select_node_next, NULL)!=SQLITE_OK)
251 if (sqlite3_prepare_v2(db, "select w.wid,w.type,w.flags,w.speed,n.nid,n.rlat,n.rlon,nn.f,nn.t,n.f,n.l "
252 "from way as w, nodes as n, way_n2n as nn where w.wid=nn.wid and nn.f=n.nid and nn.t=?",
253 -1, &sql.select_node_prev, NULL)!=SQLITE_OK)
263 if (sql.select_way_ref)
264 sqlite3_finalize(sql.select_way_ref);
265 if (sql.select_way_name)
266 sqlite3_finalize(sql.select_way_name);
267 if (sql.select_way_next_seg)
268 sqlite3_finalize(sql.select_way_next_seg);
269 if (sql.select_way_prev_seg)
270 sqlite3_finalize(sql.select_way_prev_seg);
271 if (sql.select_way_name_search)
272 sqlite3_finalize(sql.select_way_name_search);
274 sqlite3_finalize(sql.select_way2);
275 if (sql.select_place)
276 sqlite3_finalize(sql.select_place);
277 if (sql.select_place_near)
278 sqlite3_finalize(sql.select_place_near);
279 if (sql.select_node_next)
280 sqlite3_finalize(sql.select_node_next);
281 if (sql.select_node_prev)
282 sqlite3_finalize(sql.select_node_prev);
286 memset(&sql, 0, sizeof(sql));
287 g_hash_table_destroy(pcache.cache);
290 g_timer_destroy(dbt);
294 osm_init(sqlite3 **db)
297 pcache.cache=g_hash_table_new(g_direct_hash, g_direct_equal);
306 memset(&sql, 0, sizeof(sql));
307 if (osm_db_prepare(osmdb)==FALSE) {
308 g_printerr("Failed to prepare OSM SQL statements: %s", sqlite3_errmsg(osmdb));
316 osm_db_enable_mainloop(sqlite3 *db, gboolean eml)
319 sqlite3_progress_handler(db, OSM_DB_PROGRESS_NUM, NULL, NULL);
321 sqlite3_progress_handler(db, OSM_DB_PROGRESS_NUM, osm_progress, NULL);
324 /*****************************************************************************/
327 osm_way_node_new(guint id, gint lat, gint lon, gint flags)
329 osm_way_node *n=g_slice_new(osm_way_node);
339 osm_way_node_free(osm_way_node *n)
342 g_slice_free(osm_way_node, n);
346 * Free way nodes list
349 osm_way_nodes_free(osm_way *w)
356 for (iter=w->nodes; iter!=NULL; iter=iter->next)
357 g_slice_free(osm_way_node, (osm_way_node*)iter->data);
359 g_list_free(w->nodes);
363 * Free a osm_way structure
366 osm_way_free(osm_way *w)
370 osm_way_nodes_free(w);
377 g_slice_free(osm_way, w);
380 /*****************************************************************************/
383 osm_place_free(osm_place *p)
387 g_slice_free(osm_place, p);
391 osm_place_remove(gpointer k, gpointer v, gpointer ud)
393 osm_place_free((osm_place *)v);
400 return g_slice_new0(osm_place);
404 osm_place_cache_lookup(guint32 id)
407 r=g_hash_table_lookup(pcache.cache, GINT_TO_POINTER(id));
413 g_debug("OSM: Cache %d/%d", pcache.hit, pcache.miss);
418 osm_place_cache_add(osm_place *p)
420 if (osm_place_cache_lookup(p->id)==NULL)
421 g_hash_table_insert(pcache.cache, GINT_TO_POINTER(p->id), p);
425 osm_place_cache_gc(void)
429 r=g_hash_table_foreach_remove(pcache.cache, osm_place_remove, NULL);
430 g_debug("OSM: Cache cleared (%d)", r);
436 osm_place_update_distance(osm_place *p, gint lat, gint lon)
440 lam=(gdouble)((lat-p->lat)*(lat-p->lat));
441 lom=(gdouble)((lon-p->lon)*(lon-p->lon));
443 p->dist=sqrt(lam+lom);
447 * Get place with given id and distance to current location
450 osm_place_get(guint32 id, gint lat, gint lon, osm_place **nr)
455 n=osm_place_cache_lookup(id);
457 osm_place_update_distance(n, lat, lon);
462 /* XXX: better place for this */
463 if (g_hash_table_size(pcache.cache)>OSM_PLACE_CACHE_MAX_ITEMS)
464 osm_place_cache_gc();
466 sqlite3_clear_bindings(sql.select_place);
467 sqlite3_reset(sql.select_place);
469 if (SQLITE_OK != sqlite3_bind_int(sql.select_place, 1, lat) ||
470 SQLITE_OK != sqlite3_bind_int(sql.select_place, 2, lon) ||
471 SQLITE_OK != sqlite3_bind_int(sql.select_place, 3, id)) {
472 g_printerr("Failed to bind values for place\n");
476 if (SQLITE_ROW == sqlite3_step(sql.select_place)) {
481 place=sqlite3_column_text(sql.select_place, 0);
482 n->name=g_strdup(place);
483 dist=sqlite3_column_int(sql.select_place, 1);
484 n->dist=sqrt((double)dist);
485 n->lat=sqlite3_column_int(sql.select_place, 2);
486 n->lon=sqlite3_column_int(sql.select_place, 3);
487 n->type=sqlite3_column_int(sql.select_place, 4);
488 n->isin_p=sqlite3_column_int(sql.select_place, 5);
489 /* n->isin_c=sqlite3_column_int(sql.select_place, 6); */
496 * Search for the nearest place with given type
499 osm_find_nearest_place(node_type_t type, gint lat, gint lon, osm_place **nr)
505 case NODE_PLACE_SUBURB:
508 case NODE_PLACE_CITY:
509 case NODE_PLACE_TOWN:
512 case NODE_PLACE_HAMLET:
513 case NODE_PLACE_VILLAGE:
521 sqlite3_clear_bindings(sql.select_place_near);
522 sqlite3_reset(sql.select_place_near);
524 if (SQLITE_OK != sqlite3_bind_int(sql.select_place_near, 1, lat) ||
525 SQLITE_OK != sqlite3_bind_int(sql.select_place_near, 2, lon) ||
526 SQLITE_OK != sqlite3_bind_int(sql.select_place_near, 3, type) ||
527 SQLITE_OK != sqlite3_bind_int(sql.select_place_near, 4, range)) {
528 g_printerr("Failed to bind values for near place\n");
533 n->isin_p=n->lat=n->lon=n->dist=0;
534 if (SQLITE_ROW == sqlite3_step(sql.select_place_near)) {
538 place=sqlite3_column_text(sql.select_place_near, 0);
539 n->name=g_strdup(place);
540 dist=sqlite3_column_int(sql.select_place_near, 1);
541 n->dist=sqrt((double)dist);
542 n->lat=sqlite3_column_int(sql.select_place_near, 2);
543 n->lon=sqlite3_column_int(sql.select_place_near, 3);
544 n->id=sqlite3_column_int(sql.select_place_near, 4);
545 n->isin_p=sqlite3_column_int(sql.select_place_near, 5);
546 /* n->isin_c=sqlite3_column_int(sql.select_place_near, 6); */
549 osm_place_cache_add(n);
563 osm_find_nearest_way_nodes(gint lat, gint lon, guint range)
570 sqlite3_reset(sql.select_way2);
571 sqlite3_clear_bindings(sql.select_way2);
573 if (SQLITE_OK != sqlite3_bind_int(sql.select_way2, 1, lat) ||
574 SQLITE_OK != sqlite3_bind_int(sql.select_way2, 2, lon) ||
575 SQLITE_OK != sqlite3_bind_int(sql.select_way2, 3, range) ||
576 SQLITE_OK != sqlite3_bind_int(sql.select_way2, 4, WAY_ROAD_START) ||
577 SQLITE_OK != sqlite3_bind_int(sql.select_way2, 5, WAY_ROAD_END)) {
578 g_printerr("Failed to bind values for way\n");
582 #ifdef DEBUG_OSM_TIME
586 while (SQLITE_ROW == sqlite3_step(sql.select_way2)) {
591 w=g_slice_new0(osm_way);
592 w->id=sqlite3_column_int(sql.select_way2, 0);
593 w->type=sqlite3_column_int(sql.select_way2, 1);
594 w->nodecnt=sqlite3_column_int(sql.select_way2, 2);
595 w->flags=sqlite3_column_int(sql.select_way2, 3);
596 dist=sqlite3_column_int(sql.select_way2, 4);
597 w->dist=sqrt((gdouble)dist);
598 w->f=sqlite3_column_int(sql.select_way2, 5);
599 w->t=sqlite3_column_int(sql.select_way2, 6);
601 lat=sqlite3_column_int(sql.select_way2, 7);
602 lon=sqlite3_column_int(sql.select_way2, 8);
604 w->node_f=osm_way_node_new(w->f, lat, lon, 0);
606 ways=g_list_prepend(ways, w);
609 #ifdef DEBUG_OSM_TIME
611 g_printf("Query took: %f sec, found: %d ways\n", g_timer_elapsed(dbt, &tms), wc);
617 /*****************************************************************************/
620 osm_get_route_node(guint nid, osm_node_direction d)
625 sqlite3_stmt *psql=NULL;
629 psql=sql.select_node_next;
632 psql=sql.select_node_prev;
635 g_assert_not_reached();
640 sqlite3_clear_bindings(psql);
642 if (SQLITE_OK != sqlite3_bind_int(psql, 1, nid)) {
643 g_printerr("Failed to bind values for route node\n");
647 while (SQLITE_ROW == sqlite3_step(psql)) {
651 w=g_slice_new0(osm_way);
652 w->id=sqlite3_column_int(psql, 0);
653 w->type=sqlite3_column_int(psql, 1);
654 w->flags=sqlite3_column_int(psql, 2);
655 w->speed=sqlite3_column_int(psql, 3);
657 lat=sqlite3_column_double(psql, 5);
658 lon=sqlite3_column_double(psql, 6);
660 w->f=sqlite3_column_int(psql, 7);
661 w->t=sqlite3_column_int(psql, 8);
664 w->node->flags=sqlite3_column_int(psql, 9);
665 w->node->links=sqlite3_column_int(psql, 10);
668 r=g_slist_prepend(r, w);
675 /*****************************************************************************/
677 osm_way_distance(gint lat, gint lon, osm_way_node *f, osm_way_node *t, gdouble *d)
687 return distance_point_to_line((gdouble)lon, (gdouble)lat, (gdouble)f->lon, (gdouble)f->lat, (gdouble)t->lon, (gdouble)t->lat, d);
691 * Search for the nearest way (road)
692 * - First search for ways with nearest node
693 * - If only one is returned then we are done.
694 * - If more than one, go trough the results:
695 * - Load nodes for the way, check prev/next nodes
696 * - Store result if closer than before
697 * - Return closest way
700 #define START_DIST (900000.0)
703 osm_find_nearest_way(gint lat, gint lon)
707 guint range=OSM_RANGE_START;
709 gdouble pdist=START_DIST, dist_n, dist_p;
711 while ((w=osm_find_nearest_way_nodes(lat, lon, range))==NULL && range<=OSM_RANGE_STOP) {
712 range+=OSM_RANGE_STEP;
713 g_printf("Trying with range: %d\n", range);
716 g_printf("Found %d ways withing range %d\n", g_list_length(w), range);
719 if (g_list_length(w)==0)
722 for (iter=w; iter!=NULL; iter=iter->next) {
725 osm_way *way=(osm_way*)iter->data;
727 g_debug("Way: %d (%d) has %d nodes, nearest is %d,%d",
728 way->id, way->type, way->nodecnt, way->f, way->t);
732 wnn=osm_way_get_next_node(way);
733 if (osm_way_distance(lat, lon, way->node_f, wnn, &dist_n)==FALSE) {
734 osm_way_node_free(wnn);
736 } else if (dist_n<pdist) {
739 way->distance=dist_n;
741 g_debug("#1 distance: %f (%f)", dist_n, pdist);
744 wnp=osm_way_get_prev_node(way);
745 if (osm_way_distance(lat, lon, way->node_f, wnp, &dist_p)==FALSE) {
746 osm_way_node_free(wnp);
748 } else if (dist_p<pdist) {
751 way->distance=dist_n;
753 osm_way_node_free(wnn);
756 g_debug("#2 distance: %f (%f)", dist_p, pdist);
759 g_debug("Found close way, distance: %f %f (%f)", dist_n, dist_p, pdist);
771 osm_way_get_name(cw);
772 if (cw->type==WAY_MOTORWAY || cw->type==WAY_TRUNK ||
773 cw->type==WAY_PRIMARY || cw->type==WAY_SECONDARY ||
774 cw->type==WAY_TERTIARY) {
778 g_debug("Found way: (ID: %d): [%s]:[%s][%s]", cw->id, cw->name, cw->ref, cw->int_ref);
779 g_debug("T: %d F: %d N#: %d D: %f", cw->type, cw->flags, cw->nodecnt, cw->dist);
780 g_debug("\tNF#: %d NT#: %d (D: %f)", cw->f, cw->t, cw->distance);
785 /* XXX: These two should be combined to save memory */
787 * Get previous node/segment of given way node
791 osm_way_get_prev_node(osm_way *w)
793 sqlite3_reset(sql.select_way_prev_seg);
794 sqlite3_clear_bindings(sql.select_way_prev_seg);
796 if (SQLITE_OK != sqlite3_bind_int(sql.select_way_prev_seg, 1, w->id) ||
797 SQLITE_OK != sqlite3_bind_int(sql.select_way_prev_seg, 2, w->f) ) {
798 g_printerr("Failed to bind values for prev seg\n");
802 if (SQLITE_ROW == sqlite3_step(sql.select_way_prev_seg)) {
803 return osm_way_node_new(
804 sqlite3_column_int(sql.select_way_prev_seg, 0),
805 sqlite3_column_int(sql.select_way_prev_seg, 1),
806 sqlite3_column_int(sql.select_way_prev_seg, 2),
814 * Get next node/segment of given way node
818 osm_way_get_next_node(osm_way *w)
820 sqlite3_reset(sql.select_way_next_seg);
821 sqlite3_clear_bindings(sql.select_way_next_seg);
823 if (SQLITE_OK != sqlite3_bind_int(sql.select_way_next_seg, 1, w->id) ||
824 SQLITE_OK != sqlite3_bind_int(sql.select_way_next_seg, 2, w->f) ) {
825 g_printerr("Failed to bind values for next seg\n");
829 if (SQLITE_ROW == sqlite3_step(sql.select_way_next_seg)) {
830 return osm_way_node_new(
831 sqlite3_column_int(sql.select_way_next_seg, 0),
832 sqlite3_column_int(sql.select_way_next_seg, 1),
833 sqlite3_column_int(sql.select_way_next_seg, 2),
841 * Get list of nodes for given way
845 osm_way_get_nodes(osm_way *w)
850 sqlite3_reset(sql.select_way_nodes);
851 sqlite3_clear_bindings(sql.select_way_nodes);
853 if (SQLITE_OK != sqlite3_bind_int(sql.select_way_nodes, 1, w->id)) {
854 g_printerr("Failed to bind values way nodes\n");
858 while (SQLITE_ROW == sqlite3_step(sql.select_way_nodes)) {
861 n=g_slice_new(osm_way_node);
862 n->id=sqlite3_column_int(sql.select_way_nodes, 0);
863 n->lat=sqlite3_column_int(sql.select_way_nodes, 1);
864 n->lon=sqlite3_column_int(sql.select_way_nodes, 2);
865 w->nodes=g_list_append(w->nodes, n);
868 return (w->nodes==NULL) ? FALSE : TRUE;
876 osm_way_get_name(osm_way *w)
878 sqlite3_reset(sql.select_way_name);
879 sqlite3_clear_bindings(sql.select_way_name);
881 if (SQLITE_OK != sqlite3_bind_int(sql.select_way_name, 1, w->id)) {
882 g_printerr("Failed to bind values for way name\n");
886 if (SQLITE_ROW == sqlite3_step(sql.select_way_name)) {
888 place=sqlite3_column_text(sql.select_way_name, 0);
889 w->name=g_strdup(place);
896 osm_way_get_name_nls(osm_way *w)
898 sqlite3_reset(sql.select_way_name_nls);
899 sqlite3_clear_bindings(sql.select_way_name_nls);
901 if (SQLITE_OK != sqlite3_bind_int(sql.select_way_name_nls, 1, w->id) ||
902 SQLITE_OK != sqlite3_bind_) {
903 g_printerr("Failed to bind values for way name nls\n");
907 if (SQLITE_ROW == sqlite3_step(sql.select_way_name_nls)) {
909 place=sqlite3_column_text(sql.select_way_name_nls, 0);
910 w->name=g_strdup(place);
918 * Get Way ref and int_ref
922 osm_way_get_ref(osm_way *w)
924 sqlite3_reset(sql.select_way_ref);
925 sqlite3_clear_bindings(sql.select_way_ref);
927 if (SQLITE_OK != sqlite3_bind_int(sql.select_way_ref, 1, w->id)) {
928 g_printerr("Failed to bind values for way ref\n");
932 if (SQLITE_ROW == sqlite3_step(sql.select_way_ref)) {
933 const gchar *ref, *int_ref;
934 ref=sqlite3_column_text(sql.select_way_ref, 0);
935 int_ref=sqlite3_column_text(sql.select_way_ref, 1);
936 w->ref=g_strdup(ref);
937 w->int_ref=g_strdup(int_ref);
942 /******************************************************************************/
945 * Try to figure out where the given lat,lon is. Fills in the given struct,
946 * with street, secondary (suburb) and primary (city,town,village) location.
947 * Will try to minimize the amount of database access by skipping queries
948 * if we haven't moved or if we don't know where we are.
952 osm_get_location_data(gint lat, gint lon, gfloat heading, osm_location *map_loc)
955 gboolean check_place=FALSE;
958 if (map_loc->valid==FALSE) {
964 d=calculate_idistance(lat,lon,map_loc->lat,map_loc->lon);
967 /* Check if we are still near the same way as last time */
968 if (map_loc->street && osm_way_distance(lat, lon, map_loc->street->node_f, map_loc->street->node_t, &dist)==TRUE) {
969 /* We are probably on the same way as last time */
970 if ( (dist>(gdouble)way_dist_range) || (fabs(heading-map_loc->heading)>10.0)) {
971 /* We have moved a large amount, check way again */
972 g_debug("Distance %f > %f range or angle %f > 10.0, checking location",
973 dist, way_dist_range, fabs(heading-map_loc->heading));
974 osm_way_free(map_loc->street);
975 map_loc->street=osm_find_nearest_way(lat, lon);
977 map_loc->changed=TRUE;
980 g_printf("*** No change in location: %f %d\n", dist, way_dist_range);
982 /* We are still on the same way as last time */
984 map_loc->changed=FALSE;
989 /* We didn't know our location, so check it, but only if we have moved */
990 if (d>way_dist_range) {
991 g_print("*** Must check location\n");
993 osm_way_free(map_loc->street);
994 map_loc->street=osm_find_nearest_way(lat, lon);
1001 if (!map_loc->street) {
1002 g_print("*** Street not known\n");
1004 map_loc->changed=TRUE;
1006 g_print("*** Street known\n");
1008 map_loc->changed=TRUE;
1013 if (map_loc->changed==TRUE) {
1014 map_loc->heading=heading;
1018 g_printf("NFC: %d\n", map_loc->nfcnt);
1019 g_printf("D: %ld %ld\n", d,(gulong)way_dist_range);
1022 if (check_place==TRUE && d>way_dist_range*4) {
1025 fs=osm_find_nearest_place(NODE_PLACE_SUBURB, lat, lon, &map_loc->secondary);
1026 if (fs==TRUE && map_loc->secondary && map_loc->secondary->isin_p!=0) {
1027 if (osm_place_get(map_loc->secondary->isin_p, lat, lon, &(map_loc->primary))==FALSE) {
1028 if (osm_find_nearest_place(NODE_PLACE_CITY, lat, lon, &map_loc->primary)==TRUE)
1029 g_printf("Near city: %s\n", map_loc->primary->name);
1030 else if (osm_find_nearest_place(NODE_PLACE_TOWN, lat, lon, &map_loc->primary)==TRUE)
1031 g_printf("Near town: %s\n", map_loc->primary->name);
1033 g_printf("Unknown\n");
1035 g_printf("In: %s\n", map_loc->primary ? map_loc->primary->name : "?");
1037 } else if (map_loc->street && map_loc->street->isin_p!=0) {
1038 if (osm_place_get(map_loc->street->isin_p, lat, lon, &map_loc->primary)==FALSE) {
1039 g_printf("Street location not know.\n");
1041 g_printf("Street is in: %s\n", map_loc->primary ? map_loc->primary->name : "?");
1044 if (osm_find_nearest_place(NODE_PLACE_CITY, lat, lon, &map_loc->primary)==TRUE)
1045 g_printf("Near city: %s\n", map_loc->primary->name);
1046 else if (osm_find_nearest_place(NODE_PLACE_TOWN, lat, lon, &map_loc->primary)==TRUE)
1047 g_printf("Near town: %s\n", map_loc->primary->name);
1049 g_printf("Unknown\n");
1054 return map_loc->street ? TRUE : FALSE;
1061 osm_place_search(gdouble lat, gdouble lon, gchar *text, GtkListStore **store)
1066 gchar tmp1[16], tmp2[16];
1069 ltext=g_strdup_printf("%s%%", text);
1071 if (SQLITE_OK != sqlite3_bind_double(sql.select_place_search, 1, lat) ||
1072 SQLITE_OK != sqlite3_bind_double(sql.select_place_search, 2, lon) ||
1073 SQLITE_OK != sqlite3_bind_text(sql.select_place_search, 3, ltext, -1, SQLITE_TRANSIENT)) {
1074 g_printerr("Failed to bind values for sql.select_place_search\n");
1075 sqlite3_clear_bindings(sql.select_place_search);
1083 *store = gtk_list_store_new(ITEM_NUM_COLUMNS,
1084 G_TYPE_INT, /* ID */
1086 G_TYPE_DOUBLE, /* Latitude */
1087 G_TYPE_DOUBLE, /* Longitude */
1088 G_TYPE_DOUBLE, /* Distance */
1089 G_TYPE_STRING, /* Lat/Lon */
1090 G_TYPE_STRING, /* Label */
1091 G_TYPE_STRING, /* Desc. */
1092 G_TYPE_STRING, /* Category */
1093 G_TYPE_STRING, /* Dummy */
1094 G_TYPE_STRING); /* Dummy */
1096 while (SQLITE_ROW == sqlite3_step(sql.select_place_search)) {
1097 gdouble rlat, rlon, dist;
1099 rlat=sqlite3_column_double(sql.select_place_search, 3);
1100 rlon=sqlite3_column_double(sql.select_place_search, 4);
1101 lat_format(_degformat, rlat, tmp1);
1102 lon_format(_degformat, rlon, tmp2);
1103 dist=calculate_distance(lat, lon, rlat, rlon) * UNITS_CONVERT[_units];
1105 gtk_list_store_append(*store, &iter);
1106 gtk_list_store_set(*store, &iter,
1107 ITEM_ID, sqlite3_column_int(sql.select_place_search, 0),
1111 ITEM_LATLON, g_strdup_printf("%s, %s", tmp1, tmp2),
1112 ITEM_LABEL, sqlite3_column_text(sql.select_place_search, 1),
1117 g_printf("Found: %d places\n", rows);
1119 sqlite3_reset(sql.select_place_search);
1120 sqlite3_clear_bindings(sql.select_place_search);
1128 * Search for a street(way) starting with given 'text', next given lat/lon
1132 osm_way_search(gdouble lat, gdouble lon, gchar *text, GtkListStore **store)
1137 gchar tmp1[16], tmp2[16];
1140 g_printf("Way Search: [%s] around %.6f %.6f\n", text, lat, lon);
1142 ltext=g_strdup_printf("%s%%", text);
1144 if (SQLITE_OK != sqlite3_bind_double(sql.select_way_name_search, 1, lat) ||
1145 SQLITE_OK != sqlite3_bind_double(sql.select_way_name_search, 2, lon) ||
1146 SQLITE_OK != sqlite3_bind_int(sql.select_way_name_search, 3, WAY_ROAD_START) ||
1147 SQLITE_OK != sqlite3_bind_int(sql.select_way_name_search, 4, WAY_ROAD_END) ||
1148 SQLITE_OK != sqlite3_bind_double(sql.select_way_name_search, 6, range) ||
1149 SQLITE_OK != sqlite3_bind_text(sql.select_way_name_search, 5, ltext, -1, SQLITE_TRANSIENT)) {
1150 g_printerr("Failed to bind values for sql.select_way_name_search\n");
1151 sqlite3_clear_bindings(sql.select_way_name_search);
1159 *store = gtk_list_store_new(ITEM_NUM_COLUMNS,
1160 G_TYPE_INT, /* ID */
1162 G_TYPE_DOUBLE, /* Latitude */
1163 G_TYPE_DOUBLE, /* Longitude */
1164 G_TYPE_DOUBLE, /* Distance */
1165 G_TYPE_STRING, /* Lat/Lon */
1166 G_TYPE_STRING, /* Label */
1167 G_TYPE_STRING, /* Desc. */
1168 G_TYPE_STRING, /* Category */
1169 G_TYPE_STRING, /* Dummy */
1170 G_TYPE_STRING); /* Dummy */
1172 while (SQLITE_ROW == sqlite3_step(sql.select_way_name_search)) {
1173 gdouble rlat, rlon, dist;
1175 rlat=sqlite3_column_double(sql.select_way_name_search, 3);
1176 rlon=sqlite3_column_double(sql.select_way_name_search, 4);
1177 lat_format(_degformat, rlat, tmp1);
1178 lon_format(_degformat, rlon, tmp2);
1179 dist=calculate_distance(lat, lon, rlat, rlon) * UNITS_CONVERT[_units];
1181 gtk_list_store_append(*store, &iter);
1182 gtk_list_store_set(*store, &iter,
1183 ITEM_ID, sqlite3_column_int(sql.select_way_name_search, 0),
1187 ITEM_LATLON, g_strdup_printf("%s, %s", tmp1, tmp2),
1188 ITEM_LABEL, sqlite3_column_text(sql.select_way_name_search, 1),
1193 g_printf("Found: %d items\n", rows);
1195 sqlite3_reset(sql.select_way_name_search);
1196 sqlite3_clear_bindings(sql.select_way_name_search);