}
void
-map_set_place_information(osm_place *s, osm_place *mp, osm_place *sp, PoiInfo *p)
+map_set_place_information(osm_way *s, osm_place *mp, osm_place *sp, PoiInfo *p)
{
gchar buffer[256];
snprintf(buffer, sizeof(buffer), "On %s%s%s%s%s%s%s",
- s->name ? s->name : "Unknown street",
+ s ? s->name ? s->name : "unknown" : "?",
(p && p->label) ? " near " : "",
(p && p->label) ? p->label : "",
sp->name ? " in " : "",
sp->name ? sp->name : "",
- mp->name ? " in City " : "",
+ mp->name ? " in " : "",
mp->name ? mp->name : "");
gtk_label_set_label(GTK_LABEL(_info_banner), buffer);
}
gint ux, uy;
gint ilat, ilon;
gdouble lat,lon;
-osm_place street;
+osm_way *street;
osm_place mplace;
osm_place splace;
PoiInfo *p;
ilat=lat2mp_int(lat);
ilon=lon2mp_int(lon);
-street.name=NULL;
-street.isin=0;
mplace.name=NULL;
splace.name=NULL;
g_printf("IntPos: %d , %d\n", ilat, ilon);
-#if 0
-osm_find_nearest_way(ilat, ilon, &street);
-#endif
+street=osm_find_nearest_way(ilat, ilon);
+if (street)
+ g_printf("WAY: %d %s %s\n", street->id, street->name, street->ref);
p=poi_find_nearest(lat, lon);
if (osm_find_nearest_place(NODE_PLACE_SUBURB, ilat, ilon, &splace)==TRUE)
g_printf("Near suburb: %s (%d)\n", splace.name, splace.isin);
-if (splace.isin!=0 && street.isin==0) {
+if (splace.isin!=0) {
if (osm_place_get(splace.isin, ilat, ilon, &mplace)==FALSE) {
if (osm_find_nearest_place(NODE_PLACE_CITY, ilat, ilon, &mplace)==TRUE)
g_printf("Near city: %s\n", mplace.name);
} else {
g_printf("In %s\n", mplace.name);
}
-} else if (street.isin!=0) {
- if (osm_place_get(street.isin, ilat, ilon, &mplace)==FALSE) {
+} else if (street && street->isin!=0) {
+ if (osm_place_get(street->isin, ilat, ilon, &mplace)==FALSE) {
} else {
g_printf("In %s\n", mplace.name);
}
-map_set_place_information(&street, &mplace, &splace, p);
+map_set_place_information(street, &mplace, &splace, p);
}
gboolean map_cb_scroll_event(GtkWidget * widget, GdkEventScroll * event)
};
static struct sql_select_stmt sql;
+gboolean osm_way_get_nodes(osm_way *w);
+
gboolean
osm_db_prepare(sqlite3 *db)
{
-1, &sql.select_place, NULL)!=SQLITE_OK)
return FALSE;
-return TRUE;
/* Ways */
/* Select neareset ways inside lat,lon+-range */
-if (sqlite3_prepare_v2(db, "select wid from way,way_seg,nodes,"
- "(($LAT-lat)*($LAT-lat))+(($LON-lon)*($LON-lon)) as dist"
+if (sqlite3_prepare_v2(db, "select wid,type,nodes,flags,"
+ "(($LAT-lat)*($LAT-lat))+(($LON-lon)*($LON-lon)) as dist, num"
+ " from way,way_seg,nodes"
" where wid=wsid and way_seg.node=nodes.nid "
- " and nodes.lat between $LAT-$RANGE and $LAT+$RANGE "
- " and nodes.lon between $LON-$RANGE and $LON+$RANGE "
+ " and lat between $LAT-$RANGE and $LAT+$RANGE "
+ " and lon between $LON-$RANGE and $LON+$RANGE "
" order by dist",
- -1, &sql.select_way_name, NULL)!=SQLITE_OK)
+ -1, &sql.select_way, NULL)!=SQLITE_OK)
return FALSE;
/* Select way nodes */
if (SQLITE_OK != sqlite3_bind_int(sql.select_place, 1, lat) ||
SQLITE_OK != sqlite3_bind_int(sql.select_place, 2, lon) ||
SQLITE_OK != sqlite3_bind_int(sql.select_place, 3, id)) {
- g_printerr("Failed to bind values\n");
+ g_printerr("Failed to bind values for place\n");
return FALSE;
}
place=sqlite3_column_text(sql.select_place, 0);
n->name=g_strdup(place);
- n->dist=sqlite3_column_int(sql.select_place, 1);
- n->dist=sqrt(n->dist);
+ dist=sqlite3_column_int(sql.select_place, 1);
+ n->dist=sqrt((double)dist);
n->lat=sqlite3_column_int(sql.select_place, 2);
n->lon=sqlite3_column_int(sql.select_place, 3);
n->type=sqlite3_column_int(sql.select_place, 4);
SQLITE_OK != sqlite3_bind_int(sql.select_near_place, 2, lon) ||
SQLITE_OK != sqlite3_bind_int(sql.select_near_place, 3, type) ||
SQLITE_OK != sqlite3_bind_int(sql.select_near_place, 4, range)) {
- g_printerr("Failed to bind values\n");
+ g_printerr("Failed to bind values for near place\n");
return FALSE;
}
place=sqlite3_column_text(sql.select_near_place, 0);
n->name=g_strdup(place);
- n->dist=sqlite3_column_int(sql.select_near_place, 1);
- n->dist=sqrt((double)n->dist);
+ dist=sqlite3_column_int(sql.select_near_place, 1);
+ n->dist=sqrt((double)dist);
n->lat=sqlite3_column_int(sql.select_near_place, 2);
n->lon=sqlite3_column_int(sql.select_near_place, 3);
n->id=sqlite3_column_int(sql.select_near_place, 4);
return FALSE;
}
+/* Way helper */
+static GList *
+osm_find_nearest_way_nodes(gint lat, gint lon, guint range)
+{
+GList *ways=NULL;
+osm_way *w;
+
+sqlite3_reset(sql.select_way);
+sqlite3_clear_bindings(sql.select_way);
+
+if (SQLITE_OK != sqlite3_bind_int(sql.select_way, 1, lat) ||
+ SQLITE_OK != sqlite3_bind_int(sql.select_way, 2, lon) ||
+ SQLITE_OK != sqlite3_bind_int(sql.select_way, 3, range)) {
+ g_printerr("Failed to bind values for way\n");
+ return NULL;
+}
+
+while (SQLITE_ROW == sqlite3_step(sql.select_way)) {
+ guint32 dist;
+
+ w=g_slice_new0(osm_way);
+ w->id=sqlite3_column_int(sql.select_way, 0);
+ w->type=sqlite3_column_int(sql.select_way, 1);
+ w->nodecnt=sqlite3_column_int(sql.select_way, 2);
+ w->flags=sqlite3_column_int(sql.select_way, 3);
+ dist=sqlite3_column_int(sql.select_way, 4);
+ w->dist=sqrt((gdouble)dist);
+ w->node_num=sqlite3_column_int(sql.select_way, 5);
+ ways=g_list_prepend(ways, w);
+}
+
+return ways;
+}
+
+static gdouble magnitude(gdouble x1, gdouble y1, gdouble x2, gdouble y2)
+{
+gdouble x,y;
+x=x2-x1;
+y=y2-y1;
+
+return sqrt((x*x)+(y*y));
+}
+
+gboolean distance_point_to_line(gint x, gint y, gint x1, gint y1, gint x2, gint y2, gdouble *d)
+{
+gdouble lm,u;
+gdouble ix,iy;
+gdouble tmp,tx1,tx2,ty1,ty2;
+
+#if 0
+if (x1>x2) {
+ tx1=x2;
+ ty1=y2;
+ x2=x1;
+ y2=y1;
+ x1=tx1;
+ y1=ty1;
+}
+#endif
+
+lm=magnitude((gdouble)x1,(gdouble)y1,(gdouble)x2,(gdouble)y2);
+
+tmp=(gdouble)((x-x1)*(x2-x1))+((y-y1)*(y2-y1));
+u=tmp/(lm*lm);
+
+g_printf("DPL: tmp %f u %f lm %f\n", tmp, u, lm);
+
+g_printf("DPLX: (%d/%d) (%d %d)-(%d %d)\n",
+ x,y,
+ x1,y1,
+ x2,y2);
+
+if (u<0.0f || u>1.0f)
+ return FALSE;
+
+ix=(gdouble)x1+u*(gdouble)(x2-x1);
+iy=(gdouble)y1+u*(gdouble)(y2-y1);
+
+*d=magnitude((gdouble)x,(gdouble)y, ix, iy);
+
+return TRUE;
+}
+
/**
* Search for the nearest way (road)
* - First search for ways with nearest node
osm_way *
osm_find_nearest_way(gint lat, gint lon)
{
+GList *iter;
+GList *w=NULL;
+guint range=8192;
+osm_way *cw=NULL;
+while ((w=osm_find_nearest_way_nodes(lat, lon, range))==NULL && range<=65536) {
+ range=range<<1;
+ g_printf("Trying with range: %d\n", range);
+}
+
+g_printf("Found ways: %d\n", g_list_length(w));
+
+switch (g_list_length(w)) {
+ case 0:
+ return NULL;
+ break;
+ case 1:
+ cw=w->data;
+ break;
+ default:
+ {
+ gint dist=900000, ndist;
+ gdouble pdist=900000.0, pndist=9000000.0;
+
+ for (iter=w; iter!=NULL; iter=iter->next) {
+ osm_way_node *wnf;
+ osm_way_node *wnt;
+
+ osm_way *way=(osm_way*)iter->data;
+
+ g_printf("C*** WAY %d (%d) HAS %d NODES, nearest is %d\n",
+ way->id, way->type, way->nodecnt, way->node_num);
+
+ if (osm_way_get_nodes(way)==FALSE)
+ continue;
+
+ if (way->nodes==0) {
+ g_printerr("Way with 0 nodes ? Skipping\n");
+ continue;
+ }
+
+ wnf=g_list_nth_data(way->nodes, way->node_num);
+ if (!wnf)
+ continue;
+
+ g_printf("----EVAL-START:\n");
+ if (way->node_num==way->nodecnt) {
+ g_print(" <- Last\n");
+ wnt=g_list_nth_data(way->nodes, way->nodecnt-1);
+ if (!wnt)
+ continue;
+ if (distance_point_to_line(lon, lat, wnf->lon, wnf->lat, wnt->lon, wnt->lat, &pndist)==FALSE)
+ continue;
+ } else if (way->node_num==0) {
+ g_print(" First %d ->\n", wnf->num);
+ wnt=g_list_nth_data(way->nodes, 1);
+ if (!wnt)
+ continue;
+ if (distance_point_to_line(lon, lat, wnf->lon, wnf->lat, wnt->lon, wnt->lat, &pndist)==FALSE)
+ continue;
+ } else {
+ g_print(" <->\n");
+ wnt=g_list_nth_data(way->nodes, way->node_num-1);
+ if (!wnt)
+ continue;
+ if (distance_point_to_line(lon, lat, wnf->lon, wnf->lat, wnt->lon, wnt->lat, &pndist)==FALSE) {
+ wnt=g_list_nth_data(way->nodes, way->node_num+1);
+ if (!wnt)
+ continue;
+ if (distance_point_to_line(lon, lat, wnf->lon, wnf->lat, wnt->lon, wnt->lat, &pndist)==FALSE)
+ continue;
+ }
+ }
+ g_printf("----EVAL-DONE: %d <-> %d\n", wnf->num, wnt->num);
+
+ g_printf("WD: New: %f Prev:%f\n", pndist, pdist);
+ if (pndist<pdist) {
+ pdist=pndist;
+ cw=way;
+ }
+ }
+ }
+ break;
+}
+
+g_list_free(w);
+if (cw==NULL)
+ return NULL;
+
+osm_way_get_name(cw);
+if (cw->type==WAY_MOTORWAY || cw->type==WAY_TRUNK ||
+ cw->type==WAY_PRIMARY || cw->type==WAY_SECONDARY ||
+ cw->type==WAY_TERTIARY) {
+ osm_way_get_ref(cw);
+}
+
+g_printf("Way: %d %d %d %d: %s %s %s\n",
+ cw->id, cw->type, cw->flags,
+ cw->nodes, cw->dist, cw->name,
+ cw->ref, cw->int_ref);
+
+return cw;
}
/**
{
if (w->nodes!=NULL)
return TRUE;
+
+sqlite3_reset(sql.select_way_nodes);
+sqlite3_clear_bindings(sql.select_way_nodes);
+
+if (SQLITE_OK != sqlite3_bind_int(sql.select_way_nodes, 1, w->id)) {
+ g_printerr("Failed to bind values way nodes\n");
+ return FALSE;
+}
+
+while (SQLITE_ROW == sqlite3_step(sql.select_way_nodes)) {
+ osm_way_node *n;
+
+ n=g_slice_new(osm_way_node);
+ n->num=sqlite3_column_int(sql.select_way_nodes, 0);
+ n->lat=sqlite3_column_int(sql.select_way_nodes, 1);
+ n->lon=sqlite3_column_int(sql.select_way_nodes, 2);
+ w->nodes=g_list_append(w->nodes, n);
+}
+
+return (w->nodes==NULL) ? FALSE : TRUE;
+}
+
+gboolean
+osm_way_get_name(osm_way *w)
+{
+sqlite3_reset(sql.select_way_name);
+sqlite3_clear_bindings(sql.select_way_name);
+
+if (SQLITE_OK != sqlite3_bind_int(sql.select_way_name, 1, w->id)) {
+ g_printerr("Failed to bind values for way name\n");
+ return FALSE;
+}
+
+if (SQLITE_ROW == sqlite3_step(sql.select_way_name)) {
+ const gchar *place;
+ place=sqlite3_column_text(sql.select_way_name, 0);
+ w->name=g_strdup(place);
+}
+return FALSE;
+}
+
+gboolean
+osm_way_get_ref(osm_way *w)
+{
+sqlite3_reset(sql.select_way_ref);
+sqlite3_clear_bindings(sql.select_way_ref);
+
+if (SQLITE_OK != sqlite3_bind_int(sql.select_way_ref, 1, w->id)) {
+ g_printerr("Failed to bind values for way ref\n");
+ return FALSE;
+}
+
+if (SQLITE_ROW == sqlite3_step(sql.select_way_ref)) {
+ const gchar *ref, *int_ref;
+ ref=sqlite3_column_text(sql.select_way_ref, 0);
+ int_ref=sqlite3_column_text(sql.select_way_ref, 1);
+ w->ref=g_strdup(ref);
+ w->int_ref=g_strdup(int_ref);
+}
+return FALSE;
}
void
osm_way_free(osm_way *w)
{
+if (w->nodes)
+ g_list_free(w->nodes);
+if (w->name)
+ g_free(w->name);
+if (w->ref)
+ g_free(w->ref);
+if (w->int_ref)
+ g_free(w->int_ref);
+g_slice_free(osm_way, w);
}