Closed jimmykane closed 4 years ago
Hi,
it's problem of valid XML file. To use extensions you must define them in XML header. You can check how I add Garmin extension definitions in repo https://github.com/fabulator/gpx-builder/blob/master/src/builder/GarminBuilder/GarminBuilder.ts
There is also the name of extension that needs to be used in file https://github.com/fabulator/gpx-builder/blob/master/src/builder/GarminBuilder/models/GarminPoint.ts. Generated point looks like this:
<trkpt lat="51.12832496166229" lon="15.615156626701355">
<ele>314.715</ele>
<time>2018-06-10T17:39:35.000Z</time>
<extensions>
<gpxtpx:TrackPointExtension>
<gpxtpx:hr>121</gpxtpx:hr>
</gpxtpx:TrackPointExtension>
</extensions>
</trkpt>
so you would need to use something like this:
extensions: {
'gpxtpx:TrackPointExtension': {
power: <number>data[DataPower.type],
speed: <number>data[DataSpeed.type],
temperature: <number>data[DataTemperature.type],
cadence: <number>data[DataCadence.type],
}
}
The problem here is that there is no definition of power in gpx file. If you want to generate non valid XML file (most services don't validate schema anyway) you can use type-assertion to avoid typescript error.
import {Extensions} from 'gpx-builder/dist/types'
extensions: {
power: <number>data[DataPower.type],
speed: <number>data[DataSpeed.type],
temperature: <number>data[DataTemperature.type],
cadence: <number>data[DataCadence.type],
} as Extensions
Hey I found the issue to be the import way. Following the readme it was ok.
That said:
pointsArray.push(new Point(
<number>data[DataLatitudeDegrees.type],
<number>data[DataLongitudeDegrees.type],
{
ele: data[DataAltitude.type] || undefined,
time: new Date(activity.startDate.getTime() + <number>data[DataTime.type] * 1000),
hr: data[DataHeartRate.type],
power: data[DataPower.type] || undefined,
speed: data[DataSpeed.type] || undefined,
atemp: data[DataTemperature.type] || undefined,
cad: data[DataCadence.type] || undefined,
extensions: {
power: data[DataPower.type] || undefined,
distance: data[DataDistance.type] || undefined,
}
}
))
return pointsArray;
I will revert back to typescript types import and use:
import {Extensions} from 'gpx-builder/dist/types'
extensions: {
power: <number>data[DataPower.type],
speed: <number>data[DataSpeed.type],
temperature: <number>data[DataTemperature.type],
cadence: <number>data[DataCadence.type],
} as Extensions
I do understand the problem well here, I was not doubting about the extensions and it's great that you know that. FYI Strava reads the distance extension for example.
I ll get back to this
Ok,
Doing an import as:
const {buildGPX, GarminBuilder} = require('gpx-builder');
const {Point, Metadata, Person, Copyright, Link, Track, Segment} = GarminBuilder.MODELS;
Works when using eg
const tracks: typeof Track = []
event.getActivities().forEach((activity) => {
const timeStream = event.getFirstActivity().generateTimeStream([DataLatitudeDegrees.type]);
activity.addStream(timeStream);
const segment = new Segment(
event.getFirstActivity().getStreamDataTypesBasedOnDataType(DataLatitudeDegrees.type, [
DataLongitudeDegrees.type,
DataTime.type,
DataDistance.type,
DataHeartRate.type,
DataCadence.type,
DataTemperature.type,
DataPower.type,
DataAltitude.type,
DataSpeed.type
]).reduce((pointsArray: typeof Point[], data, index, array) => {
pointsArray.push(new Point(
<number>data[DataLatitudeDegrees.type],
<number>data[DataLongitudeDegrees.type],
{
ele: data[DataAltitude.type] || undefined,
time: new Date(activity.startDate.getTime() + <number>data[DataTime.type] * 1000),
hr: data[DataHeartRate.type],
power: data[DataPower.type] || undefined,
speed: data[DataSpeed.type] || undefined,
atemp: data[DataTemperature.type] || undefined,
cad: data[DataCadence.type] || undefined,
extensions: {
power: data[DataPower.type] || undefined,
distance: data[DataDistance.type] || undefined,
}
}
))
return pointsArray;
}, []))
tracks.push(new Track([segment]));
activity.removeStream(timeStream);
})
However why the issue when importing the ts type files ? That I dont get? Sorry for my ignorance
extensions: {
power: data[DataPower.type] || undefined,
distance: data[DataDistance.type] || undefined,
}
This is not valid. XML schema expect you will name your extension and put some prefix to data, so it would looks like this:
extensions: {
'gpxtpx:TrackPointExtension': {
'gpxtpx:power': data[DataPower.type] || undefined,
'gpxtpx:distance': data[DataDistance.type] || undefined,
}
}
The extensions has type
interface Extensions {
[key: string]: {[key: string]: string | number},
}
And yes, Strava read some extension directly:
Strava also detects general tags placed in the <extensions> tag of each tag. Strava extracts:
cadence as cadence
distance as distance
heartrate as heartrate
power as power
even that they are not valid by schema. I think I will add some StravaBuilder that would support them.
No worries got it :-D Thanks so much again. I am closing this as it works as expected
FYI if you are into sports I am going to use this lib to support this opensource project https://quantified-self.io/ for exporting to GPX.
great, it looks interesting
Hi and wow what a great lib:
I am writing an exporter for https://github.com/sports-alliance/sports-lib and we have this issue:
The code to create a point:
Looks like some type issue?