web-dev-qa-db-ja.com

Swiftの2つのCLLocationポイント間の方位を計算しています

Swiftのみのコードで2つの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)
}

左辺値cgfloatなどについてatan2呼び出しでエラーが発生します...

25
Jeef

これがObjective-Cソリューションです

これは簡単に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)
}

結果のタイプはDoubleです。これは、すべての位置座標が格納される方法です(CLLocationDegreesは、Doubleのタイプエイリアスです)。

44
Martin R

これは正確ではありませんが、おそらく次のように探しています。

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
}

私は このNSHipsterの記事 のコードを当てはめました。基本的な問題は、まるで世界が平らであるかのように座標を使用していることです(そうではありませんよね?)。 Matttの記事では、MKMapPointsではなくCLLocationsを使用して実際のルートを取得する方法を紹介しています。

7
Guy Kogus