根据GPS坐标iOS

时间:2018-07-27 01:49:00

标签: ios xcode gps core-location augmented-reality

我正在做一个项目,我需要在增强现实中的真实世界位置上放一个箭头。 (箭头只是一个倒置圆锥体上的圆柱体-我说这是为了解释placeArrow()中场景文件中的内容。)

该想法是获取当前位置,找出预定义第二位置的方向和距离,然后将箭头放在增强现实中的该位置上。

我感觉自己快要到了,但是每次发射时,箭头几乎都在我的右手90度而不是实际位置的方向出现。

有人做过类似的事情吗?我在做什么错了?

注意:可以在这里找到MatrixHelper:https://github.com/inorganik/MatrixHelper/blob/master/MatrixHelper.swift

import UIKit
import ARKit
import MapKit

class ViewController: UIViewController, ARSCNViewDelegate, CLLocationManagerDelegate {

    // All the IBOutlets
    @IBOutlet weak var sceneView: ARSCNView!

    // Private variables
    let locationManager = CLLocationManager()
    var location : CLLocation?

    override func viewDidLoad() {

        // Setup the view, the AR, and the location manager.
        super.viewDidLoad()
        setupAr()
        setupLocationManager()

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    func setupAr() {

        // Set up all the Augmented reality stuff.
        let configuration = ARWorldTrackingConfiguration()
        sceneView.session.run(configuration)
        sceneView.delegate = self

    }

    func setupLocationManager() {

        // Set up all the Location Manager stuff.
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.requestAlwaysAuthorization()
        locationManager.startUpdatingLocation()

    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

        // If we haven't already set up everything, set it up.
        if location == nil {
            setAnchor()
        }

    }

    func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {

        // Place arrow does all this.
        return placeArrow()

    }

    func setAnchor() {

        let destination = CLLocationCoordinate2D(latitude: <latitude>, longitude: <longitude>)
        let destinationLocation = CLLocation(latitude: destination.latitude, longitude: destination.longitude)

        // Get the current location and its distance and bearing.
        location = locationManager.location
        let distance = location!.distance(from: destinationLocation)
        let bearing = location!.coordinate.bearing(to: destination)

        // Start from scratch, move the appropriate distance, and rotate appropriately.
        var resetToHorizon = MatrixHelper.resetToHorizon(matrix_identity_float4x4)
        resetToHorizon.columns.3.z = -distance
        let transform = MatrixHelper.rotateMatrixAroundY(degrees: Float(bearing), matrix: resetToHorizon)

        // Add the anchor.
        let anchor = ARAnchor(transform: transform)
        sceneView.session.add(anchor: anchor)

    }

    func placeArrow() -> SCNNode {

        // Create the cylinder and cone and add them.
        let cylinderNode = createSceneItem(art: "art.scnassets/Arrow.scn", item: "cylinder", position: SCNVector3(0, 3, 0))
        let coneNode = createSceneItem(art: "art.scnassets/Arrow.scn", item: "cone", position: SCNVector3(0, -1, 0))
        cylinderNode.addChildNode(coneNode)

        // Return it.
        return cylinderNode

    }

    func createSceneItem(art: String, item: String, position: SCNVector3) -> SCNNode{

        // Create the scene, add the node, give it a name.
        let scene = SCNScene(named: art)
        let node = scene?.rootNode.childNode(withName: item, recursively: false)
        node?.name = item

        // Position it and return it.
        node?.position = position
        return node!

    }
}

extension CLLocationCoordinate2D {
    func bearing(to point: CLLocationCoordinate2D) -> Double {
        func degreesToRadians(_ degrees: Double) -> Double { return degrees * Double.pi / 180.0 }
        func radiansToDegrees(_ radians: Double) -> Double { return radians * 180.0 / Double.pi }

        let lat1 = degreesToRadians(latitude)
        let lon1 = degreesToRadians(longitude)

        let lat2 = degreesToRadians(point.latitude);
        let lon2 = degreesToRadians(point.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(radiansBearing)
    }
}

0 个答案:

没有答案