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);
source share