]> err.no Git - mapper/blob - src/osm-db.c
Many many changes.
[mapper] / src / osm-db.c
1 #define _GNU_SOURCE
2
3 #include <unistd.h>
4 #include <string.h>
5 #include <strings.h>
6 #include <sys/types.h>
7 #include <math.h>
8 #include <glib.h>
9 #include <glib/gstdio.h>
10 #include <gtk/gtk.h>
11 #include <sqlite3.h>
12
13 #include "osm.h"
14 #include "latlon.h"
15 #include "gps.h"
16 #include "osm-db.h"
17
18 /* #define DEBUG_OSM */
19 #define OSM_PLACE_CACHE_MAX_ITEMS (64)
20 #define OSM_DB_PROGRESS_NUM (5000)
21 #define OSM_RANGE_START (8192)
22 #define OSM_RANGE_STEP  (8192)
23 #define OSM_RANGE_STOP  (49152)
24
25 struct sql_select_stmt {
26         sqlite3_stmt *select_way;
27         sqlite3_stmt *select_way2;
28         sqlite3_stmt *select_way_next_seg;
29         sqlite3_stmt *select_way_prev_seg;
30
31         sqlite3_stmt *select_way_nodes;
32         sqlite3_stmt *select_way_name;
33         sqlite3_stmt *select_way_name_nls;
34         sqlite3_stmt *select_way_ref;
35         sqlite3_stmt *select_place;
36         sqlite3_stmt *select_near_place;
37 };
38 static struct sql_select_stmt sql;
39 static GTimer *dbt;
40 static GtkProgressBar *dbpw=NULL;
41
42 /* Cache hash tables */
43 static GHashTable *_place_cache;
44
45 static guint way_dist_range=OSM_RANGE_WAY;
46
47 osm_way_node *osm_way_get_prev_node(osm_way *w);
48 osm_way_node *osm_way_get_next_node(osm_way *w);
49
50 /*****************************************************************************/
51
52 void
53 osm_set_way_range(guint sr)
54 {
55 way_dist_range=sr;
56 }
57
58 void
59 osm_set_way_range_from_speed(gfloat speed)
60 {
61 if (speed>54.0)
62         way_dist_range=OSM_RANGE_WAY*2;
63 else
64         way_dist_range=OSM_RANGE_WAY-lrint((speed/4)*1000);
65 }
66
67 static int
68 osm_progress(void *ud)
69 {
70 if (!dbpw)
71         return 0;
72 gtk_progress_bar_pulse(dbpw);
73 gtk_main_iteration_do(FALSE);
74 return 0;
75 }
76
77 static void
78 osm_progress_hide(sqlite3 *db)
79 {
80 if (!dbpw)
81         return;
82 gtk_widget_hide(GTK_WIDGET(dbpw));
83 sqlite3_progress_handler(db, OSM_DB_PROGRESS_NUM, NULL, NULL);
84 }
85
86 static void
87 osm_progress_show(sqlite3 *db)
88 {
89 if (!dbpw)
90         return;
91 gtk_widget_show(GTK_WIDGET(dbpw));
92 sqlite3_progress_handler(db, OSM_DB_PROGRESS_NUM, osm_progress, NULL);
93 }
94
95 void
96 osm_progress_set_widget(sqlite3 *db, GtkProgressBar *w)
97 {
98 if (dbpw!=NULL && w==NULL)
99         osm_progress_hide(db);
100 dbpw=w;
101 if (w!=NULL)
102         osm_progress_show(db);
103 }
104
105 gboolean
106 osm_db_prepare(sqlite3 *db)
107 {
108 /* Place */
109 /* Select nearest place inside lat,lon+-range */
110 if (sqlite3_prepare_v2(db, "select name,(($LAT-lat)*($LAT-lat))+(($LON-lon)*($LON-lon)) as dist,"
111                                         " lat,lon,places.nid,isin "
112                                         " from places,nodes where type=$TYPE "
113                                         " and nodes.nid=places.nid "
114                                         " and lat between $LAT-$RANGE and $LAT+$RANGE"
115                                         " and lon between $LON-$RANGE and $LON+$RANGE order by dist limit 1",
116                     -1, &sql.select_near_place, NULL)!=SQLITE_OK)
117         return FALSE;
118
119 /* Select place name, distance, location, parent-place and type with given ID */
120 if (sqlite3_prepare_v2(db, "select name,(($LAT-lat)*($LAT-lat))+(($LON-lon)*($LON-lon)) as dist,"
121                                         " lat,lon,type,isin "
122                                         " from places,nodes where "
123                                         " nodes.nid=places.nid "
124                                         " and places.nid=$NID order by dist limit 1",
125                     -1, &sql.select_place, NULL)!=SQLITE_OK)
126         return FALSE;
127
128 /* Ways */
129 /* Select neareset ways inside lat,lon+-range */
130 if (sqlite3_prepare_v2(db, "select wid,type,nodes,flags,"
131                                         "(($LAT-lat)*($LAT-lat))+(($LON-lon)*($LON-lon)) as d,f,t,lat,lon "
132                                         " from way as w,way_s2s as ws,nodes as n "
133                                         " where w.wid=ws.wsid and ws.f=n.nid "
134                                         " and n.lat between $LAT-$RANGE and $LAT+$RANGE "
135                                         " and n.lon between $LON-$RANGE and $LON+$RANGE "
136                                         " and w.type between $WTS and $WTY " 
137                                         " order by d",
138                     -1, &sql.select_way2, NULL)!=SQLITE_OK)
139         return FALSE;
140
141 if (sqlite3_prepare_v2(db, "select t,lat,lon from way_s2s,nodes where wsid=? and f=? and way_s2s.t=nodes.nid limit 1",
142                     -1, &sql.select_way_next_seg, NULL)!=SQLITE_OK)
143         return FALSE;
144
145 if (sqlite3_prepare_v2(db, "select f,lat,lon from way_s2s,nodes where wsid=? and t=? and way_s2s.f=nodes.nid limit 1",
146                     -1, &sql.select_way_prev_seg, NULL)!=SQLITE_OK)
147         return FALSE;
148
149 /* Way name */
150 if (sqlite3_prepare_v2(db, "select name from way_names where wid=?",
151                     -1, &sql.select_way_name, NULL)!=SQLITE_OK)
152         return FALSE;
153 #if 0
154 if (sqlite3_prepare_v2(db, "select name from way_names_nls where wid=? and lang=?",
155                     -1, &sql.select_way_name, NULL)!=SQLITE_OK)
156         return FALSE;
157 #endif
158
159 /* Way ref and int_ref */
160 if (sqlite3_prepare_v2(db, "select ref,int_ref from way_ref where rid=?",
161                     -1, &sql.select_way_ref, NULL)!=SQLITE_OK)
162         return FALSE;
163
164 return TRUE;
165 }
166
167 gboolean
168 osm_init(void)
169 {
170 _place_cache=g_hash_table_new(g_direct_hash, g_direct_equal);
171 dbt=g_timer_new();
172 return TRUE;
173 }
174
175 void
176 osm_deinit(void)
177 {
178 g_hash_table_destroy(_place_cache);
179 g_timer_destroy(dbt);
180 }
181
182 /*****************************************************************************/
183
184 osm_way_node *
185 osm_way_node_new(guint id, gint lat, gint lon, gint flags)
186 {
187 osm_way_node *n=g_slice_new(osm_way_node);
188
189 n->id=id;
190 n->lat=lat;
191 n->lon=lon;
192 n->flags=flags;
193 return n;
194 }
195
196 void
197 osm_way_node_free(osm_way_node *n)
198 {
199 if (n)
200         g_slice_free(osm_way_node, n);
201 }
202
203 /**
204  * Free way nodes list 
205  */
206 void
207 osm_way_nodes_free(osm_way *w)
208 {
209 GList *iter;
210
211 if (!w->nodes) 
212         return;
213
214 for (iter=w->nodes; iter!=NULL; iter=iter->next)
215         g_slice_free(osm_way_node, (osm_way_node*)iter->data);
216
217 g_list_free(w->nodes);
218 }
219
220 /**
221  * Free a osm_way structure
222  */
223 void
224 osm_way_free(osm_way *w)
225 {
226 if (!w)
227         return;
228 osm_way_nodes_free(w);
229 if (w->name)
230         g_free(w->name);
231 if (w->ref)
232         g_free(w->ref);
233 if (w->int_ref)
234         g_free(w->int_ref);
235 g_slice_free(osm_way, w);
236 }
237
238 /*****************************************************************************/
239
240 static void
241 osm_place_free(osm_place *p)
242 {
243 if (p->name)
244         g_free(p->name);
245 g_slice_free(osm_place, p);
246 }
247
248 static gboolean
249 osm_place_remove(gpointer k, gpointer v, gpointer ud)
250 {
251 osm_place_free((osm_place *)v);
252 return TRUE;
253 }
254
255 static osm_place *
256 osm_place_new(void)
257 {
258 return g_slice_new0(osm_place);
259 }
260
261 static osm_place *
262 osm_place_cache_lookup(guint32 id)
263 {
264 return g_hash_table_lookup(_place_cache, GINT_TO_POINTER(id));
265 }
266
267 static void
268 osm_place_cache_add(osm_place *p)
269 {
270 if (osm_place_cache_lookup(p->id)==NULL)
271         g_hash_table_insert(_place_cache, GINT_TO_POINTER(p->id), p);
272 }
273
274 static void
275 osm_place_cache_gc(void)
276 {
277 gint r;
278 r=g_hash_table_foreach_remove(_place_cache, osm_place_remove, NULL);
279 }
280
281 static void
282 osm_place_update_distance(osm_place *p, gint lat, gint lon)
283 {
284 gdouble lam, lom;
285
286 lam=(gdouble)((lat-p->lat)*(lat-p->lat));
287 lom=(gdouble)((lon-p->lon)*(lon-p->lon));
288
289 p->dist=sqrt(lam+lom);
290 }
291
292 /**
293  * Get place with given id and distance to current location
294  */
295 gboolean
296 osm_place_get(guint32 id, gint lat, gint lon, osm_place **nr)
297 {
298 osm_place *n;
299
300 n=*nr;
301 n=osm_place_cache_lookup(id);
302 if (n) {
303         g_print("*P!\n");
304         osm_place_update_distance(n, lat, lon);
305         return TRUE;
306 }
307 n=NULL;
308
309 /* XXX: better place for this */
310 if (g_hash_table_size(_place_cache)>OSM_PLACE_CACHE_MAX_ITEMS)
311         osm_place_cache_gc();
312
313 sqlite3_clear_bindings(sql.select_place);
314 sqlite3_reset(sql.select_place);
315
316 if (SQLITE_OK != sqlite3_bind_int(sql.select_place, 1, lat) ||
317     SQLITE_OK != sqlite3_bind_int(sql.select_place, 2, lon) ||
318     SQLITE_OK != sqlite3_bind_int(sql.select_place, 3, id)) {
319         g_printerr("Failed to bind values for place\n");
320         return FALSE;
321 }
322
323 if (SQLITE_ROW == sqlite3_step(sql.select_place)) {
324         const gchar *place;
325         guint32 dist;
326
327         n=osm_place_new();
328         place=sqlite3_column_text(sql.select_place, 0);
329         n->name=g_strdup(place);
330         dist=sqlite3_column_int(sql.select_place, 1);
331         n->dist=sqrt((double)dist);
332         n->lat=sqlite3_column_int(sql.select_place, 2);
333         n->lon=sqlite3_column_int(sql.select_place, 3);
334         n->type=sqlite3_column_int(sql.select_place, 4);
335         n->isin=sqlite3_column_int(sql.select_place, 5);
336         return TRUE;
337 }
338 return FALSE;
339 }
340
341 /**
342  * Search for the nearest place, type
343  */
344 gboolean
345 osm_find_nearest_place(node_type_t type, gint lat, gint lon, osm_place **nr)
346 {
347 gint range;
348 osm_place *n=NULL;
349
350 switch (type) {
351         case NODE_PLACE_SUBURB:
352                 range=95000;
353         break;
354         case NODE_PLACE_CITY:
355         case NODE_PLACE_TOWN:
356                 range=250000;
357         break;
358         case NODE_PLACE_HAMLET:
359         case NODE_PLACE_VILLAGE:
360                 range=100000;
361         break;
362         default:
363                 range=90000;
364         break;
365 }
366
367 sqlite3_clear_bindings(sql.select_near_place);
368 sqlite3_reset(sql.select_near_place);
369
370 if (SQLITE_OK != sqlite3_bind_int(sql.select_near_place, 1, lat) ||
371     SQLITE_OK != sqlite3_bind_int(sql.select_near_place, 2, lon) ||
372     SQLITE_OK != sqlite3_bind_int(sql.select_near_place, 3, type) ||
373     SQLITE_OK != sqlite3_bind_int(sql.select_near_place, 4, range)) {
374         g_printerr("Failed to bind values for near place\n");
375         return FALSE;
376 }
377
378 n=osm_place_new();
379 n->isin=n->lat=n->lon=n->dist=0;
380 if (SQLITE_ROW == sqlite3_step(sql.select_near_place)) {
381         const gchar *place;
382         guint32 dist;
383
384         place=sqlite3_column_text(sql.select_near_place, 0);
385         n->name=g_strdup(place);
386         dist=sqlite3_column_int(sql.select_near_place, 1);
387         n->dist=sqrt((double)dist);
388         n->lat=sqlite3_column_int(sql.select_near_place, 2);
389         n->lon=sqlite3_column_int(sql.select_near_place, 3);
390         n->id=sqlite3_column_int(sql.select_near_place, 4);
391         n->isin=sqlite3_column_int(sql.select_near_place, 5);
392         n->type=type;
393
394         osm_place_cache_add(n);
395
396         *nr=n;
397         return TRUE;
398 }
399 *nr=n;
400 return FALSE;
401 }
402
403 /* Way helper */
404 static GList *
405 osm_find_nearest_way_nodes(gint lat, gint lon, guint range)
406 {
407 GList *ways=NULL;
408 osm_way *w;
409 gulong tms;
410 gint wc=0;
411
412 sqlite3_reset(sql.select_way2);
413 sqlite3_clear_bindings(sql.select_way2);
414
415 if (SQLITE_OK != sqlite3_bind_int(sql.select_way2, 1, lat) ||
416     SQLITE_OK != sqlite3_bind_int(sql.select_way2, 2, lon) ||
417     SQLITE_OK != sqlite3_bind_int(sql.select_way2, 3, range) ||
418     SQLITE_OK != sqlite3_bind_int(sql.select_way2, 4, WAY_ROAD_START) ||
419     SQLITE_OK != sqlite3_bind_int(sql.select_way2, 5, WAY_ROAD_END)) {
420         g_printerr("Failed to bind values for way\n");
421         return NULL;
422 }
423
424 g_timer_start(dbt);
425
426 while (SQLITE_ROW == sqlite3_step(sql.select_way2)) {
427         guint32 dist;
428         gint lat, lon;
429
430         wc++;
431         w=g_slice_new0(osm_way);
432         w->id=sqlite3_column_int(sql.select_way2, 0);
433         w->type=sqlite3_column_int(sql.select_way2, 1);
434         w->nodecnt=sqlite3_column_int(sql.select_way2, 2);
435         w->flags=sqlite3_column_int(sql.select_way2, 3);
436         dist=sqlite3_column_int(sql.select_way2, 4);
437         w->dist=sqrt((gdouble)dist);
438         w->f=sqlite3_column_int(sql.select_way2, 5);
439         w->t=sqlite3_column_int(sql.select_way2, 6);
440
441         lat=sqlite3_column_int(sql.select_way2, 7);
442         lon=sqlite3_column_int(sql.select_way2, 8);
443
444         w->node_f=osm_way_node_new(w->f, lat, lon, 0);
445
446         ways=g_list_prepend(ways, w);
447 }
448
449 g_timer_stop(dbt);
450 g_printf("Query took: %f sec, found: %d ways\n", g_timer_elapsed(dbt, &tms), wc);
451
452 return ways;
453 }
454
455 /*****************************************************************************/
456
457 static inline gdouble 
458 magnitude(gdouble x1, gdouble y1, gdouble x2, gdouble y2)
459 {
460 gdouble x,y;
461 x=x2-x1;
462 y=y2-y1;
463
464 return sqrt((x*x)+(y*y));
465 }
466
467 static gboolean 
468 distance_point_to_line(gdouble x, gdouble y, gdouble x1, gdouble y1, gdouble x2, gdouble y2, gdouble *d)
469 {
470 gdouble lm,u,tmp;
471 gdouble ix,iy;
472
473 lm=magnitude(x1,y1,x2,y2);
474 if (lm==0.0f)
475         return FALSE;
476
477 tmp=((x-x1)*(x2-x1))+((y-y1)*(y2-y1));
478 u=tmp/(lm*lm);
479
480 if (u<0.0f || u>1.0f)
481         return FALSE;
482  
483 ix=x1+u*(x2-x1);
484 iy=y1+u*(y2-y1);
485  
486 *d=magnitude(x,y, ix, iy);
487  
488 return TRUE;
489 }
490
491 gboolean 
492 osm_way_distance(gint lat, gint lon, osm_way_node *f, osm_way_node *t, gdouble *d)
493 {
494 if (!f) {
495         return FALSE;
496 }
497
498 if (!t) {
499         return FALSE;
500 }
501
502 return distance_point_to_line((gdouble)lon, (gdouble)lat, (gdouble)f->lon, (gdouble)f->lat, (gdouble)t->lon, (gdouble)t->lat, d);
503 }
504
505 /**
506  * Search for the nearest way (road)
507  * - First search for ways with nearest node
508  * - If only one is returned then we are done.
509  * - If more than one, go trough the results:
510  *   - Load nodes for the way, check prev/next nodes
511  *   - Store result if closer than before
512  * - Return closest way
513  */
514
515 #define START_DIST (900000.0)
516
517 osm_way *
518 osm_find_nearest_way(gint lat, gint lon)
519 {
520 GList *iter;
521 GList *w=NULL;
522 guint range=OSM_RANGE_START;
523 osm_way *cw=NULL;
524 gdouble pdist=START_DIST, dist_n, dist_p;
525
526 while ((w=osm_find_nearest_way_nodes(lat, lon, range))==NULL && range<=OSM_RANGE_STOP) {
527         range+=OSM_RANGE_STEP;
528         g_printf("Trying with range: %d\n", range);
529 }
530
531 #ifdef DEBUG_OSM
532 g_printf("Found ways: %d\n", g_list_length(w));
533 #endif
534
535 if (g_list_length(w)==0)
536         return NULL;
537
538 for (iter=w; iter!=NULL; iter=iter->next) {
539         osm_way_node *wnn;
540         osm_way_node *wnp;
541         osm_way *way=(osm_way*)iter->data;
542
543 #ifdef DEBUG_OSM
544         g_printf("WAY %d (%d) HAS %d NODES, nearest is %d\n", 
545                 way->id, way->type, way->nodecnt, way->f);
546 #endif
547
548         way->node_t=NULL;
549
550         wnn=osm_way_get_next_node(way);
551         if (osm_way_distance(lat, lon, way->node_f, wnn, &dist_n)==FALSE) {
552                 osm_way_node_free(wnn);
553                 dist_n=START_DIST;
554         } else if (dist_n<pdist) {
555                 pdist=dist_n;
556                 cw=way;
557                 way->distance=dist_n;
558                 way->node_t=wnn;
559                 g_printf("#1 distance: %f (%f)\n", dist_n, pdist);
560         }
561
562         wnp=osm_way_get_prev_node(way);
563         if (osm_way_distance(lat, lon, way->node_f, wnp, &dist_p)==FALSE) {
564                 osm_way_node_free(wnp);
565                 dist_p=START_DIST;
566         } else if (dist_p<pdist) {
567                 pdist=dist_p;
568                 cw=way;
569                 way->distance=dist_n;
570                 if (way->node_t) {
571                         osm_way_node_free(wnn);
572                 }
573                 way->node_t=wnp;
574                 g_printf("#2 distance: %f (%f)\n", dist_p, pdist);
575         }
576
577 #ifdef DEBUG_OSM
578         g_printf("Found close way, distance: %f %f (%f)\n", dist_n, dist_p, pdist);
579 #endif
580
581         if (!cw) {
582                 osm_way_free(way);
583                 way=NULL;
584         }
585 }
586
587 g_list_free(w);
588 if (cw==NULL)
589         return NULL;
590
591 osm_way_get_name(cw);
592 if (cw->type==WAY_MOTORWAY || cw->type==WAY_TRUNK || 
593         cw->type==WAY_PRIMARY || cw->type==WAY_SECONDARY ||
594         cw->type==WAY_TERTIARY) {
595                 osm_way_get_ref(cw);
596 }
597
598 #ifdef DEBUG_OSM
599 g_printf("BEST WAY(%d): %s (%s,%s)\n", 
600         cw->id, cw->name, cw->ref, cw->int_ref);
601 g_printf("\tT: %d F: %d N: %d D: %f\n", 
602         cw->type, cw->flags, cw->nodecnt, cw->dist);
603 g_printf("\tNF: %d NT: %d DT %f\n", 
604         cw->node_f->num, 
605         cw->node_t->num, cw->distance);
606 #endif
607
608 return cw;
609 }
610
611 osm_way_node *
612 osm_way_get_prev_node(osm_way *w)
613 {
614 sqlite3_reset(sql.select_way_prev_seg);
615 sqlite3_clear_bindings(sql.select_way_prev_seg);
616
617 if (SQLITE_OK != sqlite3_bind_int(sql.select_way_prev_seg, 1, w->id) ||
618         SQLITE_OK != sqlite3_bind_int(sql.select_way_prev_seg, 2, w->f)  ) {
619         g_printerr("Failed to bind values for prev seg\n");
620         return NULL;
621 }
622
623 if (SQLITE_ROW == sqlite3_step(sql.select_way_prev_seg)) {
624         return osm_way_node_new(
625                 sqlite3_column_int(sql.select_way_prev_seg, 0),
626                 sqlite3_column_int(sql.select_way_prev_seg, 1),
627                 sqlite3_column_int(sql.select_way_prev_seg, 2),
628                 0);
629 }
630
631 return NULL;
632 }
633
634 osm_way_node *
635 osm_way_get_next_node(osm_way *w)
636 {
637 sqlite3_reset(sql.select_way_next_seg);
638 sqlite3_clear_bindings(sql.select_way_next_seg);
639
640 if (SQLITE_OK != sqlite3_bind_int(sql.select_way_next_seg, 1, w->id) ||
641         SQLITE_OK != sqlite3_bind_int(sql.select_way_next_seg, 2, w->f)  ) {
642         g_printerr("Failed to bind values for next seg\n");
643         return NULL;
644 }
645
646 if (SQLITE_ROW == sqlite3_step(sql.select_way_next_seg)) {
647         return osm_way_node_new(
648                 sqlite3_column_int(sql.select_way_next_seg, 0),
649                 sqlite3_column_int(sql.select_way_next_seg, 1),
650                 sqlite3_column_int(sql.select_way_next_seg, 2),
651                 0);
652 }
653
654 return NULL;
655 }
656
657 /**
658  * Get list of nodes for given way
659  */
660 gboolean
661 osm_way_get_nodes(osm_way *w)
662 {
663 if (w->nodes!=NULL)
664         return TRUE;
665
666 sqlite3_reset(sql.select_way_nodes);
667 sqlite3_clear_bindings(sql.select_way_nodes);
668
669 if (SQLITE_OK != sqlite3_bind_int(sql.select_way_nodes, 1, w->id)) {
670         g_printerr("Failed to bind values way nodes\n");
671         return FALSE;
672 }
673
674 while (SQLITE_ROW == sqlite3_step(sql.select_way_nodes)) {
675         osm_way_node *n;
676
677         n=g_slice_new(osm_way_node);
678         n->id=sqlite3_column_int(sql.select_way_nodes, 0);
679         n->lat=sqlite3_column_int(sql.select_way_nodes, 1);
680         n->lon=sqlite3_column_int(sql.select_way_nodes, 2);
681         w->nodes=g_list_append(w->nodes, n);
682 }
683
684 return (w->nodes==NULL) ? FALSE : TRUE;
685 }
686
687 /**
688  * Get way name
689  */
690 gboolean
691 osm_way_get_name(osm_way *w)
692 {
693 sqlite3_reset(sql.select_way_name);
694 sqlite3_clear_bindings(sql.select_way_name);
695
696 if (SQLITE_OK != sqlite3_bind_int(sql.select_way_name, 1, w->id)) {
697         g_printerr("Failed to bind values for way name\n");
698         return FALSE;
699 }
700
701 if (SQLITE_ROW == sqlite3_step(sql.select_way_name)) {
702         const gchar *place;
703         place=sqlite3_column_text(sql.select_way_name, 0);
704         w->name=g_strdup(place);
705 }
706 return FALSE;
707 }
708
709 #if 0
710 gboolean
711 osm_way_get_name_nls(osm_way *w)
712 {
713 sqlite3_reset(sql.select_way_name_nls);
714 sqlite3_clear_bindings(sql.select_way_name_nls);
715
716 if (SQLITE_OK != sqlite3_bind_int(sql.select_way_name_nls, 1, w->id) ||
717         SQLITE_OK != sqlite3_bind_) {
718         g_printerr("Failed to bind values for way name nls\n");
719         return FALSE;
720 }
721
722 if (SQLITE_ROW == sqlite3_step(sql.select_way_name_nls)) {
723         const gchar *place;
724         place=sqlite3_column_text(sql.select_way_name_nls, 0);
725         w->name=g_strdup(place);
726 }
727 return FALSE;
728 }
729 #endif
730
731
732 /**
733  * Get Way ref and int_ref
734  */
735 gboolean
736 osm_way_get_ref(osm_way *w)
737 {
738 sqlite3_reset(sql.select_way_ref);
739 sqlite3_clear_bindings(sql.select_way_ref);
740
741 if (SQLITE_OK != sqlite3_bind_int(sql.select_way_ref, 1, w->id)) {
742         g_printerr("Failed to bind values for way ref\n");
743         return FALSE;
744 }
745
746 if (SQLITE_ROW == sqlite3_step(sql.select_way_ref)) {
747         const gchar *ref, *int_ref;
748         ref=sqlite3_column_text(sql.select_way_ref, 0);
749         int_ref=sqlite3_column_text(sql.select_way_ref, 1);
750         w->ref=g_strdup(ref);
751         w->int_ref=g_strdup(int_ref);
752 }
753 return FALSE;
754 }
755
756 /******************************************************************************/
757
758 /**
759  * Try to figure out where the given lat,lon is. Fills in the given struct,
760  * with street, secondary (suburb) and primary (city,town,village) location.
761  * Will try to minimize the amount of database access by skipping queries
762  * if we haven't moved or if we don't know where we are.
763  *
764  */
765 gboolean 
766 osm_get_location_data(gint lat, gint lon, osm_location *map_loc)
767 {
768 gdouble dist;
769 gboolean check_place=FALSE;
770 gulong d;
771
772 if (map_loc->valid==FALSE) {
773         map_loc->lat=lat;
774         map_loc->lon=lon;
775         map_loc->valid=TRUE;
776         d=way_dist_range*5;
777 } else {
778         d=calculate_idistance(lat,lon,map_loc->lat,map_loc->lon);
779 }
780
781 /* Check if we are still near the same way as last time */
782 if (map_loc->street && osm_way_distance(lat, lon, map_loc->street->node_f, map_loc->street->node_t, &dist)==TRUE) {
783         /* We are probably on the same way as last time */
784         if ( (dist>(gdouble)way_dist_range) || (fabs(_gps.heading-map_loc->heading)>10.0)) {
785                 /* We have moved a large amount, check way again */
786                 g_printf("*** dist %f over range, checking again\n", dist);
787                 osm_way_free(map_loc->street);
788                 map_loc->street=osm_find_nearest_way(lat, lon);
789                 check_place=TRUE;
790                 map_loc->changed=TRUE;
791         } else {
792                 g_printf("*** No change in location: %f %d\n", dist, way_dist_range);
793                 /* We are still on the same way as last time */
794                 check_place=FALSE;
795                 map_loc->changed=FALSE;
796         }
797         map_loc->lat=lat;
798         map_loc->lon=lon;
799 } else {
800         /* We didn't know our location, so check it, but only if we have moved */
801         if (d>way_dist_range) {
802                 g_print("*** Must check location\n");
803                 osm_way_free(map_loc->street);
804                 map_loc->street=osm_find_nearest_way(lat, lon);
805 #if 0
806                 map_loc->lat=lat;
807                 map_loc->lon=lon;
808 #endif
809         } 
810
811         if (!map_loc->street) {
812                 g_print("*** Street not known\n");
813                 map_loc->changed=TRUE;
814         } else {
815                 g_print("*** Street known\n");
816                 map_loc->changed=TRUE;
817                 check_place=TRUE;
818         }
819 }
820
821 if (map_loc->changed==TRUE) {
822         map_loc->heading=_gps.heading;
823         map_loc->speed=_gps.speed;
824 }
825
826 g_printf("D: %ld %ld\n", d,(gulong)way_dist_range);
827
828 if (check_place==TRUE && d>way_dist_range*4) {
829         gboolean fs;
830
831         fs=osm_find_nearest_place(NODE_PLACE_SUBURB, lat, lon, &map_loc->secondary);
832         if (fs==TRUE && map_loc->secondary && map_loc->secondary->isin!=0) {
833                 if (osm_place_get(map_loc->secondary->isin, lat, lon, &(map_loc->primary))==FALSE) {
834                         if (osm_find_nearest_place(NODE_PLACE_CITY, lat, lon, &map_loc->primary)==TRUE)
835                                 g_printf("Near city: %s\n", map_loc->primary->name);
836                         else if (osm_find_nearest_place(NODE_PLACE_TOWN, lat, lon, &map_loc->primary)==TRUE)
837                                 g_printf("Near town: %s\n", map_loc->primary->name);
838                         else
839                                 g_printf("Unknown\n");
840                 } else {
841                         g_printf("In: %s\n", map_loc->primary ? map_loc->primary->name : "?");
842                 }
843         } else if (map_loc->street && map_loc->street->isin!=0) {
844                 if (osm_place_get(map_loc->street->isin, lat, lon, &map_loc->primary)==FALSE) {
845                         g_printf("Street location not know.\n");
846                 } else {
847                         g_printf("Street is in: %s\n", map_loc->primary ? map_loc->primary->name : "?");
848                 }
849         } else {
850                 if (osm_find_nearest_place(NODE_PLACE_CITY, lat, lon, &map_loc->primary)==TRUE)
851                         g_printf("Near city: %s\n", map_loc->primary->name);
852                 else if (osm_find_nearest_place(NODE_PLACE_TOWN, lat, lon, &map_loc->primary)==TRUE)
853                         g_printf("Near town: %s\n", map_loc->primary->name);
854                 else
855                         g_printf("Unknown\n");
856
857         }
858 }
859
860 g_print("------\n\n");
861
862 return map_loc->street ? TRUE : FALSE;
863 }