How can I extrapolate further down the road?

Given the real-time location data of a moving device for a short period of time, how can I get a pair of lats / long along this road, say 2 miles or even better, 5 minutes on the road?

I see that I can use the Google Roads API to snap to the road given the long / long pair https://developers.google.com/maps/documentation/roads/snap , but that only gets me part of the way there.

This will be in the Android app.

+5
source share
1 answer

Given the route represented as List<LatLng> , this function calculates the point on the route that occurs when distance meters move from origin on this route (using the "Google Maps API Library" to do some calculations):

 private LatLng extrapolate(List<LatLng> path, LatLng origin, float distance) { LatLng extrapolated = null; if (!PolyUtil.isLocationOnPath(origin, path, false, 1)) { // If the location is not on path non geodesic, 1 meter tolerance return null; } float accDistance = 0f; boolean foundStart = false; List<LatLng> segment = new ArrayList<>(); for (int i = 0; i < path.size() - 1; i++) { LatLng segmentStart = path.get(i); LatLng segmentEnd = path.get(i + 1); segment.clear(); segment.add(segmentStart); segment.add(segmentEnd); double currentDistance = 0d; if (!foundStart) { if (PolyUtil.isLocationOnPath(origin, segment, false, 1)) { foundStart = true; currentDistance = SphericalUtil.computeDistanceBetween(origin, segmentEnd); if (currentDistance > distance) { double heading = SphericalUtil.computeHeading(origin, segmentEnd); extrapolated = SphericalUtil.computeOffset(origin, distance - accDistance, heading); break; } } } else { currentDistance = SphericalUtil.computeDistanceBetween(segmentStart, segmentEnd); if (currentDistance + accDistance > distance) { double heading = SphericalUtil.computeHeading(segmentStart, segmentEnd); extrapolated = SphericalUtil.computeOffset(segmentStart, distance - accDistance, heading); break; } } accDistance += currentDistance; } return extrapolated; } 

Here are some tests:

 List<LatLng> route = new ArrayList<>(); route.add(new LatLng(40, 4)); route.add(new LatLng(40.1, 4)); route.add(new LatLng(40.1, 4.1)); route.add(new LatLng(40.2, 4.1)); route.add(new LatLng(40.2, 4.2)); route.add(new LatLng(40.3, 4.2)); route.add(new LatLng(40.3, 4.3)); LatLng origin; LatLng extrapolated; origin = new LatLng(40.1, 4.05); extrapolated = extrapolate(route, origin, 30000); Log.e("Extrapolated1", "" + extrapolated); // lat/lng: (40.25517043951189,4.2) origin = new LatLng(40.05, 4); extrapolated = extrapolate(route, origin, 100); Log.e("Extrapolated2", "" + extrapolated); // lat/lng: (40.05089932033549,4.0) origin = new LatLng(40.05, 4); extrapolated = extrapolate(route, origin, 50000); Log.e("Extrapolated3", "" + extrapolated); // lat/lng: (40.300010207449226,4.261348349980259) origin = new LatLng(40.05, 4); extrapolated = extrapolate(route, origin, 100000); Log.e("Extrapolated4", "" + extrapolated); // null (result out of the route) 
+5
source

All Articles