- Use a thread to do the import in the background.
- Very simple import dialog.. would need some love.
filter.c \
filter.h \
filter-gui.c \
+ import-gui.c \
gps-browse.c \
gps-panels.c \
gps-panels.h \
return TRUE;
}
+gboolean
+menu_cb_import_osm(GtkAction * action)
+{
+osm_import_dialog(_window);
+return TRUE;
+}
+
+
gboolean
menu_cb_help(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);
--- /dev/null
+/*
+ * 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;
+}
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;
sqlite3_finalize(sql.insert_way_names_nls);
}
-void
+static void
db_prepare(sqlite3 *db)
{
/* Way nodes */
{
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;
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
*
db_create_tables(db);
db_create_indexes(db);
db_prepare(db);
-
osm_planet_parser_init();
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;
+}
#include <glib.h>
+#include "osm.h"
+
/* POI or Place node extra data */
typedef struct _node_data node_data;
struct _node_data {
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
" <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'>"
{"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 },