Skip to content
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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

HabibaaElsherbiny
Copy link

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.

@HabibaaElsherbiny HabibaaElsherbiny requested a review from a team as a code owner November 19, 2024 09:17
package.json Show resolved Hide resolved
src/from-csv/tracepoints-converter.ts Show resolved Hide resolved
* ]
* ```
*/
export function csvStringToRoadSnapTracePointList(csvString: string) {
Copy link
Contributor

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.

src/from-geojson/tracepoints-converter.ts Show resolved Hide resolved
* ]
* ```
*/
export function featureCollectionToRoadSnapTracePointList(featureCollection: FeatureCollection<Point>) {
Copy link
Contributor

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.

Comment on lines +37 to +42
* "provider": "gps",
* "timestamp_msec": 1700470815000,
* "accuracy": 23.891,
* "altitude": 45.63214111328125,
* "heading": 201.3,
* "speed_mps": 4.12
Copy link
Contributor

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).

src/from-gpx/tracepoints-converter.test.ts Show resolved Hide resolved
Comment on lines +81 to +82
const xmlParser = new fastXmlParser.XMLParser(options);
const jsonObj = xmlParser.parse(content, options);
Copy link
Contributor

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;
Copy link
Contributor

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.

Comment on lines +9 to +10
* 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.
Copy link
Contributor

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)?

package.json Show resolved Hide resolved
README.md Show resolved Hide resolved
src/from-csv/tracepoints-converter.ts Show resolved Hide resolved
src/from-csv/tracepoints-converter.ts Show resolved Hide resolved
src/from-csv/tracepoints-converter.ts Show resolved Hide resolved
@@ -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.
Copy link
Contributor

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>
Copy link
Contributor

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?

Copy link
Author

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.

src/from-kml/tracepoints-converter.ts Show resolved Hide resolved
Comment on lines +80 to +81
const latitude = parseCoordinate(latitudeStr, latitudeDir);
const longitude = parseCoordinate(longitudeStr, longitudeDir);
Copy link
Contributor

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?

Comment on lines +5 to +16
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",
},
Copy link
Contributor

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants