我想找到Qibla方向(简单的指南针方向)在Swift



所有代码都运行良好,但没有给出所需的结果。方向针没有移动到理想位置。有时有效,有时无效。

func DegreesToRadians (value:Double) -> Double {
    return value * M_PI / 180.0
}
func RadiansToDegrees (value:Double) -> Double {
    return value * 180.0 / M_PI
}
class ViewController: UIViewController , CLLocationManagerDelegate {
    var needleAngle : Double?
    //Main Composs
    @IBOutlet weak var composs: UIImageView!
    //Needle Move with respect to compose
    @IBOutlet weak var needle: UIImageView!
    @IBOutlet weak var mapView: MKMapView!
    // Kabhalocation 
    var kabahLocation : CLLocation?
    var latitude  : Double?
    var longitude : Double?
    var distanceFromKabah : Double?
    let locationManger = CLLocationManager()
    override func viewDidLoad() {
        super.viewDidLoad()
        //KabhaLocation Hardcoded.
        kabahLocation = CLLocation(latitude: 21.42 , longitude: 39.83)
        //Delegate
        self.locationManger.delegate = self
        self.locationManger.desiredAccuracy = kCLLocationAccuracyBest
        if #available(iOS 8.0, *) {
            self.locationManger.requestAlwaysAuthorization()
        } else {
            // Fallback on earlier versions
        }
        self.locationManger.startUpdatingLocation()
        self.locationManger.startUpdatingHeading()
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    // Mark: - LocationManger Delegate
    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let location = locations.last
 let center = CLLocationCoordinate2D(latitude: (location?.coordinate.latitude)!, longitude: (location?.coordinate.longitude)!)
        print("current location latitude ((location?.coordinate.latitude)!) and longitude ((location?.coordinate.longitude)!)")
        self.latitude = location?.coordinate.latitude
        self.longitude = location?.coordinate.longitude
//
//        self.latitude = 31.5497
//        self.longitude = 74.3436
        self.locationManger.startUpdatingLocation()
        needleAngle     = self.setLatLonForDistanceAndAngle(location!)
    }
    func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
        print("Error " + error.localizedDescription)
    }
    func setLatLonForDistanceAndAngle(userlocation: CLLocation) -> Double
    {
        let lat1 = DegreesToRadians(userlocation.coordinate.latitude)
        let lon1 = DegreesToRadians(userlocation.coordinate.longitude)
        let lat2 = DegreesToRadians(kabahLocation!.coordinate.latitude)
        let lon2 = DegreesToRadians(kabahLocation!.coordinate.longitude)
        distanceFromKabah = userlocation.distanceFromLocation(kabahLocation!)
        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*M_PI;
        }
//        print("Initial Bearing (radiansBearing*180/M_PI)")
        let distanceFromKabahUnit  = 0.0
        return radiansBearing
    }
    func locationManager(manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {
        let needleDirection   = -newHeading.trueHeading;
        let compassDirection  = -newHeading.magneticHeading;
        self.needle.transform = CGAffineTransformMakeRotation(CGFloat(((Double(needleDirection) ) / 180.0) + needleAngle!))
        print("Needle (CGAffineTransformMakeRotation(CGFloat(((Double(needleDirection) ) / 180.0) + needleAngle!)))")
        self.composs.transform = CGAffineTransformMakeRotation(CGFloat((Double(compassDirection) ) / 180.0))
        print("composs (CGAffineTransformMakeRotation(CGFloat((Double(compassDirection) ) / 180.0)))")
    }
    override func viewDidAppear(animated: Bool) {
        needleAngle = 0.0
        self.locationManger.startUpdatingHeading()
        kabahLocation = CLLocation(latitude: 21.42 , longitude: 39.83)
        self.locationManger.delegate = self
    }
    override func viewDidDisappear(animated: Bool) {
        self.locationManger.delegate = nil
    }

实际上你在这里做错的是使指南针在didLocationChange方法中旋转。实际上,你需要根据地球的真北进行旋转,为此你需要使用didUpdateLocationHeader,这会给你根据地球的真北的读数。我在下面张贴我的代码。你也可以在我的github上找到一个完整的工作项目

import UIKit
import CoreLocation
class ViewController: UIViewController ,CLLocationManagerDelegate{
@IBOutlet weak var ivCompassBack: UIImageView!
@IBOutlet weak var ivCompassNeedle: UIImageView!
let latOfKabah = 21.4225
let lngOfKabah = 39.8262
var location: CLLocation?
let locationManager = CLLocationManager()

var bearingOfKabah = Double()
override func viewDidLoad() {
    super.viewDidLoad()
    initManager()
}

func initManager(){
    locationManager.requestAlwaysAuthorization()
    locationManager.requestWhenInUseAuthorization()
    if CLLocationManager.locationServicesEnabled() {
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
        locationManager.startUpdatingLocation()
        locationManager.startUpdatingHeading()
    }
}
func locationManager(_ manager: CLLocationManager, didUpdateHeading heading: CLHeading) {

    let north = -1 * heading.magneticHeading * Double.pi/180
    let directionOfKabah = bearingOfKabah * Double.pi/180 + north
    ivCompassBack.transform =   CGAffineTransform(rotationAngle: CGFloat(north));
    ivCompassNeedle.transform =       CGAffineTransform(rotationAngle: CGFloat(directionOfKabah));

}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    let newLocation = locations.last!
    location = newLocation
    bearingOfKabah = getBearingBetweenTwoPoints1(location!, latitudeOfKabah: self.latOfKabah, longitudeOfKabah: self.lngOfKabah) //calculating the bearing of KABAH
}

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

func radiansToDegrees(_ radians: Double) -> Double { return radians * 180.0 / Double.pi }
func getBearingBetweenTwoPoints1(_ point1 : CLLocation, latitudeOfKabah : Double , longitudeOfKabah :Double) -> Double {
    let lat1 = degreesToRadians(point1.coordinate.latitude)
    let lon1 = degreesToRadians(point1.coordinate.longitude)
    let lat2 = degreesToRadians(latitudeOfKabah);
    let lon2 = degreesToRadians(longitudeOfKabah);
    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 * Double.pi;
    }
    return radiansToDegrees(radiansBearing)
}
}
//
//  ViewController.swift
//  CurrentLocation
//
//  Created by Muhammad Rizwan Anjum on 26/8/16.
//  Copyright © 2016 Muhammad Rizwan Anjum. All rights reserved.
//
import UIKit
import MapKit
import CoreLocation
func DegreesToRadians (value:Double) -> Double {
    return value * M_PI / 180.0
}
func RadiansToDegrees (value:Double) -> Double {
    return value * 180.0 / M_PI
}
class ViewController: UIViewController , CLLocationManagerDelegate {
    var needleAngle : Double?
    @IBOutlet weak var composs: UIImageView!
    @IBOutlet weak var needle: UIImageView!
    @IBOutlet weak var mapView: MKMapView!
    var kabahLocation : CLLocation?
    var latitude  : Double?
    var longitude : Double?
    var distanceFromKabah : Double?
    let locationManger = CLLocationManager()
    override func viewDidLoad() {
        super.viewDidLoad()
        kabahLocation = CLLocation(latitude: 21.42 , longitude: 39.83)
        self.locationManger.delegate = self
        self.locationManger.desiredAccuracy = kCLLocationAccuracyBest
        if #available(iOS 8.0, *) {
            self.locationManger.requestAlwaysAuthorization()
        } else {
            // Fallback on earlier versions
        }
        self.locationManger.startUpdatingLocation()
        self.locationManger.startUpdatingHeading()
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    // Mark: - LocationManger Delegate
    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let location = locations.last
//        let center = CLLocationCoordinate2D(latitude: (location?.coordinate.latitude)!, longitude: (location?.coordinate.longitude)!)
        print("current location latitude ((location?.coordinate.latitude)!) and longitude ((location?.coordinate.longitude)!)")
        self.latitude = location?.coordinate.latitude
        self.longitude = location?.coordinate.longitude
//
//        self.latitude = 31.5497
//        self.longitude = 74.3436
        self.locationManger.startUpdatingLocation()
        needleAngle     = self.setLatLonForDistanceAndAngle(location!)
    }
    func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
        print("Error " + error.localizedDescription)
    }
    func setLatLonForDistanceAndAngle(userlocation: CLLocation) -> Double
    {
        let lat1 = DegreesToRadians(userlocation.coordinate.latitude)
        let lon1 = DegreesToRadians(userlocation.coordinate.longitude)
        let lat2 = DegreesToRadians(kabahLocation!.coordinate.latitude)
        let lon2 = DegreesToRadians(kabahLocation!.coordinate.longitude)
        distanceFromKabah = userlocation.distanceFromLocation(kabahLocation!)
        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*M_PI;
        }
//        print("Initial Bearing (radiansBearing*180/M_PI)")
        let distanceFromKabahUnit  = 0.0

        return radiansBearing
    }
    func locationManager(manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {
        let needleDirection   = -newHeading.trueHeading;
        let compassDirection  = -newHeading.magneticHeading;
//you Need to Multiply With M_PI
        self.needle.transform = CGAffineTransformMakeRotation(CGFloat(((Double(needleDirection) * M_PI) / 180.0) + needleAngle!))
        print("Needle (CGAffineTransformMakeRotation(CGFloat(((Double(needleDirection) * M_PI) / 180.0) + needleAngle!)))")
        self.composs.transform = CGAffineTransformMakeRotation(CGFloat((Double(compassDirection) * M_PI) / 180.0))
        print("composs (CGAffineTransformMakeRotation(CGFloat((Double(compassDirection) * M_PI) / 180.0)))")
    }
    override func viewDidAppear(animated: Bool) {
        needleAngle = 0.0
        self.locationManger.startUpdatingHeading()
        kabahLocation = CLLocation(latitude: 21.42 , longitude: 39.83)
        self.locationManger.delegate = self
    }
    override func viewDidDisappear(animated: Bool) {
        self.locationManger.delegate = nil
    }


}

最新更新