使用ogr和Python在Polygon中指向(线串)


10

我目前正在一个项目中,我需要根据在shapefile中找到的几何特征来构建拓扑网络。到目前为止,使用Ben Reilly的开源项目,我已经设法将线串转换为networkx边缘,并检测到封闭特征(将其他线串说成)并将其添加到最近的点,以便我可以运行最短路径算法。

但这对于一个shapefile很好。但是,我现在需要将来自不同shapefile的要素连接到一个大的networkx图形中。因此,例如,如果某个点在多边形内,则将其连接(通过连接,我的意思是添加一个networkx边-add_edge(g.GetPoint(1),g.GetPoint(2)),并在下一个shapefile中将该点也位于共享相似属性(例如ID)的多边形内,请注意,不同shps中的多边形仅共享相同的ID,而不共享坐标,而位于多边形内的点也不共享相同的坐标。

我对这个问题的解决方案是识别位于多边形中的点,将其存储,在下一个shapefile中找到具有相同ID的多边形中的点,然后在它们之间添加networkx边。

如何查找点是否位于多边形内?嗯,有一个众所周知的算法:RayCasting算法可以做到这一点。不过,这实际上是我遇到的问题,因为要实现算法,我需要多边形的坐标,而且即使浏览了OGR的Geometry 文档也不知道如何立即访问它们。因此,我要问的问题是如何访问多边形点或坐标,或者是否有更简单的方法来检测点是否落在多边形内?在osgeo.ogr库中使用python,我编写了以下代码:

 if g.GetGeometryType() == 3: #polygon
                c = g.GetDimension()
                x = g.GetPointCount()
                y = g.GetY()
                z = g.GetZ()

查看图片以更好地了解我的问题。 替代文字

[编辑] 到目前为止,我已经尝试将所有多边形对象存储在列表中,然后再与之比较线串的第一和最后一点。但是Paolo的示例与使用“点对象”引用和“多边形对象”引用有关,这与线对象引用不兼容,因为不是整个线都在多边形内,而是其线串的第一个或最后一个点。

[EDIT3] 从线串的第一个点和最后一个点的坐标创建一个新的Geometry点对象,然后使用该对象与列表中保存的多边形几何对象进行比较似乎很好:

for findex in xrange(lyr.GetFeatureCount()):
    f = lyr.GetFeature(findex)
    flddata = getfieldinfo(lyr,f,fields)
    g = f.geometry()
    if g.GetGeometryType() == 2:
        for j in xrange(g.GetPointCount()):
            if j == 0 or j == g.GetPointCount():
                point = ogr.Geometry(ogr.wkbPoint)
                point.AddPoint(g.Getx(j),g.GetY(j))
                if point.Within(Network.polygons[x][0].GetGeometryRef()):
    print g.GetPoint(j)

感谢PaoloChris的提示。

Answers:


11

Shapely既酷又优雅,但是为什么不使用带有空间运算符的OGR(在OGRGeometry类中)呢?

样例代码:

from osgeo import ogr
driver = ogr.GetDriverByName('ESRI Shapefile')
polyshp = driver.Open('/home/pcorti/data/shapefile/multipoly.shp')
polylyr = polyshp.GetLayer(0)
pointshp = driver.Open('/home/pcorti/data/shapefile/point.shp')
pointlyr = pointshp.GetLayer(0)
point = pointlyr.GetNextFeature()
polygon = polylyr.GetNextFeature()
point_geom = point.GetGeometryRef()
polygon_geom = polygon.GetGeometryRef()
print point_geom.Within(polygon_geom)

请注意,您需要在具有GEOS支持的情况下编译GDAL。


grzie Paolo,但我真正需要的不是将点的对象引用与多边形中的对象引用进行比较,而是将线串的最后一个点与第一个点进行比较,我目前正在使用GetPoint对其进行访问。我没有发现GetPointRef。我将如何实施呢?
user39901230 2011年

1
线串是点(顶点)的可迭代几何集合,您可以轻松地访问它们的第一个和最后一个。
capooti 2011年

我试图将多边形对象存储在列表中,以后将用它来检查线串的第一个和最后一个点。但是,由于某些原因,没有将点添加到多边形内的点列表中:在此处查看:codepad.org/Cm2BV5mp
user39901230 2011年

8

我不熟悉networkx,但是如果我正确理解了您的问题,则可以使用shapely和OGR lib从shapefile中查找多边形中的点。这是一个示例,说明如何从一个shapefile中查找一个点(2000,1200)是否由于任何多边形而失败。为了得到结果,它将打印该多边形的坐标。

from shapely.geometry import Point, Polygon
from shapely.wkb import loads
from osgeo import ogr

file1 = ogr.Open("d:\\fileWithData.shp")
layer1 = file1.GetLayerByName("fileWithData")

point1 = Point(2000,1200)

polygon1 = layer1.GetNextFeature()

while polygon1 is not None:
    geomPolygon = loads(polygon1.GetGeometryRef().ExportToWkb())
    if geomPolygon.contains(point1):
        xList,yList = geomPolygon.exterior.xy
        print xList
        print yList
    polygon1 = layer1.GetNextFeature()

希望对您有所帮助。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.