Cálculo del rumbo entre dos puntos de CLLocation en Swift

Estoy tratando de calcular un rumbo entre dos puntos de CLLocation en el código de solo swift. Me encontré con cierta dificultad y supuse que esta es una function bastante simple. El desbordamiento de stack no parecía tener nada en la list.

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

Estoy recibiendo un error con mi llamada atan2 sobre lvalue cgfloat o algo así …

Aquí hay una solución Objective-C

  • CL Categorización para el cálculo del rodamiento con function Haversine

que se puede traducir fácilmente a 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) } 

El tipo de resultado es Double porque así es como se almacenan todas las coorderadas de location ( CLLocationDegrees es un tipo de alias para Double ).

Esto no es exactamente exacto, pero probablemente esté buscando algo similar a:

 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 } 

Me apropié del código de este artículo de NSHipster que entra en más detalles sobre lo que está mal con él. El problema básico es que está utilizando las coorderadas como si el mundo fuera plano (que no es, ¿verdad?). El artículo de Mattt puede mostrarle cómo get las direcciones reales utilizando MKMapPoint s en lugar de CLLocation s.