VB.NET-来自KML文件的多边形中的点 [英] VB.NET - Point in Polygon From KML file

查看:0
本文介绍了VB.NET-来自KML文件的多边形中的点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从KML文件中提取了大量Polygons。这些多边形代表地球表面上的积木。 我可以读取多边形的坐标并存储它们的值,以及我拥有的一些有关该多边形的其他信息。

我的问题是,我现在有一个点的集合(以及它们的坐标,我们再次讨论的是地球表面上的点),我需要检查它们属于哪个多边形。

我知道PiP不是一个微不足道的新问题,所以我不想重新发明轮子! 有没有VB.NET库可以帮助我快速解决这个问题? 谢谢

编辑

我的多边形是n元组的形状,例如5元组(其中一些有更多,所有的第一个和最后一个点都相等):

[( -59.00002600000005,-52.00002600000001,0 ),
 ( -59.00002600000005,-51.50002600000001,0 ), 
 ( -59.50002600000005,-51.50002600000001,0 ),
 ( -59.50002600000005,-52.00002600000001,0 ),
 ( -59.00002600000005,-52.00002600000001,0 ) ]

目前我是这样阅读KML文件的:

'foreach KML Placemark
For Each p As System.XML.Linq.XElement In xdata.Descendants(ns +"Placemark")
    ID =  p.Element(ns+"name").Value        
    'coordinates, every substring has triple x,y,z but i only care about x,y
    temp = p.Descendants(ns+"coordinates").Value
    str = temp.split(" ")
    
    'number of polygon vertexes
    lunghezza(ID) = str.length()-1
    'polygon vertexes
    Dim polygonPoints(str.length()-1) As System.Drawing.PointF
    'first substring is empty
    for s = 1 to str.length()-1
        'i get x,y
        x = String2Array(str(s),",",false)(1)
        y = String2Array(str(s),",",false)(2)
        'cast to double
        flt_x = double.Parse(x)
        flt_y = double.Parse(y)
        'point is made
        polygonPoints(s-1) = new System.Drawing.PointF(flt_x, flt_y)
    next
    'points are associated to the polygon ID
    punti(ID) = polygonPoints
Next

此时,我尝试查看点是否位于我存储的其中一个面中:为此,我使用了我找到的算法here

dim ok as boolean = false
dim xinters as double
' flt_y  and flt_x contain my test latitude and longitude
'foreach polygon stored
for each id in IDS
    if not empty(id)
        'get number of points defining the polygon
        Dim polygonPoints2(lunghezza(id)) As System.Drawing.PointF
        'i get the polygon vertexes
        polygonPoints2 = punti(id)
        dim p1, p2 as System.Drawing.PointF
        'first point
        p1 = polygonPoints2(0)
        'counter
        dim c as integer = 0
    
        for i as integer = 1 to lunghezza(id)
            p2 = polygonPoints2(i Mod lunghezza(id))
            if ( flt_x > Math.min(p1.x, p2.x) and flt_x <= Math.max(p1.x, p2.x) and flt_y <= Math.max(p1.y, p2.y) and p1.x <> p2.x) then
                xinters = (flt_x - p1.x) * (p2.y - p1.y) / (p2.x - p1.x) + p1.y
                if (p1.y = p2.y or flt_y <= xinters) 
                    c = c + 1
                end if
            end if
            p1 = p2
        next 
        
        if (c mod 2) <> 0
            'found one!
            ok = true
            exit for
        end if
    end if
next

但我从来没有找到我的点属于哪个多边形! 我做错了什么?

为了测试我使用的坐标:x: 44,3034627 y: 7,800283

我确信这些可以放入这个多边形中:

 <Polygon>
    <extrude>0</extrude>
    <altitudeMode>clampToGround</altitudeMode>
    <outerBoundaryIs>
    <LinearRing>
    <coordinates> 
        10.99997399999995,45.999974,0
         10.99997399999995,46.499974,0
         10.49997399999995,46.499974,0
         9.999973999999952,46.499974,0
         9.499973999999952,46.499974,0
         8.999973999999952,46.499974,0
         8.499973999999952,46.499974,0
         7.999973999999952,46.499974,0
         7.999973999999952,45.999974,0
         7.499973999999952,45.999974,0
         6.999973999999952,45.999974,0
         6.999973999999952,45.499974,0
         6.999973999999952,44.999974,0
         6.999973999999952,44.499974,0 
         6.999973999999952,43.999974,0
         7.499973999999952,43.999974,0 
         7.999973999999952,43.999974,0 
         7.999973999999952,44.499974,0 
         8.499973999999952,44.499974,0
         8.999973999999952,44.499974,0
         9.499973999999952,44.499974,0
         9.999973999999952,44.499974,0
         10.49997399999995,44.499974,0
         10.49997399999995,43.999974,0
         10.99997399999995,43.999974,0
         11.49997399999995,43.999974,0
         11.99997399999995,43.999974,0 
         11.99997399999995,44.499974,0
         12.49997399999995,44.499974,0 
         12.49997399999995,44.999974,0 
         11.99997399999995,44.999974,0 
         11.49997399999995,44.999974,0
         11.49997399999995,45.499974,0 
         10.99997399999995,45.499974,0 
         10.99997399999995,45.999974,0
     </coordinates>
     </LinearRing>
     </outerBoundaryIs>
 </Polygon>

我开始怀疑问题出在PiP算法中,更具体地说是关于<>=之间的比较,因此重新标记

推荐答案

最终,我的所有工作都是正确的,我只是以错误的顺序读取坐标,没有正确处理输入字符串。以下是读取KML的更正代码:

'foreach KML Placemark
For Each p As System.XML.Linq.XElement In xdata.Descendants(ns +"Placemark")
    ID =  p.Element(ns+"name").Value        
    'coordinates, every substring has triple x,y,z but i only care about x,y
    temp = p.Descendants(ns+"coordinates").Value
    str = temp.split(" ")
    
    'number of polygon vertexes
    lunghezza(ID) = str.length()-1
    'polygon vertexes
    Dim polygonPoints(str.length()-1) As System.Drawing.PointF
    'first substring is empty
    for s = 1 to str.length()-1
        'i get x,y
        y = String2Array(str(s),",",false)(1)
        x = String2Array(str(s),",",false)(2)
        'cast to double
        flt_x = double.Parse(x.replace(".", ","))
        flt_y = double.Parse(y.replace(".", ","))
        'point is made
        polygonPoints(s-1) = new System.Drawing.PointF(flt_x, flt_y)
    next
    'points are associated to the polygon ID
    punti(ID) = polygonPoints
Next

这篇关于VB.NET-来自KML文件的多边形中的点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆