如何沿道路进一步推算?
考虑到移动设备在短时间内的实时位置数据,我如何才能沿着这条路进一步取得经纬度,例如2英里,甚至更好,行驶5分钟?
Given realtime location data of a moving device over a short period of time, how can I get a lat/long pair further along this road, say, 2 miles, or even better, 5 minutes worth of driving?
我看到我可以使用Google的Roads API捕捉到一条经纬度
I see that I can use Google's Roads API to snap to a road given a lat/long pair https://developers.google.com/maps/documentation/roads/snap, but that only gets me part way there.
这将在Android应用中.
This will be in an Android app.
给出一个以List<LatLng>
表示的路线,此函数计算该路线上的点,该点是由该路线上的distance
米从origin
行进所产生的(使用 Google Maps API实用程序库进行一些计算):
Given a route represented as a List<LatLng>
, this function calculates the point on the route that results from travelling distance
meters from origin
on that route (using the Google Maps API Utility 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;
}
以下是一些测试:
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)