]> err.no Git - mapper/blob - src/osm-db.c
Add min/max zoom fields to repo struct
[mapper] / src / osm-db.c
1 /*
2  * This file is part of mapper
3  *
4  * Copyright (C) 2007 Kaj-Michael Lang
5  *
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.
10  *
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.
15  *
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.
19  */
20 #include "config.h"
21
22 #include <unistd.h>
23 #include <string.h>
24 #include <strings.h>
25 #include <sys/types.h>
26 #include <math.h>
27 #include <glib.h>
28 #include <glib/gstdio.h>
29 #include <glib/gi18n.h>
30 #include <gtk/gtk.h>
31 #include <sqlite3.h>
32
33 #include "osm.h"
34 #include "latlon.h"
35 #include "db.h"
36 #include "osm-db.h"
37 #include "settings.h"
38 #include "osm-sql-tables.h"
39
40 /* #define DEBUG_OSM */
41 #define DEBUG_OSM_TIME
42 #define OSM_PLACE_CACHE_MAX_ITEMS (64)
43
44 #define OSM_DB_PROGRESS_NUM (30000)
45
46 /* Node search ranges */
47 #define OSM_RANGE_START (16384*2)
48 #define OSM_RANGE_STEP  (8192)
49 #define OSM_RANGE_STOP  (65535)
50
51 /* Way range for searching again */
52 #define OSM_RANGE_WAY (12000)
53
54 #ifdef DEBUG_OSM_TIME
55 #define QT_START { g_timer_start(dbt); }
56 #define QT_END { g_timer_stop(dbt); g_debug("Query took: %f sec", g_timer_elapsed(dbt, &tms)); }
57 #else
58 #define QT_START 
59 #define QT_END
60 #endif
61
62 static sqlite3 *osmdb;
63 static gboolean osm_db_ok;
64
65 struct sql_select_stmt {
66         sqlite3_stmt *select_way;
67         sqlite3_stmt *select_way2;
68         sqlite3_stmt *select_way_next_seg;
69         sqlite3_stmt *select_way_prev_seg;
70
71         sqlite3_stmt *select_way_nodes;
72         sqlite3_stmt *select_way_name;
73         sqlite3_stmt *select_way_name_nls;
74         sqlite3_stmt *select_way_name_search;
75         sqlite3_stmt *select_way_ref;
76         sqlite3_stmt *select_place;
77         sqlite3_stmt *select_place_near;
78         sqlite3_stmt *select_place_search;
79
80         sqlite3_stmt *select_node_next;
81         sqlite3_stmt *select_node_prev;
82 };
83 static struct sql_select_stmt sql;
84 static GTimer *dbt;
85 static gulong tms;
86 static GtkProgressBar *dbpw=NULL;
87
88 static const gchar *osm_tables[]={
89         OSM_TABLE_NODES,
90         OSM_TABLE_NODE_TAGS,
91         OSM_TABLE_WAY,
92         OSM_TABLE_WAY_TAGS,
93         OSM_TABLE_WAY_UPDATES,
94         OSM_TABLE_WAY_N2N,
95         OSM_TABLE_WAY_NAMES,
96         OSM_TABLE_WAY_PC,
97         OSM_TABLE_WAY_NAMES_NLS,
98         OSM_TABLE_WAY_REF,
99         OSM_TABLE_PLACES,
100         OSM_TABLE_POI,
101         OSM_TABLE_POI_CATEGORY, 
102         NULL};
103
104 static const gchar *osm_indexes[]={
105         OSM_INDEX_1,
106         OSM_INDEX_2,
107         OSM_INDEX_3,
108         OSM_INDEX_4,
109         OSM_INDEX_5,
110         OSM_INDEX_6,
111         OSM_INDEX_7,
112         OSM_INDEX_8,
113         OSM_INDEX_9,
114         OSM_INDEX_10,
115         OSM_INDEX_11,
116         OSM_INDEX_12,
117         OSM_INDEX_13,
118         OSM_INDEX_14,
119         OSM_INDEX_15,
120         NULL };
121
122 /* Cache hash tables */
123 struct osm_place_cache {
124         GHashTable *cache;
125         guint hit;
126         guint miss;
127 };
128 static struct osm_place_cache pcache;
129
130 static guint way_dist_range=OSM_RANGE_WAY;
131 static gint sid=0;
132
133 osm_way_node *osm_way_get_prev_node(osm_way *w);
134 osm_way_node *osm_way_get_next_node(osm_way *w);
135
136 /*****************************************************************************/
137
138 gboolean
139 osm_db_create(sqlite3 *db)
140 {
141 return db_exec_sql_array(db, osm_tables) && db_exec_sql_array(db, osm_indexes);
142 }
143
144 /*****************************************************************************/
145
146 void
147 osm_set_way_range(guint sr)
148 {
149 way_dist_range=sr;
150 g_debug("way_range set to %d", sr);
151 }
152
153 void
154 osm_set_way_range_from_speed(gfloat speed)
155 {
156 osm_set_way_range(speed>54.0 ? OSM_RANGE_WAY : (OSM_RANGE_WAY-lrint((speed/4)*1000)));
157 }
158
159 /*****************************************************************************/
160
161 static gboolean
162 osm_progress_pulse(void)
163 {
164 if (!dbpw)
165         return FALSE;
166 gtk_progress_bar_pulse(dbpw);
167 return TRUE;
168 }
169
170 static int
171 osm_progress(void *ud)
172 {
173 g_debug("SQL: Running gtk mainloop");
174 #if 1
175 while (gtk_events_pending())
176         gtk_main_iteration();
177 #else
178 gtk_main_iteration_do(FALSE);
179 #endif
180 return 0;
181 }
182
183 static void
184 osm_progress_hide(sqlite3 *db)
185 {
186 if (!dbpw)
187         return;
188 gtk_progress_bar_set_text(dbpw, "");
189 gtk_progress_bar_set_fraction(dbpw, 0.0);
190 }
191
192 static void
193 osm_progress_show(sqlite3 *db)
194 {
195 if (!dbpw)
196         return;
197 gtk_progress_bar_set_text(dbpw, _("Searching..."));
198 gtk_progress_bar_pulse(dbpw);
199 gtk_main_iteration_do(FALSE);
200 }
201
202 void
203 osm_progress_set_widget(sqlite3 *db, GtkProgressBar *w)
204 {
205 if (dbpw!=NULL && w==NULL) {
206         osm_progress_hide(db);
207         if (sid!=0)
208                 g_source_remove(sid);
209         sid=0;
210         dbpw=NULL;
211         return;
212 }
213 dbpw=w;
214 if (w!=NULL) {
215         osm_progress_show(db);
216         sid=g_timeout_add(330, (GSourceFunc)osm_progress_pulse, NULL);
217 }
218 }
219
220 /*****************************************************************************/
221
222 static gboolean
223 osm_db_prepare(sqlite3 *db)
224 {
225 /*****************
226  * Place queries *
227  *****************/
228
229 /* Select nearest place inside lat,lon+-range */
230 DB_PREP(db, "select name,(($LAT-ilat)*($LAT-ilat))+(($LON-ilon)*($LON-ilon)) as d,"
231                                         " ilat,ilon,places.nid,isin_p,isin_c "
232                                         " from places,nodes where type=$TYPE "
233                                         " and nodes.nid=places.nid "
234                                         " and ilat between $LAT-$RANGE and $LAT+$RANGE "
235                                         " and ilon between $LON-$RANGE and $LON+$RANGE "
236                                         " order by d limit 1", 
237                                         sql.select_place_near);
238
239 /* Select place name, distance, location, parent-place and type with given ID */
240 DB_PREP(db, "select name,(($LAT-ilat)*($LAT-ilat))+(($LON-ilon)*($LON-ilon)) as d,"
241                                         " ilat,ilon,type,isin_p,isin_c "
242                                         " from places,nodes where "
243                                         " nodes.nid=places.nid "
244                                         " and places.nid=$NID order by d limit 1",
245                                         sql.select_place);
246
247 /* Search place names */
248 DB_PREP(db, "select places.nid,name,(($LAT-ilat)*($LAT-ilat))+(($LON-ilon)*($LON-ilon)) as d,"
249                                         " rlat,rlon,type,isin_p,isin_c "
250                                         " from places,nodes where "
251                                         " nodes.nid=places.nid "
252                                         " and name like $NAME order by d limit 200",
253                                         sql.select_place_search);
254
255 /***********************
256  * Way related queries *
257  ***********************/
258
259 /* Select nearest ways inside lat,lon+-range */
260 DB_PREP(db, "select w.wid,type,nodes,flags,"
261                                         "(($LAT-n.ilat)*($LAT-n.ilat))+(($LON-n.ilon)*($LON-n.ilon)) as d,wn.f,wn.t,n.ilat,n.ilon "
262                                         " from way as w,way_n2n as wn,nodes as n "
263                                         " where w.wid=wn.wid and wn.f=n.nid "
264                                         " and n.ilat between $LAT-$RANGE and $LAT+$RANGE "
265                                         " and n.ilon between $LON-$RANGE and $LON+$RANGE "
266                                         " and w.type between $WTS and $WTY " 
267                                         " order by d",
268                                         sql.select_way2);
269
270 /* Search way names inside bbox, using both primary and secondary language names */
271 DB_PREP(db, "select w.wid,w.name as name,"
272                                         "(($LAT-ww.lat)*($LAT-ww.lat))+(($LON-ww.lon)*($LON-ww.lon)) as d,ww.lat,ww.lon "
273                                         " from way_names as w,way as ww where "
274                                         " ww.type between $WTS and $WTY and w.wid=ww.wid and w.name like $NAME "
275                                         " and ww.lat between $LAT-$RANGE and $LAT+$RANGE "
276                                         " and ww.lon between $LON-$RANGE and $LON+$RANGE "
277                                         " union "
278                                         " select w.wid,n.name as name,"
279                                         "(($LAT-ww.lat)*($LAT-ww.lat))+(($LON-ww.lon)*($LON-ww.lon)) as d,ww.lat,ww.lon "
280                                         " from way_names as w, way as ww,way_names_nls as n on w.wid=n.wid where "
281                                         " ww.type between $WTS and $WTY and w.wid=ww.wid and n.name like $NAME "
282                                         " and ww.lat between $LAT-$RANGE and $LAT+$RANGE "
283                                         " and ww.lon between $LON-$RANGE and $LON+$RANGE "
284                                         " order by d, name limit 500",
285                                         sql.select_way_name_search);
286
287 /* Get way segment */
288 DB_PREP(db, "select wn.t,ilat,ilon from way_n2n as wn,nodes where wid=? and wn.f=? and wn.t=nodes.nid limit 1",
289                     sql.select_way_next_seg);
290
291 /* Get way segment */
292 DB_PREP(db, "select wn.f,ilat,ilon from way_n2n as wn,nodes where wid=? and wn.t=? and wn.f=nodes.nid limit 1",
293                     sql.select_way_prev_seg);
294
295 /* Get Way name */
296 DB_PREP(db, "select name from way_names where wid=?", sql.select_way_name);
297
298 /* Get Way ref and int_ref */
299 DB_PREP(db, "select ref,int_ref from way_ref where rid=?", sql.select_way_ref);
300
301 /* Get way all way nodes */
302 DB_PREP(db, "select wn.f,ilat,ilon from way_n2n as wn,nodes where wid=? and wn.f=nodes.nid", sql.select_way_nodes);
303
304 /* Get next, prev node + way information. For routing. */
305 DB_PREP(db, "select w.wid,w.type,w.flags,w.speed,n.nid,n.rlat,n.rlon,nn.f,nn.t,n.f,n.l "
306                         "from way as w, nodes as n, way_n2n as nn where w.wid=nn.wid and nn.f=n.nid and nn.f=?",
307                         sql.select_node_next);
308
309 DB_PREP(db, "select w.wid,w.type,w.flags,w.speed,n.nid,n.rlat,n.rlon,nn.f,nn.t,n.f,n.l "
310                         "from way as w, nodes as n, way_n2n as nn where w.wid=nn.wid and nn.f=n.nid and nn.t=?",
311                     sql.select_node_prev);
312
313 return TRUE;
314 }
315
316 void
317 osm_deinit(void)
318 {
319 if (osmdb) {
320         if (sql.select_way_ref)
321                 sqlite3_finalize(sql.select_way_ref);
322         if (sql.select_way_name)
323                 sqlite3_finalize(sql.select_way_name);
324         if (sql.select_way_next_seg)
325                 sqlite3_finalize(sql.select_way_next_seg);
326         if (sql.select_way_prev_seg)
327                 sqlite3_finalize(sql.select_way_prev_seg);
328         if (sql.select_way_name_search)
329                 sqlite3_finalize(sql.select_way_name_search);
330         if (sql.select_way2)
331                 sqlite3_finalize(sql.select_way2);
332         if (sql.select_place)
333                 sqlite3_finalize(sql.select_place);
334         if (sql.select_place_near)
335                 sqlite3_finalize(sql.select_place_near);
336         if (sql.select_node_next)
337                 sqlite3_finalize(sql.select_node_next);
338         if (sql.select_node_prev)
339                 sqlite3_finalize(sql.select_node_prev);
340 }
341 osmdb=NULL;
342 osm_db_ok=FALSE;
343 memset(&sql, 0, sizeof(sql));
344 g_hash_table_destroy(pcache.cache);
345 pcache.cache=NULL;
346 pcache.hit=0;
347 pcache.miss=0;
348 g_timer_destroy(dbt);
349 }
350
351 gboolean
352 osm_init(sqlite3 **db)
353 {
354 osm_db_ok=FALSE;
355 pcache.cache=g_hash_table_new(g_direct_hash, g_direct_equal);
356 dbt=g_timer_new();
357
358 if (!db || !*db) {
359         osmdb=NULL;
360         return FALSE;
361 }
362
363 osmdb=*db;
364 memset(&sql, 0, sizeof(sql));
365 if (osm_db_create(osmdb)==FALSE) {
366         g_printerr("Failed to create OSM tables or indexes: %s", sqlite3_errmsg(osmdb));
367         return FALSE;
368 }
369
370 if (osm_db_prepare(osmdb)==FALSE) {
371         g_printerr("Failed to prepare OSM SQL statements: %s", sqlite3_errmsg(osmdb));
372         return FALSE;
373 }
374 osm_db_ok=TRUE;
375 return TRUE;
376 }
377
378 void
379 osm_db_enable_mainloop(sqlite3 *db, gboolean eml)
380 {
381 if (eml==FALSE)
382         sqlite3_progress_handler(db, OSM_DB_PROGRESS_NUM, NULL, NULL);
383 else
384         sqlite3_progress_handler(db, OSM_DB_PROGRESS_NUM, osm_progress, NULL);
385 }
386
387 /*****************************************************************************/
388
389 osm_way_node *
390 osm_way_node_new(guint id, gint lat, gint lon, gint flags)
391 {
392 osm_way_node *n=g_slice_new(osm_way_node);
393
394 n->id=id;
395 n->lat=lat;
396 n->lon=lon;
397 n->flags=flags;
398 return n;
399 }
400
401 void
402 osm_way_node_free(osm_way_node *n)
403 {
404 if (n)
405         g_slice_free(osm_way_node, n);
406 }
407
408 /**
409  * Free way nodes list 
410  */
411 void
412 osm_way_nodes_free(osm_way *w)
413 {
414 GList *iter;
415
416 if (!w->nodes) 
417         return;
418
419 for (iter=w->nodes; iter!=NULL; iter=iter->next)
420         g_slice_free(osm_way_node, (osm_way_node*)iter->data);
421
422 g_list_free(w->nodes);
423 }
424
425 /**
426  * Free a osm_way structure
427  */
428 void
429 osm_way_free(osm_way *w)
430 {
431 if (!w)
432         return;
433 osm_way_nodes_free(w);
434 if (w->name)
435         g_free(w->name);
436 if (w->ref)
437         g_free(w->ref);
438 if (w->int_ref)
439         g_free(w->int_ref);
440 g_slice_free(osm_way, w);
441 }
442
443 /*****************************************************************************/
444
445 static void
446 osm_place_free(osm_place *p)
447 {
448 if (p->name)
449         g_free(p->name);
450 g_slice_free(osm_place, p);
451 }
452
453 static gboolean
454 osm_place_remove(gpointer k, gpointer v, gpointer ud)
455 {
456 osm_place_free((osm_place *)v);
457 return TRUE;
458 }
459
460 static osm_place *
461 osm_place_new(void)
462 {
463 return g_slice_new0(osm_place);
464 }
465
466 static osm_place *
467 osm_place_cache_lookup(guint32 id)
468 {
469 osm_place *r;
470 r=g_hash_table_lookup(pcache.cache, GINT_TO_POINTER(id));
471 if (r) 
472         pcache.hit++; 
473 else 
474         pcache.miss++;
475
476 g_debug("OSM: Cache %d/%d", pcache.hit, pcache.miss);
477 return r;
478 }
479
480 static void
481 osm_place_cache_add(osm_place *p)
482 {
483 if (osm_place_cache_lookup(p->id)==NULL)
484         g_hash_table_insert(pcache.cache, GINT_TO_POINTER(p->id), p);
485 }
486
487 static void
488 osm_place_cache_gc(void)
489 {
490 guint r;
491
492 r=g_hash_table_foreach_remove(pcache.cache, osm_place_remove, NULL);
493 g_debug("OSM: Cache cleared (%d)", r);
494 pcache.hit=0;
495 pcache.miss=0;
496 }
497
498 static void
499 osm_place_update_distance(osm_place *p, gint lat, gint lon)
500 {
501 gdouble lam, lom;
502
503 lam=(gdouble)((lat-p->lat)*(lat-p->lat));
504 lom=(gdouble)((lon-p->lon)*(lon-p->lon));
505
506 p->dist=sqrt(lam+lom);
507 }
508
509 /**
510  * Get place with given id and distance to current location
511  */
512 gboolean
513 osm_place_get(guint32 id, gint lat, gint lon, osm_place **nr)
514 {
515 osm_place *n;
516
517 g_return_val_if_fail(sql.select_place, FALSE);
518
519 n=*nr;
520 n=osm_place_cache_lookup(id);
521 if (n) {
522         osm_place_update_distance(n, lat, lon);
523         return TRUE;
524 }
525 n=NULL;
526
527 /* XXX: better place for this */
528 if (g_hash_table_size(pcache.cache)>OSM_PLACE_CACHE_MAX_ITEMS)
529         osm_place_cache_gc();
530
531 sqlite3_clear_bindings(sql.select_place);
532 sqlite3_reset(sql.select_place);
533
534 if (SQLITE_OK != sqlite3_bind_int(sql.select_place, 1, lat) ||
535     SQLITE_OK != sqlite3_bind_int(sql.select_place, 2, lon) ||
536     SQLITE_OK != sqlite3_bind_int(sql.select_place, 3, id)) {
537         g_warning("Failed to bind values for place");
538         return FALSE;
539 }
540
541 QT_START
542 if (SQLITE_ROW == sqlite3_step(sql.select_place)) {
543         const gchar *place;
544         guint32 dist;
545
546         n=osm_place_new();
547         place=sqlite3_column_text(sql.select_place, 0);
548         n->name=g_strdup(place);
549         dist=sqlite3_column_int(sql.select_place, 1);
550         n->dist=sqrt((double)dist);
551         n->lat=sqlite3_column_int(sql.select_place, 2);
552         n->lon=sqlite3_column_int(sql.select_place, 3);
553         n->type=sqlite3_column_int(sql.select_place, 4);
554         n->isin_p=sqlite3_column_int(sql.select_place, 5);
555 /*      n->isin_c=sqlite3_column_int(sql.select_place, 6); */
556         return TRUE;
557 }
558 QT_END
559 return FALSE;
560 }
561
562 /**
563  * Search for the nearest place with given type
564  */
565 gboolean
566 osm_find_nearest_place(node_type_t type, gint lat, gint lon, osm_place **nr)
567 {
568 gint range;
569 osm_place *n=NULL;
570
571 g_return_val_if_fail(sql.select_place_near, FALSE);
572
573 switch (type) {
574         case NODE_PLACE_SUBURB:
575                 range=95000;
576         break;
577         case NODE_PLACE_CITY:
578         case NODE_PLACE_TOWN:
579                 range=250000;
580         break;
581         case NODE_PLACE_HAMLET:
582         case NODE_PLACE_VILLAGE:
583                 range=100000;
584         break;
585         default:
586                 range=90000;
587         break;
588 }
589
590 sqlite3_clear_bindings(sql.select_place_near);
591 sqlite3_reset(sql.select_place_near);
592
593 if (SQLITE_OK != sqlite3_bind_int(sql.select_place_near, 1, lat) ||
594     SQLITE_OK != sqlite3_bind_int(sql.select_place_near, 2, lon) ||
595     SQLITE_OK != sqlite3_bind_int(sql.select_place_near, 3, type) ||
596     SQLITE_OK != sqlite3_bind_int(sql.select_place_near, 4, range)) {
597         g_warning("Failed to bind values for near place");
598         return FALSE;
599 }
600
601 n=osm_place_new();
602 n->isin_p=n->lat=n->lon=n->dist=0;
603 QT_START
604 if (SQLITE_ROW == sqlite3_step(sql.select_place_near)) {
605         const gchar *place;
606         guint32 dist;
607
608         place=sqlite3_column_text(sql.select_place_near, 0);
609         n->name=g_strdup(place);
610         dist=sqlite3_column_int(sql.select_place_near, 1);
611         n->dist=sqrt((double)dist);
612         n->lat=sqlite3_column_int(sql.select_place_near, 2);
613         n->lon=sqlite3_column_int(sql.select_place_near, 3);
614         n->id=sqlite3_column_int(sql.select_place_near, 4);
615         n->isin_p=sqlite3_column_int(sql.select_place_near, 5);
616 /*      n->isin_c=sqlite3_column_int(sql.select_place_near, 6); */
617         n->type=type;
618
619         QT_END
620         osm_place_cache_add(n);
621
622         *nr=n;
623         return TRUE;
624 }
625 *nr=n;
626 return FALSE;
627 }
628
629 /*
630  * Way helper 
631  *
632  */
633 static GList *
634 osm_find_nearest_way_nodes(gint lat, gint lon, guint range)
635 {
636 GList *ways=NULL;
637 osm_way *w;
638 guint wc=0;
639
640 g_return_val_if_fail(sql.select_way2, NULL);
641
642 sqlite3_reset(sql.select_way2);
643 sqlite3_clear_bindings(sql.select_way2);
644
645 if (SQLITE_OK != sqlite3_bind_int(sql.select_way2, 1, lat) ||
646     SQLITE_OK != sqlite3_bind_int(sql.select_way2, 2, lon) ||
647     SQLITE_OK != sqlite3_bind_int(sql.select_way2, 3, range) ||
648     SQLITE_OK != sqlite3_bind_int(sql.select_way2, 4, WAY_ROAD_START) ||
649     SQLITE_OK != sqlite3_bind_int(sql.select_way2, 5, WAY_ROAD_END)) {
650         g_warning("Failed to bind values for way");
651         return NULL;
652 }
653
654 QT_START
655 while (SQLITE_ROW == sqlite3_step(sql.select_way2)) {
656         guint32 dist;
657         gint lat, lon;
658
659         wc++;
660         w=g_slice_new0(osm_way);
661         w->id=sqlite3_column_int(sql.select_way2, 0);
662         w->type=sqlite3_column_int(sql.select_way2, 1);
663         w->nodecnt=sqlite3_column_int(sql.select_way2, 2);
664         w->flags=sqlite3_column_int(sql.select_way2, 3);
665         dist=sqlite3_column_int(sql.select_way2, 4);
666         w->dist=sqrt((gdouble)dist);
667         w->f=sqlite3_column_int(sql.select_way2, 5);
668         w->t=sqlite3_column_int(sql.select_way2, 6);
669
670         lat=sqlite3_column_int(sql.select_way2, 7);
671         lon=sqlite3_column_int(sql.select_way2, 8);
672
673         w->node_f=osm_way_node_new(w->f, lat, lon, 0);
674
675         ways=g_list_prepend(ways, w);
676 }
677 QT_END
678
679 return ways;
680 }
681
682 /*****************************************************************************/
683
684 GSList *
685 osm_get_route_node(guint nid, osm_node_direction d)
686 {
687 GSList *r=NULL;
688 osm_way *w;
689 guint wc=0;
690 sqlite3_stmt *psql=NULL;
691
692 g_return_val_if_fail(sql.select_node_next, FALSE);
693 g_return_val_if_fail(sql.select_node_prev, FALSE);
694
695 switch (d) {
696         case OSM_NODE_NEXT:
697                 psql=sql.select_node_next;
698         break;
699         case OSM_NODE_PREV:
700                 psql=sql.select_node_prev;
701         break;
702         default:
703                 g_assert_not_reached();
704         break;
705 }
706
707 sqlite3_reset(psql);
708 sqlite3_clear_bindings(psql);
709
710 if (SQLITE_OK != sqlite3_bind_int(psql, 1, nid)) {
711         g_warning("Failed to bind values for route node");
712         return NULL;
713 }
714
715 while (SQLITE_ROW == sqlite3_step(psql)) {
716         gdouble lat, lon;
717
718         wc++;
719         w=g_slice_new0(osm_way);
720         w->id=sqlite3_column_int(psql, 0);
721         w->type=sqlite3_column_int(psql, 1);
722         w->flags=sqlite3_column_int(psql, 2);
723         w->speed=sqlite3_column_int(psql, 3);
724
725         lat=sqlite3_column_double(psql, 5);
726         lon=sqlite3_column_double(psql, 6);
727
728         w->f=sqlite3_column_int(psql, 7);
729         w->t=sqlite3_column_int(psql, 8);
730 #if 0
731         w->node=
732         w->node->flags=sqlite3_column_int(psql, 9);
733         w->node->links=sqlite3_column_int(psql, 10);
734 #endif
735
736         r=g_slist_prepend(r, w);
737 }
738
739 return r;
740 }
741
742
743 /*****************************************************************************/
744 gboolean 
745 osm_way_distance(gint lat, gint lon, osm_way_node *f, osm_way_node *t, gdouble *d)
746 {
747 if (!f) {
748         return FALSE;
749 }
750
751 if (!t) {
752         return FALSE;
753 }
754
755 return distance_point_to_line((gdouble)lon, (gdouble)lat, (gdouble)f->lon, (gdouble)f->lat, (gdouble)t->lon, (gdouble)t->lat, d);
756 }
757
758 /**
759  * Search for the nearest way (road)
760  * - First search for ways with nearest node
761  * - If only one is returned then we are done.
762  * - If more than one, go trough the results:
763  *   - Load nodes for the way, check prev/next nodes
764  *   - Store result if closer than before
765  * - Return closest way
766  */
767
768 #define START_DIST (900000.0)
769
770 osm_way *
771 osm_find_nearest_way(gint lat, gint lon)
772 {
773 GList *iter;
774 GList *w=NULL;
775 guint range=OSM_RANGE_START;
776 osm_way *cw=NULL;
777 guint found_ways=0;
778 gdouble pdist=START_DIST, dist_n, dist_p;
779
780 while ((w=osm_find_nearest_way_nodes(lat, lon, range))==NULL && range<=OSM_RANGE_STOP) {
781         range+=OSM_RANGE_STEP;
782         g_debug("Trying with range: %d", range);
783 }
784 found_ways=g_list_length(w);
785 g_debug("Found %d ways withing range %d", found_ways, range);
786
787 if (found_ways==0)
788         return NULL;
789
790 for (iter=w; iter!=NULL; iter=iter->next) {
791         osm_way_node *wnn;
792         osm_way_node *wnp;
793         osm_way *way=(osm_way*)iter->data;
794
795         way->node_t=NULL;
796
797         wnn=osm_way_get_next_node(way);
798         if (osm_way_distance(lat, lon, way->node_f, wnn, &dist_n)==FALSE) {
799                 osm_way_node_free(wnn);
800                 dist_n=START_DIST;
801         } else if (dist_n<pdist) { /* Is it near ?*/
802                 pdist=dist_n;
803                 cw=way;
804                 way->distance=dist_n;
805                 way->node_t=wnn;
806         } else {
807                 dist_n=START_DIST;
808         }
809
810         g_debug("WayN: #%d (T:%d), %d nodes, near [%d-%d], D: %.2f (Valid: %s)",
811                 way->id, way->type, way->nodecnt, way->f, way->t, dist_n, dist_n==START_DIST ? "F" : "T");
812
813         wnp=osm_way_get_prev_node(way);
814         if (osm_way_distance(lat, lon, way->node_f, wnp, &dist_p)==FALSE) {
815                 osm_way_node_free(wnp);
816                 dist_p=START_DIST;
817         } else if (dist_p<pdist) {
818                 pdist=dist_p;
819                 cw=way;
820                 way->distance=dist_n;
821                 if (way->node_t) {
822                         osm_way_node_free(wnn);
823                 }
824                 way->node_t=wnp;
825         } else {
826                 dist_p=START_DIST;
827         }
828
829         g_debug("WayP: #%d (T:%d), %d nodes, near [%d-%d], D: %.2f (Valid: %s)",
830                 way->id, way->type, way->nodecnt, way->f, way->t, dist_p, dist_p==START_DIST ? "F" : "T");
831
832         if (!cw) {
833                 osm_way_free(way);
834                 way=NULL;
835         }
836 }
837
838 g_list_free(w);
839 if (cw==NULL)
840         return NULL;
841
842 osm_way_get_name(cw);
843 if (cw->type==WAY_MOTORWAY || cw->type==WAY_TRUNK || 
844         cw->type==WAY_PRIMARY  || cw->type==WAY_SECONDARY || cw->type==WAY_TERTIARY) {
845                 osm_way_get_ref(cw);
846 }
847 osm_way_get_nodes(cw);
848
849 g_debug("Found: (#%d): [%s]:[%s][%s]", cw->id, cw->name, cw->ref, cw->int_ref);
850 g_debug("T: %d F: %d N#: %d D: %.2f", cw->type, cw->flags, cw->nodecnt, cw->dist);
851 g_debug("NF#: %d NT#: %d (DC: %.2f)", cw->f, cw->t, cw->distance);
852
853 return cw;
854 }
855
856 /* XXX: These two should be combined to save memory */
857 /**
858  * Get previous node/segment of given way node
859  *
860  */
861 osm_way_node *
862 osm_way_get_prev_node(osm_way *w)
863 {
864 g_return_val_if_fail(sql.select_way_prev_seg, NULL);
865
866 sqlite3_reset(sql.select_way_prev_seg);
867 sqlite3_clear_bindings(sql.select_way_prev_seg);
868
869 if (SQLITE_OK != sqlite3_bind_int(sql.select_way_prev_seg, 1, w->id) ||
870         SQLITE_OK != sqlite3_bind_int(sql.select_way_prev_seg, 2, w->f)  ) {
871         g_warning("Failed to bind values for prev seg");
872         return NULL;
873 }
874
875 if (SQLITE_ROW == sqlite3_step(sql.select_way_prev_seg)) {
876         return osm_way_node_new(
877                 sqlite3_column_int(sql.select_way_prev_seg, 0),
878                 sqlite3_column_int(sql.select_way_prev_seg, 1),
879                 sqlite3_column_int(sql.select_way_prev_seg, 2),
880                 0);
881 }
882
883 return NULL;
884 }
885
886 /**
887  * Get next node/segment of given way node
888  *
889  */
890 osm_way_node *
891 osm_way_get_next_node(osm_way *w)
892 {
893 g_return_val_if_fail(sql.select_way_next_seg, NULL);
894
895 sqlite3_reset(sql.select_way_next_seg);
896 sqlite3_clear_bindings(sql.select_way_next_seg);
897
898 if (SQLITE_OK != sqlite3_bind_int(sql.select_way_next_seg, 1, w->id) ||
899         SQLITE_OK != sqlite3_bind_int(sql.select_way_next_seg, 2, w->f)  ) {
900         g_warning("Failed to bind values for next seg");
901         return NULL;
902 }
903
904 if (SQLITE_ROW == sqlite3_step(sql.select_way_next_seg)) {
905         return osm_way_node_new(
906                 sqlite3_column_int(sql.select_way_next_seg, 0),
907                 sqlite3_column_int(sql.select_way_next_seg, 1),
908                 sqlite3_column_int(sql.select_way_next_seg, 2),
909                 0);
910 }
911
912 return NULL;
913 }
914
915 /**
916  * Get list of nodes for given way
917  *
918  */
919 gboolean
920 osm_way_get_nodes(osm_way *w)
921 {
922 if (w->nodes!=NULL)
923         return TRUE;
924
925 g_return_val_if_fail(sql.select_way_nodes, FALSE);
926
927 sqlite3_reset(sql.select_way_nodes);
928 sqlite3_clear_bindings(sql.select_way_nodes);
929
930 if (SQLITE_OK != sqlite3_bind_int(sql.select_way_nodes, 1, w->id)) {
931         g_warning("Failed to bind values for way nodes");
932         return FALSE;
933 }
934
935 while (SQLITE_ROW == sqlite3_step(sql.select_way_nodes)) {
936         osm_way_node *n;
937
938         n=g_slice_new(osm_way_node);
939         n->id=sqlite3_column_int(sql.select_way_nodes, 0);
940         n->lat=sqlite3_column_int(sql.select_way_nodes, 1);
941         n->lon=sqlite3_column_int(sql.select_way_nodes, 2);
942         w->nodes=g_list_append(w->nodes, n);
943 }
944
945 return (w->nodes==NULL) ? FALSE : TRUE;
946 }
947
948 /**
949  * Get way name
950  *
951  */
952 gboolean
953 osm_way_get_name(osm_way *w)
954 {
955 g_return_val_if_fail(sql.select_way_name, FALSE);
956
957 sqlite3_reset(sql.select_way_name);
958 sqlite3_clear_bindings(sql.select_way_name);
959
960 if (SQLITE_OK != sqlite3_bind_int(sql.select_way_name, 1, w->id)) {
961         g_warning("Failed to bind values for way name");
962         return FALSE;
963 }
964
965 if (SQLITE_ROW == sqlite3_step(sql.select_way_name)) {
966         const gchar *place;
967         place=sqlite3_column_text(sql.select_way_name, 0);
968         w->name=g_strdup(place);
969 }
970 return FALSE;
971 }
972
973 #if 0
974 gboolean
975 osm_way_get_name_nls(osm_way *w)
976 {
977 g_return_val_if_fail(sql.select_way_name_nls, FALSE);
978
979 sqlite3_reset(sql.select_way_name_nls);
980 sqlite3_clear_bindings(sql.select_way_name_nls);
981
982 if (SQLITE_OK != sqlite3_bind_int(sql.select_way_name_nls, 1, w->id) ||
983         SQLITE_OK != sqlite3_bind_) {
984         g_warning("Failed to bind values for way name nls");
985         return FALSE;
986 }
987
988 if (SQLITE_ROW == sqlite3_step(sql.select_way_name_nls)) {
989         const gchar *place;
990         place=sqlite3_column_text(sql.select_way_name_nls, 0);
991         w->name=g_strdup(place);
992 }
993 return FALSE;
994 }
995 #endif
996
997
998 /**
999  * Get Way ref and int_ref
1000  *
1001  */
1002 gboolean
1003 osm_way_get_ref(osm_way *w)
1004 {
1005 g_return_val_if_fail(sql.select_way_ref, FALSE);
1006
1007 sqlite3_reset(sql.select_way_ref);
1008 sqlite3_clear_bindings(sql.select_way_ref);
1009
1010 if (SQLITE_OK != sqlite3_bind_int(sql.select_way_ref, 1, w->id)) {
1011         g_warning("Failed to bind values for way ref");
1012         return FALSE;
1013 }
1014
1015 if (SQLITE_ROW == sqlite3_step(sql.select_way_ref)) {
1016         const gchar *ref, *int_ref;
1017         ref=sqlite3_column_text(sql.select_way_ref, 0);
1018         int_ref=sqlite3_column_text(sql.select_way_ref, 1);
1019         w->ref=g_strdup(ref);
1020         w->int_ref=g_strdup(int_ref);
1021 }
1022 return FALSE;
1023 }
1024
1025 /******************************************************************************/
1026
1027 /**
1028  * Check if we have moved away from the last known street
1029  */
1030 gboolean
1031 osm_check_location(osm_location *map_loc, gint lat, gint lon)
1032 {
1033 gdouble dist;
1034 if (map_loc->street && osm_way_distance(lat, lon, map_loc->street->node_f, map_loc->street->node_t, &dist)==TRUE) {
1035         return (dist>(gdouble)way_dist_range) ? FALSE : TRUE;
1036 } else
1037         return FALSE;
1038 }
1039
1040 /**
1041  * Try to figure out where the given lat,lon is. Fills in the given struct,
1042  * with street, secondary (suburb) and primary (city,town,village) location.
1043  * Will try to minimize the amount of database access by skipping queries
1044  * if we haven't moved or if we don't know where we are.
1045  *
1046  */
1047 gboolean 
1048 osm_get_location_data(gint lat, gint lon, gfloat heading, osm_location *map_loc)
1049 {
1050 gdouble dist;
1051 gboolean check_place=FALSE;
1052 gulong d;
1053
1054 /* Check 10 times, if location is not known then assume we are in here-be-dragons land */
1055 if (map_loc->nfcnt>10) {
1056         time_t t;
1057         t=time(NULL)-map_loc->last_valid; 
1058         if (t<30) {
1059                 g_debug("Here be dragons");
1060                 return FALSE;
1061         } else {
1062                 g_debug("Trying again");
1063                 map_loc->last_valid=time(NULL);
1064                 map_loc->nfcnt=0;
1065                 map_loc->valid=FALSE;
1066         }
1067 }
1068
1069 if (map_loc->valid==FALSE) {
1070         map_loc->lat=lat;
1071         map_loc->lon=lon;
1072         map_loc->valid=TRUE;
1073         d=way_dist_range*5;
1074 } else {
1075         d=calculate_idistance(lat,lon,map_loc->lat,map_loc->lon);
1076 }
1077
1078 /* Check if we are still near the same way as last time */
1079 if (map_loc->street && osm_way_distance(lat, lon, map_loc->street->node_f, map_loc->street->node_t, &dist)==TRUE) {
1080         /* We are probably on the same way as last time, 
1081            but check if the distance is over a limit or our heading has changed significantly.
1082      */
1083         if ( (dist>(gdouble)way_dist_range) || (fabs(angle_diff(heading, map_loc->heading))>15.0)) {
1084                 /* We have moved a large amount, check way again */
1085                 g_debug("Distance %.2f > %.2f range or angle %f > 15.0, checking location", 
1086                         dist, (gdouble)way_dist_range, fabs(heading-map_loc->heading));
1087                 osm_way_free(map_loc->street);
1088                 map_loc->street=osm_find_nearest_way(lat, lon);
1089                 check_place=TRUE;
1090                 map_loc->changed=TRUE;
1091         } else {
1092                 g_debug("*** No change in location: %f %d", dist, way_dist_range);
1093                 /* We are still on the same way as last time */
1094                 check_place=FALSE;
1095                 map_loc->changed=FALSE;
1096         }
1097         map_loc->lat=lat;
1098         map_loc->lon=lon;
1099 } else {
1100         /* We didn't know our location, so check it, but only if we have moved */
1101         if (d>way_dist_range) {
1102                 g_debug("*** Must check location");
1103                 check_place=TRUE;
1104                 osm_way_free(map_loc->street);
1105                 map_loc->street=osm_find_nearest_way(lat, lon);
1106 #if 0
1107                 map_loc->lat=lat;
1108                 map_loc->lon=lon;
1109 #endif
1110         } 
1111
1112         if (!map_loc->street) {
1113                 g_debug("*** Street not known");
1114                 map_loc->nfcnt++;
1115                 map_loc->changed=TRUE;
1116         } else {
1117                 g_debug("*** Street known");
1118                 map_loc->nfcnt=0;
1119                 map_loc->last_valid=time(NULL);
1120                 map_loc->changed=TRUE;
1121                 check_place=TRUE;
1122         }
1123 }
1124
1125 if (map_loc->changed==TRUE) {
1126         map_loc->heading=heading;
1127 }
1128
1129 g_debug("NotFoundCounter: %d", map_loc->nfcnt);
1130 g_debug("D: %ld %ld", d, (gulong)way_dist_range);
1131
1132 if (check_place==TRUE || d>way_dist_range*4) {
1133         gboolean fs;
1134
1135         fs=osm_find_nearest_place(NODE_PLACE_SUBURB, lat, lon, &map_loc->secondary);
1136         if (fs==TRUE && map_loc->secondary && map_loc->secondary->isin_p!=0) {
1137                 if (osm_place_get(map_loc->secondary->isin_p, lat, lon, &(map_loc->primary))==FALSE) {
1138                         if (osm_find_nearest_place(NODE_PLACE_CITY, lat, lon, &map_loc->primary)==TRUE)
1139                                 g_debug("Near city: %s", map_loc->primary->name);
1140                         else if (osm_find_nearest_place(NODE_PLACE_TOWN, lat, lon, &map_loc->primary)==TRUE)
1141                                 g_debug("Near town: %s", map_loc->primary->name);
1142                         else {
1143                                 g_assert(map_loc->primary!=NULL);
1144                                 g_debug("Unknown");
1145                         }
1146                 } else {
1147                         g_debug("In: %s", map_loc->primary ? map_loc->primary->name : "?");
1148                 }
1149         } else if (map_loc->street && map_loc->street->isin_p!=0) {
1150                 if (osm_place_get(map_loc->street->isin_p, lat, lon, &map_loc->primary)==FALSE) {
1151                         g_debug("Street location not know.");
1152                 } else {
1153                         g_debug("Street is in: %s", map_loc->primary ? map_loc->primary->name : "?");
1154                 }
1155         } else {
1156                 if (osm_find_nearest_place(NODE_PLACE_CITY, lat, lon, &map_loc->primary)==TRUE)
1157                         g_debug("Near city: %s", map_loc->primary->name);
1158                 else if (osm_find_nearest_place(NODE_PLACE_TOWN, lat, lon, &map_loc->primary)==TRUE)
1159                         g_debug("Near town: %s", map_loc->primary->name);
1160                 else {
1161                         g_assert(map_loc->primary!=NULL);
1162                         g_debug("Unknown");
1163                 }
1164         }
1165 }
1166
1167 return map_loc->street ? TRUE : FALSE;
1168 }
1169
1170 /**
1171  * osm_place_search
1172  */
1173 gboolean
1174 osm_place_search(gdouble lat, gdouble lon, gchar *text, GtkListStore **store)
1175 {
1176 GtkTreeIter iter;
1177 gchar *ltext=NULL;
1178 guint rows=0;
1179 gchar tmp1[16], tmp2[16];
1180 gdouble range=6;
1181
1182 g_return_val_if_fail(sql.select_place_search, FALSE);
1183 g_return_val_if_fail(text, FALSE);
1184
1185 ltext=g_strdup_printf("%s%%", text);
1186
1187 if (SQLITE_OK != sqlite3_bind_double(sql.select_place_search, 1, lat) ||
1188     SQLITE_OK != sqlite3_bind_double(sql.select_place_search, 2, lon) ||
1189         SQLITE_OK != sqlite3_bind_text(sql.select_place_search,   3, ltext, -1, SQLITE_TRANSIENT)) {
1190                 g_warning("Failed to bind values for sql.select_place_search");
1191                 sqlite3_clear_bindings(sql.select_place_search);
1192                 g_free(ltext);
1193                 return FALSE;
1194 }
1195
1196 if (ltext)
1197         g_free(ltext);
1198
1199 *store = gtk_list_store_new(ITEM_NUM_COLUMNS, 
1200                                 G_TYPE_INT,             /* ID */
1201                                 G_TYPE_INT,             /*  */
1202                                 G_TYPE_DOUBLE,  /* Latitude */
1203                                 G_TYPE_DOUBLE,  /* Longitude */
1204                                 G_TYPE_DOUBLE,  /* Distance */
1205                                 G_TYPE_STRING,  /* Lat/Lon */
1206                                 G_TYPE_STRING,  /* Label */
1207                                 G_TYPE_STRING,  /* Desc. */
1208                                 G_TYPE_STRING,  /* Category */
1209                                 G_TYPE_STRING,  /* Dummy */
1210                                 G_TYPE_STRING); /* Dummy */
1211
1212 while (SQLITE_ROW == sqlite3_step(sql.select_place_search)) {
1213         gdouble rlat, rlon, dist;
1214
1215         rlat=sqlite3_column_double(sql.select_place_search, 3);
1216         rlon=sqlite3_column_double(sql.select_place_search, 4);
1217         lat_format(_degformat, rlat, tmp1);
1218         lon_format(_degformat, rlon, tmp2);
1219         dist=calculate_distance(lat, lon, rlat, rlon) * UNITS_CONVERT[_units];
1220
1221         gtk_list_store_append(*store, &iter);
1222         gtk_list_store_set(*store, &iter,
1223                 ITEM_ID, sqlite3_column_int(sql.select_place_search, 0),
1224                 ITEM_LAT, rlat,
1225                 ITEM_LON, rlon,
1226                 ITEM_DIST, dist,
1227                 ITEM_LATLON, g_strdup_printf("%s, %s", tmp1, tmp2),
1228                 ITEM_LABEL, sqlite3_column_text(sql.select_place_search, 1),
1229                 -1);
1230         rows++;
1231 }
1232
1233 g_debug("Found: %d places", rows);
1234
1235 sqlite3_reset(sql.select_place_search);
1236 sqlite3_clear_bindings(sql.select_place_search);
1237
1238 return TRUE;
1239 }
1240
1241 /**
1242  * osm_way_search
1243  *
1244  * Search for a street(way) starting with given 'text', next given lat/lon
1245  *
1246  */
1247 gboolean
1248 osm_way_search(gdouble lat, gdouble lon, gchar *text, GtkListStore **store)
1249 {
1250 GtkTreeIter iter;
1251 gchar *ltext=NULL;
1252 guint rows=0;
1253 gchar tmp1[16], tmp2[16];
1254 gdouble range=6;
1255
1256 g_return_val_if_fail(sql.select_way_name_search, FALSE);
1257 g_return_val_if_fail(text, FALSE);
1258
1259 g_debug("Way Search: [%s] around %.6f %.6f", text, lat, lon);
1260
1261 ltext=g_strdup_printf("%s%%", text);
1262
1263 if (SQLITE_OK != sqlite3_bind_double(sql.select_way_name_search, 1, lat) ||
1264     SQLITE_OK != sqlite3_bind_double(sql.select_way_name_search, 2, lon) ||
1265     SQLITE_OK != sqlite3_bind_int(sql.select_way_name_search,    3, WAY_ROAD_START) ||
1266     SQLITE_OK != sqlite3_bind_int(sql.select_way_name_search,    4, WAY_ROAD_END) ||
1267     SQLITE_OK != sqlite3_bind_double(sql.select_way_name_search, 6, range) ||
1268         SQLITE_OK != sqlite3_bind_text(sql.select_way_name_search,   5, ltext, -1, SQLITE_TRANSIENT)) {
1269                 g_warning("Failed to bind values for sql.select_way_name_search");
1270                 sqlite3_clear_bindings(sql.select_way_name_search);
1271                 g_free(ltext);
1272                 return FALSE;
1273 }
1274
1275 if (ltext)
1276         g_free(ltext);
1277
1278 *store = gtk_list_store_new(ITEM_NUM_COLUMNS, 
1279                                 G_TYPE_INT,             /* ID */
1280                                 G_TYPE_INT,             /*  */
1281                                 G_TYPE_DOUBLE,  /* Latitude */
1282                                 G_TYPE_DOUBLE,  /* Longitude */
1283                                 G_TYPE_DOUBLE,  /* Distance */
1284                                 G_TYPE_STRING,  /* Lat/Lon */
1285                                 G_TYPE_STRING,  /* Label */
1286                                 G_TYPE_STRING,  /* Desc. */
1287                                 G_TYPE_STRING,  /* Category */
1288                                 G_TYPE_STRING,  /* Dummy */
1289                                 G_TYPE_STRING); /* Dummy */
1290
1291 while (SQLITE_ROW == sqlite3_step(sql.select_way_name_search)) {
1292         gdouble rlat, rlon, dist;
1293
1294         rlat=sqlite3_column_double(sql.select_way_name_search, 3);
1295         rlon=sqlite3_column_double(sql.select_way_name_search, 4);
1296         lat_format(_degformat, rlat, tmp1);
1297         lon_format(_degformat, rlon, tmp2);
1298         dist=calculate_distance(lat, lon, rlat, rlon) * UNITS_CONVERT[_units];
1299
1300         gtk_list_store_append(*store, &iter);
1301         gtk_list_store_set(*store, &iter,
1302                 ITEM_ID, sqlite3_column_int(sql.select_way_name_search, 0),
1303                 ITEM_LAT, rlat,
1304                 ITEM_LON, rlon,
1305                 ITEM_DIST, dist,
1306                 ITEM_LATLON, g_strdup_printf("%s, %s", tmp1, tmp2),
1307                 ITEM_LABEL, sqlite3_column_text(sql.select_way_name_search, 1),
1308                 -1);
1309         rows++;
1310 }
1311
1312 g_debug("Found: %d items", rows);
1313
1314 sqlite3_reset(sql.select_way_name_search);
1315 sqlite3_clear_bindings(sql.select_way_name_search);
1316
1317 return TRUE;
1318 }