如何计算iPhone地图应用程序中两个POI(兴趣点)坐标之间的角度?
答案 0 :(得分:12)
我猜你试着计算两个兴趣点(POI)坐标之间的度数。
计算great circle的弧度:
+(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)
答案 1 :(得分:2)
你在这里从一个点到另一个点计算'方位'。这个网页上有很多公式,以及许多其他地理数量,例如距离和跨轨错误:
http://www.movable-type.co.uk/scripts/latlong.html
公式有多种格式,因此您可以轻松转换为iPhone所需的任何语言。还有javascript计算器,所以你可以测试你的代码获得与他们相同的答案。
答案 2 :(得分: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;
}