Расчет пеленга между двумя точками CLLocation в Swift
Я пытаюсь вычислить отношение между двумя точками 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)
}
Я получаю сообщение об ошибке с моим вызовом atan2 о lvalue cgfloat или о чем-то...
2 ответа
Вот решение 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
).
Это не совсем точно, но вы, вероятно, ищете что-то вроде:
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, в котором более подробно рассказывается, что с ним не так. Основная проблема в том, что он использует координаты, как будто мир плоский (что не так, правда?). Статья Мэтта может показать вам, как получить реальные направления, используя MKMapPoint
с вместо CLLocation
s.