Skip to content

Commit

Permalink
Get gpx write working
Browse files Browse the repository at this point in the history
  • Loading branch information
scheibo committed Mar 2, 2014
1 parent c7a1e3e commit 98aa5a4
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 16 deletions.
8 changes: 4 additions & 4 deletions TODO
@@ -1,11 +1,11 @@
csv read - make sure to exit if invalid
gpx write
activity clean/verify points
activity laps
activity summary
modify fix.c for doubles
* gpx write - mostly done, modulo laps and metadata time
proper testing
fix Makefile
activity clean/verify points
activity laps
activity summary

additional fixes (gaps, hr, power)
tcx + fit data
Expand Down
2 changes: 1 addition & 1 deletion activity.h
Expand Up @@ -117,7 +117,7 @@ static inline void unset_data_point(DataPoint *dp) {
static inline void print_data_point(DataPoint *dp) {
double *d = dp->data;
fprintf(stderr,
"time: %.0f, lat: %.15f, lon: %.15f, alt: %.2f, dist: %.2f, speed: "
"time: %.0f, lat: %.7f, lon: %.7f, alt: %.2f, dist: %.2f, speed: "
"%.2f, pow: %.0f, grd: %.2f, hr: %.0f, cad: %.0f, bal: %.0f, temp: "
"%.0f\n",
d[Timestamp], d[Latitude], d[Longitude], d[Altitude], d[Distance],
Expand Down
4 changes: 2 additions & 2 deletions csv.c
Expand Up @@ -164,8 +164,8 @@ int csv_write_options(char *filename, Activity *a, CSVOptions o) {
/* print data points - must be at least one non empty */
for (i = 0, first = true; i < a->num_points; i++, first = true) {
write_field(f, "%.0f", i, Timestamp, a, o, &first);
write_field(f, "%.15f", i, Latitude, a, o, &first);
write_field(f, "%.15f", i, Longitude, a, o, &first);
write_field(f, "%.7f", i, Latitude, a, o, &first);
write_field(f, "%.7f", i, Longitude, a, o, &first);
write_field(f, "%.3f", i, Altitude, a, o, &first);
write_field(f, "%.2f", i, Distance, a, o, &first);
write_field(f, "%.2f", i, Speed, a, o, &first);
Expand Down
2 changes: 1 addition & 1 deletion fitparse.c
Expand Up @@ -79,7 +79,7 @@ Activity *fitparse_read(char *filename) {

int fitparse_write(char *filename, Activity *activity) {
FileFormat format = file_format_from_name(filename);
if (format != UnknownFileFormat) {
if (format == UnknownFileFormat) {
format = DEFAULT_WRITE_FORMAT;
}
return fitparse_write_format(filename, format, activity);
Expand Down
84 changes: 78 additions & 6 deletions gpx.c
Expand Up @@ -73,8 +73,7 @@ static int sax_cb(mxml_node_t *node, mxml_sax_event_t event, void *sax_data) {
return 1; /* stop reading the file */
}

/* TODO confirm no memory leak */
/* We must retain an element so that mxmlSAXLoadFile can return it */
/* we must retain an element so that mxmlSAXLoadFile can return it */
mxmlRetain(node);
}

Expand Down Expand Up @@ -118,7 +117,6 @@ static int sax_cb(mxml_node_t *node, mxml_sax_event_t event, void *sax_data) {
parse_field(Power, state, data);
} else if (!strcmp(name, "trkpt")) {
activity_add_point(state->activity, &(state->dp));
/*print_data_point(&(state->dp)); [> TODO <]*/
unset_data_point(&(state->dp));
}
} else if (event == MXML_SAX_DATA) {
Expand Down Expand Up @@ -161,13 +159,83 @@ Activity *gpx_read(char *filename) {
}

static mxml_node_t *to_gpx_xml(Activity *a) {
char buf[TIME_BUFSIZ];
unsigned i;
mxml_node_t *xml; /*, *gpx, *trk, *trkseg, *trkpt, *ele, *time, *hr, *temp,
*cadence, *bikepower; */
mxml_node_t *xml, *gpx, *metadata, *trk, *time, *name, *trkseg, *trkpt, *ele,
*extensions, *gpxtpx, *atemp, *hr, *cad;

xml = mxmlNewXML("1.0");

/* create gpx root */
gpx = mxmlNewElement(xml, "gpx");
mxmlElementSetAttr(gpx, "creator", "fitparse");
mxmlElementSetAttr(gpx, "version", "1.1");
mxmlElementSetAttr(gpx, "xmlns", "http://www.topografix.com/GPX/1/1");
mxmlElementSetAttr(gpx, "xmlns:xsi",
"http://www.w3.org/2001/XMLSchema-instance");
mxmlElementSetAttr(gpx, "xmlns:gpxtpx",
"http://www.garmin.com/xmlschemas/TrackPointExtension/v1");
mxmlElementSetAttr(gpx, "xmlns:gpxx",
"http://www.garmin.com/xmlschemas/GpxExtensions/v3");
mxmlElementSetAttr(gpx, "xsi:schemaLocation",
"http://www.topografix.com/GPX/1/1 "
"http://www.topografix.com/GPX/1/1/gpx.xsd "
"http://www.garmin.com/xmlschemas/GpxExtensions/v3 "
"http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd "
"http://www.garmin.com/xmlschemas/TrackPointExtension/v1 "
"http://www.garmin.com/xmlschemas/"
"TrackPointExtensionv1.xsd");

/* write metadata element */
metadata = mxmlNewElement(gpx, "metadata");
time = mxmlNewElement(metadata, "time");
format_timestamp(buf, 1393740341); /* TODO */
mxmlNewText(time, 0, buf);
memset(buf, '\0', TIME_BUFSIZ);

/* TODO lap waypoints? or lap as metadata? */

trk = mxmlNewElement(gpx, "trk");
name = mxmlNewElement(trk, "name");
mxmlNewText(name, 0, "Untitled");

trkseg = mxmlNewElement(trk, "trkseg");
for (i = 0; i < a->num_points; i++) {
/* TODO */
trkpt = mxmlNewElement(trkseg, "trkpt");
mxmlElementSetAttrf(trkpt, "lat", "%.7f", a->data_points[i].data[Latitude]);
mxmlElementSetAttrf(trkpt, "lon", "%.7f",
a->data_points[i].data[Longitude]);

if (a->data_points[i].data[Altitude] != UNSET_FIELD) {
ele = mxmlNewElement(trkpt, "ele");
mxmlNewTextf(ele, 0, "%.2f", a->data_points[i].data[Altitude]);
}
if (a->data_points[i].data[Timestamp] != UNSET_FIELD) {
time = mxmlNewElement(trkpt, "time");
format_timestamp(buf, a->data_points[i].data[Timestamp]);
mxmlNewText(time, 0, buf);
memset(buf, '\0', TIME_BUFSIZ);
}

if ((a->data_points[i].data[HeartRate] != UNSET_FIELD) ||
(a->data_points[i].data[Cadence] != UNSET_FIELD) ||
(a->data_points[i].data[Temperature] != UNSET_FIELD)) {
extensions = mxmlNewElement(trkpt, "extensions");
gpxtpx = mxmlNewElement(extensions, "gpxtpx:TrackPointExtension");

if (a->data_points[i].data[HeartRate] != UNSET_FIELD) {
hr = mxmlNewElement(gpxtpx, "gpxtpx:hr");
mxmlNewInteger(hr, a->data_points[i].data[HeartRate]);
}
if (a->data_points[i].data[Cadence] != UNSET_FIELD) {
cad = mxmlNewElement(gpxtpx, "gpxtpx:cad");
mxmlNewInteger(cad, a->data_points[i].data[Cadence]);
}
if (a->data_points[i].data[Temperature] != UNSET_FIELD) {
atemp = mxmlNewElement(gpxtpx, "gpxtpx:atemp");
mxmlNewInteger(atemp, a->data_points[i].data[Temperature]);
}
}
}
return xml;
}
Expand All @@ -176,6 +244,10 @@ int gpx_write(char *filename, Activity *a) {
FILE *f;
mxml_node_t *tree;

if (!(a->has_data[Latitude] && a->has_data[Longitude])) {
return 1;
}

f = fopen(filename, "w");
if (!(f = fopen(filename, "w")) || !(tree = to_gpx_xml(a))) {
return 1;
Expand Down
6 changes: 4 additions & 2 deletions test.c
Expand Up @@ -60,8 +60,10 @@ bool test(const char *filename, const char *dir) {
strncpy(namebuf + len, PREFIX, sizeof(PREFIX) - 1);
strcpy(namebuf + len + (sizeof(PREFIX) - 1), strrchr(filename, '/') + 1);

change_extension(namebuf, "csv"), print("writing to file %s\n", namebuf);
fitparse_write_format(namebuf, CSV, a);
/*change_extension(namebuf, "csv");*/
print("writing to file %s\n", namebuf);
/*fitparse_write_format(namebuf, GPX, a);*/
fitparse_write(namebuf, a);
activity_destroy(a);
return 0;
#if 0
Expand Down
2 changes: 2 additions & 0 deletions util.h
Expand Up @@ -22,6 +22,8 @@
#include <ctype.h>
#include <string.h>

#define TIME_BUFSIZ 32

static inline char *extension(char *filename) {
char *s = strrchr(filename, '.');
return s ? s + 1 : s;
Expand Down

0 comments on commit 98aa5a4

Please sign in to comment.