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

Flutter Map绘制多边形仅显示最后一个,旧多边形消失求助

解决方案:维护持久化多边形列表解决绘制后消失问题

核心问题出在你没有保留已完成的多边形数据,每次开始新绘制时只渲染了当前的多边形,覆盖了之前的图层。以下是具体修复步骤:

1. 定义状态变量

在你的State类或状态管理容器中,维护两个关键列表:

// 存储所有已完成的多边形(每组顶点对应一个多边形)
List<List<LatLng>> completedPolygons = [];
// 存储当前正在绘制的临时多边形顶点
List<LatLng> currentDraftPolygon = [];

2. 调整绘制交互逻辑

修改你的点击、长按、右键事件处理逻辑,确保已完成的多边形数据不会丢失:

  • 单击开始/继续绘制:仅更新currentDraftPolygon,不要清空completedPolygons
    void onMapTap(LatLng tapPoint) {
      setState(() {
        // 如果是首次点击,初始化;否则添加顶点
        if (currentDraftPolygon.isEmpty) {
          currentDraftPolygon.add(tapPoint);
        } else {
          currentDraftPolygon.add(tapPoint);
        }
      });
    }
    
  • 再次单击结束绘制:将临时多边形顶点存入completedPolygons,然后清空临时列表
    // 可在第二次点击时触发,或者单独的结束逻辑
    void finishCurrentPolygon() {
      if (currentDraftPolygon.length >= 3) { // 多边形至少需要3个顶点
        setState(() {
          completedPolygons.add(List.from(currentDraftPolygon)); // 深拷贝避免引用问题
          currentDraftPolygon.clear();
        });
      }
    }
    
  • 长按丢弃当前多边形:直接清空临时顶点列表
    void discardCurrentPolygon() {
      setState(() {
        currentDraftPolygon.clear();
      });
    }
    
  • 右键保存多边形:将临时多边形加入完成列表(和结束绘制逻辑一致,可复用)
    void handleRightClick(LatLng point) {
      finishCurrentPolygon();
      // 如需本地持久化,可在这里将completedPolygons写入文件
    }
    

3. 配置地图图层同时渲染所有多边形

在FlutterMap的children中,同时添加已完成多边形图层和临时多边形图层,确保所有多边形都被渲染:

FlutterMap(
  options: MapOptions(
    onTap: onMapTap,
    onLongPress: (point) => discardCurrentPolygon(),
    // 其他配置
  ),
  children: [
    TileLayer(
      urlTemplate: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
      subdomains: const ['a', 'b', 'c'],
    ),
    // 渲染所有已完成的多边形
    PolygonLayer(
      polygons: completedPolygons.map((points) {
        return Polygon(
          points: points,
          color: Colors.blue.withOpacity(0.3),
          borderColor: Colors.blue,
          borderStrokeWidth: 2,
        );
      }).toList(),
    ),
    // 渲染当前正在绘制的临时多边形(有顶点时才显示)
    if (currentDraftPolygon.isNotEmpty)
      PolygonLayer(
        polygons: [
          Polygon(
            points: currentDraftPolygon,
            color: Colors.red.withOpacity(0.2),
            borderColor: Colors.red,
            borderStrokeWidth: 2,
          ),
        ],
      ),
    // 右键事件监听(Windows平台)
    Listener(
      onPointerDown: (event) {
        if (event.buttons == kSecondaryMouseButton) {
          // 将地图坐标转换为LatLng,需根据你的地图缩放、中心点计算
          final latLng = mapController.pointToLatLng(event.localPosition);
          if (latLng != null) handleRightClick(latLng);
        }
      },
      child: const SizedBox.expand(),
    ),
  ],
)

4. 关键注意事项

  • 必须使用深拷贝将临时顶点加入completedPolygons(比如List.from(currentDraftPolygon)),避免后续修改临时列表影响已完成的多边形
  • 每次修改列表后,务必调用setState()(StatefulWidget)或通知状态管理工具更新,确保UI重新渲染
  • Windows平台右键事件需要通过Listener监听PointerDownEvent的buttons属性判断,kSecondaryMouseButton代表右键

内容的提问来源于stack exchange,提问作者masoud Afrakhteh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 04:29:49