Ogr ve Python kullanarak Polygon içindeki nokta (linestring)


10

Şu anda şekil dosyalarında bulduğum geometri özelliklerinden topolojik bir ağ oluşturmam gereken bir proje üzerinde çalışıyorum. Şimdiye kadar Ben Reilly'nin açık kaynak projesini kullanarak , linestringleri networkx kenarlarına dönüştürmeyi ve yakın özellikleri (diğer linestrings söylüyor) tespit etmeyi ve en kısa yol algoritmalarını çalıştırabilmem için onları en yakın noktaya eklemeyi başardım.

Ama bu bir şekil dosyası için iyi. Ancak, şimdi farklı şekil dosyalarından özellikleri büyük bir networkx grafiğine bağlamam gerekiyor. Örneğin, bir nokta bir çokgenin içindeyse, onu bağlarım (bağlanarak bir networkx kenarı - add_edge (g.GetPoint (1), g.GetPoint (2)) ekleyeceğim, bir sonraki şekil dosyasındaki nokta ile Ayrıca benzer bir özniteliği paylaşan bir poligon içindedir (örneğin, ID) Farklı bölümlerdeki çokgenlerin koordinatları değil, aynı kimlikleri paylaştığını ve çokgenlerin içine giren noktaların da aynı koordinatları paylaşmadığını unutmayın.

Bu soruna çözümüm, bir çokgenin içinde bulunan noktayı tanımlamak, depolamak, aynı kimliğe sahip çokgende bulunan bir sonraki şekil dosyasındaki noktayı bulmak ve aralarına networkx kenarını eklemekti.

Bir noktanın bir çokgenin içinde olup olmadığı nasıl bulunur? Bilinen bir algoritma var: Bunu yapan RayCasting algoritması. Gerçi burada sıkışıp kaldım, çünkü algoritmayı uygulamak için çokgenin koordinatlarına ihtiyacım var ve OGR'nin Geometrisinin bir dokümantasyonundan geçtikten sonra bile onlara nasıl erişeceğimi bilmiyorum . Yani, sorduğum soru çokgen noktalarına veya koordinatlarına nasıl erişileceğidir VEYA bir noktanın çokgenin içine düşüp düşmediğini tespit etmenin daha kolay bir yolu var mı? Osgeo.ogr kütüphanesi ile python kullanarak aşağıdakileri kodladım:

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

sorunumu daha iyi anlamak için resme bakın. alternatif metin

[EDIT] Şimdiye kadar çokgen nesnelerini daha sonra linestring'i ilk ve son noktayla karşılaştıracağım bir listede saklamayı denedim . Ancak Paolo'nun örneği, tüm çizgi çokgen içinde değil, linestring'inin ilk veya son noktası olduğu için bir çizgi nesnesi başvurusu ile çalışmayan Nokta Nesnesi başvurusunu ve Çokgen Nesnesi başvurusunu kullanmakla ilgilidir.

[EDIT3] Köprünün ilk ve son noktasının koordinatlarından yeni bir Geometri noktası nesnesi oluşturmak ve daha sonra bunu bir listede kaydedilen çokgen geometri nesnelerine karşı karşılaştırmak için kullanmak gayet iyi görünüyor:

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)

İpuçları için Paolo ve Chris'e teşekkürler .

Yanıtlar:


11

Şekilli serin ve zarif, ama neden uzaysal operatörleriyle (OGRGeometry sınıfında) hala ogr kullanmıyorsunuz?

basit kod:

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)

GDAL'ı GEOS desteği ile derlemeniz gerektiğini unutmayın.


grzie Paolo, ama gerçekten ihtiyacım olan şey bir noktanın nesne referanslarını çokgenin biriyle karşılaştırmak değil, şu anda GetPoint ile eriştiğim bir linestring'in son ve ilk noktası. Fark ettiğim GetPointRef yok. Bunu nasıl uygulayabilirim?
user39901230

1
linestring, yinelenebilir bir nokta geometrisi koleksiyonudur (tepe noktası), bunlardan ilkine ve sonuna kolayca erişebilirsiniz.
capooti

Çokgen nesnelerini daha sonra bir linestring'in ilk ve son noktasına karşı kontrol etmek için kullanacağım bir listede saklamaya çalıştım. Ancak, bir nedenden dolayı çokgenler içindeki noktalar listesine hiçbir nokta eklenmez: buraya bir göz atın: codepad.org/Cm2BV5mp
user39901230

8

Networkx'e aşina değilim, ancak sorunuzu doğru bir şekilde anladıysam , şekil dosyasından çokgende nokta bulmak için düzgün ve OGR lib'i kullanabilirsiniz . Aşağıda, bir noktanın (2000,1200) bir şekil dosyasından herhangi bir çokgen ile başarısız olup olmadığını bulmak için nasıl çalıştığı bir örnek verilmiştir. Sonuç olarak, bu çokgenin koordinatlarını yazdırır.

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()

Umut ediyorum bu yardım eder.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.