Author: akv
Date: 2013-05-31 23:35:07 +0200 (Fri, 31 May 2013)
New Revision: 4400
Added:
trunk/src/rs-geo-db.c
trunk/src/rs-geo-db.h
Modified:
trunk/configure.in
trunk/librawstudio/rs-settings.h
trunk/src/Makefile.am
trunk/src/application.h
trunk/src/gtk-interface.c
trunk/src/rs-actions.c
trunk/src/rs-cache.c
trunk/src/rs-photo.c
Log:
Initial commit of geo-tagging code (gui disabled for now).
Modified: trunk/configure.in
===================================================================
--- trunk/configure.in 2013-05-08 23:22:56 UTC (rev 4399)
+++ trunk/configure.in 2013-05-31 21:35:07 UTC (rev 4400)
@@ -133,6 +133,10 @@
AC_SUBST(FLICKCURL_CFLAGS)
AC_SUBST(FLICKCURL_LIBS)
+PKG_CHECK_MODULES(OSMGPSMAP, [osmgpsmap])
+AC_SUBST(OSMGPSMAP_CFLAGS)
+AC_SUBST(OSMGPSMAP_LIBS)
+
GETTEXT_PACKAGE=rawstudio
AC_SUBST(GETTEXT_PACKAGE)
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [Gettext package.])
Modified: trunk/librawstudio/rs-settings.h
===================================================================
--- trunk/librawstudio/rs-settings.h 2013-05-08 23:22:56 UTC (rev 4399)
+++ trunk/librawstudio/rs-settings.h 2013-05-31 21:35:07 UTC (rev 4400)
@@ -59,6 +59,7 @@
MASK_CHANNELMIXER = MASK_CHANNELMIXER_RED | MASK_CHANNELMIXER_GREEN |
MASK_CHANNELMIXER_BLUE,
MASK_VIGNETTING = (1<<15),
MASK_PROFILE = (1<<16),
+ MASK_TIME_OFFSET = (1<<17),
MASK_TRANSFORM = (1<<30),
MASK_ALL = 0x00ffffff,
} RSSettingsMask;
Modified: trunk/src/Makefile.am
===================================================================
--- trunk/src/Makefile.am 2013-05-08 23:22:56 UTC (rev 4399)
+++ trunk/src/Makefile.am 2013-05-31 21:35:07 UTC (rev 4400)
@@ -3,7 +3,7 @@
INCLUDES = \
-DPACKAGE_DATA_DIR=\""$(datadir)"\" \
-DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \
- @PACKAGE_CFLAGS@ @GCONF_CFLAGS@ @LENSFUN_CFLAGS@ @LIBGPHOTO2_CFLAGS@
@DBUS_CFLAGS@ \
+ @PACKAGE_CFLAGS@ @GCONF_CFLAGS@ @LENSFUN_CFLAGS@ @LIBGPHOTO2_CFLAGS@
@DBUS_CFLAGS@ @OSMGPSMAP_CFLAGS@ \
-I$(top_srcdir)/librawstudio/ \
-I$(top_srcdir)/
@@ -46,7 +46,8 @@
rs-dir-selector.c rs-dir-selector.h \
rs-tag-gui.c rs-tag-gui.h\
rs-tethered-shooting.c rs-tethered-shooting.h \
- rs-enfuse.c rs-enfuse.h
+ rs-enfuse.c rs-enfuse.h \
+ rs-geo-db.c rs-geo-db.h
-rawstudio_LDADD = ../librawstudio/librawstudio-@[email protected] @PACKAGE_LIBS@
@GCONF_LIBS@ @LENSFUN_LIBS@ @LIBGPHOTO2_LIBS@ @DBUS_LIBS@ $(INTLLIBS)
+rawstudio_LDADD = ../librawstudio/librawstudio-@[email protected] @PACKAGE_LIBS@
@GCONF_LIBS@ @LENSFUN_LIBS@ @LIBGPHOTO2_LIBS@ @DBUS_LIBS@ @OSMGPSMAP_LIBS@
$(INTLLIBS)
Modified: trunk/src/application.h
===================================================================
--- trunk/src/application.h 2013-05-08 23:22:56 UTC (rev 4399)
+++ trunk/src/application.h 2013-05-31 21:35:07 UTC (rev 4400)
@@ -65,9 +65,9 @@
RSFilter *auto_wb_filter;
gdouble *auto_wb_mul;
RS_MAIN_SIGNAL* signal;
+ gint time_offset;
} RS_PHOTO;
-
typedef struct {
RS_PHOTO *photo;
RSSettings *settings_buffer;
@@ -76,6 +76,7 @@
RS_RECT crop_buffer;
gdouble angle_buffer;
guint orientation_buffer;
+ gint time_offset_buffer;
gint current_setting;
RS_QUEUE *queue;
RSStore *store;
Modified: trunk/src/gtk-interface.c
===================================================================
--- trunk/src/gtk-interface.c 2013-05-08 23:22:56 UTC (rev 4399)
+++ trunk/src/gtk-interface.c 2013-05-31 21:35:07 UTC (rev 4400)
@@ -43,6 +43,7 @@
#include "rs-toolbox.h"
#include "rs-library.h"
#include "rs-tag-gui.h"
+#include "rs-geo-db.h"
static GtkStatusbar *statusbar;
static gboolean fullscreen;
@@ -1574,6 +1575,10 @@
gtk_box_pack_start (GTK_BOX(open_box), library_expander, FALSE, TRUE,
0);
gtk_box_pack_start (GTK_BOX(open_box), directory_expander, TRUE, TRUE,
0);
+ GtkWidget *geolocbox = gtk_vbox_new(FALSE, 0);
+ RSGeoDb *geodb = rs_geo_db_get_singleton();
+ GtkWidget *map = rs_geo_db_get_widget(geodb);
+ gtk_box_pack_start (GTK_BOX(geolocbox), map, TRUE, TRUE, 0);
if (client_mode)
rs->toolbox = tools;
@@ -1581,6 +1586,7 @@
{
rs->toolbox = gtk_notebook_new();
gtk_notebook_append_page(GTK_NOTEBOOK(rs->toolbox), tools,
gtk_label_new(_("Tools")));
+ //gtk_notebook_append_page(GTK_NOTEBOOK(rs->toolbox),
geolocbox, gtk_label_new(_("Map")));
gtk_notebook_append_page(GTK_NOTEBOOK(rs->toolbox), batchbox,
gtk_label_new(_("Batch")));
gtk_notebook_append_page(GTK_NOTEBOOK(rs->toolbox), open_box,
gtk_label_new(_("Open")));
}
Modified: trunk/src/rs-actions.c
===================================================================
--- trunk/src/rs-actions.c 2013-05-08 23:22:56 UTC (rev 4399)
+++ trunk/src/rs-actions.c 2013-05-31 21:35:07 UTC (rev 4400)
@@ -43,6 +43,7 @@
#include "rs-toolbox.h"
#include "rs-tethered-shooting.h"
#include "rs-enfuse.h"
+#include "rs-geo-db.h"
static GtkActionGroup *core_action_group = NULL;
static GStaticMutex rs_actions_spinlock = G_STATIC_MUTEX_INIT;
@@ -479,10 +480,10 @@
static const gint COPY_MASK_ALL =
MASK_PROFILE|MASK_EXPOSURE|MASK_SATURATION|MASK_HUE|
MASK_CONTRAST|MASK_WB|MASK_SHARPEN|MASK_DENOISE_LUMA|MASK_DENOISE_CHROMA|
- MASK_CHANNELMIXER|MASK_TCA|MASK_VIGNETTING|MASK_CURVE;
+ MASK_CHANNELMIXER|MASK_TCA|MASK_VIGNETTING|MASK_CURVE|MASK_TIME_OFFSET;
/* Widgets for copy dialog */
-static GtkWidget *cb_profile, *cb_exposure, *cb_saturation, *cb_hue,
*cb_contrast, *cb_whitebalance, *cb_curve, *cb_sharpen, *cb_denoise_luma,
*cb_denoise_chroma, *cb_channelmixer, *cb_tca, *cb_vignetting,*cb_transform,
*b_all_none;
+static GtkWidget *cb_profile, *cb_exposure, *cb_saturation, *cb_hue,
*cb_contrast, *cb_whitebalance, *cb_curve, *cb_sharpen, *cb_denoise_luma,
*cb_denoise_chroma, *cb_channelmixer, *cb_tca, *cb_vignetting,*cb_transform,
*cb_time_offset, *b_all_none;
static void
all_none_clicked(GtkButton *button, gpointer user_data)
@@ -516,6 +517,7 @@
cb_vignetting = gtk_check_button_new_with_label (_("Vignetting"));
cb_curve = gtk_check_button_new_with_label (_("Curve"));
cb_transform = gtk_check_button_new_with_label (_("Transform"));
+ cb_time_offset = gtk_check_button_new_with_label (_("Time offset
(GPS)"));
b_all_none = gtk_button_new_with_label (_("Select All/None"));
g_signal_connect(b_all_none, "clicked", G_CALLBACK(all_none_clicked),
NULL);
@@ -537,6 +539,7 @@
gtk_box_pack_start (GTK_BOX (cb_box), cb_vignetting, FALSE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (cb_box), cb_curve, FALSE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (cb_box), cb_transform, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (cb_box), cb_time_offset, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (cb_box), b_all_none, FALSE, TRUE, 0);
dialog = gui_dialog_make_from_widget(GTK_STOCK_DIALOG_QUESTION,
_("Select Settings to Copy"), cb_box);
@@ -563,6 +566,7 @@
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cb_vignetting), !!(mask
& MASK_VIGNETTING));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cb_curve), !!(mask &
MASK_CURVE));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cb_transform), !!(mask &
MASK_TRANSFORM));
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cb_time_offset), !!(mask
& MASK_TIME_OFFSET));
}
static gint
@@ -597,6 +601,8 @@
mask |= MASK_CURVE;
if (GTK_TOGGLE_BUTTON(cb_transform)->active)
mask |= MASK_TRANSFORM;
+ if (GTK_TOGGLE_BUTTON(cb_time_offset)->active)
+ mask |= MASK_TIME_OFFSET;
return mask;
}
@@ -632,6 +638,7 @@
rs->crop_buffer.x1 = -1;
rs->angle_buffer = rs->photo->angle;
rs->orientation_buffer = rs->photo->orientation;
+ rs->time_offset_buffer = rs->photo->time_offset;
gui_status_notify(_("Copied settings"));
}
@@ -699,6 +706,11 @@
rs_photo_set_dcp_profile(photo,
rs->dcp_buffer);
else if (rs->icc_buffer)
rs_photo_set_icc_profile(photo,
rs->icc_buffer);
+ }
+ if (mask & MASK_TIME_OFFSET)
+ {
+ RSGeoDb *geodb =
rs_geo_db_get_singleton();
+ rs_geo_db_set_offset(geodb, photo,
rs->time_offset_buffer);
}
rs_cache_save(photo, (new_mask | mask) &
MASK_ALL);
g_object_unref(photo);
@@ -721,6 +733,11 @@
rs_photo_set_angle(rs->photo,
rs->angle_buffer, FALSE);
rs_photo_set_crop(rs->photo,
&rs->crop_buffer);
}
+ if (mask & MASK_TIME_OFFSET)
+ {
+ RSGeoDb *geodb =
rs_geo_db_get_singleton();
+ rs_geo_db_set_offset(geodb, photo,
rs->time_offset_buffer);
+ }
}
if (rs->photo)
Modified: trunk/src/rs-cache.c
===================================================================
--- trunk/src/rs-cache.c 2013-05-08 23:22:56 UTC (rev 4399)
+++ trunk/src/rs-cache.c 2013-05-31 21:35:07 UTC (rev 4400)
@@ -125,6 +125,11 @@
rs_cache_save_settings(photo->settings[id], mask, writer);
xmlTextWriterEndElement(writer);
}
+ if (photo->time_offset)
+ {
+ xmlTextWriterWriteFormatElement(writer, BAD_CAST "time_offset",
"%d", photo->time_offset);
+ }
+
int ret = xmlTextWriterEndDocument(writer);
xmlFreeTextWriter(writer);
g_free(cachename);
@@ -517,6 +522,15 @@
g_strfreev(vals);
xmlFree(val);
}
+ else if ((!xmlStrcmp(cur->name, BAD_CAST "time_offset")))
+ {
+ val = xmlNodeListGetString(doc, cur->xmlChildrenNode,
1);
+ if (val)
+ {
+ photo->time_offset = atoi((gchar *) val);
+ xmlFree(val);
+ }
+ }
cur = cur->next;
}
Added: trunk/src/rs-geo-db.c
===================================================================
--- trunk/src/rs-geo-db.c (rev 0)
+++ trunk/src/rs-geo-db.c 2013-05-31 21:35:07 UTC (rev 4400)
@@ -0,0 +1,453 @@
+#include <rawstudio.h>
+#include <application.h>
+#include <glib.h>
+#include <libxml/encoding.h>
+#include <libxml/xmlwriter.h>
+#include <sqlite3.h>
+#include "osm-gps-map.h"
+#include "rs-geo-db.h"
+#include "gtk-progress.h"
+
+struct _RSGeoDb {
+ GObject parent;
+
+ OsmGpsMap *map;
+ sqlite3 *db;
+ GtkAdjustment *offset_adj;
+};
+
+G_DEFINE_TYPE (RSGeoDb, rs_geo_db, GTK_TYPE_OBJECT)
+
+static void
+rs_geo_db_finalize (GObject *object)
+{
+ RSGeoDb *geodb = RS_GEO_DB(object);
+
+ sqlite3_close(geodb->db);
+
+ if (G_OBJECT_CLASS (rs_geo_db_parent_class)->finalize)
+ G_OBJECT_CLASS (rs_geo_db_parent_class)->finalize (object);
+}
+
+static void
+dispose(GObject *object)
+{
+ G_OBJECT_CLASS(rs_geo_db_parent_class)->dispose(object);
+}
+
+
+static void
+rs_geo_db_class_init (RSGeoDbClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->dispose = dispose;
+ object_class->finalize = rs_geo_db_finalize;
+}
+
+static void
+rs_geo_db_init (RSGeoDb *geodb)
+{
+ gchar *database = g_strdup_printf("%s/.rawstudio/geo.db",
g_get_home_dir());
+
+ if(sqlite3_open(database, &geodb->db))
+ {
+ gchar *msg = g_strdup_printf("Could not open database %s",
database);
+ g_warning("sqlite3: %s\n", msg);
+ g_free(msg);
+ sqlite3_close(geodb->db);
+ }
+ g_free(database);
+
+ sqlite3_stmt *stmt;
+ gint rc;
+
+ if (rc);
+
+ sqlite3_prepare_v2(geodb->db, "create table imports (id INTEGER PRIMARY
KEY, checksum VARCHAR(1024) UNIQUE, priority INTEGER);", -1, &stmt, NULL);
+ rc = sqlite3_step(stmt);
+ sqlite3_finalize(stmt);
+
+ sqlite3_prepare_v2(geodb->db, "CREATE TABLE trkpts (time INTEGER
PRIMARY KEY, lon DOUBLE, lat DOUBLE, ele DOUBLE, import INTEGER, FOREIGN
KEY(import) REFERENCES imports(id));", -1, &stmt, NULL);
+ rc = sqlite3_step(stmt);
+ sqlite3_finalize(stmt);
+}
+
+
+RSGeoDb *
+rs_geo_db_new(void)
+{
+ return g_object_new (RS_TYPE_GEO_DB, NULL);
+}
+
+RSGeoDb *
+rs_geo_db_get_singleton(void)
+{
+ static RSGeoDb *geodb = NULL;
+ static GStaticMutex lock = G_STATIC_MUTEX_INIT;
+
+ g_static_mutex_lock(&lock);
+ if (!geodb)
+ {
+ geodb = rs_geo_db_new();
+ }
+ g_static_mutex_unlock(&lock);
+
+ return geodb;
+}
+
+void load_gpx(gchar *gpxfile, gint priority, sqlite3 *db, gint num, gint total)
+{
+ sqlite3_stmt *stmt;
+ gint rc;
+
+ if (rc); /* FIXME */
+
+ xmlDocPtr doc;
+ xmlNodePtr cur;
+ xmlNodePtr trk = NULL;
+ xmlNodePtr trkseg = NULL;
+ xmlNodePtr trkpt = NULL;
+ xmlChar *val;
+
+ gdouble lon = 0.0, lat = 0.0, ele = 0.0;
+ gchar *year, *month, *day, *hour, *min, *sec;
+ GDateTime *timestamp = NULL;
+
+ doc = xmlParseFile(gpxfile);
+ if (!doc)
+ return;
+
+ gchar *checksum = rs_file_checksum(gpxfile);
+ gint import_id = 0;
+
+ sqlite3_prepare_v2(db, "INSERT INTO imports (checksum, priority) VALUES
(?1, ?2);", -1, &stmt, NULL);
+ rc = sqlite3_bind_text(stmt, 1, checksum, -1, SQLITE_TRANSIENT);
+ rc = sqlite3_bind_int (stmt, 2, priority);
+ rc = sqlite3_step(stmt);
+ import_id = sqlite3_last_insert_rowid(db);
+ sqlite3_finalize(stmt);
+
+ if (import_id == 0)
+ return;
+
+ cur = xmlDocGetRootElement(doc);
+ cur = cur->xmlChildrenNode;
+
+ gint count = 0;
+
+ while(cur)
+ {
+ if ((!xmlStrcmp(cur->name, BAD_CAST "trk")))
+ {
+ trk = cur->xmlChildrenNode;
+ while (trk)
+ {
+ if ((!xmlStrcmp(trk->name, BAD_CAST "trkseg")))
+ {
+ trkseg = trk->xmlChildrenNode;
+ while (trkseg)
+ {
+ if ((!xmlStrcmp(trkseg->name,
BAD_CAST "trkpt")))
+ {
+ count++;
+ }
+ trkseg = trkseg->next;
+ }
+ }
+ trk = trk->next;
+ }
+ }
+ cur = cur->next;
+ }
+
+ RS_PROGRESS *progress = NULL;
+ gchar *title = g_strdup_printf("Loading GPX (%d/%d)...", num, total);
+ progress = gui_progress_new(title, count);
+ g_free(title);
+ GUI_CATCHUP();
+
+ cur = xmlDocGetRootElement(doc);
+ cur = cur->xmlChildrenNode;
+
+ while(cur)
+ {
+ if ((!xmlStrcmp(cur->name, BAD_CAST "trk")))
+ {
+ trk = cur->xmlChildrenNode;
+ while (trk)
+ {
+ if ((!xmlStrcmp(trk->name, BAD_CAST "trkseg")))
+ {
+ trkseg = trk->xmlChildrenNode;
+ while (trkseg)
+ {
+ if ((!xmlStrcmp(trkseg->name,
BAD_CAST "trkpt")))
+ {
+ trkpt =
trkseg->xmlChildrenNode;
+
+ // Reset values
+ lon = 0.0;
+ lat = 0.0;
+ ele = 0.0;
+
+ while (trkpt)
+ {
+ if
((!xmlStrcmp(trkpt->name, BAD_CAST "ele")))
+ {
+ val =
xmlNodeListGetString(doc, trkpt->xmlChildrenNode, 1);
+ ele =
atof((gchar *) val);
+
xmlFree(val);
+ }
+ if
((!xmlStrcmp(trkpt->name, BAD_CAST "time")))
+ {
+ val =
xmlNodeListGetString(doc, trkpt->xmlChildrenNode, 1);
+ year =
g_utf8_substring((gchar *) val, 0, 4);
+ month =
g_utf8_substring((gchar *) val, 5, 7);
+ day =
g_utf8_substring((gchar *) val, 8, 10);
+ hour =
g_utf8_substring((gchar *) val, 11, 13);
+ min =
g_utf8_substring((gchar *) val, 14, 16);
+ sec =
g_utf8_substring((gchar *) val, 17, 19);
+
xmlFree(val);
+
timestamp = g_date_time_new_utc(atoi(year), atoi(month), atoi(day), atoi(hour),
atoi(min), atoi(sec));
+
g_free(year);
+
g_free(month);
+
g_free(day);
+
g_free(hour);
+
g_free(min);
+
g_free(sec);
+ }
+ trkpt =
trkpt->next;
+ }
+ val =
xmlGetProp(trkseg, BAD_CAST "lat");
+ lat = atof((gchar *)
val);
+ xmlFree(val);
+
+ val =
xmlGetProp(trkseg, BAD_CAST "lon");
+ lon = atof((gchar *)
val);
+ if (lat && lon)
+ {
+
sqlite3_prepare_v2(db, "INSERT INTO trkpts (time, lon, lat, ele, import) VALUES
(?1, ?2, ?3, ?4, ?5);", -1, &stmt, NULL);
+ rc =
sqlite3_bind_int (stmt, 1, atoi(g_date_time_format(timestamp, "%s")));
+ rc =
sqlite3_bind_double (stmt, 2, lon);
+ rc =
sqlite3_bind_double (stmt, 3, lat);
+ rc =
sqlite3_bind_double (stmt, 4, ele);
+ rc =
sqlite3_bind_int (stmt, 5, import_id);
+ rc =
sqlite3_step(stmt);
+
sqlite3_finalize(stmt);
+ }
+
gui_progress_advance_one(progress);
+ GUI_CATCHUP();
+
+
g_date_time_unref(timestamp);
+ }
+ trkseg = trkseg->next;
+ }
+ }
+ trk = trk->next;
+ }
+ }
+ cur = cur->next;
+ }
+ gui_progress_free(progress);
+}
+
+
+void
+rs_geo_db_find_coordinate(RSGeoDb *geodb, gint timestamp, gdouble *lon,
gdouble *lat, gdouble *ele)
+{
+ sqlite3 *db = geodb->db;
+
+ sqlite3_stmt *stmt;
+ gint rc;
+
+ gint before_timestamp = 0;
+ gdouble before_lon = 0.0, before_lat = 0.0, before_ele = 0.0;
+
+ gint after_timestamp = 0;
+ gdouble after_lon = 0.0, after_lat = 0.0, after_ele = 0.0;
+
+ rc = sqlite3_prepare_v2(db, "SELECT * FROM trkpts WHERE time <= ?1
ORDER BY TIME DESC LIMIT 1;", -1, &stmt, NULL);
+ rc = sqlite3_bind_int(stmt, 1, timestamp);
+ rc = sqlite3_step(stmt);
+ if (rc == SQLITE_ROW)
+ {
+ before_timestamp = sqlite3_column_int(stmt, 0);
+ before_lon = sqlite3_column_double(stmt, 1);
+ before_lat = sqlite3_column_double(stmt, 2);
+ before_ele = sqlite3_column_double(stmt, 3);
+ }
+
+ rc = sqlite3_prepare_v2(db, "SELECT * FROM trkpts WHERE time >= ?1
ORDER BY TIME ASC LIMIT 1;", -1, &stmt, NULL);
+ rc = sqlite3_bind_int(stmt, 1, timestamp);
+ rc = sqlite3_step(stmt);
+ if (rc == SQLITE_ROW)
+ {
+ after_timestamp = sqlite3_column_int(stmt, 0);
+ after_lon = sqlite3_column_double(stmt, 1);
+ after_lat = sqlite3_column_double(stmt, 2);
+ after_ele = sqlite3_column_double(stmt, 3);
+ }
+
+ if (after_timestamp == before_timestamp)
+ {
+ *lon = after_lon;
+ *lat = after_lat;
+ *ele = after_ele;
+ return;
+ }
+
+ gint diff_timestamp = after_timestamp - before_timestamp;
+ gint diff = after_timestamp - timestamp;
+ gdouble diff_lon = (after_lon - before_lon) / diff_timestamp;
+ gdouble diff_lat = (after_lat - before_lat) / diff_timestamp;
+ gdouble diff_ele = (after_ele - before_ele) / diff_timestamp;
+
+ *lon = after_lon - diff*diff_lon;
+ *lat = after_lat - diff*diff_lat;
+ *ele = after_ele - diff*diff_ele;
+}
+
+void
+rs_geo_db_set_coordinates(RSGeoDb *geodb, gdouble lon, gdouble lat)
+{
+ osm_gps_map_set_center((OsmGpsMap *) geodb->map, lat, lon);
+}
+
+void spinbutton_change (GtkAdjustment *adj, gpointer user_data)
+{
+ RS_BLOB *rs = (RS_BLOB *) user_data;
+ gdouble lon, lat, ele;
+ RSGeoDb *geodb = rs_geo_db_get_singleton();
+
+ gint time_offset= gtk_adjustment_get_value(adj);
+ rs->photo->time_offset = time_offset;
+
+ rs_geo_db_find_coordinate(geodb, rs->photo->metadata->timestamp +
time_offset, &lon, &lat, &ele);
+ rs_geo_db_set_coordinates(geodb, lon, lat);
+}
+
+void update_label (GtkAdjustment *adj, GtkLabel *label)
+{
+ gint offset = gtk_adjustment_get_value(adj);
+ gint hour = (gint) (offset%(60*60*60)/60/60);
+ gint min = (gint) (offset%(60*60)/60);
+ if (min < 0)
+ min *= -1;
+ gint sec = (gint) (offset%(60));
+ if (sec < 0)
+ sec *= -1;
+ gchar *text = g_strdup_printf("offset: %02d:%02d:%02d (h:m:s)\n", hour,
min, sec);
+ gtk_label_set_text(label, text);
+}
+
+void import_gpx(GtkButton *button, RSGeoDb *geodb)
+{
+ GtkWidget *fc = gtk_file_chooser_dialog_new ("Import GPX ...", NULL,
+
GTK_FILE_CHOOSER_ACTION_OPEN,
+
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
+ gtk_dialog_set_default_response(GTK_DIALOG(fc), GTK_RESPONSE_ACCEPT);
+
+ GtkFileFilter *filter = gtk_file_filter_new();
+ gtk_file_filter_set_name(filter, "GPX");
+ gtk_file_filter_add_pattern(filter, "*.gpx");
+ gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fc), filter);
+ gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(fc), TRUE);
+
+ //gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (fc), dir); //
FIXME: save last used directory
+
+ if (gtk_dialog_run (GTK_DIALOG (fc)) == GTK_RESPONSE_ACCEPT)
+ {
+ GSList *filenames;
+ gchar *filename;
+ filenames = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER
(fc));
+ gtk_widget_destroy(fc);
+ if (filenames)
+ {
+ gint i;
+
+ for(i=0;i<g_slist_length(filenames);i++)
+ {
+ filename = g_slist_nth_data(filenames, i);
+ load_gpx(filename, 1, geodb->db, (i+1),
g_slist_length(filenames));
+ g_free(filename);
+ }
+ g_slist_free(filenames);
+ }
+ }
+ else
+ {
+ gtk_widget_destroy(fc);
+ }
+}
+
+void map_changed (OsmGpsMap *map, RSGeoDb *geodb)
+{
+ /* FIXME: save zoom */
+}
+
+GtkWidget *
+rs_geo_db_get_widget(RSGeoDb *geodb) {
+ OsmGpsMapSource_t source = OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_SATELLITE;
+
+ if ( !osm_gps_map_source_is_valid(source) )
+ return NULL;
+
+ GtkWidget *map = g_object_new (OSM_TYPE_GPS_MAP,
+
"map-source", source,
+
"tile-cache", "/tmp/",
+ NULL);
+
+ g_signal_connect(map, "changed", G_CALLBACK(map_changed), geodb);
+
+ OsmGpsMapLayer *osd = g_object_new (OSM_TYPE_GPS_MAP_OSD,
+
"show-scale",TRUE,
+
"show-coordinates",TRUE,
+
"show-crosshair",TRUE,
+
"show-dpad",TRUE,
+
"show-zoom",TRUE,
+
"show-gps-in-dpad",TRUE,
+
"show-gps-in-zoom",FALSE,
+
"dpad-radius", 30,
+
NULL);
+
+ osm_gps_map_layer_add(OSM_GPS_MAP(map), osd);
+ g_object_unref(G_OBJECT(osd));
+
+ osm_gps_map_set_center((OsmGpsMap *) map, 57.0, 10.0);
+ gtk_widget_show_all (map);
+
+ geodb->map = (OsmGpsMap *) map;
+
+ GtkWidget *box = gtk_vbox_new(FALSE, 0);
+ gtk_box_pack_start (GTK_BOX(box), map, TRUE, TRUE, 0);
+
+ GtkWidget *offset_box = gtk_hbox_new(FALSE, 0);
+
+ GtkAdjustment *adj = (GtkAdjustment *) gtk_adjustment_new(0, -43200,
43200, 1, 10, 0);
+ geodb->offset_adj = adj;
+ GtkWidget *spin = gtk_spin_button_new(GTK_ADJUSTMENT(adj), 1, 1);
+ GtkWidget *offset_label = gtk_label_new("offset: 00:00:00 (h:m:s)");
+ gtk_box_pack_start (GTK_BOX(box), offset_box, FALSE, FALSE, 5);
+
+ gtk_box_pack_start (GTK_BOX(offset_box), spin, TRUE, FALSE, 5);
+ gtk_box_pack_start (GTK_BOX(offset_box), offset_label, TRUE, FALSE, 5);
+
+ g_signal_connect(adj, "value_changed", G_CALLBACK(spinbutton_change),
rs_get_blob());
+ g_signal_connect(adj, "value_changed", G_CALLBACK(update_label),
offset_label);
+
+ GtkWidget *button = gtk_button_new_with_label("Import GPX file");
+ g_signal_connect(button, "clicked", G_CALLBACK(import_gpx), geodb);
+ gtk_box_pack_start (GTK_BOX(box), button, FALSE, FALSE, 5);
+
+ return box;
+}
+
+void rs_geo_db_set_offset(RSGeoDb *geodb, RS_PHOTO *photo, gint offset)
+{
+ photo->time_offset = offset;
+
+ RS_BLOB *rs = rs_get_blob();
+ if (rs->photo)
+ gtk_adjustment_set_value(geodb->offset_adj, photo->time_offset);
+}
Added: trunk/src/rs-geo-db.h
===================================================================
--- trunk/src/rs-geo-db.h (rev 0)
+++ trunk/src/rs-geo-db.h 2013-05-31 21:35:07 UTC (rev 4400)
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2006-2011 Anders Brander <[email protected]>,
+ * Anders Kvist <[email protected]> and Klaus Post <[email protected]>
+ *
+ * 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.
+ */
+
+#ifndef RS_GEO_DB_H
+#define RS_GEO_DB_H
+
+#include <rawstudio.h>
+#include "application.h"
+#include <sqlite3.h>
+#include "osm-gps-map.h"
+
+G_BEGIN_DECLS
+
+#define RS_TYPE_GEO_DB rs_geo_db_get_type()
+#define RS_GEO_DB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RS_TYPE_GEO_DB,
RSGeoDb))
+#define RS_GEO_DB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),
RS_TYPE_GEO_DB, RSGeoDbClass))
+#define RS_IS_GEO_DB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RS_TYPE_GEO_DB))
+#define RS_IS_GEO_DB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),
RS_TYPE_GEO_DB))
+#define RS_GEO_DB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
RS_TYPE_GEO_DB, RSGeoDbClass))
+
+typedef struct _RSGeoDb RSGeoDb;
+
+typedef struct {
+ GtkScrolledWindowClass parent_class;
+} RSGeoDbClass;
+
+GType rs_geo_db_get_type (void);
+
+extern RSGeoDb *
+rs_geo_db_new (void);
+RSGeoDb *rs_geo_db_get_singleton(void);
+
+extern GtkWidget * rs_geo_db_get_widget(RSGeoDb *geodb);
+extern void rs_geo_db_set_coordinates(RSGeoDb *geodb, gdouble lon, gdouble
lat);
+void rs_geo_db_find_coordinate(RSGeoDb *geodb, gint timestamp, gdouble *lon,
gdouble *lat, gdouble *ele);
+void rs_geo_db_set_offset(RSGeoDb *geodb, RS_PHOTO *time_offset, gint offset);
+
+#endif /* RS_GEO_DB */
+
+
+
Modified: trunk/src/rs-photo.c
===================================================================
--- trunk/src/rs-photo.c 2013-05-08 23:22:56 UTC (rev 4399)
+++ trunk/src/rs-photo.c 2013-05-31 21:35:07 UTC (rev 4400)
@@ -23,6 +23,7 @@
#include "rs-cache.h"
#include "rs-camera-db.h"
#include "rs-profile-factory.h"
+#include "rs-geo-db.h"
static void rs_photo_class_init (RS_PHOTOClass *klass);
@@ -152,6 +153,7 @@
photo->exported = FALSE;
photo->auto_wb_mul = NULL;
photo->embedded_profile = NULL;
+ photo->time_offset = 0;
}
static void
@@ -422,6 +424,15 @@
RSLensDb *lens_db = rs_lens_db_get_default();
RSLens *lens = rs_lens_db_lookup_from_metadata(lens_db, meta);
+ gdouble lon, lat, ele;
+ RSGeoDb *geodb = rs_geo_db_get_singleton();
+ rs_geo_db_set_offset(geodb, photo, photo->time_offset);
+ if (photo->time_offset != 0)
+ {
+ rs_geo_db_find_coordinate(geodb, meta->timestamp +
photo->time_offset, &lon, &lat, &ele);
+ rs_geo_db_set_coordinates(geodb, lon, lat);
+ }
+
/* Apply lens information to RSLensfun */
if (lens)
{
_______________________________________________
Rawstudio-commit mailing list
[email protected]
http://rawstudio.org/cgi-bin/mailman/listinfo/rawstudio-commit