Flutter Map绘制多边形仅显示最后一个,旧多边形消失求助
解决方案:维护持久化多边形列表解决绘制后消失问题
核心问题出在你没有保留已完成的多边形数据,每次开始新绘制时只渲染了当前的多边形,覆盖了之前的图层。以下是具体修复步骤:
1. 定义状态变量
在你的State类或状态管理容器中,维护两个关键列表:
// 存储所有已完成的多边形(每组顶点对应一个多边形) List<List<LatLng>> completedPolygons = []; // 存储当前正在绘制的临时多边形顶点 List<LatLng> currentDraftPolygon = [];
2. 调整绘制交互逻辑
修改你的点击、长按、右键事件处理逻辑,确保已完成的多边形数据不会丢失:
- 单击开始/继续绘制:仅更新
currentDraftPolygon,不要清空completedPolygonsvoid 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
相关产品推荐
相关产品推荐

