Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Get gpx write working

  • Loading branch information...
commit 98aa5a409afde56356493b0a6a7708cbb0c6f8f2 1 parent c7a1e3e
@scheibo authored
View
8 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
View
2  activity.h
@@ -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],
View
4 csv.c
@@ -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);
View
2  fitparse.c
@@ -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);
View
84 gpx.c
@@ -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);
}
@@ -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) {
@@ -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;
}
@@ -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;
View
6 test.c
@@ -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
View
2  util.h
@@ -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;
Please sign in to comment.
Something went wrong with that request. Please try again.