17

我想通过更改方位角值来旋转 GMap,因此相机围绕中心点旋转(360 度一整圈)。当我们改变方位时,在相机起点和终点会有缓动效果。如何控制/更改它以在更改Bearing值时使旋转平滑(以 360 度旋转地图,平滑动画)?

所有语言都需要这个,因为不同语言库中的缓动效果似乎不同。例如 Swift、Android、PHP、JS、Node.js、React。

Swift 示例(在线性动画中运行良好):

请注意,最初动画在 iOS 中也确实存在抖动,但是当我们CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear沿其CATransaction属性使用时,GMap 动画变成了平滑动画。所以现在如果你看到下面的代码,Bearing值的变化不会产生生涩的效果(由于 GMap 动画中的缓动效果)。我也在寻找合适的解决Android方案Web

//Move the map around current location, first loop
let timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
CATransaction.begin()
CATransaction.setValue(3.0, forKey: kCATransactionAnimationDuration)
CATransaction.setAnimationTimingFunction(timingFunction)
CATransaction.setCompletionBlock({
    //Move the map around current location, second loop
    let timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
    CATransaction.begin()
    CATransaction.setValue(3.0, forKey: kCATransactionAnimationDuration)
    CATransaction.setAnimationTimingFunction(timingFunction)
    CATransaction.setCompletionBlock({
        //Move the map around current location, third loop
        let timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
        CATransaction.begin()
        CATransaction.setValue(3.0, forKey: kCATransactionAnimationDuration)
        CATransaction.setAnimationTimingFunction(timingFunction)
        CATransaction.setCompletionBlock({
            UIView.animate(withDuration: 0.5, animations: {
                self.findingYourLocation.alpha = 0.0
            })
            //TODO: Set nearest branch
            // Zoom in one zoom level
            let zoomCamera = GMSCameraUpdate.zoomIn()
            self.mapView.animate(with: zoomCamera)

            // Center the camera on UBL Branch when animation finished
            //let nearestBranch = CLLocationCoordinate2D(latitude: 24.850751, longitude: 67.016589)
            let nearestBranch = CLLocationCoordinate2D.init(latitude: 24.806849, longitude: 67.038734)
            let nearestBranchCam = GMSCameraUpdate.setTarget(nearestBranch)



            CATransaction.begin()

            let timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
            CATransaction.setValue(3.0, forKey: kCATransactionAnimationDuration)
            CATransaction.setAnimationTimingFunction(timingFunction)
            CATransaction.setCompletionBlock({
                self.nextButton.alpha = 1.0
            })
            self.mapView.animate(with: nearestBranchCam)
            self.mapView.animate(toZoom: 15)
            self.mapView.animate(toBearing: 0)
            self.mapView.animate(toViewingAngle: 0)

            CATransaction.commit()

        })
        self.mapView.animate(toBearing: self.mapView.camera.bearing + 120)
        CATransaction.commit()

    })
    self.mapView.animate(toBearing: self.mapView.camera.bearing + 120)
    CATransaction.commit()

})
self.mapView.animate(toBearing: self.mapView.camera.bearing + 120)
CATransaction.commit()

Android示例代码(有问题):

可以在此处找到 Android 示例/示例代码:https ://issuetracker.google.com/issues/71738889

其中还包括一个.apk文件,一个.mp4示例应用程序输出的视频。Bearing这清楚地显示了在 360 度旋转地图时值发生变化时的抖动效果。

4

4 回答 4

6

将此作为评论作为答案将很难阅读;这取自谷歌文档

考虑这段代码:

CameraPosition cameraPosition = new CameraPosition.Builder()
    .target(MOUNTAIN_VIEW)      // Sets the center of the map to Mountain View
    .zoom(17)                   // Sets the zoom
    .bearing(90)                // Sets the orientation of the camera to east
    .tilt(30)                   // Sets the tilt of the camera to 30 degrees
    .build();                   // Creates a CameraPosition from the builder
map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));

这段代码创建了一个新的相机位置,而这正是你想要改变的:相机的方位。因此,如果您像这样创建一个新的相机位置:

CameraPosition cameraPosition = new CameraPosition.Builder()
    .bearing(50)
    .build();

然后将相机动画到该位置:

map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));

这应该够了吧。要提供有关您需要用作轴承的更多信息:

90 度的方位角导致地图向上指向正东。

祝你好运。

于 2018-04-03T12:40:17.323 回答
2

我将把它写成另一个答案,因为我想花时间写一堵文字墙,而我想让另一个答案尽可能短,因为它仍然可以帮助其他有类似情况的人问题。

问题

因此,如果我理解正确,您要做的是使用适用于不同平台的 Google 地图构建应用程序。您在使用 Google 地图(生涩的运动)时遇到了问题,并且您正在尝试为所有平台找到解决方案。

我提出的解决方案

我将把它分成几个部分,因为我看到了不同的前进方式。

  • 为所有平台找到解决方案。

这似乎是最简单的,但它可能类似于 XY 问题。我已经尝试向您介绍一些动画视图的方法,并且您已经解决了 iOS 应用程序中的问题,但您处理的核心问题是更改方位时 Google 地图动画中的一个缺陷。我不确定是否有办法在每个平台上解决这个问题,因为我还没有尝试过。

  • 使用不同的地图

这听起来像是一大步,并且根据您的使用情况,您不想做一些事情。但是,我已经在 iOS 和 Android 上成功地使用了带有 WKWebView 的 Leaflet(一个 JS 地图),并且效果都很好(这显然在浏览器中也可以正常工作)。请记住,其他一些地图也可能有生涩的动画。

把它包起来

我希望我已经给出了一些见解。当我们发现有关该问题的新事物时,我将添加到此答案中。您能否尝试提供一个最小的可重现示例?这样我可以更好地尝试。祝你好运!

于 2018-04-16T18:05:19.997 回答
0

在经历了所有可能的情况后,我才知道,它GMap并没有使用自定义动画一次性构建 360 度旋转地图所需的功能。不知道这是否会出现在下一个GMapapi 版本中。

目前,可能的解决方案是更改动画逻辑,而不是旋转 360 度,我们可以旋转到例如 180 度,同时降低动画速度(动画持续时间)。

这使我们能够为用户带来所需的地图周边搜索体验。

(现在我发布这个临时答案,并允许其他人在将来更新或发布最新答案)。


我已经在 GMap 问题跟踪器上提交了这个动画控制问题,请开始这个问题以显示您的兴趣和反馈,以便 Google 团队可以将此功能作为最终考虑。 https://issuetracker.google.com/u/1/issues/71738889

于 2018-04-25T13:18:43.010 回答
0

这是我的方法:

  • 倾斜 = 45f
  • 缩放 = 18
  • 目标=当前位置
  • 轴承 = lastKnownLocation.bearingTo(currentLocation)
  1. 使用 map.animateCamera(); //而不是移动相机
CameraPosition cameraPosition;
        if (currentLocation.distanceTo(lastKnownLocation) > 50) {
            cameraPosition = new CameraPosition.Builder()
                    .target(currentLatLng).zoom(20).tilt(45f).bearing(bearingValue).build();
        } else {
            cameraPosition = new CameraPosition.Builder()
                    .target(currentLatLng).zoom(20).tilt(45f).build();
        }

        map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));

你还需要做什么?您必须从 LocationCallback(您正在获取位置更新的位置)调用此方法,然后我们才能获得流畅的体验。

因此,如果用户移动(步行或驾驶)并且 lastKnownLocation 和 currentLocation 之间的距离大于 50 米,那么只有我们会设置方位,否则我们只会不断更改 targetLocation。

通过这种方式,我们可以像在谷歌地图中一样显示航向。

于 2021-05-15T06:28:58.500 回答