动画相机以定位和设置谷歌地图中的平移

问题描述 投票:1回答:1

我试图实现类似于谷歌地图中的导航工作方式,请查看下面的图像以供参考。在谷歌地图中,​​标记看起来处于静态位置,但相机正在变化


.

enter image description here

为了达到这个目的,每次我的位置改变时,我都会为标记设置动画,然后通过在Y坐标中平移-300px将其定位到屏幕底部。

但我不能动画相机的位置变化同时向下移动屏幕300px。

当我为相机设置动画以改变位置时,标记会精确地移动到屏幕的中心,之后当我将相机移动300px以下时,其他动画会发生,这看起来非常烦人。

有没有办法可以实现谷歌地图的功能?任何参考或帮助表示赞赏。

android google-maps animation maps
1个回答
1
投票

该代码完全在onLocationChanged中实现,但据记载,其中一些可以在init期间提取。

基本上正在做的是使用从屏幕像素偏移导出的距离从当前位置计算阴影目标,使用来自最后位置的计算轴承外推。

在屏幕录制(下图)中,绿色圆圈表示当前位置(也由地图位置点描绘),蓝色圆圈表示阴影目标,该阴影目标始终位于屏幕中心,因为它是目标地图动画。

这是一个概念的快速绘图:

enter image description here

和代码(下面有一个屏幕录制):

@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类中完成的。

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.