You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Google Maps dragListener实现可编辑多多边形的问题求助

我来帮你解决这个问题!你遇到的崩溃和编辑失效问题,核心原因是你只用了单个变量来存储当前多边形的点、标记和多边形对象,当你新建第二个多边形时,旧多边形的标记和点就和当前的points、markerList脱节了——拖动旧标记时,代码会去当前的points里找对应的位置,自然找不到(返回-1),调用points.set(position, ...)就会抛出索引越界异常。

解决方案:封装多边形数据,维护多边形列表

我们需要为每个多边形创建独立的数据集,确保每个标记都能关联到自己所属的多边形。具体实现步骤如下:

1. 定义多边形数据类

创建一个类来封装单个多边形的所有关联信息:

public class PolygonData {
    public List<LatLng> points;
    public List<Marker> markers;
    public Polygon polygon;

    public PolygonData() {
        points = new ArrayList<>();
        markers = new ArrayList<>();
    }
}

2. 替换全局变量为多边形列表

在你的Activity中,替换原来的单个变量为多边形列表和当前绘制的多边形:

private GoogleMap mMap;
private List<PolygonData> polygonList = new ArrayList<>();
private PolygonData currentPolygon; // 当前正在绘制的多边形

3. 修改地图初始化与点击逻辑

更新onMapReady方法,确保每次点击地图时,标记和点都关联到当前多边形:

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    // 保留原有的地图初始化代码(相机位置、缩放等)
    CameraUpdate center = CameraUpdateFactory.newLatLng(new LatLng(40.76793169992044, -73.98180484771729));
    CameraUpdate zoom = CameraUpdateFactory.zoomTo(15);
    mMap.moveCamera(center);
    mMap.animateCamera(zoom);
    mMap.setIndoorEnabled(false);

    // 初始化第一个多边形
    newPolygon(null);

    mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
        @Override
        public void onMapClick(LatLng latLng) {
            Marker marker = mMap.addMarker(new MarkerOptions().position(latLng).draggable(true));
            // 将当前多边形关联到标记,拖动时能找到所属多边形
            marker.setTag(currentPolygon);
            
            currentPolygon.markers.add(marker);
            currentPolygon.points.add(latLng);
            drawCurrentPolygon();
        }
    });

    mMap.setOnMarkerDragListener(new GoogleMap.OnMarkerDragListener() {
        @Override
        public void onMarkerDragStart(Marker marker) {}

        @Override
        public void onMarkerDrag(Marker marker) {
            updateMarkerPosition(marker, false);
        }

        @Override
        public void onMarkerDragEnd(Marker marker) {
            updateMarkerPosition(marker, true);
        }
    });
}

4. 更新新建多边形方法

每次点击新建按钮时,创建一个新的多边形实例并加入列表:

public void newPolygon(View view) {
    currentPolygon = new PolygonData();
    polygonList.add(currentPolygon);
}

5. 修复标记拖动更新逻辑

现在通过标记的Tag找到对应的多边形,再更新该多边形的点和图形:

private void updateMarkerPosition(Marker marker, boolean redraw) {
    PolygonData polygonData = (PolygonData) marker.getTag();
    if (polygonData == null) return;

    // 找到标记在当前多边形中的索引
    int markerIndex = polygonData.markers.indexOf(marker);
    if (markerIndex == -1) return;

    // 更新对应的点位置
    polygonData.points.set(markerIndex, marker.getPosition());
    if (redraw) {
        drawPolygon(polygonData);
    }
}

6. 重写多边形绘制方法

针对单个PolygonData绘制,确保每个多边形独立更新:

private void drawCurrentPolygon() {
    drawPolygon(currentPolygon);
}

private void drawPolygon(PolygonData polygonData) {
    // 移除旧的多边形实例
    if (polygonData.polygon != null) {
        polygonData.polygon.remove();
    }

    // 至少3个点才能绘制多边形
    if (polygonData.points.size() >= 3) {
        PolygonOptions polygonOptions = new PolygonOptions()
                .addAll(polygonData.points)
                .strokeColor(Color.BLUE)
                .fillColor(Color.argb(50, 0, 0, 255));
        polygonData.polygon = mMap.addPolygon(polygonOptions);
    } else {
        polygonData.polygon = null;
    }
}

7. 可选:完善闭合多边形功能

你可以在closePolygon方法中添加自动闭合逻辑:

public void closePolygon(View view) {
    if (currentPolygon != null && currentPolygon.points.size() >= 3) {
        // 闭合多边形(将第一个点添加到列表末尾)
        currentPolygon.points.add(currentPolygon.points.get(0));
        drawPolygon(currentPolygon);
        // 可选:闭合后自动新建一个多边形
        // newPolygon(null);
    }
}

关键改进点说明

  • 每个多边形的点、标记、图形对象都封装在PolygonData中,不同多边形之间不会互相干扰
  • 标记通过Tag关联到所属多边形,拖动时能精准定位到对应的数据集
  • 维护了所有多边形的列表,方便后续的批量编辑、保存等扩展操作

内容的提问来源于stack exchange,提问作者Arpit Patel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 08:22:43