Extracting information from a webservice

Dirk Hohndel dirk at hohndel.org
Wed Jan 23 05:56:57 PST 2013


Dirk Hohndel <dirk at hohndel.org> writes:

> Finally returning to this part of the puzzle - it's something we either
> need to disable prior to the 3.0 release, or make marginally more useful
> :-)
>
> One thing that I noticed, Pierre & Aurélien, is this:
>
>     <dive>
>       <name>shark+pit</name>
>       <latitude>20.8621345041</latitude>
>       <longitude>-156.67578307</longitude>
>       <date>2012-12-14</date>
>       <time>01:23:00</time>
>     </dive>
>
> While I do like my night dives as much as anyone else... this dive was
> actually at 13:34. And a quick check seems to indicate that all dives
> are mapped into the first 12h of the day - is that a bug in the Android
> companion app or in the webservice?
>
> Once that is figured out I think it wouldn't be too hard to show the
> closest dive to the time returned (or the closest two dives if this is
> roughly in the middle between "end of dive one" and "beginning of dive
> two") and ask if the GPS location should be applied to that dive.
>
> For extra credits one could of course also open a quick map window with
> those coordinates...

To make this a little easier to envision, here's a trivial hack that
actually parses the data downloaded from the webservice (without
attempting to fix the incorrect "middle of the night" timestamps
mentioned above - you can just edit the timestamps once the "dives" are
imported).

Because the times are not close enough to the real dives I didn't expect
this to simply match the dives that I have. And looking a little more
closely, the "likely_same_dive" logic calls dives different because the
imported dives have no depth and duration (and are therefore different).
Also, try_to_merge isn't even called if dives don't overlap (completely
reasonable for "real" dives).

So there are a few more hacks involved here, but nonetheless, this does
get me GPS locations for the dives that I have tracked with the
Subsurface Companion App :-)

So no - this is not the somewhat more fancy "help the user match"
algorithm envisioned above. This simply loads the gps information from
the webservice and tries to match it with 20 minutes fuzz into the
existing dives - which catches at least some of my dives and shows that
this could work as a proof of concept.

I'm running out of time (I tried to fight insomnia for a few hours
before getting up... should have just given up on sleep when I
originally woke up at 1:45am), but I'll try to create a few dummy
entries on the webservice that use the key included in the sources and
that match test dives... this way hopefully more people can play with
this. 

/D

diff --git a/dive.c b/dive.c
index fe9ce3a..db8ebda 100644
--- a/dive.c
+++ b/dive.c
@@ -1209,12 +1209,17 @@ static int max_time(duration_t a, duration_t b)
  */
 static int likely_same_dive(struct dive *a, struct dive *b)
 {
-	int fuzz, match;
+	int match, fuzz = 20 * 60;
 
 	/* Don't try to merge dives in different trips */
 	if (a->divetrip && b->divetrip && a->divetrip != b->divetrip)
 		return 0;
 
+	/* if one of the dives has no depth and duration this could be
+	 * a location marker from the webservice */
+	if ((!a->maxdepth.mm && !a->duration.seconds) ||
+	    (!b->maxdepth.mm && !b->duration.seconds))
+		return ((a->when <= b->when + fuzz) && (a->when >= b->when - fuzz));
 	/*
 	 * Do some basic sanity testing of the values we
 	 * have filled in during 'fixup_dive()'
diff --git a/main.c b/main.c
index b96c39f..27458f8 100644
--- a/main.c
+++ b/main.c
@@ -165,7 +165,10 @@ void report_dives(gboolean is_imported, gboolean prefer_imported)
 		struct dive *dive = pp[1];
 		struct dive *merged;
 
-		if (prev->when + prev->duration.seconds < dive->when)
+		/* only try to merge overlapping dives - or if one of the dives has
+		 * zero duration (that might be a gps marker from the webservice) */
+		if (prev->duration.seconds && dive->duration.seconds &&
+		    prev->when + prev->duration.seconds < dive->when)
 			continue;
 
 		merged = try_to_merge(prev, dive, prefer_imported);
diff --git a/parse-xml.c b/parse-xml.c
index 35ebf04..6aa0634 100644
--- a/parse-xml.c
+++ b/parse-xml.c
@@ -909,6 +909,22 @@ static degrees_t parse_degrees(char *buf, char **end)
 	return ret;
 }
 
+static void gps_lat(char *buffer, void *_dive)
+{
+	char *end;
+	struct dive *dive = _dive;
+
+	dive->latitude = parse_degrees(buffer, &end);
+}
+
+static void gps_long(char *buffer, void *_dive)
+{
+	char *end;
+	struct dive *dive = _dive;
+
+	dive->longitude = parse_degrees(buffer, &end);
+}
+
 static void gps_location(char *buffer, void *_dive)
 {
 	char *end;
@@ -984,8 +1000,14 @@ static void try_to_fill_dive(struct dive *dive, const char *name, char *buf)
 		return;
 	if (MATCH(".gps", gps_location, dive))
 		return;
+	if (MATCH(".latitude", gps_lat, dive))
+		return;
+	if (MATCH(".longitude", gps_long, dive))
+		return;
 	if (MATCH(".location", utf8_string, &dive->location))
 		return;
+	if (MATCH(".name", utf8_string, &dive->location))
+		return;
 	if (MATCH(".suit", utf8_string, &dive->suit))
 		return;
 	if (MATCH(".divesuit", utf8_string, &dive->suit))
diff --git a/webservice.c b/webservice.c
index 5acfb2d..cbfe0dd 100644
--- a/webservice.c
+++ b/webservice.c
@@ -198,7 +198,9 @@ void webservice_download_dialog(void)
 	result = gtk_dialog_run(GTK_DIALOG(dialog));
 	if (result == GTK_RESPONSE_ACCEPT) {
 		/* apply download */
-		g_message("\napply download should happen here: \n\n %s", state.xmldata);
+		/* g_message("\napply download should happen here: \n\n %s", state.xmldata); */
+		parse_xml_buffer(_("Webservice"), state.xmldata, strlen(state.xmldata), NULL);
+		report_dives(TRUE, FALSE);
 	}
 	download_dialog_release_xml(&state);
 	gtk_widget_destroy(dialog);


More information about the subsurface mailing list