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

VB.NET KML提取多边形PiP(点在多边形内)匹配异常问题求助

问题原因与修复方案

现有代码的核心错误

  1. KML坐标读取逻辑完全错误
    KML的coordinates节点内每个坐标三元组格式为经度,纬度,海拔,按逗号分割后索引0对应经度、1对应纬度,你现有代码取索引1、2作为x/y,既搞反了经纬度的存储对应关系,还误读了不需要的海拔字段,坐标存储完全错误自然无法匹配到正确的多边形。
  2. 精度损失严重
    你用System.Drawing.PointF存储坐标,其X/Y属性为单精度浮点数,将解析得到的双精度经纬度转成单精度会产生最大几十米的误差,完全不符合GIS计算的精度要求。
  3. 浮点数比较逻辑错误
    直接用=、<>判断浮点数相等,受精度误差影响几乎不可能得到正确结果,需要加入合理容差(如1e-8度,对应分米级误差)。
  4. 射线法逻辑瑕疵
    你的多边形本身已经是首尾闭合的,不需要额外用i Mod lunghezza(id)处理索引,边界判断逻辑也没有覆盖点刚好落在多边形边上的场景。

修复建议

如果要继续使用手写算法,首先修正坐标读取逻辑:

' 正确读取KML坐标,0为经度,1为纬度
x = Double.Parse(String2Array(str(s),",",False)(0)) ' 经度
y = Double.Parse(String2Array(str(s),",",False)(1)) ' 纬度
' 不要用PointF,用自定义结构体存储Double类型的经纬度

其次将所有浮点数比较改为带容差的判断,例如:

' 替换p1.x <> p2.x
If Math.Abs(p1.x - p2.x) > 1e-8 Then
' 替换p1.y = p2.y
If Math.Abs(p1.y - p2.y) < 1e-8 Then

推荐现成库方案

不需要自己手写PiP算法,直接用.NET生态最成熟的GIS计算库NetTopologySuite(NTS),原生支持VB.NET,直接通过Nuget安装NetTopologySuite包即可,内置点在多边形判断、空间索引等成熟功能,性能远高于手写实现,还自动处理球面坐标的边界问题。
使用示例:

' 安装Nuget包后导入命名空间
Imports NetTopologySuite.Geometries
Imports NetTopologySuite.Index.Strtree

' 存储多边形时构建Geometry对象
Dim factory As New GeometryFactory()
Dim coordinates As New List(Of Coordinate)()
' 读取KML坐标存入coordinates列表
Dim polygon As Polygon = factory.CreatePolygon(coordinates.ToArray())

' 点在多边形判断
Dim testPoint As Point = factory.CreatePoint(New Coordinate(经度, 纬度))
Dim isInside As Boolean = polygon.Contains(testPoint)

如果需要批量判断大量点归属,还可以用NTS的STRtree空间索引加速查询,不需要遍历所有多边形。

内容的提问来源于stack exchange,提问作者Carlo Prato

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 19:57:02