GMap轴承旋转运动平稳(更改轴承值时避免生涩效应)

时间:2018-01-06 02:29:58

标签: javascript android swift google-maps bearing

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

对于所有语言都需要这样,因为在不同语言库中缓动效果不同。例如Swift,Android,PHP,JS,Node.js,React。

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

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

//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视频。当在360度旋转地图时Bearing值发生变化时,这清楚地显示了生涩效应。

4 个答案:

答案 0 :(得分:6)

将此作为答案作为评论将难以阅读;这取自google documentation

考虑以下代码:

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度的方位会产生一个地图,其中向上的方向指向正东方。

祝你好运。

答案 1 :(得分:2)

我打算将此作为另一个答案,因为我想花点时间写一个文字墙,而我希望尽可能缩短其他答案。它可能仍然可以帮助其他有类似问题的人。

问题

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

我建议的解决方案

我将此分为几个部分,因为我看到了不同的方法。

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

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

  • 使用其他地图

这听起来很重要,根据您的使用情况,您不想做的事情。但是,我已经在iOS和Android上成功使用了Leaflet(JS地图)和WKWebView,并且一切运行良好(这显然在浏览器中也能正常工作)。请记住,其他一些地图也可能有不稳定的动画。

结束

我希望我能给出一些见解。当我们发现有关问题的新内容时,我会添加这个答案。你能尝试提供一个可重复性最小的例子吗?这样我可以给它一个更好的尝试。祝你好运!

答案 2 :(得分:0)

在完成所有可能的情况之后,我发现GMap并非使用自定义动画一次性旋转360度的地图所需的功能。不知道这是否出现在下一个GMap api版本中。

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

这使我们能够将所需的地图周围的搜索体验带给用户。

(目前我发布此临时答案,并允许其他人更新或发布最新答案)。

我已在GMap问题跟踪器上提交此动画控件问题,请启动此问题以显示您的兴趣和反馈,因此Google团队可以将此功能纳入其最终考虑范围。 https://issuetracker.google.com/u/1/issues/71738889

答案 3 :(得分:0)

这是我的方法:

  • 倾斜 = 45f
  • 缩放 = 18
  • 目标 = 当前位置
  • bearing = 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。

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