Рассчитайте точную ориентацию для маркеров анимации в Картах Google, используя данные из Google Directions API - PullRequest
0 голосов
/ 12 марта 2020

Я использую API маршрутов , чтобы получить маршруты между двумя точками, и моя цель - перемещать, вращать и анимировать маркеры в направлении, указанном Google.
Карта, полилиния, перемещение маркеров работают нормально. Но я изо всех сил пытаюсь выяснить , как точно изменить курс, как показывает ломаная линия.
Вот видео того, что я мог бы сделать так далеко: Видео с маркером анимации.
Вы можете видеть, что маркер не следует всем кривым на дороге, как предполагает ломаная линия. Есть ли способ заставить маркер следовать точному маршруту со всеми кривыми, как предложено полилинией? Мы не будем использовать местоположение в реальном времени, отправленное с самого транспортного средства. Таким образом, мы зависим от json, предоставленного Google.
* Я думал, можно ли декодировать ломаную линию от строки до координат карты или CGPoints. Это возможно?
А вот что я пробовал:

func startAnimatingMarker() {
        marker.icon = #imageLiteral(resourceName: "car")
        guard let steps = directionModel?.routes?.first?.legs?.first?.steps else { return }
        guard staticIndex < steps.count else { return }
        guard let start = steps[staticIndex].startLocation, let end = steps[staticIndex].endLocation else { return }
        animateMarker(from: .init(latitude: start.lat ?? 0, longitude: start.lng ?? 0),
                      to: .init(latitude: end.lat ?? 0, longitude: end.lng ?? 0), duration: Double(steps[staticIndex].duration?.value ?? 0) / 50) {
                        print(self.staticIndex)
                        self.staticIndex += 1
                        self.startAnimatingMarker()
        }
    }

func animateMarker(from: CLLocation, to: CLLocation, duration: Double, completion: @escaping () -> Void) {
        marker.position = .init(latitude: from.coordinate.latitude, longitude: from.coordinate.longitude)

        // Bearing
        let dLon = to.coordinate.longitude - from.coordinate.longitude
        let y = sin(dLon) * cos(to.coordinate.latitude)
        let x = cos(from.coordinate.latitude) * sin(to.coordinate.latitude) - sin(from.coordinate.latitude) * cos(to.coordinate.latitude) * cos(dLon)
        var bearing = (atan2(y, x)) * 180 / .pi
        bearing = 360 - (bearing + 360).truncatingRemainder(dividingBy: 360)
        self.marker.rotation = bearing

        CATransaction.begin()
        CATransaction.setValue(duration, forKey: kCATransactionAnimationDuration)
        CATransaction.setValue(CAMediaTimingFunction(name: .linear), forKey: kCATransactionAnimationTimingFunction)
        CATransaction.setCompletionBlock {
            self.marker.groundAnchor = .init(x: 0.5, y: 0.5)
            completion()
        }
        marker.position = CLLocationCoordinate2D(latitude: to.coordinate.latitude,
                                                 longitude: to.coordinate.longitude)
        marker.map = mapView
        CATransaction.commit()
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...