]> err.no Git - mapper/commitdiff
Add OSM import function directly in the UI.
authorKaj-Michael Lang <milang@onion.tal.org>
Thu, 21 Feb 2008 11:51:19 +0000 (13:51 +0200)
committerKaj-Michael Lang <milang@onion.tal.org>
Thu, 21 Feb 2008 11:51:19 +0000 (13:51 +0200)
- Use a thread to do the import in the background.
- Very simple import dialog.. would need some love.

src/Makefile.am
src/cb.c
src/cb.h
src/import-gui.c [new file with mode: 0644]
src/osm-db-import.c
src/osm-db-import.h
src/ui-common.c

index f25cf07b609d424bcbd881f763f8766bae45c33d..a09595d3ab6c252dfbe76b03adc027a566c86fa1 100644 (file)
@@ -57,6 +57,7 @@ mapper_SOURCES = \
        filter.c \
        filter.h \
        filter-gui.c \
+       import-gui.c \
        gps-browse.c \
        gps-panels.c \
        gps-panels.h \
index 955e1ea285798af5135a660caeeee478fe210b82..e01851a3a5413f5dedb1a53a72969f42cd635337 100644 (file)
--- a/src/cb.c
+++ b/src/cb.c
@@ -527,6 +527,14 @@ settings_dialog_osm();
 return TRUE;
 }
 
+gboolean 
+menu_cb_import_osm(GtkAction * action)
+{
+osm_import_dialog(_window);
+return TRUE;
+}
+
+
 gboolean 
 menu_cb_help(GtkAction * action)
 {
index 00e7d3ad042a681656b271d9fe9840a96c806f2b..8a2ebaaed22f79c82dd70e7f7438ed424907c035 100644 (file)
--- a/src/cb.h
+++ b/src/cb.h
@@ -72,6 +72,7 @@ gboolean menu_cb_settings(GtkAction * action);
 gboolean menu_cb_settings_gps(GtkAction * action);
 gboolean menu_cb_settings_osm(GtkAction * action);
 gboolean menu_cb_settings_colors(GtkAction * action);
+gboolean menu_cb_import_osm(GtkAction * action);
 gboolean menu_cb_help(GtkAction * action);
 gboolean menu_cb_about(GtkAction * action);
 
diff --git a/src/import-gui.c b/src/import-gui.c
new file mode 100644 (file)
index 0000000..a0bc5c2
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * This file is part of mapper
+ *
+ * Copyright (C) 2007 Kaj-Michael Lang
+ *
+ * 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 "config.h"
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <stddef.h>
+#include <glib/gstdio.h>
+#include <gtk/gtk.h>
+#include <libintl.h>
+#include <locale.h>
+
+#include "hildon-mapper.h"
+#include "utils.h"
+#include "osm-db-import.h"
+#include "dialogs.h"
+
+static GtkWidget *progress;
+static GtkWidget *import_dialog;
+
+static gboolean
+osm_import_progress_cb(gpointer data)
+{
+gtk_progress_bar_pulse(progress);
+return TRUE;
+}
+
+static gboolean
+osm_import_done_cb(gpointer data)
+{
+gint ret;
+
+ret=osm_import_join_bg();
+
+if (ret!=0)
+       popup_error(import_dialog, _("OSM Data import failed!"));
+
+progress_dialog_remove(import_dialog);
+return FALSE;
+}
+
+gboolean
+osm_import_dialog(GtkWidget *window)
+{
+GtkWidget *dialog;
+GtkWidget *vbox;
+GtkWidget *picker_planet;
+GtkWidget *entry_db;
+
+dialog = gtk_dialog_new_with_buttons(_("OSM Data import"),
+                               GTK_WINDOW(window),
+                               GTK_DIALOG_MODAL, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, 
+                               GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL);
+
+gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), vbox = gtk_vbox_new (FALSE, 3), TRUE, TRUE, 0);
+
+picker_planet=gtk_file_chooser_button_new(_("OSM Planet file"), GTK_FILE_CHOOSER_ACTION_OPEN);
+entry_db=gtk_entry_new();
+
+gtk_box_pack_start(GTK_BOX(vbox), gtk_label_new("OSM Planet"), TRUE, TRUE, 0);
+gtk_box_pack_start(GTK_BOX(vbox), picker_planet, TRUE, TRUE, 0);
+
+gtk_box_pack_start(GTK_BOX(vbox), gtk_label_new("Destination database"), TRUE, TRUE, 0);
+gtk_box_pack_start(GTK_BOX(vbox), entry_db, TRUE, TRUE, 0);
+
+gtk_widget_show_all(dialog);
+
+if (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog))) {
+       gchar *planet, *db;
+
+       planet=gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(picker_planet));
+       db=gtk_entry_get_text(GTK_ENTRY(entry_db));
+
+       if (planet && db) {
+               progress=gtk_progress_bar_new();
+               import_dialog=progress_dialog(window, "Importing OSM data...", progress);
+
+               if (osm_import_bg(planet, db, osm_import_progress_cb, osm_import_done_cb)==TRUE)
+                       gtk_widget_destroy(dialog);
+               else
+                       popup_error(dialog, _("Failed to start import thread."));
+       } else {
+               popup_error(dialog, _("Missing file selection!"));
+       }
+} else {
+       gtk_widget_destroy(dialog);
+}
+return TRUE;
+}
index ce05fd4cca43e171bf2b01726649c7c6a1353621..a7bffb10989b0494de183aac1110db5995b64b0a 100644 (file)
@@ -72,6 +72,12 @@ static guint dbnode_cnt=0;
 static guint dbnoded_cnt=0;
 static guint dbway_cnt=0;
 
+/* For threaded importing */
+static GThread* import_thread=NULL;
+static GSourceFunc osm_import_progress_cb=NULL;
+static osm_import_data_req osm_import_req;
+static guint import_sid=0;
+
 static gboolean is_update=FALSE;
 static XML_Parser xp;
 
@@ -384,7 +390,7 @@ sqlite3_finalize(sql.delete_way_names_nls);
 sqlite3_finalize(sql.insert_way_names_nls);
 }
 
-void
+static void
 db_prepare(sqlite3 *db)
 {
 /* Way nodes */
@@ -1657,8 +1663,8 @@ osm_planet_parse_buffer(gchar *buffer, size_t r)
 {
 if (XML_Parse(xp, buffer, r, r>0 ? 0:1) == XML_STATUS_ERROR) {
        g_printerr("Parse error at line %d:\n%s\n",
-       XML_GetCurrentLineNumber(xp),
-       XML_ErrorString(XML_GetErrorCode(xp)));
+               (gint)XML_GetCurrentLineNumber(xp),
+               XML_ErrorString(XML_GetErrorCode(xp)));
        return FALSE;
 }
 return TRUE;
@@ -1720,6 +1726,16 @@ g_printf("Skipping data outside of box: %f,%f - %f,%f\n",
        bbox.lat_min, bbox.lon_min,     bbox.lat_max, bbox.lon_max);
 }
 
+static void
+osm_print_import_stats(void)
+{
+g_printf("Total nodes %d, POIs: %d and Ways %d.\n",    node_cnt, noded_cnt, way_cnt);
+g_printf("Cities/Towns: %d\n", g_hash_table_size(osm_place_city));
+g_printf("Villages/Hamlets: %d\n", g_hash_table_size(osm_place_village));
+g_printf("Suburbs: %d\n", g_hash_table_size(osm_place_suburb));
+g_printf("Nodes: %d\n", g_hash_table_size(osm_nodes));
+}
+
 /**
  * Simple helper to do all preparations and importing from planet -> database
  *
@@ -1735,7 +1751,6 @@ if (db_connect(&db, database)!=TRUE) {
 db_create_tables(db);
 db_create_indexes(db);
 db_prepare(db);
-
 osm_planet_parser_init();
 
 if (osm_planet_parse_file(planet)==FALSE) {
@@ -1743,16 +1758,82 @@ if (osm_planet_parse_file(planet)==FALSE) {
        return FALSE;
 }
 
-g_printf("Total nodes %d, POIs: %d and Ways %d.\n",    node_cnt, noded_cnt, way_cnt);
-g_printf("Cities/Towns: %d\n", g_hash_table_size(osm_place_city));
-g_printf("Villages/Hamlets: %d\n", g_hash_table_size(osm_place_village));
-g_printf("Suburbs: %d\n", g_hash_table_size(osm_place_suburb));
-g_printf("Nodes: %d\n", g_hash_table_size(osm_nodes));
+osm_print_import_stats();
 
 osm_planet_save_all_nodes();
 osm_planet_save_all_ways();
 osm_planet_parser_deinit();
+db_finalize();
 db_close(&db);
+g_printf("All done.\n");
 return TRUE;
 }
 
+static gpointer 
+osm_import_thread(gpointer user_data)
+{
+gboolean r;
+osm_import_data_req *req=(osm_import_data_req *)user_data;
+
+g_assert(req);
+g_assert(req->planet);
+g_assert(req->db);
+
+osm_import_progress_cb=req->progress_cb!=NULL ? req->progress_cb : NULL;
+
+r=osm_import(req->planet, req->db);
+g_debug("OSM import result: %d", r);
+
+g_free(req->planet);
+g_free(req->db);
+
+if (req->done_cb!=NULL)
+       g_idle_add(req->done_cb, GINT_TO_POINTER(r==TRUE ? 0 : 1));
+
+return r==TRUE ? 0 : 1;
+}
+
+/**
+ * Helper to start an import in the background using a thread.
+ *
+ * Two callback can be given, one for progress feedback and one when the operation is done.
+ * Done callback must call the join function.
+ * Only one import thread can run at a time.
+ *
+ */
+gboolean 
+osm_import_bg(const gchar *planet, const gchar *database, GSourceFunc progress_cb, GSourceFunc done_cb)
+{
+GError *error=NULL;
+
+g_return_val_if_fail(import_thread==NULL, FALSE);
+
+osm_import_req.planet=g_strdup(planet);
+osm_import_req.db=g_strdup(database);
+osm_import_req.progress_cb=progress_cb;
+osm_import_req.done_cb=done_cb;
+
+import_thread=g_thread_create(osm_import_thread, &osm_import_req, TRUE, &error);
+if (import_thread==NULL) {
+       g_free(osm_import_req.planet);
+       g_free(osm_import_req.db);
+       g_printerr("Import thread creation failed.\n");
+       return FALSE;
+}
+if (osm_import_progress_cb!=NULL)
+       import_sid=g_timeout_add(1000, osm_import_progress_cb, NULL);
+return TRUE;
+}
+
+gint
+osm_import_join_bg(void)
+{
+gint ret;
+g_assert(import_thread!=NULL);
+
+if (import_sid!=0)
+       g_source_remove(import_sid);
+ret=g_thread_join(import_thread);
+import_thread=NULL;
+return ret;
+}
index 42c0059a186bf3005be3589cdb4aaa6076cd28cf..fefacf973278cb6ce0fd0ee548610c62d8ff8801 100644 (file)
@@ -3,6 +3,8 @@
 
 #include <glib.h>
 
+#include "osm.h"
+
 /* POI or Place node extra data */
 typedef struct _node_data node_data;
 struct _node_data {
@@ -56,7 +58,18 @@ struct map_bbox {
        gdouble lon_max;
 };
 
+/* Struct with import request */
+typedef struct _osm_import_data_req osm_import_data_req;
+struct _osm_import_data_req {
+       gchar *planet;
+       gchar *db;
+       GSourceFunc progress_cb;
+       GSourceFunc done_cb;
+};
+
 void osm_import_set_bbox(gboolean use_bb, gdouble latmin, gdouble lonmin, gdouble latmax, gdouble lonmax);
 gboolean osm_import(const gchar *planet, const gchar *database);
+gboolean osm_import_bg(const gchar *planet, const gchar *database, GSourceFunc progress_cb, GSourceFunc done_cb);
+gint osm_import_join_bg(void);
 
 #endif
index 75243a68fb7c0f3c861f0d8b8a3b503703804899..7d8039d04c3195745766f10793f9c61561583324 100644 (file)
@@ -87,9 +87,7 @@ static const gchar *mapper_ui =
 "       <menuitem action='file_settings_osm'/>"
 "         </menu>"
 "      <separator/>"
-#if 0
 "      <menuitem action='file_import_osm'/>"
-#endif
 "      <menuitem action='file_quit'/>"
 "    </menu>"
 "    <menu action='map' name='map'>"
@@ -217,6 +215,7 @@ static GtkActionEntry ui_entries[] = {
        {"file_settings_colors", NULL, N_("_Colors..."), NULL, NULL, G_CALLBACK(menu_cb_settings_colors) },
        {"file_settings_gps", NULL, N_("_Gps..."), NULL, NULL, G_CALLBACK(menu_cb_settings_gps) },
        {"file_settings_osm", NULL, N_("_Map info..."), NULL, NULL, G_CALLBACK(menu_cb_settings_osm) },
+       {"file_import_osm", NULL, N_("_Import OSM data..."), NULL, NULL, G_CALLBACK(menu_cb_import_osm) },
        {"file_quit", GTK_STOCK_QUIT, N_("_Quit"), "<control>Q", NULL, G_CALLBACK(mapper_cb_quit) },
 
        {"help", NULL, N_("_Help"), NULL, NULL, NULL },