Index: src/garmin_gpx.c
===================================================================
--- a/src/garmin_gpx.c (revision 27)
+++ b/src/garmin_gpx.c (working copy)
@@ -20,6 +20,7 @@
#include "config.h"
#include <math.h>
#include <stdio.h>
+#include <string.h>
#include <time.h>
#include "garmin.h"
@@ -34,16 +35,21 @@
{
float lat, lon, elev;
time_t t;
+ int lap;
+ int pause;
+ uint8 hr;
+ uint8 cad;
} route_point;
int
-get_gpx_data ( garmin_data * data,
- route_point ** points,
+get_gpx_data ( garmin_data * fulldata,
+ route_point *** tracks,
position_type * sw,
position_type * ne )
{
garmin_list * dlist;
garmin_list_node * node;
+ garmin_list_node * lapnode;
garmin_data * point;
D304 * d304;
route_point * rp;
@@ -52,10 +58,29 @@
float minlon = 180.0;
float maxlon = -180.0;
int ok = 0;
+ garmin_data * data;
+ garmin_list * glaps;
+ garmin_data* points;
- if ( data != NULL ) {
- data = garmin_list_data(data,2);
+ if ( fulldata != NULL ) {
+ // lists: 1=laps, 2=points
+
+ glaps=garmin_list_data(fulldata,1)->data; // get lap information
+
+ // fixme: crash if we didn't get it
+ int laps=glaps->elements+1;
+
+ *tracks = malloc(sizeof(route_point) * (laps));
+ memset(*tracks,0,laps*sizeof(route_point));
+
+ int curlapnum=0;
+
+ lapnode=glaps->head;
+ D1015* lapdata=lapnode->data->data;
+
+ data = garmin_list_data(fulldata, 2); // get track points
+
if ( data == NULL ) {
printf("get_gpx_data: no track points found\n");
@@ -64,30 +89,81 @@
dlist = data->data;
- *points = malloc(sizeof(route_point) * (dlist->elements+1));
- rp = *points;
+ points = malloc(sizeof(route_point) * (dlist->elements+1+(laps*2)));
+ (*tracks)[curlapnum]=points;
+ rp = points;
+ int pause=0;
+
for ( node = dlist->head; node != NULL; node = node->next ) {
- point = node->data;
- if ( point->type == data_D304 ) {
+ point = node->data;
- d304 = point->data;
+ switch (point->type) {
+ case data_D304: // position point
- if ( d304->posn.lat == 0x7fffffff && d304->posn.lon == 0x7fffffff )
- continue;
+ d304 = point->data;
- rp->lat = SEMI2DEG(d304->posn.lat);
- rp->lon = SEMI2DEG(d304->posn.lon);
- rp->elev = d304->alt;
- rp->t = d304->time;
+ if ( d304->posn.lat == 0x7fffffff && d304->posn.lon == 0x7fffffff ) {
+ pause++;
+ continue;
+ }
- if ( rp->lat < minlat ) minlat = rp->lat;
- if ( rp->lat > maxlat ) maxlat = rp->lat;
- if ( rp->lon < minlon ) minlon = rp->lon;
- if ( rp->lon > maxlon ) maxlon = rp->lon;
+ rp->lap=0;
+ if (lapdata!=NULL) {
+ if (d304->time >= lapdata->start_time) {
+ if (curlapnum>0) {
+ rp->t=0; // end previous lap
+ rp++;
+ (*tracks)[curlapnum]=rp; // new track
+ }
+ curlapnum++;
- ++rp;
- }
+ rp->lap=curlapnum;
+ if (d304->time != lapdata->start_time) {
+ // if lap start point doesn't exist, create it
+ rp->lat = SEMI2DEG(lapdata->begin.lat);
+ rp->lon = SEMI2DEG(lapdata->begin.lon);
+
+ rp->elev = d304->alt; // lap data doesn't contain alt :(
+ rp->hr=d304->heart_rate;
+ rp->cad=d304->cadence;
+
+ rp->t = lapdata->start_time;
+ rp++;
+ rp->lap=0;
+ rp->pause=0;
+ }
+ lapnode=lapnode->next;
+ if (lapnode!=NULL)
+ lapdata=lapnode->data->data;
+ else
+ lapdata=NULL; // last lap
+ }
+ }
+
+ rp->lat = SEMI2DEG(d304->posn.lat);
+ rp->lon = SEMI2DEG(d304->posn.lon);
+ rp->elev = d304->alt;
+ rp->t = d304->time;
+ rp->hr=d304->heart_rate;
+ rp->cad=d304->cadence;
+
+
+ if (pause==2) {
+ rp->pause=1;
+ pause=0;
+ } else rp->pause=0;
+
+ if ( rp->lat < minlat ) minlat = rp->lat;
+ if ( rp->lat > maxlat ) maxlat = rp->lat;
+ if ( rp->lon < minlon ) minlon = rp->lon;
+ if ( rp->lon > maxlon ) maxlon = rp->lon;
+
+ ++rp;
+ break;
+ default: //printf("unknown frame %i\n", point->type);
+ ;
+ }
}
rp->t = 0;
@@ -152,11 +228,15 @@
{
print_spaces(fp,spaces);
fprintf(fp,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
- fprintf(fp,"<gpx version=\"1.0\"\n"
+ fprintf(fp,"<gpx version=\"1.1\"\n"
"creator=\"Garmin Forerunner Tools - http://garmintools.googlecode.com\"\n"
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
- "xmlns=\"http://www.topografix.com/GPX/1/0\"\n"
- "xsi:schemaLocation=\"http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd\">\n");
+ "xmlns:gpxtpx=\"http://www.garmin.com/xmlschemas/TrackPointExtension/v1\"\n"
+ "xmlns=\"http://www.topografix.com/GPX/1/1\"\n"
+ "xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 "
+ "http://www.topografix.com/GPX/1/1/gpx.xsd "
+ "http://www.garmin.com/xmlschemas/TrackPointExtension/v1 "
+ "http://www8.garmin.com/xmlschemas/TrackPointExtensionv1.xsd\">\n");
}
static void
@@ -192,11 +272,37 @@
route_point * rp = points;
while (rp->t > 0) {
print_spaces(fp, spaces);
- fprintf(fp, "<rtept lat=\"%f\" lon=\"%f\">\n", rp->lat, rp->lon);
+ fprintf(fp, "<trkpt lat=\"%f\" lon=\"%f\">\n", rp->lat, rp->lon);
print_spaces(fp, spaces+2);
fprintf(fp, "<ele>%f</ele>\n", rp->elev);
print_time_tag(rp->t + TIME_OFFSET, fp, spaces+2);
- print_close_tag("rtept", fp, spaces);
+ if (rp->lap) {
+ print_spaces(fp, spaces+2);
+ fprintf(fp,"<name>Lap %i</name>\n",rp->lap);
+ } else if (rp->pause) {
+ print_spaces(fp, spaces+2);
+ fprintf(fp,"<name>Pause</name>\n");
+ }
+
+ if ((rp->hr != 0) || (rp->cad != 0xff)) {
+ print_spaces(fp, spaces+2);
+ fprintf(fp,"<extensions>\n");
+ print_spaces(fp, spaces+2);
+ fprintf(fp,"<gpxtpx:TrackPointExtension>\n");
+ if (rp->hr != 0) {
+ print_spaces(fp, spaces+4);
+ fprintf(fp,"<gpxtpx:hr>%i</gpxtpx:hr>\n",rp->hr);
+ }
+ if (rp->cad != 0xff) {
+ print_spaces(fp, spaces+4);
+ fprintf(fp,"<gpxtpx:cad>%i</gpxtpx:cad>\n",rp->cad);
+ }
+
+ print_close_tag("gpxtpx:TrackPointExtension", fp, spaces+2);
+ print_close_tag("extensions", fp, spaces+2);
+ }
+
+ print_close_tag("trkpt", fp, spaces);
++rp;
}
}
@@ -204,20 +310,29 @@
void
print_gpx_data ( garmin_data * data, FILE * fp, int spaces )
{
- route_point * points = NULL;
+ route_point ** laps = NULL;
+ route_point * points;
position_type sw;
position_type ne;
-
- if ( get_gpx_data(data,&points,&sw,&ne) != 0 ) {
+
+ if ( get_gpx_data(data,&laps,&sw,&ne) != 0 ) {
print_gpx_header(fp,spaces);
print_time_tag(time(NULL),fp,spaces);
print_bounds_tag(&sw,&ne,fp,spaces);
- print_open_tag("rte",fp,spaces);
- print_route_points(points,fp,spaces+2);
- print_close_tag("rte",fp,spaces);
+
+ int i;
+ print_open_tag("trk",fp,spaces);
+ for (i=0; laps[i]!=NULL; i++) {
+ points=laps[i];
+ print_open_tag("trkseg",fp,spaces);
+ print_route_points(points,fp,spaces+2);
+ print_close_tag("trkseg",fp,spaces);
+ }
+ print_close_tag("trk",fp,spaces);
print_close_tag("gpx",fp,spaces);
-
- if ( points != NULL ) free(points);
+
+ free(laps[i]);
+ free(laps);
}
}