计算两个GeoLocations之间的地理位置

时间:2015-11-02 15:33:25

标签: algorithm google-maps math geolocation geometry

我有两个已知的Google Geolocation点A和B.我需要返回位于AB线上的GeoLocation点C和距离点A的距离x:

Geolocation returnGeolocationC(Geolocation A, Geolocation B, double x) {
     ...
     return C;
}

enter image description here

我知道我可以使用Haversine公式,我可以计算AB距离,因此我也有AC和CB距离。有任何想法或暗示如何实现这个?

编辑:直线,无需考虑道路。

1 个答案:

答案 0 :(得分:1)

您可以在this link找到一个非常简单的公式。

由于距离其中一个点的距离而不是段上距离的分数,您可以稍微修改公式:

    A=sin(d-x)/sin(d)
    B=sin(x)/sin(d)
    x = A*cos(lat1)*cos(lon1) +  B*cos(lat2)*cos(lon2)
    y = A*cos(lat1)*sin(lon1) +  B*cos(lat2)*sin(lon2)
    z = A*sin(lat1)           +  B*sin(lat2)
    lat=atan2(z,sqrt(x^2+y^2))
    lon=atan2(y,x)

其中x是所需距离,d是A和B之间的距离(您可以使用Haversine进行评估),两者都除以地球半径。

您还可以使用sin(d)的其他公式:

 nx =  cos(lat1)*sin(lon1)*sin(lat2)           - sin(lat1)*          cos(lat2)*sin(lon2)
 ny = -cos(lat1)*cos(lon1)*sin(lat2)           + sin(lat1)*          cos(lat2)*cos(lon2)
 nz =  cos(lat1)*cos(lon1)*cos(lat2)*sin(lon2) - cos(lat1)*sin(lon1)*cos(lat2)*cos(lon2)
 sind = sqrt(nx^2+ny^2+nz^2)

它比Haversine公式更复杂,但您可以在两个步骤中记住一些因素。

由于OP发布了一个非工作的Java实现,这是我的更正,以使其工作。

private static GpsLocation CalcGeolocationWithDistance(GpsLocation pointA, GpsLocation pointB, double distanceFromA)
{   //distanceFromA = 2.0 km, PointA and PointB are in Europe on 4.0km distance.
    double earthRadius = 6371000.0;
    double distanceAB = CalcDistance(pointA.Latitude, pointA.Longitude, pointB.Latitude, pointB.Longitude);
    //distance AB is calculated right according to Google Maps (4.0 km)
    double a = Math.Sin((distanceAB - distanceFromA) / earthRadius) / Math.Sin(distanceAB / earthRadius);
    double b = Math.Sin(distanceFromA / earthRadius) / Math.Sin(distanceAB / earthRadius);
    double x = a * Math.Cos(pointA.Latitude * Math.PI / 180) * Math.Cos(pointA.Longitude * Math.PI / 180) + b * Math.Cos(pointB.Latitude * Math.PI / 180) * Math.Cos(pointB.Longitude * Math.PI / 180);
    double y = a * Math.Cos(pointA.Latitude * Math.PI / 180) * Math.Sin(pointA.Longitude * Math.PI / 180) + b * Math.Cos(pointB.Latitude * Math.PI / 180) * Math.Sin(pointB.Longitude * Math.PI / 180);
    double z = a * Math.Sin(pointA.Latitude * Math.PI / 180) + b * Math.Sin(pointB.Latitude * Math.PI / 180);
    double lat = Math.Atan2(z, Math.Sqrt(x * x + y * y)) * 180 / Math.PI;
    double lon = Math.Atan2(y, x) * 180 / Math.PI;
    //lat and lon are mo more placed somewhere in Africa ;)
    return new GpsLocation(lat, lon);
}