当标记物超出屏幕范围时如何移动相机?

5

我正在开发一个基于地图的应用程序,用于动画标记。有一个标记每30秒从服务器更新一次。标记始终移动到地图中心,因此我关闭了moveCamera标记,但是当标记移动到地图外时,标记不会出现在地图视图中。因此,当标记从地图视图中消失时,我想要相机移动。


1
如果你手头有Marker,只需获取其latlng并将相机移动到它即可...就这么简单:map.moveCamera(CameraUpdateFactory.newLatLng(latLng)); - Ofek Ron
感谢@OfekRon的回复,如果我移动相机,则标记始终位于地图视图的中心。如果用户缩放地图,当标记移出地图视图时,我希望移动标记。 - Suman
你想移动相机还是标记? - Ofek Ron
标记移动得非常完美。但是当标记移动并且超出可见地图视图时,需要移动相机。 - Suman
你尝试过使用 map.moveCamera(CameraUpdateFactory.newLatLng(latLng)); 吗?其中 latlng 是标记的经纬度。 - Ofek Ron
是的,我做了,但当标记移动时,地图视图始终居中。 - Suman
3个回答

9
在设置标记的新位置之前,请检查其新位置和地图视图的当前边界。
LatLng newPosition = new LatLng(...);

boolean contains = mMap.getProjection()
    .getVisibleRegion()
    .latLngBounds
    .contains(newPosition);

if(!contains){
    // MOVE CAMERA
}
// UPDATE MARKER POSITION
  • 在地图视图中,标记每次移动时会移动(而不是地图中心)
  • 仅当下一个位置超出视图范围时,相机和标记将居中显示。

编辑

我创建了一个示例路线,以模拟地图上的每个点定期移动。 路线要点

public class SampleRoute {
    public static List<LatLng> GetPoints() {
        return new ArrayList<>(Arrays.asList(
            new LatLng(38.4670419, 27.1647131),
            new LatLng(38.4667244, 27.1648277),
            new LatLng(38.4666633, 27.1649079),
            new LatLng(38.4665983, 27.1648022),
            new LatLng(38.4665958, 27.1647843),
            new LatLng(38.4665958, 27.1647843),
            new LatLng(38.4665809, 27.1646429),
            new LatLng(38.4665704, 27.1645506),
            new LatLng(38.4665529, 27.1644067),
            ...
        }
    }
}

然后我在示例活动中创建了一个方法,该方法计算当前区域的边界和此区域上标记的X、Y点。活动代码片段

private void moveCamera(LatLng destination){
    Projection projection =  mMap.getProjection();

    LatLngBounds bounds = projection.getVisibleRegion().latLngBounds;
    int boundsTopY = projection.toScreenLocation(bounds.northeast).y;
    int boundsBottomY = projection.toScreenLocation(bounds.southwest).y;
    int boundsTopX = projection.toScreenLocation(bounds.northeast).x;
    int boundsBottomX = projection.toScreenLocation(bounds.southwest).x;

    int offsetY = (boundsBottomY - boundsTopY) / 10;
    int offsetX = (boundsTopX - boundsBottomX ) / 10;

    Point destinationPoint = projection.toScreenLocation(destination);
    int destinationX = destinationPoint.x;
    int destinationY = destinationPoint.y;

    int scrollX = 0;
    int scrollY = 0;

    if(destinationY <= (boundsTopY + offsetY)){
        scrollY = -(Math.abs((boundsTopY + offsetY) - destinationY));
    }
    else if(destinationY >= (boundsBottomY - offsetY)){
        scrollY = (Math.abs(destinationY - (boundsBottomY - offsetY)));
    }
    if(destinationX >= (boundsTopX - offsetX)){
        scrollX = (Math.abs(destinationX - (boundsTopX - offsetX)));
    }
    else if(destinationX <= (boundsBottomX + offsetX)){
        scrollX = -(Math.abs((boundsBottomX + offsetX) - destinationX));
    }
    mMap.animateCamera(CameraUpdateFactory.scrollBy(scrollX, scrollY));
    mMarker.setPosition(destination);
}

接着开始模拟点数

mHandler.postDelayed(new Runnable() {
    @Override
    public void run() {
        moveCamera(mPoints.get(mCurrentPos));
        if(++mCurrentPos < mPoints.size()){
            mHandler.postDelayed(this, 1500);
        }
    }
}, 1500);

我尝试过,对我来说很有效。

因此,如果我理解你的意思并且它对你也有效,那么我可以解释一下。


谢谢您的回复。是否有可能只让标记出现在视图中,而不移动到中心? - Suman
如果新位置超出地图视图,相机必须聚焦到新位置,否则你怎么看到标记呢?这正是我写上面两件事的原因。 - blackkara
标记和相机两者都存在。当标记移出地图视图时,相机会跟随移动,但这时相机会移动到地图的中心位置,而我希望只有标记进入地图视图,而不是移动到地图中心。这可能吗? - Suman
我的意思是,我希望就像标记移动时地图也能一起移动。感谢您的支持。 - Suman
我会尝试使用您更新后的代码,并在结果出来后回复您。 - Suman
显示剩余2条评论

1
当标记位置更新时,您可以将摄像机动画到标记位置。以下示例代码可能会对您有所帮助。
  LatLng definedLoc = new LatLng(latitudeValue, longitudeValue);
  CameraPosition cameraPosition = new CameraPosition.Builder().target(definedLoc).zoom(13.0F).build();
  map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));

感谢@Kanchan的回复,如果我移动相机,那么标记始终会来到地图视图的中心。如果用户缩放地图,当标记移出地图视图时,我希望移动标记。 - Suman

1
如果地图范围不包含标记,则可以使用 GoogleMap.OnCameraChangeListener 将相机动画移动到标记位置:
private Marker marker;

// ...

@Override
public void onCameraChange(final CameraPosition cameraPosition) {
    ensureMarkerOnBounds();
}

private void ensureMarkerOnBounds() {
    if (marker != null) {
        if (!mMap.getProjection().getVisibleRegion().latLngBounds.contains(marker.getPosition())) {
            mMap.animateCamera(CameraUpdateFactory.newLatLng(marker.getPosition()));
        }
    }
}

// This is the function that you use to move your marker
private void moveMarker (Marker marker) {
    // ... Your code to move your marker
    ensureMarkerOnBounds();
}

这正是示例所做的。 - antonio
我会尝试联系你。 - Suman
1
嗨 @antonio,标记正在移动,但相机没有移动,因此标记不在地图视图中。 - Suman
1
你是否在地图对象中设置了OnCameraChangeListener监听器,代码为mMap.setOnCameraChangeListener(this); - antonio
我想在地图视图中只显示标记,而不是像出租车应用程序一样居中显示。这可能吗? - Suman
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接