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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 03:40:41  来源:igfitidea点击:

Calculating bearing between two CLLocation points in Swift

iosswiftcllocation

提问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 Doublebecause that is how all location coordinates are stored (CLLocationDegreesis 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 MKMapPoints instead of CLLocations.

我从这篇 NSHipster 文章中挪用了代码,该文章更详细地说明了它有什么问题。基本问题是它使用坐标就好像世界是平的一样(事实并非如此,对吧?)。Mattt 的文章可以向您展示如何使用MKMapPoints 而不是CLLocations来获得真实的方向。