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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 03:24:03