如何获取两个POI之间的角度?

3

如何在 iPhone 地图应用程序中计算两个 POI(兴趣点)坐标之间的角度(以度为单位)?


2
什么是POI,什么是“iPhone amp应用程序”? - user142019
@Radek S:在@Jano更新原始问题后,它应该有意义。 - Claus Broch
3个回答

13
我猜您试图计算两个兴趣点(POI)之间坐标的度数。
计算大圆弧的方法:
+(float) greatCircleFrom:(CLLocation*)first 
                      to:(CLLocation*)second {

    int radius = 6371; // 6371km is the radius of the earth
    float dLat = second.coordinate.latitude-first.coordinate.latitude;
    float dLon = second.coordinate.longitude-first.coordinate.longitude;
    float a = pow(sin(dLat/2),2) + cos(first.coordinate.latitude)*cos(second.coordinate.latitude) * pow(sin(dLon/2),2);
    float c = 2 * atan2(sqrt(a),sqrt(1-a));
    float d = radius * c;

    return d;
}

另一个选择是假装你在笛卡尔坐标系上(更快但在长距离上不完全准确):

+(float)angleFromCoordinate:(CLLocationCoordinate2D)first 
               toCoordinate:(CLLocationCoordinate2D)second {

    float deltaLongitude = second.longitude - first.longitude;
    float deltaLatitude = second.latitude - first.latitude;
    float angle = (M_PI * .5f) - atan(deltaLatitude / deltaLongitude);

    if (deltaLongitude > 0)      return angle;
    else if (deltaLongitude < 0) return angle + M_PI;
    else if (deltaLatitude < 0)  return M_PI;

    return 0.0f;
}

如果你想要以度数而不是弧度来表示结果,你需要进行以下转换:

#define RADIANS_TO_DEGREES(radians) ((radians) * 180.0 / M_PI)

GreatCircle 不会将输入转换为弧度。 - gjpc

2
你正在计算从一个点到另一个点的“方位角”。这个网页上有很多公式,以及许多其他地理量,比如距离和横向误差:http://www.movable-type.co.uk/scripts/latlong.html。这些公式有多种格式,因此你可以轻松转换为iPhone所需的任何语言。还有javascript计算器,可以测试你的代码是否得到与它们相同的答案。

确实,Jano的东西在这里不起作用,但你提到的网站确实帮了很大的忙。但要注意:他们忘记在Javascript的方位示例中提到纬度/经度必须以弧度格式给出。 - brainray

1
如果其他解决方案对您无效,请尝试以下方法:
- (int)getInitialBearingFrom:(CLLocation *)first
                        to:(CLLocation *)second
{
    float lat1 = [self degreesToRad:first.coordinate.latitude];
    float lat2 = [self degreesToRad:second.coordinate.latitude];
    float lon1 = [self degreesToRad:first.coordinate.longitude];
    float lon2 = [self degreesToRad:second.coordinate.longitude];
    float dLon = lon2 - lon1;
    float y = sin (dLon) * cos (lat2);
    float x1 = cos (lat1) * sin (lat2);
    float x2 = sin (lat1) * cos (lat2) * cos (dLon);
    float x = x1 - x2;
    float bearingRadRaw = atan2f (y, x);
    float bearingDegRaw = bearingRadRaw * 180 / M_PI;
    int bearing = ((int) bearingDegRaw + 360) % 360; // +- 180 deg to 360 deg

    return bearing;
}

对于最终方位角,只需从终点到起点获取初始方位角并将其反转(使用θ =(θ + 180)%360)。

您需要以下两个辅助程序:

-(float)radToDegrees:(float)radians
{
    return radians * 180 / M_PI;
}
-(float)degreesToRad:(float)degrees
{
    return degrees * M_PI /180;
}

将输入转换为弧度。 - gjpc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接