Google Street View вращает камеру с помощью гироскопа устройства

Я создаю мобильное приложение с помощью SDK Google Maps для iOS и пытаюсь использовать данные гироскопа мобильного устройства для панорамирования камеры вокруг панорамы в Просмотре улиц. Я установил GMSPanoramaView и GMSPanoramaCamera с начальными позициями. Я использую метод -updateCamera в GMSPanoramaView, но не могу плавно перемещаться по каждой панораме. Если кто-нибудь знает, как я могу реализовать эту функцию, пожалуйста, дайте мне знать. Вот мой код в части -viewDidLoad моего контроллера представления:

if manager.gyroAvailable {
        let queue = NSOperationQueue.mainQueue()
        manager.startGyroUpdatesToQueue(queue, withHandler: { (data, error) -> Void in

            NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
                // Update UI
                let cameraUpdate = GMSPanoramaCameraUpdate.rotateBy((data?.rotationRate.x.radiansToDegrees)!)
                self.panoView.updateCamera(cameraUpdate, animationDuration: 1)
            })
        })
    }

person Steve-o    schedule 17.12.2015    source источник
comment
Привет, есть ответы по этому поводу???   -  person mllm    schedule 20.07.2016


Ответы (3)


Следующий код работает в Swift 3

if motionManager.isGyroAvailable {
        motionManager.startGyroUpdates(to: OperationQueue.main, withHandler: { (gyroData: CMGyroData?, error: Error?) in
            let y = gyroData!.rotationRate.y
            print("gyrodata: \(y)")
            let cameraUpdate = GMSPanoramaCameraUpdate.rotate(by: -CGFloat((gyroData?.rotationRate.y)!))
            panoView.updateCamera(cameraUpdate, animationDuration: 1)
          })
    }
person Nandhu    schedule 14.10.2016

Рабочий код в Swift 4 (управляет как слева направо, так и вверх вниз, поэтому везде, где телефон указывает, где будет обновляться вид)

import GoogleMaps
import CoreMotion

class ViewController: UIViewController, GMSPanoramaViewDelegate  {

    let motionManager = CMMotionManager()

    override func loadView() {
        let panoView = GMSPanoramaView(frame: .zero)
        panoView.delegate = self
        self.view = panoView

        // you can choose any latitude longitude here, this is my random choice
        panoView.moveNearCoordinate(CLLocationCoordinate2D(latitude: 48.858, longitude: 2.284))

        motionManager.startDeviceMotionUpdates()

        if motionManager.isGyroAvailable {
            motionManager.startGyroUpdates(to: OperationQueue.main, withHandler: { (gyroData: CMGyroData?, error: Error?) in

                // needed to figure out the rotation
                let y = (gyroData?.rotationRate.y)!

                let motion = self.motionManager.deviceMotion

                if(motion?.attitude.pitch != nil) {
                    // calculate the pitch movement (up / down) I subtract 40 just as
                    // an offset to the view so it's more at face level.
                    // the -40 is optional, can be changed to anything.
                    let pitchCamera = GMSPanoramaCameraUpdate.setPitch( CGFloat(motion!.attitude.pitch).radiansToDegrees - 40 )

                    // rotation calculation (left / right)
                    let rotateCamera = GMSPanoramaCameraUpdate.rotate(by: -CGFloat(y) )

                    // rotate camera immediately
                    panoView.updateCamera(pitchCamera, animationDuration: 0)

                    // for some reason, when trying to update camera
                    // immediately after one another, it will fail
                    // here we are dispatching after 1 millisecond for success
                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.0001, execute: {
                        panoView.updateCamera(rotateCamera, animationDuration: 0)
                    })

                }
            })
        }
    }

}


extension BinaryInteger {
    var degreesToRadians: CGFloat { return CGFloat(Int(self)) * .pi / 180 }
}

extension FloatingPoint {
    var degreesToRadians: Self { return self * .pi / 180 }
    var radiansToDegrees: Self { return self * 180 / .pi }
}

И не забудьте положить это в свой info.plist

Privacy - Motion Usage Description

Добавьте правильный дескриптор того, почему вам нужны эти данные в info.plist, и это должно правильно настроить ваше приложение.

person Áron Géczy    schedule 09.03.2018

У меня есть простой способ, в моем проекте я использую "CLLocationManagerDelegate" - func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading)

self.locationManager.startUpdatingHeading() // put this line on viewdidload for example

func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {
    self.panoramaView.animate(to: GMSPanoramaCamera(heading: newHeading.magneticHeading, pitch: newHeading.y, zoom: 1), animationDuration: 0.1)
}
person Fadielse    schedule 22.06.2018