-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add utilities to convert GPS trace file formats into SnapToRoads request #44
base: main
Are you sure you want to change the base?
Conversation
* ] | ||
* ``` | ||
*/ | ||
export function csvStringToRoadSnapTracePointList(csvString: string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be valuable to provide some options that provide mappings (either alternate columns of functions, which might do some transformation) to the expected columns (which will help developers avoid rewriting their CSVs twice). Latitude might be in a y
column, for example, or capitalization may vary.
Mappings would also enable an additional option that allows the header row to be omitted.
I understand that HERE documents a specific CSV structure, but without knowing what tools produce it (and having confidence that some high percentage of inputs will come in that form), I think we need more flexibility for CSV conversion.
* ] | ||
* ``` | ||
*/ | ||
export function featureCollectionToRoadSnapTracePointList(featureCollection: FeatureCollection<Point>) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is highly specific about the shape of properties
. The opinionated nature may be fine (especially since JavaScript objects can be transformed pretty easily), so I'm not necessarily advocating for options. However, it would be valuable to create a TypeScript type defining the structure of properties
and applying it to the FeatureCollection
in order to provide guidance via type safety: FeatureCollection<Point, TracePointProperties>
.
If callers have already structured their properties to include some combination of Timestamp
,Speed
, and Heading
, TracePointProperties
could be the union of the assumed properties (timestamp_msec
, speed_mps
, heading
) and Timestamp
, Speed
, Heading
to make the types work.
What about speed_kmh
and speed_mph
? You could share logic with the CSV transformation and support those.
* "provider": "gps", | ||
* "timestamp_msec": 1700470815000, | ||
* "accuracy": 23.891, | ||
* "altitude": 45.63214111328125, | ||
* "heading": 201.3, | ||
* "speed_mps": 4.12 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's valuable to include unused properties (since some combination of provider
, accuracy
, and altitude
may be present in customer data, and it might be confusing if they were omitted from the docs). However, it's probably also worthwhile to document that they'll be ignored (so developers don't go to unnecessary lengths to try to populate them).
const xmlParser = new fastXmlParser.XMLParser(options); | ||
const jsonObj = xmlParser.parse(content, options); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://github.com/placemark/togeojson might be a worthwhile dependency to pick up, even if it goes to an intermediate format (GeoJSON), since it supports multiple file types (including KML, which would simplify that converter by sharing with this one).
Alternately, it probably makes sense to support its GeoJSON output in case customers use that dependency.
|
||
import { RoadSnapTracePoint } from "@aws-sdk/client-geo-routes"; | ||
|
||
const PIVOT_YEAR = 80; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please provide a comment explaining what this is.
* It converts a NMEA string containing $GPRMC and/or $GPGGA records to an array of RoadSnapTracePoint, so the result | ||
* can be used to assemble the request to SnapToRoads API. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this valuable to extract as a separate dependency (so it can be used for broader NMEA parsing purposes)?
@@ -86,6 +86,86 @@ const request = { | |||
}; | |||
``` | |||
|
|||
### featureCollectionToRoadSnapTracePointList | |||
|
|||
Converts a GeoJSON FeatureCollection with Point Features to an array of RoadSnapTracePoint, so the result can be used to assemble the request to SnapToRoads API. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should list out the optional properties that it's looking for and converting.
<trk> | ||
<name>Rome</name> | ||
<trkseg> | ||
<trkpt lat="41.899689" lon="12.419255"> <extensions><speed>10</speed></extensions> <time>2013-07-15T10:24:52Z</time> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What extension adds speed to a trkpt? What's the unit on it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I got the first question. This is based on HERE's documentation. The unit is meter per second. Adding a comment to specify the expected elements and their units in the next commit.
const latitude = parseCoordinate(latitudeStr, latitudeDir); | ||
const longitude = parseCoordinate(longitudeStr, longitudeDir); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't you need different parsing functions for lat vs long? Lat is DDmm.* and Long is DDDmm.*, right?
const nmeaString = `$GPGGA,123519,4916.45,N,12311.12,W,1,08,0.9,545.4,M,46.9,M,,*47 | ||
$GPRMC,225446,A,3751.65,S,14507.36,E,022.4,084.4,191194,003.1,W*6A`; | ||
|
||
expect(nmeaStringToRoadSnapTracePointList(nmeaString)).toEqual([ | ||
{ | ||
Position: [-17.185333, 49.274167], | ||
}, | ||
{ | ||
Position: [22.456, -37.860833], | ||
Speed: 41.48, | ||
Timestamp: "1994-11-19T22:54:46.000Z", | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this test is invalid, it doesn't appear to be parsing longitude correctly. From reading the string, the long values should be -123.* and +145.*, right?
Description of changes:
This PR adds utilities to convert different GPS trace file formats into SnapToRoads request JSON.
The following are the supported trace file formats as described in HERE's documentation:
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.