web-dev-qa-db-fra.com

Calcul du relèvement entre deux points CLLocation dans Swift

J'essaie de calculer un relèvement entre deux points CLLocation en code Swift uniquement. J'ai rencontré quelques difficultés et je supposais que c'était une fonction assez simple. Le débordement de la pile ne semblait rien contenir.

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)
}

Je reçois une erreur avec mon appel atan2 à propos de lvalue cgfloat ou quelque chose ...

25
Jeef

Voici une solution Objective-C

qui peut être facilement traduit en 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)
}

Le type de résultat est Double car c'est ainsi que toutes les coordonnées d'emplacement sont stockées (CLLocationDegrees est un alias de type pour Double).

44
Martin R

Ce n'est pas exactement exact, mais vous cherchez probablement quelque chose dans le sens de:

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
}

Je me suis approprié le code de cet article NSHipster qui donne plus de détails sur ce qui ne va pas. Le problème de base est qu'il utilise les coordonnées comme si le monde était plat (ce qui n'est pas le cas, non?). L'article de Mattt peut vous montrer comment obtenir les directions réelles en utilisant MKMapPoints au lieu de CLLocations.

7
Guy Kogus