ios - Cálculo del rumbo entre dos puntos CLLocation en Swift
cllocationmanager (2)
Esta pregunta ya tiene una respuesta aquí:
Estoy tratando de calcular una demora entre dos puntos CLLocation en un código de solo velocidad. Me he encontrado con algunas dificultades y asumí que esta es una función bastante simple. Desbordamiento de pila no parece tener nada en la lista.
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)
}
Recibo un error con mi llamada atan2 sobre lvalue cgfloat o algo así ...
Aquí hay una solución Objective-C
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 coordenadas de ubicación ( CLLocationDegrees
es un alias de tipo para Double
).
Esto no es exactamente exacto, pero probablemente estés buscando algo como:
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 explica más detalladamente qué tiene de malo. El problema básico es que utiliza las coordenadas como si el mundo fuera plano (lo que no es, ¿no?). El artículo de Mattt puede mostrarle cómo obtener las direcciones reales utilizando MKMapPoint
s en lugar de CLLocation
s.