设置相机动画以在Google地图中定位和设置平移 [英] Animate camera to position and set panning in google maps

查看:218
本文介绍了设置相机动画以在Google地图中定位和设置平移的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现类似于Google地图导航的工作方式,请查看下面的图片以供参考.在Google地图中,标记看起来是在静态位置,除了相机在变化

I'm trying to achieve similar to how navigation in google maps works, check the below image for reference. In google maps, the marker looks to be at a static location except the camera is changing

.

为此,我会在每次更改位置时为标记设置动画,然后通过在Y坐标上将其平移-300px来将其定位到屏幕底部.

To achieve this I animate the marker every time my location changes and later I position it towards the bottom of the screen by panning it by -300px in Y coordinate.

但是我无法为相机动画以改变位置,同时将屏幕向下移动300px.

But I cannot animate the camera for change in location an moving the screen 300px down at the same time.

当我对照相机进行动画处理以改变位置时,标记会精确地移动到屏幕的中心,后来当我将照相机移动300px时,其他动画会发生,这看起来非常烦人.

When I animate the camera for change in location the marker moves exactly to the centre of the screen and later when I move the camera 300px below other animation takes place which looks very annoying.

有没有一种方法可以实现Google Maps的功能?任何参考或帮助,表示赞赏.

Is there a way I can achieve what google maps do? Any reference or help is appreciated.

推荐答案

该代码已在onLocationChanged中完全实现,但如记录所示,其中一些可以在初始化期间提取.

The code is completely implemented in the onLocationChanged but as documented some of it can be extracted during init.

基本上,使用从屏幕像素偏移量得出的距离从当前位置计算出阴影目标,该距离是使用从最后一个位置计算出的方位推算出来的.

Essentially what is being done is a shadow target is computed from the current location using the distance derived from a screen pixel offset, extrapolated using a computed bearing from last location.

在屏幕记录(下)中,绿色圆圈代表当前位置(也由地图位置点表示),蓝色圆圈代表阴影目标,由于阴影目标始终位于屏幕中央地图动画的目标.

In the screen recording (below), the green circle represents the current location (also depicted by the map location dot) and the blue circle represents the shadow target which is always in the center of the screen as a result of being the target of the map animate.

以下是概念的简要说明:

Here's a quick drawing of concept:

和代码(下面有屏幕记录):

And the code (with a screen recording below):

@Override
public void onLocationChanged(Location location) {

    // First point processing
    if (lastLocation == null) {

        // save last location
        lastLocation = location;

        // initial camera
        CameraPosition.Builder b = CameraPosition.builder().
                zoom(15.0F).
                target(new LatLng(lastLocation.getLatitude(), lastLocation.getLongitude()));
        CameraUpdate cu = CameraUpdateFactory.newCameraPosition(b.build());
        mMap.animateCamera(cu);
        return;
    }

    // subsequent updates

    LatLng oldPos = new LatLng(lastLocation.getLatitude(), lastLocation.getLongitude());
    LatLng newPos = new LatLng(location.getLatitude(), location.getLongitude());

    // ignore very small position deviations (prevents wild swinging)
    double d = SphericalUtil.computeDistanceBetween(oldPos, newPos);
    if (d < 10) {
        return;
    }


    // compute our own bearing (do not use location bearing)
    double bearing = SphericalUtil.computeHeading(oldPos, newPos);

    //-----------------------------------------------
    // Next section really only needs to be done once

    // Compute distance of pixels on screen using some desirable "offset"

    Projection p = mMap.getProjection();
    Point  bottomRightPoint = p.toScreenLocation(p.getVisibleRegion().nearRight);
    Point center = new Point(bottomRightPoint.x/2,bottomRightPoint.y/2);
    Point offset = new Point(center.x, (center.y + 300));

    LatLng centerLoc = p.fromScreenLocation(center);
    LatLng offsetNewLoc = p.fromScreenLocation(offset);

    // this computed value only changes on zoom
    double offsetDistance = SphericalUtil.computeDistanceBetween(centerLoc, offsetNewLoc);
    //-----------------------------------------------


    // Compute shadow target position from current position (see diagram)
    LatLng shadowTgt = SphericalUtil.computeOffset(newPos,offsetDistance,bearing);

    // update circles
    if (centerCircle != null) {
        centerCircle.setCenter(shadowTgt);
    } else {
        centerCircle = mMap.addCircle(new CircleOptions().strokeColor(Color.BLUE).center(shadowTgt).radius(50));
    }
    if (carCircle != null) {
        carCircle.setCenter(newPos);
    } else {
        carCircle = mMap.addCircle(new CircleOptions().strokeColor(Color.GREEN).center(newPos).radius(50));
    }


    // update camera

    CameraPosition.Builder b = CameraPosition.builder();
    b.zoom(15.0F);
    b.bearing((float)(bearing));
    b.target(shadowTgt);
    CameraUpdate cu = CameraUpdateFactory.newCameraPosition(b.build());
    mMap.animateCamera(cu);

    // save location as last for next update
    lastLocation = location;
}

注意:

  • 缩放比例更改时,需要重新计算offsetDistance. (但是请注意,并不需要每次更改位置都完成此操作.)
  • 轴承在概念图中显示为0-360,但实际上是-180-180.
  • 如您所见,大多数工作是在SphericalUtil类中完成的.
  • When the zoom changes, the offsetDistance needs to be recomputed. (But as noted it does not need to be done every location changed.)
  • Bearing is shown in concept diagram as 0-360 but is actually -180-180.
  • As you can see, most of the work is done in the SphericalUtil class.

这篇关于设置相机动画以在Google地图中定位和设置平移的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆