ios 在 Swift 中计算两个 CLLocation 点之间的方位
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26998029/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Calculating bearing between two CLLocation points in Swift
提问by Jeef
I'm trying to calculate a bearing between two CLLocation points in swift-only code. I've run into some difficulty and was assuming this is a pretty simple function. Stack overflow didn't seem to have anything listed.
我正在尝试在 swift-only 代码中计算两个 CLLocation 点之间的方位。我遇到了一些困难,并假设这是一个非常简单的函数。堆栈溢出似乎没有列出任何内容。
func d2r(degrees : Double) -> Double {
return degrees * M_PI / 180.0
}
func RadiansToDegrees(radians : Double) -> Double {
return radians * 180.0 / M_PI
}
func getBearing(fromLoc : CLLocation, toLoc : CLLocation) {
let fLat = d2r(fromLoc.coordinate.latitude)
let fLng = d2r(fromLoc.coordinate.longitude)
let tLat = d2r(toLoc.coordinate.latitude)
let tLng = d2r(toLoc.coordinate.longitude)
var a = CGFloat(sin(fLng-tLng)*cos(tLat));
var b = CGFloat(cos(fLat)*sin(tLat)-sin(fLat)*cos(tLat)*cos(fLng-tLng))
return atan2(a,b)
}
I'm getting an error with my atan2 call about lvalue cgfloat or something...
我的 atan2 调用出现关于左值 cgfloat 或其他内容的错误...
回答by Martin R
Here is an Objective-C solution
这是一个Objective-C解决方案
which can easily be translated to Swift:
可以很容易地转换为 Swift:
func degreesToRadians(degrees: Double) -> Double { return degrees * .pi / 180.0 }
func radiansToDegrees(radians: Double) -> Double { return radians * 180.0 / .pi }
func getBearingBetweenTwoPoints1(point1 : CLLocation, point2 : CLLocation) -> Double {
let lat1 = degreesToRadians(degrees: point1.coordinate.latitude)
let lon1 = degreesToRadians(degrees: point1.coordinate.longitude)
let lat2 = degreesToRadians(degrees: point2.coordinate.latitude)
let lon2 = degreesToRadians(degrees: point2.coordinate.longitude)
let dLon = lon2 - lon1
let y = sin(dLon) * cos(lat2)
let x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon)
let radiansBearing = atan2(y, x)
return radiansToDegrees(radians: radiansBearing)
}
The result type is Double
because that is how all location coordinates are
stored (CLLocationDegrees
is a type alias for Double
).
结果类型是Double
因为这是所有位置坐标的存储方式(CLLocationDegrees
是 的类型别名Double
)。
回答by Guy Kogus
This isn't exactly accurate, but you're probably looking for something along the lines of:
这并不完全准确,但您可能正在寻找以下方面的内容:
func XXRadiansToDegrees(radians: Double) -> Double {
return radians * 180.0 / M_PI
}
func getBearingBetweenTwoPoints(point1 : CLLocation, point2 : CLLocation) -> Double {
// Returns a float with the angle between the two points
let x = point1.coordinate.longitude - point2.coordinate.longitude
let y = point1.coordinate.latitude - point2.coordinate.latitude
return fmod(XXRadiansToDegrees(atan2(y, x)), 360.0) + 90.0
}
I appropriated the code from this NSHipster articlethat goes into more detail about what's wrong with it. The basic issue is that it's using the coordinates as though the world is flat (which it isn't, right?). Mattt's article can show you how to get the real directions using MKMapPoint
s instead of CLLocation
s.
我从这篇 NSHipster 文章中挪用了代码,该文章更详细地说明了它有什么问题。基本问题是它使用坐标就好像世界是平的一样(事实并非如此,对吧?)。Mattt 的文章可以向您展示如何使用MKMapPoint
s 而不是CLLocation
s来获得真实的方向。