Расчет Азимута между двумя точками CLLocation в Swift [дубликат]

этот вопрос уже есть ответ здесь:

Я пытаюсь вычислить пеленг между двумя точками CLLocation в коде только для swift. Я столкнулся с некоторыми трудностями и предполагал, что это довольно простая функция. Переполнение стека кажется, ничего не было в списке.

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 это более подробно о том, что с ним не так. Основная проблема заключается в том, что он использует координаты, как будто мир плоский (чего нет, верно?). Статья Мэтта может показать вам, как получить реальные направления, используя MKMapPoints вместо CLLocations.