[PATCH 1/2] Initial communication between Subsurface and the GoogleMaps API
Lubomir I. Ivanov
neolit123 at gmail.com
Wed Jan 16 05:55:39 PST 2013
From: "Lubomir I. Ivanov" <neolit123 at gmail.com>
A menu entry is added in the Log menu:
'Dive Locations (GoogleMaps)'
A couple of new methods are added to gps.c:
- open_google_maps_for_dives(), which is called from
the menu entry
- add_maker_info_for_dive(), which appends maker information
for dives into a URI buffer
In open_google_maps_for_dives(), we consider doing a malloc
for the URI buffer before calling subsurface_launch_for_uri().
Given that the location string is truncated to 60 gunichars
(in add_maker_info_for_dive())
and that we know the relative size of all other characters
needed for coordinates and separators, we can estimate a buffer
of length in gchars for a single dive:
dive_info_buf = ((60 * 2) * enc_inflate) + (16 * 2) + sep
where:
enc_inflate is set to 3, e.g. " " => "%20"
sep is set to 6, e.g. for "@", "'", etc.
dive_info_buf = 360 + 32 + 6 = 398
then the the total length of the buffer would be:
total = dive_info_buf * amount_selected
Signed-off-by: Lubomir I. Ivanov <neolit123 at gmail.com>
---
display-gtk.h | 2 ++
gps.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
gtk-gui.c | 2 ++
3 files changed, 74 insertions(+), 1 deletion(-)
diff --git a/display-gtk.h b/display-gtk.h
index b889ff1..2dc419e 100644
--- a/display-gtk.h
+++ b/display-gtk.h
@@ -45,6 +45,8 @@ extern int process_ui_events(void);
extern void update_progressbar(progressbar_t *progress, double value);
extern void update_progressbar_text(progressbar_t *progress, const char *text);
+extern void open_google_maps_for_dives(void);
+
extern const char *default_dive_computer_vendor;
extern const char *default_dive_computer_product;
extern const char *default_dive_computer_device;
diff --git a/gps.c b/gps.c
index 87c8a99..40c052c 100644
--- a/gps.c
+++ b/gps.c
@@ -30,7 +30,6 @@ static void add_gps_point(OsmGpsMap *map, float latitude, float longitude)
osm_gps_map_track_add (map, track);
}
-
OsmGpsMap *init_map()
{
OsmGpsMap *map;
@@ -134,3 +133,73 @@ void show_gps_locations()
show_map(map);
}
+
+void add_maker_info_for_dive(char *buf, struct dive *dp)
+{
+ const double inv_10e6 = 1.0 / 1000000.0;
+ const int buf_sz_fp = 16;
+ gchar locbuf[360] = {0}; /* possible URI inflation post the escape */
+ gchar fbuf[16], *utf8_uri;
+
+ strcat(buf, "q=");
+ if (dp->location) {
+ /* append truncated location */
+ g_utf8_strncpy(locbuf, dp->location, 60);
+ utf8_uri = g_uri_escape_string(locbuf, NULL, TRUE);
+ } else {
+ utf8_uri = g_uri_escape_string(_("No location specified"), NULL, TRUE);
+ }
+ strcat(buf, utf8_uri);
+ free(utf8_uri);
+ strcat(buf, "@");
+ /* append coordinates using locale agnostic "ftoa" conversation */
+ g_ascii_formatd(fbuf, buf_sz_fp, "%.6f", (double)dp->latitude.udeg * inv_10e6);
+ strcat(buf, fbuf);
+ g_ascii_formatd(fbuf, buf_sz_fp, "%.6f", (double)dp->longitude.udeg * inv_10e6);
+ strcat(buf, ",");
+ strcat(buf, fbuf);
+ strcat(buf, "&");
+}
+
+/* example of how to make a call to a online google maps based interface
+ * by passing coordinates and location to create a marker. used format is:
+ *
+ * http://econym.org.uk/gmap/example_plotpoints.htm?q=Some%20Location@53,-2&..
+ *
+ * the above website (view source) provides an example of an easy URL based
+ * implementation. */
+void open_google_maps_for_dives(void)
+{
+ const char *url = "http://econym.org.uk/gmap/example_plotpoints.htm?";
+ const int buf_chunk = 398;
+ char *buf;
+ struct dive *dp;
+ int i, with_coord = 0;
+
+ if (!amount_selected) {
+ g_message("open_google_maps_for_dives(): no dives selected");
+ return;
+ }
+ /* an estimate for the URI buffer */
+ buf = (char *)malloc(buf_chunk * amount_selected);
+ memset(buf, 0, buf_chunk);
+ if (!buf)
+ g_error("open_google_maps_for_dives(): failed to allocate buffer");
+
+ /* append url */
+ strcat(buf, url);
+ for (i = 0; i < dive_table.nr; i++) {
+ dp = dive_table.dives[i];
+ if (dp->selected) {
+ if (dp->latitude.udeg == 0 || dp->longitude.udeg == 0)
+ continue;
+ add_maker_info_for_dive(buf, dp);
+ with_coord++;
+ }
+ }
+ if (with_coord)
+ subsurface_launch_for_uri(buf);
+ else
+ g_message("open_google_maps_for_dives(): no coordinates for selected dives");
+ free(buf);
+}
diff --git a/gtk-gui.c b/gtk-gui.c
index d21fac5..ab2599a 100644
--- a/gtk-gui.c
+++ b/gtk-gui.c
@@ -1063,6 +1063,7 @@ static GtkActionEntry menu_items[] = {
{ "Renumber", NULL, N_("Renumber..."), NULL, NULL, G_CALLBACK(renumber_dialog) },
{ "YearlyStats", NULL, N_("Yearly Statistics"), NULL, NULL, G_CALLBACK(show_yearly_stats) },
{ "DivesLocations", NULL, N_("Dives Locations"), CTRLCHAR "M", NULL, G_CALLBACK(show_gps_locations) },
+ { "DivesLocationsGoogle", NULL, N_("Dive Locations (GoogleMaps)"), NULL, NULL, G_CALLBACK(open_google_maps_for_dives) },
{ "SelectEvents", NULL, N_("Select Events..."), NULL, NULL, G_CALLBACK(selectevents_dialog) },
{ "Quit", GTK_STOCK_QUIT, N_("Quit"), CTRLCHAR "Q", NULL, G_CALLBACK(quit) },
{ "About", GTK_STOCK_ABOUT, N_("About Subsurface"), NULL, NULL, G_CALLBACK(about_dialog) },
@@ -1110,6 +1111,7 @@ static const gchar* ui_string = " \
<menuitem name=\"Toggle Zoom\" action=\"ToggleZoom\" /> \
<menuitem name=\"YearlyStats\" action=\"YearlyStats\" /> \
<menuitem name=\"DivesLocations\" action=\"DivesLocations\" /> \
+ <menuitem name=\"DivesLocationsGoogle\" action=\"DivesLocationsGoogle\" /> \
<menu name=\"View\" action=\"ViewMenuAction\"> \
<menuitem name=\"List\" action=\"ViewList\" /> \
<menuitem name=\"Profile\" action=\"ViewProfile\" /> \
--
1.7.11.msysgit.0
More information about the subsurface
mailing list