Flutter开发中如何判断地图上marker是否位于用户绘制的polygon范围内
实现Flutter地图Marker是否在Polygon范围内的校验方案
核心实现基于计算机图形学通用的射线法判断逻辑:从标记点向水平右侧发射一条虚拟射线,统计射线和多边形所有边的交点数量,奇数则标记点在多边形内部,偶数则在外部。具体落地步骤如下:
1. 准备坐标数据
不管你用的是google_maps_flutter还是flutter_map地图库,首先提取两类核心坐标:
- 用户绘制的多边形顶点集合:
List<LatLng> polygonVertices - 待校验的标记点坐标:
LatLng markerPosition
2. 实现核心校验工具函数
直接复制下方Dart代码即可使用,无需引入额外第三方依赖:
import 'package:google_maps_flutter/google_maps_flutter.dart'; // 若使用flutter_map,替换上方导入为对应LatLng类的导入即可 bool isMarkerInPolygon(LatLng markerPos, List<LatLng> polygonVertices) { int vertexCount = polygonVertices.length; bool isInside = false; // 遍历多边形的每一条相邻边 for (int i = 0, j = vertexCount - 1; i < vertexCount; j = i++) { LatLng vertexI = polygonVertices[i]; LatLng vertexJ = polygonVertices[j]; // 判断标记点纬度是否在当前边两个端点的纬度区间内 bool latInRange = ((vertexI.latitude > markerPos.latitude) != (vertexJ.latitude > markerPos.latitude)); if (latInRange) { // 计算当前边和标记点水平射线的交点经度 double intersectLng = ( (markerPos.latitude - vertexI.latitude) * (vertexJ.longitude - vertexI.longitude) / (vertexJ.latitude - vertexI.latitude) ) + vertexI.longitude; // 若标记点经度小于交点经度,说明射线穿过当前边,翻转内外状态 if (markerPos.longitude < intersectLng) { isInside = !isInside; } } } return isInside; }
3. 特殊场景兼容处理
- 若需要判断标记点是否刚好在多边形边界上,可在上述逻辑前新增边界校验:计算标记点到每条边的距离是否小于误差阈值(比如0.00001度,对应实际误差约1米),满足条件直接返回true即可
- 若使用
flutter_map框架,可直接用依赖自带的latlong2包内置方法:Polygon.isPointInside(yourPolygon, markerPoint),无需自行实现算法 - 带空洞的多边形场景,需要额外校验标记点不在所有内部空洞多边形的范围内
4. 业务逻辑调用示例
提交前批量校验所有标记的代码参考:
// 已获取的用户绘制多边形顶点 List<LatLng> userPolygon = [...]; // 已获取的所有用户放置的标记坐标 List<LatLng> allMarkers = [...]; // 校验所有标记都在绘制区域内 bool allValid = allMarkers.every((marker) => isMarkerInPolygon(marker, userPolygon)); if(allValid){ // 校验通过,执行后续保存/提交逻辑 }else{ // 校验不通过,提示用户存在超出绘制区域的标记 }
内容的提问来源于stack exchange,提问作者krishnas
相关产品推荐
相关产品推荐

