سؤال

أحاول أن أكتب فئة لـ Cllocation لإعادة المحمل إلى Cllocation آخر.

أعتقد أنني أفعل شيئًا خاطئًا في هذه الصيغة (لا يعتبر النسب الدعوتي القوية). المحمل الذي تم إرجاعه هو دائما خارج.

لقد كنت أبحث في هذا السؤال وحاولت تطبيق التغييرات التي تم قبولها كإجابة صحيحة وصفحة الويب التي تشير إليها:

حساب المحمل بين اثنين

http://www.movable-type.co.uk/scripts/latlong.html

شكرا على أي مؤشرات. لقد حاولت دمج ردود الفعل من هذا السؤال الآخر وما زلت لا أحصل على شيء ما.

شكرًا

ها هي فئتي -

----- Cllocation+Bearing.H

#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>


@interface CLLocation (Bearing)

-(double) bearingToLocation:(CLLocation *) destinationLocation;
-(NSString *) compassOrdinalToLocation:(CLLocation *) nwEndPoint;

@end

--------- Cllocation+Bearing.M

#import "CLLocation+Bearing.h"

double DegreesToRadians(double degrees) {return degrees * M_PI / 180;};
double RadiansToDegrees(double radians) {return radians * 180/M_PI;};


@implementation CLLocation (Bearing)

-(double) bearingToLocation:(CLLocation *) destinationLocation {

 double lat1 = DegreesToRadians(self.coordinate.latitude);
 double lon1 = DegreesToRadians(self.coordinate.longitude);

 double lat2 = DegreesToRadians(destinationLocation.coordinate.latitude);
 double lon2 = DegreesToRadians(destinationLocation.coordinate.longitude);

 double dLon = lon2 - lon1;

 double y = sin(dLon) * cos(lat2);
 double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon);
 double radiansBearing = atan2(y, x);

 return RadiansToDegrees(radiansBearing);
}
هل كانت مفيدة؟

المحلول

الرمز الخاص بك يبدو جيدا بالنسبة لي. لا حرج في حساب حساب. لا تحدد المدى الذي تبعده عن نتائجك ، ولكن قد تحاول تعديل محولات Radian/Degrees الخاصة بك إلى هذا:

double DegreesToRadians(double degrees) {return degrees * M_PI / 180.0;};
double RadiansToDegrees(double radians) {return radians * 180.0/M_PI;};

إذا كنت تحصل على محامل سلبية ، أضف 2*M_PI إلى النتيجة النهائية في Radiansbearing (أو 360 إذا قمت بذلك بعد التحويل إلى درجات). ATAN2 يعيد النتيجة في النطاق -M_PI إلى M_PI (-180 إلى 180 درجة) ، لذلك قد ترغب في تحويلها إلى محامل البوصلة ، باستخدام شيء مثل الكود التالي

if(radiansBearing < 0.0)
    radiansBearing += 2*M_PI;

نصائح أخرى

هذا هو النقل في فئة سريعة في البداية:

import Foundation
import CoreLocation
public extension CLLocation{

    func DegreesToRadians(_ degrees: Double ) -> Double {
        return degrees * M_PI / 180
    }

    func RadiansToDegrees(_ radians: Double) -> Double {
        return radians * 180 / M_PI
    }


    func bearingToLocationRadian(_ destinationLocation:CLLocation) -> Double {

        let lat1 = DegreesToRadians(self.coordinate.latitude)
        let lon1 = DegreesToRadians(self.coordinate.longitude)

        let lat2 = DegreesToRadians(destinationLocation.coordinate.latitude);
        let lon2 = DegreesToRadians(destinationLocation.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 radiansBearing
    }

    func bearingToLocationDegrees(destinationLocation:CLLocation) -> Double{
        return   RadiansToDegrees(bearingToLocationRadian(destinationLocation))
    }
}

هنا تطبيق آخر

public func bearingBetweenTwoPoints(#lat1 : Double, #lon1 : Double, #lat2 : Double, #lon2: Double) -> Double {

func DegreesToRadians (value:Double) -> Double {
    return value * M_PI / 180.0
}

func RadiansToDegrees (value:Double) -> Double {
    return value * 180.0 / M_PI
}

let y = sin(lon2-lon1) * cos(lat2)
let x = (cos(lat1) * sin(lat2)) - (sin(lat1) * cos(lat2) * cos(lat2-lon1))

let degrees = RadiansToDegrees(atan2(y,x))

let ret = (degrees + 360) % 360

return ret;

}

العمل سريع 3 و 4

جربت الكثير من الإصدارات وهذا الإليك أخيرًا يعطي القيم الصحيحة!

extension CLLocation {


    func getRadiansFrom(degrees: Double ) -> Double {

        return degrees * .pi / 180

    }

    func getDegreesFrom(radians: Double) -> Double {

        return radians * 180 / .pi

    }


    func bearingRadianTo(location: CLLocation) -> Double {

        let lat1 = self.getRadiansFrom(degrees: self.coordinate.latitude)
        let lon1 = self.getRadiansFrom(degrees: self.coordinate.longitude)

        let lat2 = self.getRadiansFrom(degrees: location.coordinate.latitude)
        let lon2 = self.getRadiansFrom(degrees: location.coordinate.longitude)

        let dLon = lon2 - lon1

        let y = sin(dLon) * cos(lat2)
        let x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon)

        var radiansBearing = atan2(y, x)

        if radiansBearing < 0.0 {

            radiansBearing += 2 * .pi

        }


        return radiansBearing
    }

    func bearingDegreesTo(location: CLLocation) -> Double {

        return self.getDegreesFrom(radians: self.bearingRadianTo(location: location))

    }


}

الاستخدام:

let degrees = location1.bearingDegreesTo(location: location2)

هذا آخر cllocation يمكن استخدام التمديد في سريع 3 و سريع 4

public extension CLLocation {

    func degreesToRadians(degrees: Double) -> Double {
        return degrees * .pi / 180.0
    }

    func radiansToDegrees(radians: Double) -> Double {
        return radians * 180.0 / .pi
    }

    func getBearingBetweenTwoPoints(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)
    }

}

أنا استخدم قانون جيب التمام في سويفت. إنه يعمل بشكل أسرع من هافرين ونتيجةه متشابهة للغاية. تباين 1 متر على مسافات ضخمة.

لماذا أستخدم قانون جيب التمام:

  • ركض بسرعة (لأنه لا توجد وظائف SQRT)
  • دقيق بما فيه الكفاية ما لم تفعل بعض علم الفلك
  • مثالي لمهمة الخلفية

func calculateDistance(from: CLLocationCoordinate2D, to: CLLocationCoordinate2D) -> Double {

    let π = M_PI
    let degToRad: Double = π/180
    let earthRadius: Double = 6372797.560856

    // Law of Cosines formula
    // d = r . arc cos (sin 𝜑A sin 𝜑B + cos 𝜑A cos 𝜑B cos(𝜆B - 𝜆A) )

    let 𝜑A = from.latitude * degToRad
    let 𝜑B = to.latitude * degToRad
    let 𝜆A = from.longitude * degToRad
    let 𝜆B = to.longitude * degToRad

    let angularDistance = acos(sin(𝜑A) * sin(𝜑B) + cos(𝜑A) * cos(𝜑B) * cos(𝜆B - 𝜆A) )
    let distance = earthRadius * angularDistance

    return distance

}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top