specification
specification copied to clipboard
Track API
I added track handling as part of the http API to the Node server InfluxDb plugin.
it creates a /track
endpoint under self vessel, but I don't see why the same API could not be used for any vessel.
The endpoint accepts two query parameters, timespan
and resolution
, each in in xxxY format, where xxx
is a Number and Y
one of
- s (seconds)
- m (minutes)
- h (hours)
- d (days)
- w (weeks) Duration expression is a direct copy from InfluxDb's duration, just omitting ms and us.
The response is a GeoJSON MultiLineString with proper mime type application/vnd.geo+json
.
The big difference here is that this is real API endpoint as opposed to just adding stuff to the Signal K full document and the equivalent RESTish paths. I don't think it makes sense to include this data in the full response, as the data is different in nature (historical time series) versus latest values.
Per the current implementation the track is just a MultiLineString: a list of position lists. There is no time data in the response. I am not aware of any standard way to represent tracks with time information. I think it would be a good idea to define either a separate mime type (application/json comes to mind) or an optional query string that would allow you to retrieve the same MultiLineString plus the corresponding timestamp data in two top level properties:
{
timestamp: [ [...], [...],...]
geojson: {...MultiLineString data... }
}
https://github.com/tkurki/signalk-to-influxdb/pull/9
See also time series / historical data issue https://github.com/SignalK/specification/issues/89
Another addition would be the ability to specify start and end timestamps.
Another alternative way to retrieve track data is by bounding box.
Nice addition. I agree its an api call, not an extension to the data model. Geojson is a great way to transport the track as it works most web-mapping (like freeboard-sk) and is a defined std. I think form memory there is the ability to add arbitrary properties into the geojson object.
Then we could define a specific one for the timestamp.
Same api call technique can apply to grabbing data for any timespan or bounding box. Vessels, routes, features, charts, notes...
I partially rewrote the Node implementation based on geohashes in SQLite and actual data in InfluxDb. This version supports just bounding box searching, no time related searching.
The response is now a GeoJSON FeatureCollection with name, starttime and endtime metadata in track feature's properties.
https://github.com/tkurki/signalk-to-influxdb/pull/12
UI work available at https://github.com/vokkim/tuktuk-chart-plotter/pull/10
With a url like http://localhost:3000/signalk/v1/api/vessels/self/tracks?bbox=25.1447868347168,60.14940913733063,25.261344909667972,60.16329064994213&paths=navigation.speedOverGround,environment.wind.speedTrue
you get now a response like
{
"type": "FeatureCollection",
"properties": {
"dataPaths": [ //what data in addition to track positions with timestamp to query
"navigation.speedOverGround",
"environment.wind.speedTrue"
]
},
"features": [
{
"type": "Feature",
"properties": {
"name": "Track", //a human readable name
"starttime": "2017-08-26T08:12:30.000Z",
"endtime": "2017-08-26T08:50:30.000Z"
},
"geometry": {
"type": "MultiLineString",
"coordinates": [
[
[
25.1403593,
60.134275,
0, //altitude (not used)
1503735150000, //timestamp
3.44, //sog
13.770717205710989 //true wind speed
],
...
I think the human readable names need a management API, so one can update them, and we need a track listing api.
The tracks also need identifiers (the implementation already has numeric ids, but uuid would probably be a better choice).
Todo:
- [ ] add track ids and necessary id oriented apis
- [ ] name management
- [ ] track listing api
I really like the idea of GeoJSON and embedding the extra variables directly with the coordinates. This seem a very efficient way to pack the data.
However, after doing more research on this, this seems to be discouraged now. The GeoJSON spec says:
Implementations SHOULD NOT extend positions beyond three elements because the semantics of extra elements are unspecified and ambiguous. Historically, some implementations have used a fourth element to carry a linear referencing measure (sometimes denoted as "M") or a numerical timestamp, but in most situations a parser will not be able to properly interpret these values. The interpretation and meaning of additional elements is beyond the scope of this specification, and additional elements MAY be ignored by parsers. (see also this message and issue on the topic)
To add a few more reference, there is the @mapbox/geojson-tidy library that uses one property to store an array of timestamps:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"coordTimes": []
},
"geometry": {
"type": "LineString",
"coordinates": []
}
}
]
}
This is also how @mapbox/togeojson preserves timestamps when converting a GPX file to GeoJSON and we could extend it to include more variables.
Thanks for digging deeper the GeoJSON issue. I remember hunting high and low for a pre-existing format, must have missed the GeoJSON spec explicitly forbidding extension.
Your example looks good to me, but in addition to coordtimes the response should also cater to returning the time series data for the requested paths (& sources).
You should not add time directly into the coordinates, but you can add additional arbitrary properties in the main body.
{
"type": "Feature",
"id": "f1",
"geometry": {...},
"properties": {...},
"title": "Example Feature"
}
properties
can be used. title
is a 'foreign body' and legal, so we could add a signalk
foreign body with additional data