From: Kaj-Michael Lang Date: Fri, 2 Nov 2007 22:42:36 +0000 (+0200) Subject: POI Code cleanups: X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bd7a8bced5b7477318fe04d48b1928d9b6baaaed;p=mapper POI Code cleanups: - Use poi_info struct instead of many parameters - Cache POI information in map-poi.c - Fixes to POI search - Other fixups here and there to POI code --- diff --git a/src/cb.c b/src/cb.c index 01fe720..0ce90de 100644 --- a/src/cb.c +++ b/src/cb.c @@ -1,3 +1,28 @@ +/* + * This file is part of mapper + * + * Copyright (C) 2007 Kaj-Michael Lang + * Copyright (C) 2006-2007 John Costigan. + * + * POI and GPS-Info code originally written by Cezary Jackiewicz. + * + * Default map data provided by http://www.openstreetmap.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + #include #define _GNU_SOURCE @@ -978,7 +1003,11 @@ return TRUE; gboolean cmenu_cb_loc_add_poi(GtkAction * action) { -poi_dialog(ACTION_ADD_POI, x2unit(_cmenu_position_x), y2unit(_cmenu_position_y)); +poi_info *poi; +poi=poi_new(); +poi->lat=x2unit(_cmenu_position_x); +poi->lon=y2unit(_cmenu_position_y); +poi_edit_dialog(ACTION_ADD_POI, poi); return TRUE; } @@ -988,7 +1017,12 @@ cb_poi_search(GtkAction *action) poi_info poi; gdouble lat, lon; -unit2latlon(_center.unitx, _center.unity, lat, lon); +if (_center_mode>0) { + lat=_gps.lat; + lon=_gps.lon; +} else { + unit2latlon(_center.unitx, _center.unity, lat, lon); +} mapper_search_dialog(SEARCH_TYPE_POI, lat, lon); return TRUE; @@ -997,20 +1031,24 @@ return TRUE; gboolean cb_poi_add(GtkAction *action) { -guint unitx, unity; +gdouble lat,lon; const gchar *name = gtk_action_get_name(action); +poi_info *p; -if (_center_mode > 0) { - latlon2unit(_gps.lat, _gps.lon, unitx, unity); +if (_center_mode>0) { + lat=_gps.lat; + lon=_gps.lon; } else { - unitx=_center.unitx; - unity=_center.unity; + unit2latlon(_center.unitx, _center.unity, lat, lon); } -if (strcmp(name, "poi_add")==0) - poi_dialog(ACTION_ADD_POI, unitx, unity); -else if (strcmp(name, "poi_quick_add")==0) - poi_quick_dialog(unitx, unity); +if (strcmp(name, "poi_add")==0) { + p=poi_new(); + p->lat=lat; + p->lon=lon; + poi_edit_dialog(ACTION_ADD_POI, p); +} else if (strcmp(name, "poi_quick_add")==0) + poi_quick_dialog(lat, lon); else g_assert_not_reached(); @@ -1022,7 +1060,12 @@ menu_cb_search_address(GtkAction *action) { gdouble lat, lon; -unit2latlon(_center.unitx, _center.unity, lat, lon); +if (_center_mode>0) { + lat=_gps.lat; + lon=_gps.lon; +} else { + unit2latlon(_center.unitx, _center.unity, lat, lon); +} mapper_search_dialog(SEARCH_TYPE_WAY, lat, lon); return TRUE; } @@ -1051,7 +1094,9 @@ unitx = x2unit(_cmenu_position_x); unity = y2unit(_cmenu_position_y); unit2latlon(unitx, unity, _dest.lat, _dest.lon); _dest.valid=TRUE; +#if 0 map_update_location_from_center(); +#endif return TRUE; } @@ -1144,8 +1189,7 @@ if ((way = find_nearest_waypoint(x2unit(_cmenu_position_x), y2unit(_cmenu_positi gchar buffer[BUFFER_SIZE]; GtkWidget *confirm; - snprintf(buffer, sizeof(buffer), "%s:\n%s\n", - _("Confirm delete of waypoint"), way->desc); + snprintf(buffer, sizeof(buffer), "%s:\n%s\n", _("Confirm delete of waypoint"), way->desc); confirm = hildon_note_new_confirmation(GTK_WINDOW(_window), buffer); if (GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm))) { @@ -1217,9 +1261,13 @@ cmenu_cb_way_add_poi(GtkAction * action) { WayPoint *way; -if ((way = find_nearest_waypoint(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y)))) - poi_dialog(ACTION_ADD_POI, way->point->unitx, way->point->unity); +if ((way = find_nearest_waypoint(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y)))) { + poi_info *p; + p=poi_new(); + unit2latlon(way->point->unitx, way->point->unity, p->lat, p->lon); + poi_edit_dialog(ACTION_ADD_POI, p); +} return TRUE; } @@ -1228,7 +1276,7 @@ cmenu_cb_poi_route_to(GtkAction * action) { poi_info poi; -if (poi_select(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y), &poi)) { +if (poi_select(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y), 4, &poi)) { guint unitx, unity; latlon2unit(poi.lat, poi.lon, unitx, unity); cmenu_route_to(unitx, unity); @@ -1242,7 +1290,7 @@ cmenu_cb_poi_distance_to(GtkAction * action) { poi_info poi; -if (poi_select(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y), &poi)) { +if (poi_select(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y), 4, &poi)) { guint unitx, unity; latlon2unit(poi.lat, poi.lon, unitx, unity); cmenu_distance_to(unitx, unity); @@ -1256,7 +1304,7 @@ cmenu_cb_poi_add_route(GtkAction * action) { poi_info poi; -if (poi_select(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y), &poi)) { +if (poi_select(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y), 4, &poi)) { guint unitx, unity; latlon2unit(poi.lat, poi.lon, unitx, unity); cmenu_add_route(unitx, unity); @@ -1270,7 +1318,7 @@ cmenu_cb_poi_add_way(GtkAction * action) { poi_info poi; -if (poi_select(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y), &poi)) { +if (poi_select(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y), 4, &poi)) { guint unitx, unity; latlon2unit(poi.lat, poi.lon, unitx, unity); cmenu_route_add_way(unitx, unity); @@ -1279,9 +1327,25 @@ if (poi_select(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y), &poi)) { return TRUE; } +gboolean +cmenu_cb_poi_show_poi(GtkAction *action) +{ +/* XXX: Write this */ +return TRUE; +} + gboolean cmenu_cb_poi_edit_poi(GtkAction * action) { -poi_dialog(ACTION_EDIT_POI, x2unit(_cmenu_position_x), y2unit(_cmenu_position_y)); +poi_info *p; +gdouble lat, lon; + +unit2latlon(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y), lat, lon); +p=poi_find_nearest(lat, lon); +if (!p) { + popup_error(_window, _("No POI found at location.")); + return TRUE; +} +poi_edit_dialog(ACTION_EDIT_POI, p); return TRUE; } diff --git a/src/map-poi.c b/src/map-poi.c index 42ac9e5..f630d8f 100644 --- a/src/map-poi.c +++ b/src/map-poi.c @@ -1,3 +1,28 @@ +/* + * This file is part of mapper + * + * Copyright (C) 2007 Kaj-Michael Lang + * Copyright (C) 2006-2007 John Costigan. + * + * POI and GPS-Info code originally written by Cezary Jackiewicz. + * + * Default map data provided by http://www.openstreetmap.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + #include #define _GNU_SOURCE @@ -14,15 +39,19 @@ #include "ui-common.h" #include "db.h" -#define POI_FONT_SIZE_BIG (12) -#define POI_FONT_SIZE_SMALL (10) +#define POI_FONT_SIZE_BIG (10) +#define POI_FONT_SIZE_SMALL (8) +/* Hash table for caching POI icons */ static GHashTable *poi_icon_hash = NULL; + +/* POI icon text pango stuff */ static PangoContext *context = NULL; static PangoLayout *layout = NULL; static PangoFontDescription *fontdesc = NULL; static GdkGC *poi_gc; +/* POI Icon theme. "classic" or "square". Should be made into a configuration option */ static gchar *theme="square"; gboolean @@ -36,7 +65,7 @@ pango_font_description_set_family(fontdesc,"Sans Serif"); pango_font_description_set_size(fontdesc, POI_FONT_SIZE_SMALL*PANGO_SCALE); pango_layout_set_font_description (layout, fontdesc); pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); -pango_layout_set_width(layout, 70*PANGO_SCALE); +pango_layout_set_width(layout, 80*PANGO_SCALE); poi_gc=gdk_gc_new(map_widget->window); return TRUE; } @@ -73,14 +102,32 @@ pixbuf=gdk_pixbuf_new_from_file(buffer, &error); if (error) return NULL; -g_printf("Found POI icon: %s.png\n", buffer); - g_hash_table_insert(poi_icon_hash, g_strdup(buffer), pixbuf); return pixbuf; } +/** + * Set POI color from given #rrggbb string, fallback to default if it fails + */ +static inline GdkGC * +map_set_poi_fg_color_from_string(gchar *hexcolor, GdkGC *def) +{ +GdkColor color; + +if (!hexcolor) + return def; + +if (gdk_color_parse(hexcolor, &color)) { + gdk_gc_set_rgb_fg_color(poi_gc, &color); + return poi_gc; +} + +return def; +} + /** - * Render all the POI data. This should be done before rendering track data. + * Render all the POI data. + * This should be done before rendering track data. */ void map_render_poi(void) @@ -89,9 +136,12 @@ guint unitx, unity; gdouble lat1, lat2, lon1, lon2; gint poix, poiy; GdkPixbuf *pixbuf = NULL; - -if (!_db) - return; +static GtkListStore *store=NULL; +GtkTreeIter iter; +guint pois; +gboolean valid; +static gint last_zoom=-1; +static guint prev_ux=0, prev_uy=0; if (_poi_zoom <= _zoom) return; @@ -103,74 +153,79 @@ unitx = x2unit(BUF_WIDTH_PIXELS); unity = y2unit(0); unit2latlon(unitx, unity, lat2, lon2); -if (SQLITE_OK != sqlite3_bind_double(poisql.select_poi, 1, lat1) - || SQLITE_OK != sqlite3_bind_double(poisql.select_poi, 2,lat2) - || SQLITE_OK != sqlite3_bind_double(poisql.select_poi, 3,lon1) - || SQLITE_OK != sqlite3_bind_double(poisql.select_poi, 4,lon2)) { - g_printerr("Failed to bind values for poisql.select_poi"); - return; +/* Reload POIs if we zoom out or have moved */ +if ((last_zoom<_zoom || prev_ux!=unitx || prev_uy!=unity) && store!=NULL) { + gtk_list_store_clear(store); + g_object_unref(G_OBJECT(store)); + store=NULL; + g_printf("Reloading POIs\n"); +} else { + g_printf("Using cached POIs\n"); +} + +if (store==NULL) { + if (poi_get_list_inside(lat1, lon1, lat2, lon2, &store, &pois)==FALSE) + return; } +valid=gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter); +if (!valid) + return; + if (_zoom<2) { pango_font_description_set_size(fontdesc, POI_FONT_SIZE_BIG*PANGO_SCALE); pango_layout_set_font_description (layout, fontdesc); pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE); - pango_layout_set_width(layout, 90*PANGO_SCALE); } else { pango_font_description_set_size(fontdesc, POI_FONT_SIZE_SMALL*PANGO_SCALE); pango_layout_set_font_description (layout, fontdesc); pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); - pango_layout_set_width(layout, 70*PANGO_SCALE); } +last_zoom=_zoom; +prev_ux=unitx; +prev_uy=unity; -while (SQLITE_ROW == sqlite3_step(poisql.select_poi)) { - GdkColor color; +while (valid) { GdkGC *gc; + gchar *label; + gchar *icon=NULL, *color=NULL; - lat1 = sqlite3_column_double(poisql.select_poi, 0); - lon1 = sqlite3_column_double(poisql.select_poi, 1); - gchar *poi_label = sqlite3_column_text(poisql.select_poi, 3); - gchar *cat_icon = sqlite3_column_text(poisql.select_poi, 8); - gchar *cat_color = sqlite3_column_text(poisql.select_poi, 9); - - latlon2unit(lat1, lon1, unitx, unity); - poix = unit2bufx(unitx); - poiy = unit2bufy(unity); + gtk_tree_model_get(GTK_TREE_MODEL(store), + &iter, + ITEM_LAT, &lat1, + ITEM_LON, &lon1, + ITEM_LABEL, &label, + ITEM_ICON, &icon, + ITEM_COLOR, &color, + -1); - pixbuf=map_poi_get_icon(cat_icon); + pixbuf=map_poi_get_icon(icon); + gc=map_set_poi_fg_color_from_string(color, _gc[COLORABLE_POI]); - // XXX: Cache instead of parsing every time... - if (gdk_color_parse(cat_color, &color)) { - gdk_gc_set_rgb_fg_color(poi_gc, &color); - gc=poi_gc; - } else { - gc=_gc[COLORABLE_POI]; - } + latlon2unit(lat1, lon1, unitx, unity); + poix=unit2bufx(unitx); + poiy=unit2bufy(unity); if (!pixbuf) { /* No icon for POI or for category - draw default. */ - - gdk_draw_arc(_map_pixmap, gc, FALSE, - poix - _draw_width, poiy - _draw_width, + gdk_draw_arc(_map_pixmap, gc, FALSE, poix - _draw_width, poiy - _draw_width, (MAX_ZOOM-_zoom)/6 * _draw_width, (MAX_ZOOM-_zoom)/6 * _draw_width, 0, 360 * 64); } else { guint w,h; w=gdk_pixbuf_get_width(pixbuf); h=gdk_pixbuf_get_height(pixbuf); - gdk_draw_pixbuf(_map_pixmap, - gc, - pixbuf, 0, 0, - poix-w/2, - poiy-h/2, - -1, -1, GDK_RGB_DITHER_NONE, - 0, 0); + gdk_draw_pixbuf(_map_pixmap, gc, pixbuf, 0, 0, poix-w/2, poiy-h/2, -1, -1, GDK_RGB_DITHER_NONE, 0, 0); +#if 0 + /* Draw rectangle around icon. Not really need with the square icons */ if (_zoom<2) gdk_draw_rectangle(_map_pixmap, gc, FALSE, poix-w/2-1, poiy-h/2-1, w+1, h+1); +#endif } - if (_zoom<3 && poi_label) { - map_poi_title(poix, poiy, gc, poi_label); + + if (_zoom<3 && label) { + map_poi_title(poix, poiy, gc, label); } + + valid=gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter); } -sqlite3_reset(poisql.select_poi); -sqlite3_clear_bindings(poisql.select_poi); } diff --git a/src/poi-gui.c b/src/poi-gui.c index cef63ac..5a91b7d 100644 --- a/src/poi-gui.c +++ b/src/poi-gui.c @@ -141,16 +141,18 @@ gtk_list_store_clear(store); if (add_na) { gtk_list_store_append(store, &iter); - gtk_list_store_set(store, &iter, 0, -1, 1, "[Not set]", -1); + gtk_list_store_set(store, &iter, 0, -1, 1, _("[No category]"), -1); } while (SQLITE_ROW == sqlite3_step(poisql.selall_cat)) { guint cid = sqlite3_column_int(poisql.selall_cat, 0); gtk_list_store_append(store, &iter); - gtk_list_store_set(store, &iter, 0, cid, 1, sqlite3_column_text(poisql.selall_cat, 1), -1); - if (cid == cat_id) { - active = iter; - has_active = TRUE; + gtk_list_store_set(store, &iter, + 0, cid, + 1, sqlite3_column_text(poisql.selall_cat, 1), -1); + if (cid==cat_id) { + active=iter; + has_active=TRUE; } } sqlite3_reset(poisql.selall_cat); @@ -638,17 +640,17 @@ return selected; } gboolean -poi_select(guint unitx, guint unity, poi_info *poi) +poi_select(guint unitx, guint unity, guint range, poi_info *poi) { GtkListStore *store; -guint num_cats; +guint num_pois; GtkTreeIter iter; gdouble lat, lon; -if (poi_get_list_near(unitx, unity, &store, &num_cats)==FALSE) +if (poi_get_list_near_unit(unitx, unity, range, &store, &num_pois)==FALSE) return FALSE; -switch (num_cats) { +switch (num_pois) { case 0: MACRO_BANNER_SHOW_INFO(_window, _("No POIs found.")); g_object_unref(G_OBJECT(store)); @@ -681,10 +683,15 @@ if (poi_category_list()) return TRUE; } +/** + * poi_edit_dialog + * + * Edit or Add POI with given information in poi_info + * + */ gboolean -poi_dialog(POIAction action, guint unitx, guint unity) +poi_edit_dialog(POIAction action, poi_info *poi) { -poi_info poi; gchar slat1[10], slon1[10]; gchar *p_latlon; GtkWidget *dialog; @@ -693,6 +700,7 @@ GtkWidget *label; GtkWidget *txt_label; GtkWidget *cmb_category; GtkWidget *txt_desc; +GtkWidget *txt_postal_code, *txt_url; GtkWidget *btn_delete = NULL; GtkWidget *btn_catedit; GtkWidget *hbox; @@ -703,45 +711,32 @@ delete_poi dpoi = { NULL, NULL, 0 }; PoiCategoryEditInfo pcedit; gchar tmp1[16], tmp2[16]; -if (action == ACTION_EDIT_POI) { - if (!poi_select(unitx, unity, &poi)) - return FALSE; +/* Fatal, poi must be set */ +if (!poi) + return FALSE; + +dialog = gtk_dialog_new_with_buttons(action == ACTION_EDIT_POI ? _("Edit POI") : _("Add POI"), + GTK_WINDOW(_window), + GTK_DIALOG_MODAL, + GTK_STOCK_OK, + GTK_RESPONSE_ACCEPT, + GTK_STOCK_CANCEL, + GTK_RESPONSE_REJECT, NULL); - dialog = gtk_dialog_new_with_buttons(_("Edit POI"), - GTK_WINDOW(_window), - GTK_DIALOG_MODAL, - GTK_STOCK_OK, - GTK_RESPONSE_ACCEPT, NULL); +if (action == ACTION_EDIT_POI) { gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area), btn_delete = gtk_button_new_with_label(_("Delete"))); - dpoi.dialog = dialog; - dpoi.txt_label = g_strdup(poi.label); - dpoi.id = poi.poi_id; + dpoi.dialog=dialog; + dpoi.txt_label=g_strdup(poi->label); + dpoi.id=poi->poi_id; g_signal_connect(G_OBJECT(btn_delete), "clicked", G_CALLBACK(poi_delete_confirm), &dpoi); - - gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT); -} else { - unit2latlon(unitx, unity, poi.lat, poi.lon); - - poi.poi_id = 0; - poi.cat_id = 0; - poi.desc = g_strdup(""); - poi.label = g_strdup(""); - - dialog = gtk_dialog_new_with_buttons(_("Add POI"), - GTK_WINDOW(_window), - GTK_DIALOG_MODAL, - GTK_STOCK_OK, - GTK_RESPONSE_ACCEPT, - GTK_STOCK_CANCEL, - GTK_RESPONSE_REJECT, NULL); } /* Set the p_latlon string. */ -lat_format(poi.lat, tmp1); -lon_format(poi.lon, tmp2); -p_latlon = g_strdup_printf("%s, %s", tmp1, tmp2); +lat_format(poi->lat, tmp1); +lon_format(poi->lon, tmp2); +p_latlon=g_strdup_printf("%s, %s", tmp1, tmp2); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), table = gtk_table_new(6, 4, FALSE), TRUE, TRUE, 0); @@ -759,8 +754,7 @@ gtk_table_attach(GTK_TABLE(table), label = gtk_label_new(_("Category")), 0, 1, 3 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f); gtk_table_attach(GTK_TABLE(table), hbox = gtk_hbox_new(FALSE, 4), 1, 2, 3, 4, GTK_EXPAND | GTK_FILL, 0, 2, 4); -cmb_category = category_combo_new(); -gtk_box_pack_start(GTK_BOX(hbox), cmb_category, FALSE, FALSE, 4); +gtk_box_pack_start(GTK_BOX(hbox), cmb_category = category_combo_new(), FALSE, FALSE, 4); gtk_box_pack_start(GTK_BOX(hbox), btn_catedit = gtk_button_new_with_label(_("Edit Categories...")), FALSE, FALSE, 4); @@ -773,36 +767,34 @@ gtk_table_attach(GTK_TABLE(table), txt_scroll, 1, 2, 5, 6, GTK_EXPAND | GTK_FILL gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(txt_scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); -txt_desc = gtk_text_view_new(); +txt_desc=gtk_text_view_new(); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt_desc), GTK_WRAP_WORD); gtk_container_add(GTK_CONTAINER(txt_scroll), txt_desc); gtk_widget_set_size_request(GTK_WIDGET(txt_scroll), 400, 60); -desc_txt = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txt_desc)); +desc_txt=gtk_text_view_get_buffer(GTK_TEXT_VIEW(txt_desc)); /* label */ -gtk_entry_set_text(GTK_ENTRY(txt_label), poi.label); - -/* category */ -poi_category_combo_populate(cmb_category, poi.cat_id, FALSE); +if (poi->label) + gtk_entry_set_text(GTK_ENTRY(txt_label), poi->label); +if (poi->desc) + gtk_text_buffer_set_text(desc_txt, poi->desc, -1); -/* poi_desc */ -gtk_text_buffer_set_text(desc_txt, poi.desc, -1); +poi_category_combo_populate(cmb_category, poi->cat_id, FALSE); /* Connect Signals */ -pcedit.cmb_category = cmb_category; -pcedit.cat_id = poi.cat_id; +pcedit.cmb_category=cmb_category; +pcedit.cat_id=poi->cat_id; + g_signal_connect(G_OBJECT(btn_catedit), "clicked", G_CALLBACK(poi_edit_cat), &pcedit); gtk_widget_show_all(dialog); while (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog))) { - gchar *poi_label = NULL; - gchar *poi_desc = NULL; GtkTreeIter iter; if (strlen(gtk_entry_get_text(GTK_ENTRY(txt_label)))) - poi_label = gtk_entry_get_text(GTK_ENTRY(txt_label)); + poi->label=g_strdup(gtk_entry_get_text(GTK_ENTRY(txt_label))); else { popup_error(dialog, _("Please specify a name for the POI.")); continue; @@ -814,22 +806,22 @@ while (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog))) { } gtk_text_buffer_get_bounds(desc_txt, &begin, &end); - poi_desc = gtk_text_buffer_get_text(desc_txt, &begin, &end, TRUE); + poi->desc=gtk_text_buffer_get_text(desc_txt, &begin, &end, TRUE); - gtk_tree_model_get(gtk_combo_box_get_model(GTK_COMBO_BOX(cmb_category)), &iter, 0, &poi.cat_id, -1); + gtk_tree_model_get(gtk_combo_box_get_model(GTK_COMBO_BOX(cmb_category)), &iter, 0, &poi->cat_id, -1); if (action == ACTION_EDIT_POI) { /* edit poi */ - if (poi_update(poi.poi_id, poi.cat_id, poi_label, poi_desc)==FALSE) { + if (poi_update(poi)==FALSE) { popup_error(_window, _("Problem updating POI")); } else { map_render_data(); } } else { /* add poi */ - g_ascii_dtostr(slat1, sizeof(slat1), poi.lat); - g_ascii_dtostr(slon1, sizeof(slon1), poi.lon); - if (poi_add(poi.lat, poi.lon, poi.cat_id, poi_label, poi_desc)==FALSE) { + g_ascii_dtostr(slat1, sizeof(slat1), poi->lat); + g_ascii_dtostr(slon1, sizeof(slon1), poi->lon); + if (poi_add(poi)==FALSE) { popup_error(_window, _("Problem adding POI")); } else { map_render_data(); @@ -837,13 +829,12 @@ while (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog))) { } break; } -g_free(dpoi.txt_label); -g_free(poi.label); -g_free(poi.desc); +poi_free(poi); +g_free(dpoi.txt_label); g_free(p_latlon); -gtk_widget_hide_all(dialog); +gtk_widget_destroy(dialog); return TRUE; } @@ -851,36 +842,42 @@ return TRUE; static gboolean poi_quick_button_cb(GtkWidget *w, gpointer data) { -guint cat_id; -gchar *label; +poi_info *p; -cat_id=GPOINTER_TO_INT(data); +p=poi_new(); +p->cat_id=GPOINTER_TO_INT(data); if (strlen(gtk_entry_get_text(GTK_ENTRY(qp.label)))>0) { - label=g_strdup(gtk_entry_get_text(GTK_ENTRY(qp.label))); + p->label=g_strdup(gtk_entry_get_text(GTK_ENTRY(qp.label))); } else { - label=g_strdup(""); + p->label=g_strdup(""); } +p->lat=qp.lat; +p->lon=qp.lon; +p->desc=g_strdup("Quick POI, update information please."); + /* poi_add frees the label and desc so strdup */ -if (poi_add(qp.lat, qp.lon, cat_id, label, g_strdup("Quick POI, update information please."))==FALSE) { +if (poi_add(p)==FALSE) { popup_error(_window, _("Problem adding POI")); } else { map_render_data(); gtk_widget_destroy(qp.dialog); } +poi_free(p); return TRUE; } gboolean -poi_quick_dialog(guint unitx, guint unity) +poi_quick_dialog(gdouble lat, gdouble lon) { GtkWidget *table; GtkWidget *buttons[POI_QUICK_BUTTONS]; guint x,y; -unit2latlon(unitx, unity, qp.lat, qp.lon); +qp.lat=lat; +qp.lon=lon; qp.dialog = gtk_dialog_new_with_buttons(_("Quick POI"), GTK_WINDOW(_window), diff --git a/src/poi-gui.h b/src/poi-gui.h index 5295762..b4d5987 100644 --- a/src/poi-gui.h +++ b/src/poi-gui.h @@ -28,10 +28,10 @@ #include #include "poi.h" -gboolean poi_select(guint unitx, guint unity, poi_info *poi); -gboolean poi_dialog(POIAction action, guint unitx, guint unity); +gboolean poi_select(guint unitx, guint unity, guint range, poi_info *poi); +gboolean poi_edit_dialog(POIAction action, poi_info *poi); gboolean poi_search_dialog(GtkListStore *store, poi_info *poi, gdouble lat, gdouble lon); -gboolean poi_quick_dialog(guint unitx, guint unity); +gboolean poi_quick_dialog(gdouble lat, gdouble lon); gboolean poi_category_dialog(guint cat_id); gboolean poi_category_list(); diff --git a/src/poi.c b/src/poi.c index d0d08e5..2fe4f80 100644 --- a/src/poi.c +++ b/src/poi.c @@ -201,42 +201,64 @@ return TRUE; gboolean poi_db_prepare(sqlite3 *db) { - /* select from poi */ + /* Select POIs inside given minmax lat,lon */ if (sqlite3_prepare_v2(db, "select p.lat, p.lon, p.poi_id, p.label, p.desc," " p.cat_id, c.label, c.desc, c.icon, c.color" " from poi p, category c " " where p.lat between ? and ? " " and p.lon between ? and ? " - " and c.enabled = 1 and p.cat_id = c.cat_id", + " and c.enabled=1 and p.cat_id=c.cat_id order by c.priority limit 500", -1, &poisql.select_poi, NULL)!=SQLITE_OK) return FALSE; - /* Search POI label */ + /* Get POI with given ID */ + if (sqlite3_prepare_v2(db, + "select p.lat, p.lon, p.poi_id, p.label, p.desc," + " p.cat_id, c.label, c.desc, c.icon, c.color" + " from poi p, category c " + " where p.poi_id = ? " + " and p.cat_id=c.cat_id", + -1, &poisql.select_poi_by_id, NULL)!=SQLITE_OK) + return FALSE; + + /* Search POIs by label */ if (sqlite3_prepare_v2(db, "select p.lat, p.lon, p.poi_id, p.label, p.desc," " p.cat_id, c.label, c.desc, c.icon, c.color" " from poi p, category c " " where p.lat between ? and ? " " and p.lon between ? and ? " - " and c.enabled = 1 and p.cat_id = c.cat_id and p.label like ? order by p.label", + " and c.enabled=1 and p.cat_id = c.cat_id and p.label like ? order by p.label, c.label", -1, &poisql.select_poi_search, NULL)!=SQLITE_OK) return FALSE; - /* Search POI label && category */ + /* Search POI by label and specific category */ if (sqlite3_prepare_v2(db, "select p.lat, p.lon, p.poi_id, p.label, p.desc," " p.cat_id, c.label, c.desc, c.icon, c.color" " from poi p, category c " " where p.lat between ? and ? " " and p.lon between ? and ? " - " and c.enabled = 1 and p.cat_id = c.cat_id and p.label like ? and c.cat_id = ? order by p.label", + " and c.enabled=1 and p.cat_id = c.cat_id and p.label like ? and c.cat_id = ? order by p.label", -1, &poisql.select_poi_search_cat, NULL)!=SQLITE_OK) return FALSE; - /* select nearest pois */ + /* Search specific category */ if (sqlite3_prepare_v2(db, - "select p.lat, p.lon, p.label, c.label, c.icon, c.color" + "select p.lat, p.lon, p.poi_id, p.label, p.desc," + " p.cat_id, c.label, c.desc, c.icon, c.color" + " from poi p, category c " + " where p.lat between ? and ? " + " and p.lon between ? and ? " + " and c.enabled=1 and p.cat_id=c.cat_id and c.cat_id=? order by p.label", + -1, &poisql.select_poi_by_cat, NULL)!=SQLITE_OK) + return FALSE; + + /* Select nearest POI */ + if (sqlite3_prepare_v2(db, + "select p.lat, p.lon, p.poi_id, p.label, p.desc," + " p.cat_id, c.label, c.desc, c.icon, c.color " " from poi p, category c " " where c.enabled = 1 and p.cat_id = c.cat_id " " and p.lat between $LAT-0.10 and $LAT+0.10 " @@ -246,18 +268,15 @@ poi_db_prepare(sqlite3 *db) -1, &poisql.select_nearest_poi, NULL)!=SQLITE_OK) return FALSE; - /* insert poi */ - sqlite3_prepare_v2(db, - "insert into poi (lat, lon, label, desc, cat_id, public)" - " values (?, ?, ?, ?, ?, 1)", -1, &poisql.insert_poi, NULL); + /* Insert POI */ + sqlite3_prepare_v2(db, "insert into poi (lat, lon, label, desc, url, postal_code, cat_id, public, source)" + " values (?, ?, ?, ?, ?, ?, ?, 1, ?)", -1, &poisql.insert_poi, NULL); /* update poi */ - sqlite3_prepare_v2(db, "update poi set label = ?, desc = ?, cat_id = ? where poi_id = ?", -1, &poisql.update_poi, NULL); + sqlite3_prepare_v2(db, "update poi set label=?, desc=?, cat_id=? where poi_id=?", -1, &poisql.update_poi, NULL); /* delete from poi */ - sqlite3_prepare_v2(db, "delete from poi where poi_id = ?", -1, &poisql.delete_poi, NULL); + sqlite3_prepare_v2(db, "delete from poi where poi_id=?", -1, &poisql.delete_poi, NULL); /* delete from poi by cat_id */ - sqlite3_prepare_v2(db, "delete from poi where cat_id = ?", -1, &poisql.delete_poi_by_catid, NULL); - /* get next poilabel */ - sqlite3_prepare_v2(db, "select ifnull(max(poi_id) + 1,1) from poi", -1, &poisql.nextlabel_poi, NULL); + sqlite3_prepare_v2(db, "delete from poi where cat_id=?", -1, &poisql.delete_poi_by_catid, NULL); /* select from category */ sqlite3_prepare_v2(db, @@ -312,7 +331,6 @@ sqlite3_finalize(poisql.insert_poi); sqlite3_finalize(poisql.update_poi); sqlite3_finalize(poisql.delete_poi); sqlite3_finalize(poisql.delete_poi_by_catid); -sqlite3_finalize(poisql.nextlabel_poi); sqlite3_finalize(poisql.select_nearest_poi); sqlite3_finalize(poisql.select_poi); sqlite3_finalize(poisql.select_poi_search); @@ -338,15 +356,48 @@ return TRUE; poi_info * poi_new(void) { -return g_slice_new0(poi_info); +poi_info *p; + +p=g_slice_new0(poi_info); +p->source=POI_SOURCE_USER; +/* XXX: Set defaults ? */ +return p; } void poi_free(poi_info *p) { +if (p->label) + g_free(p->label); +if (p->desc) + g_free(p->desc); +if (p->url) + g_free(p->url); +if (p->postal_code) + g_free(p->postal_code); +if (p->cat_label) + g_free(p->cat_label); +if (p->cat_desc) + g_free(p->cat_desc); g_slice_free(poi_info, p); } +static GtkListStore * +poi_list_store_new(void) { +return gtk_list_store_new(ITEM_NUM_COLUMNS, + G_TYPE_INT, /* POI ID */ + G_TYPE_INT, /* Category ID */ + G_TYPE_DOUBLE, /* Latitude */ + G_TYPE_DOUBLE, /* Longitude */ + G_TYPE_DOUBLE, /* Dist */ + G_TYPE_STRING, /* Lat/Lon */ + G_TYPE_STRING, /* Label */ + G_TYPE_STRING, /* Desc. */ + G_TYPE_STRING, /* Category Label */ + G_TYPE_STRING, /* Icon */ + G_TYPE_STRING); /* Color */ +} + /************************************* * POI Category functions * @@ -437,7 +488,7 @@ return results; gboolean poi_category_delete(guint id) { -if (!_db) +if (!poidb) return FALSE; if (SQLITE_OK != sqlite3_bind_int(poisql.delete_poi_by_catid, 1, id) || SQLITE_DONE != sqlite3_step(poisql.delete_poi_by_catid)) { @@ -460,7 +511,7 @@ return TRUE; gboolean poi_delete(guint id) { -if (!_db) +if (!poidb) return FALSE; if (SQLITE_OK != sqlite3_bind_int(poisql.delete_poi, 1, id) || SQLITE_DONE != sqlite3_step(poisql.delete_poi)) { @@ -480,20 +531,19 @@ sqlite3_stmt *sql=NULL; gchar *ltext=NULL; guint rows=0; gchar tmp1[16], tmp2[16]; +guint range=1; -if (!_db) +if (!poidb) return FALSE; -g_printf("POI Search: [%s] around %.6f %.6f (%d)\n", text, lat, lon, cat); +g_printf("POI Search: [%s] around %.6f %.6f (%d %d)\n", text, lat, lon, cat, pst); switch (pst) { case POI_SEARCH_NEAR: if (SQLITE_OK != sqlite3_bind_double(poisql.select_poi, 1, lat-0.5) || - SQLITE_OK != sqlite3_bind_double(poisql.select_poi, 2, lat+0.5) || - SQLITE_OK != sqlite3_bind_double(poisql.select_poi, 3, lon-0.5) || SQLITE_OK != sqlite3_bind_double(poisql.select_poi, 4, lon+0.5)) { g_printerr("Failed to bind values for poisql.select_poi\n"); - sqlite3_clear_bindings(sql); + sqlite3_clear_bindings(poisql.select_poi); return FALSE; } sql=poisql.select_poi; @@ -501,50 +551,53 @@ switch (pst) { case POI_SEARCH_TEXT: ltext=g_strdup_printf("%s%%", text); - if (SQLITE_OK != sqlite3_bind_double(poisql.select_poi_search, 1, lat-1) || - SQLITE_OK != sqlite3_bind_double(poisql.select_poi_search, 2, lat+1) || - SQLITE_OK != sqlite3_bind_double(poisql.select_poi_search, 3, lon-1) || - SQLITE_OK != sqlite3_bind_double(poisql.select_poi_search, 4, lon+1) || - SQLITE_OK != sqlite3_bind_text(poisql.select_poi_search, 5, ltext, -1, SQLITE_TRANSIENT)) { + if (SQLITE_OK != sqlite3_bind_text(poisql.select_poi_search, 5, ltext, -1, SQLITE_TRANSIENT)) { g_printerr("Failed to bind values for poisql.select_poi_search\n"); - sqlite3_clear_bindings(sql); + sqlite3_clear_bindings(poisql.select_poi_search); g_free(ltext); return FALSE; } + g_free(ltext); sql=poisql.select_poi_search; break; case POI_SEARCH_TEXT_CAT: ltext=g_strdup_printf("%s%%", text); - if (SQLITE_OK != sqlite3_bind_double(poisql.select_poi_search_cat, 1, lat-1) || - SQLITE_OK != sqlite3_bind_double(poisql.select_poi_search_cat, 2, lat+1) || - SQLITE_OK != sqlite3_bind_double(poisql.select_poi_search_cat, 3, lon-1) || - SQLITE_OK != sqlite3_bind_double(poisql.select_poi_search_cat, 4, lon+1) || - SQLITE_OK != sqlite3_bind_int(poisql.select_poi_search_cat, 6, cat) || - SQLITE_OK != sqlite3_bind_text(poisql.select_poi_search_cat, 5, ltext, -1, SQLITE_TRANSIENT)) { + if (SQLITE_OK != sqlite3_bind_int(poisql.select_poi_search_cat, 6, cat) || + SQLITE_OK != sqlite3_bind_text(poisql.select_poi_search_cat, 5, ltext, -1, SQLITE_TRANSIENT)) { g_printerr("Failed to bind values for poisql.select_poi_search_cat\n"); - sqlite3_clear_bindings(sql); + sqlite3_clear_bindings(poisql.select_poi_search_cat); g_free(ltext); return FALSE; } + g_free(ltext); sql=poisql.select_poi_search_cat; break; + case POI_SEARCH_CAT: + if (SQLITE_OK != sqlite3_bind_int(poisql.select_poi_by_cat, 5, cat)) { + g_printerr("Failed to bind values for poisql.select_poi_by_cat\n"); + sqlite3_clear_bindings(poisql.select_poi_by_cat); + return FALSE; + } + sql=poisql.select_poi_by_cat; + break; default: g_assert_not_reached(); return FALSE; break; } -*store = gtk_list_store_new(ITEM_NUM_COLUMNS, - G_TYPE_INT, /* POI ID */ - G_TYPE_INT, /* Category ID */ - G_TYPE_DOUBLE, /* Latitude */ - G_TYPE_DOUBLE, /* Longitude */ - G_TYPE_DOUBLE, /* Distance */ - G_TYPE_STRING, /* Lat/Lon */ - G_TYPE_STRING, /* POI Label */ - G_TYPE_STRING, /* POI Desc. */ - G_TYPE_STRING); /* Category Label */ +/* XXX: Use common bind for common variables */ +if (SQLITE_OK != sqlite3_bind_double(sql, 1, lat-range) || + SQLITE_OK != sqlite3_bind_double(sql, 2, lat+range) || + SQLITE_OK != sqlite3_bind_double(sql, 3, lon-range) || + SQLITE_OK != sqlite3_bind_double(sql, 4, lon+range)) { + g_printerr("Failed to bind common variables for POI search\n"); + sqlite3_clear_bindings(sql); + return FALSE; +} + +*store = poi_list_store_new(); while (SQLITE_ROW == sqlite3_step(sql)) { gdouble rlat, rlon, dist; @@ -575,32 +628,20 @@ g_printf("Found: %d items\n", rows); sqlite3_reset(sql); sqlite3_clear_bindings(sql); -if (ltext) - g_free(ltext); - return TRUE; } gboolean -poi_get_list_near(guint unitx, guint unity, GtkListStore **store, guint *_num_cats) +poi_get_list_inside(gdouble lat1, gdouble lon1, gdouble lat2, gdouble lon2, GtkListStore **store, guint *num_poi) { -guint x, y; -gdouble lat1, lon1, lat2, lon2; GtkTreeIter iter; gchar tmp1[16], tmp2[16]; -gint num_cats=0; + +num_poi=0; if (!_db) return FALSE; -x = unitx - pixel2unit(3 * _draw_width); -y = unity + pixel2unit(3 * _draw_width); -unit2latlon(x, y, lat1, lon1); - -x = unitx + pixel2unit(3 * _draw_width); -y = unity - pixel2unit(3 * _draw_width); -unit2latlon(x, y, lat2, lon2); - if (SQLITE_OK != sqlite3_bind_double(poisql.select_poi, 1, lat1) || SQLITE_OK != sqlite3_bind_double(poisql.select_poi, 2, lat2) || SQLITE_OK != sqlite3_bind_double(poisql.select_poi, 3, lon1) || @@ -609,22 +650,13 @@ if (SQLITE_OK != sqlite3_bind_double(poisql.select_poi, 1, lat1) || return FALSE; } -*store = gtk_list_store_new(ITEM_NUM_COLUMNS, - G_TYPE_INT, /* POI ID */ - G_TYPE_INT, /* Category ID */ - G_TYPE_DOUBLE, /* Latitude */ - G_TYPE_DOUBLE, /* Longitude */ - G_TYPE_DOUBLE, /* Dist */ - G_TYPE_STRING, /* Lat/Lon */ - G_TYPE_STRING, /* Label */ - G_TYPE_STRING, /* Desc. */ - G_TYPE_STRING); /* Category Label */ +*store = poi_list_store_new(); while (SQLITE_ROW == sqlite3_step(poisql.select_poi)) { gdouble lat, lon, dist=0; - lat = sqlite3_column_double(poisql.select_poi, 0); - lon = sqlite3_column_double(poisql.select_poi, 1); + lat=sqlite3_column_double(poisql.select_poi, 0); + lon=sqlite3_column_double(poisql.select_poi, 1); lat_format(lat, tmp1); lon_format(lon, tmp2); @@ -632,32 +664,53 @@ while (SQLITE_ROW == sqlite3_step(poisql.select_poi)) { gtk_list_store_set(*store, &iter, ITEM_ID, sqlite3_column_int(poisql.select_poi, 2), ITEM_CATID, sqlite3_column_int(poisql.select_poi, 5), - ITEM_LAT, lat, - ITEM_LON, lon, - ITEM_DIST, dist, + ITEM_LAT, lat, + ITEM_LON, lon, + ITEM_DIST, dist, ITEM_LATLON, g_strdup_printf("%s, %s", tmp1, tmp2), ITEM_LABEL, sqlite3_column_text(poisql.select_poi, 3), ITEM_DESC, sqlite3_column_text(poisql.select_poi, 4), ITEM_CATLAB, sqlite3_column_text(poisql.select_poi, 6), + ITEM_ICON, sqlite3_column_text(poisql.select_poi, 8), + ITEM_COLOR, sqlite3_column_text(poisql.select_poi, 9), -1); - num_cats++; + *num_poi++; } sqlite3_reset(poisql.select_poi); sqlite3_clear_bindings(poisql.select_poi); -*_num_cats=num_cats; return TRUE; } gboolean -poi_update(guint poi_id, guint cat_id, gchar *poi_label, gchar *poi_desc) +poi_get_list_near_unit(guint unitx, guint unity, guint range, GtkListStore **store, guint *num_poi) { -if (!_db) +gdouble lat1, lon1, lat2, lon2; +guint x, y; + +x=unitx-pixel2unit(3*range); +y=unity+pixel2unit(3*range); +unit2latlon(x, y, lat1, lon1); + +x=unitx+pixel2unit(3*range); +y=unity-pixel2unit(3*range); +unit2latlon(x, y, lat2, lon2); + +return poi_get_list_inside(lat1, lon1, lat2, lon2, store, num_poi); +} + +gboolean +poi_update(poi_info *p) +{ +if (!poidb) return FALSE; -if (SQLITE_OK != sqlite3_bind_text(poisql.update_poi, 1, poi_label, -1, SQLITE_STATIC) - || SQLITE_OK != sqlite3_bind_text(poisql.update_poi, 2, poi_desc, -1, g_free) - || SQLITE_OK != sqlite3_bind_int(poisql.update_poi, 3, cat_id) - || SQLITE_OK != sqlite3_bind_int(poisql.update_poi, 4, poi_id) +if (p->poi_id==0) + return FALSE; + +if (SQLITE_OK != sqlite3_bind_text(poisql.update_poi, 1, p->label, -1, SQLITE_STATIC) + || SQLITE_OK != sqlite3_bind_text(poisql.update_poi, 2, p->desc, -1, SQLITE_STATIC) + || SQLITE_OK != sqlite3_bind_int(poisql.update_poi, 3, p->cat_id) + || SQLITE_OK != sqlite3_bind_int(poisql.update_poi, 4, p->poi_id) || SQLITE_DONE != sqlite3_step(poisql.update_poi)) { return FALSE; } @@ -666,17 +719,22 @@ sqlite3_clear_bindings(poisql.update_poi); return TRUE; } +/* XXX: Add url and postal_code */ gboolean -poi_add(gdouble lat, gdouble lon, guint cat_id, gchar *poi_label, gchar *poi_desc) +poi_add(poi_info *p) { -if (!_db) +if (!poidb) return FALSE; -if (SQLITE_OK != sqlite3_bind_double(poisql.insert_poi, 1, lat) - || SQLITE_OK != sqlite3_bind_double(poisql.insert_poi, 2, lon) - || SQLITE_OK != sqlite3_bind_text(poisql.insert_poi, 3, poi_label, -1, g_free) - || SQLITE_OK != sqlite3_bind_text(poisql.insert_poi, 4, poi_desc, -1, g_free) - || SQLITE_OK != sqlite3_bind_int(poisql.insert_poi, 5, cat_id) +if (p->poi_id!=0) + return FALSE; + +if (SQLITE_OK != sqlite3_bind_double(poisql.insert_poi, 1, p->lat) + || SQLITE_OK != sqlite3_bind_double(poisql.insert_poi, 2, p->lon) + || SQLITE_OK != sqlite3_bind_text(poisql.insert_poi, 3, p->label, -1, SQLITE_STATIC) + || SQLITE_OK != sqlite3_bind_text(poisql.insert_poi, 4, p->desc, -1, SQLITE_STATIC) + || SQLITE_OK != sqlite3_bind_int(poisql.insert_poi, 5, p->cat_id) + || SQLITE_OK != sqlite3_bind_double(poisql.insert_poi, 6, p->source) || SQLITE_DONE != sqlite3_step(poisql.insert_poi)) { return FALSE; } @@ -690,7 +748,7 @@ poi_find_nearest(gdouble lat, gdouble lon) { poi_info *p; -if (!_db) +if (!poidb) return FALSE; sqlite3_reset(poisql.select_nearest_poi); @@ -701,10 +759,13 @@ if (SQLITE_OK == sqlite3_bind_double(poisql.select_nearest_poi, 1, lat) && SQLITE_ROW == sqlite3_step(poisql.select_nearest_poi)) { p=poi_new(); - p->lat = sqlite3_column_double(poisql.select_nearest_poi, 0); - p->lon = sqlite3_column_double(poisql.select_nearest_poi, 1); - p->label=g_strdup(sqlite3_column_text(poisql.select_nearest_poi, 2)); - p->cat_label=g_strdup(sqlite3_column_text(poisql.select_nearest_poi, 3)); + p->lat=sqlite3_column_double(poisql.select_nearest_poi, 0); + p->lon=sqlite3_column_double(poisql.select_nearest_poi, 1); + p->poi_id=sqlite3_column_double(poisql.select_nearest_poi, 2); + p->label=g_strdup(sqlite3_column_text(poisql.select_nearest_poi, 3)); + p->desc=g_strdup(sqlite3_column_text(poisql.select_nearest_poi, 4)); + p->cat_id=sqlite3_column_double(poisql.select_nearest_poi, 5); + p->cat_desc=g_strdup(sqlite3_column_text(poisql.select_nearest_poi, 6)); return p; } return NULL; @@ -716,22 +777,23 @@ poi_category_generate_store(void) GtkTreeIter iter; GtkListStore *store; -if (!_db) +if (!poidb) return NULL; -store = gtk_list_store_new(CAT_NUM_COLUMNS, - G_TYPE_UINT, - G_TYPE_BOOLEAN, - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT); +store=gtk_list_store_new(CAT_NUM_COLUMNS, + G_TYPE_UINT, + G_TYPE_BOOLEAN, + G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_UINT); while (SQLITE_ROW == sqlite3_step(poisql.selall_cat)) { gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, - CAT_ID, sqlite3_column_int(poisql.selall_cat, 0), - CAT_ENABLED, sqlite3_column_int(poisql.selall_cat, 3), - CAT_LABEL, sqlite3_column_text(poisql.selall_cat, 1), - CAT_DESC, sqlite3_column_text(poisql.selall_cat, 2), - CAT_POI_CNT, sqlite3_column_int(poisql.selall_cat, 6), -1); + CAT_ID, sqlite3_column_int(poisql.selall_cat, 0), + CAT_ENABLED, sqlite3_column_int(poisql.selall_cat, 3), + CAT_LABEL, sqlite3_column_text(poisql.selall_cat, 1), + CAT_DESC, sqlite3_column_text(poisql.selall_cat, 2), + CAT_POI_CNT, sqlite3_column_int(poisql.selall_cat, 6), -1); } sqlite3_reset(poisql.selall_cat); diff --git a/src/poi.h b/src/poi.h index 0eb49a1..ebd421d 100644 --- a/src/poi.h +++ b/src/poi.h @@ -19,8 +19,15 @@ typedef enum { POI_SEARCH_NEAR=0, POI_SEARCH_TEXT, POI_SEARCH_TEXT_CAT, + POI_SEARCH_CAT, } poi_search_type; +typedef enum { + POI_SOURCE_USER=0, + POI_SOURCE_OSM=1, + POI_SOURCE_GPX_IMPORT=2, +} poi_source; + typedef struct _poi_db poi_db; struct _poi_db { sqlite3 *db; @@ -28,21 +35,31 @@ struct _poi_db { guint zoom; }; -/** Data to describe a POI. */ +/** + * Data to describe a POI. + */ typedef struct _poi_info poi_info; struct _poi_info { guint poi_id; guint cat_id; - guint is_in; + guint is_in_c; + guint is_in_p; + guint source; + time_t addtime; gdouble lat; gdouble lon; + gboolean public; gchar *label; gchar *desc; gchar *cat_label; gchar *cat_desc; + gchar *postal_code; + gchar *url; }; -/** Data used during action: add or edit category/poi **/ +/** + * Data used during action: add or edit category/poi + */ typedef struct _delete_poi delete_poi; struct _delete_poi { GtkWidget *dialog; @@ -50,6 +67,9 @@ struct _delete_poi { guint id; }; +/** + * Data describing a single POI category + */ typedef struct _poi_category poi_category; struct _poi_category { guint id; @@ -59,16 +79,18 @@ struct _poi_category { gchar *desc; }; +/* POI SQL */ struct sql_poi_stmt { sqlite3_stmt *select_poi; + sqlite3_stmt *select_poi_by_id; sqlite3_stmt *select_nearest_poi; sqlite3_stmt *select_poi_search; sqlite3_stmt *select_poi_search_cat; + sqlite3_stmt *select_poi_by_cat; sqlite3_stmt *insert_poi; sqlite3_stmt *update_poi; sqlite3_stmt *delete_poi; sqlite3_stmt *delete_poi_by_catid; - sqlite3_stmt *nextlabel_poi; sqlite3_stmt *select_cat; sqlite3_stmt *insert_cat; sqlite3_stmt *update_cat; @@ -90,20 +112,26 @@ gboolean poi_db_prepare(sqlite3 *db); poi_info *poi_new(void); void poi_free(poi_info *p); -gboolean poi_get_list_near(guint unitx, guint unity, GtkListStore **store, guint *num_cats); -gboolean poi_update(guint poi_id, guint cat_id, gchar *poi_label, gchar *poi_desc); -gboolean poi_add(gdouble lat, gdouble lon, guint cat_id, gchar *poi_label, gchar *poi_desc); +gboolean poi_get_list_near_unit(guint unitx, guint unity, guint range, GtkListStore **store, guint *num_poi); +gboolean poi_get_list_inside(gdouble lat1, gdouble lon1, gdouble lat2, gdouble lon2, GtkListStore **store, guint *num_poi); + +gboolean poi_update(poi_info *p); +gboolean poi_add(poi_info *p); gboolean poi_delete(guint id); gboolean poi_search(poi_search_type pst, gdouble lat, gdouble lon, gchar *text, guint cat, GtkListStore **store); +poi_info *poi_find_nearest(gdouble lat, gdouble lon); + +gboolean poi_get_list_near_unit(guint unitx, guint unity, guint range, GtkListStore **store, guint *num_poi); poi_category *poi_category_new(void); void poi_category_free(poi_category *c); + gboolean poi_category_get(guint cat_id, poi_category **c); gboolean poi_category_delete(guint id); gboolean poi_category_update(guint cat_id, poi_category *c); -poi_info *poi_find_nearest(gdouble lat, gdouble lon); gboolean poi_category_toggle(guint cat_id, gboolean cat_enabled); + GtkListStore *poi_category_generate_store(void); #endif diff --git a/src/search.c b/src/search.c index dd10f70..22f71f1 100644 --- a/src/search.c +++ b/src/search.c @@ -106,7 +106,7 @@ st=g_strdup(gtk_entry_get_text(GTK_ENTRY(s->search_entry))); switch (s->stype) { case SEARCH_TYPE_POI: - sres=poi_search((cid==-1) ? POI_SEARCH_TEXT : POI_SEARCH_TEXT_CAT, s->lat, s->lon, st, cid, &s->store); + sres=poi_search((cid==-1 && slen>0) ? POI_SEARCH_TEXT : (cid!=-1 && slen==0) ? POI_SEARCH_CAT : POI_SEARCH_TEXT_CAT, s->lat, s->lon, st, cid, &s->store); break; case SEARCH_TYPE_WAY: sres=osm_way_search(s->lat, s->lon, st, &s->store);