GDAL kullanarak Python'da özellik başına şekil dosyası bölünüyor mu?


15

bir şekil dosyasını python'da bölmek mümkün mü? (en iyisi geçici olarak elde edilen vektör nesnelerini diske bellek yerine belleğe kaydedebileceğiniz bir çözüm olacaktır).

Nedeni: gdal rasterizeLayer işlevini birkaç farklı şekil dosyası alt kümesiyle kullanmak istiyorum. İşlev bir osgeo.ogr.Layer nesnesi gerektirir.


mkay, biraz denedim ve aşağıdaki gibi çalışabilir. Özellik başına gdal katmanı nesnelerinin geometrisini aşağıdaki gibi alabilirsiniz.

#  Load shape into gdal
shapefile=str(vectorPath)
layer_source = ogr.Open(shapefile)
lyr = layer_source.GetLayer(0)
for i in range(0,lyr.GetFeatureCount()):
     feat = lyr.GetFeature(i)
     ge = feat.geometry()

Şimdi sadece bu geometriye dayalı bir osgeo.ogr.layer nesnesi oluşturmak için bilmek gerekir.


Netleştirmek adına. Düz ogr / gdal kodunda bir işleve ihtiyacım var! Bu da diğer insanlar için bazı ilgi çekici gibi görünüyor ve ben hala herhangi bir ikincil modüller olmadan bir çözüm istiyorum (buradan gelen herhangi bir çözüm ücretsiz kullanılabilir qgis eklentisinde kullanılacak olsa da).

Yanıtlar:


7

Tamam, sorunuzu saf bir GDAL çözümü ile cevaplamak için ikinci bir girişim.

İlk olarak, GDAL (Jeo-Uzamsal Veri Soyutlama Kütüphanesi) başlangıçta sadece raster coğrafi-uzamsal verilerle çalışmak için bir kütüphane iken, ayrı OGR kütüphanesinin vektör verileriyle çalışması amaçlanmıştır. Bununla birlikte, iki kütüphane şimdi kısmen birleştirilmiştir ve genellikle GDAL'ın birleşik adı altında indirilir ve kurulur. Bu yüzden çözüm gerçekten OGR'nin altına düşüyor. İlk kodunuzda bu var, bu yüzden bunu biliyordum ama ipuçları ve ipuçları ararken hatırlamak önemli bir ayrım.

Bir vektör katmanından veri okumak için ilk kodunuz iyidir:

from osgeo import ogr
shapefile = ogr.Open(shapefile)
layer = shapefile.GetLayer(0)

for i in range(layer.GetFeatureCount()):
    feature = layer.GetFeature(i)
    name = feature.GetField("NAME")
    geometry = feature.GetGeometryRef()
    print i, name, geometry.GetGeometryName()

Bir şekil dosyasına (veya başka bir vektör veri kümesine) yazmadan önce yeni bir özellik oluşturmamız gerekir. Yeni bir özellik oluşturmak için öncelikle şunlara ihtiyacımız vardır: - Bir geometri - Büyük olasılıkla alan tanımlarını içerecek bir özellik tanımı Boş bir Geometri nesnesi oluşturmak için Geometry yapıcısı ogr.Geometry () öğesini kullanın. Her bir tür için (nokta, çizgi, çokgen vb.) Geometrinin ne olduğunu tanımlayın. Yani mesela:

point = ogr.Geometry(ogr.wkbPoint)
point.AddPoint(10,20)

veya

line = ogr.Geometry(ogr.wkbLineString)
line.AddPoint(10,10)
line.AddPoint(20,20)
line.SetPoint(0,30,30) #(10,10) -> (30,30)

Alan tanımı için

fieldDefn = ogr.FieldDefn('id', ogr.OFTInteger)

Artık vektör katmanınızı oluşturabilirsiniz. Bu örnekte, bir kare çokgen:

#create simple square polygon shapefile:
from osgeo import ogr
driver = ogr.GetDriverByName('ESRI Shapefile')

datasource = driver.CreateDataSource('YOUR_PATH')
layer = datasource.CreateLayer('layerName',geom_type=ogr.wkbPolygon)

#create polygon object:
myRing = ogr.Geometry(type=ogr.wkbLinearRing)
myRing.AddPoint(0.0, 0.0)     #LowerLeft
myRing.AddPoint(0.0, 10.0)    #UpperLeft
myRing.AddPoint(10.0, 10.0)   #UpperRight
myRing.AddPoint(10.0, 0.0)    #Lower Right
myRing.AddPoint(0.0, 0.0)     #close ring
myPoly = ogr.Geometry(type=ogr.wkbPolygon)
myPoly.AddGeometry(myRing)
print ('Polygon area =',myPoly.GetArea())  #returns correct area of 100.0

#create feature object with point geometry type from layer object:
feature = ogr.Feature( layer.GetLayerDefn())
feature.SetGeometry(myPoly)
layer.CreateFeature(feature)

#flush memory - very important
feature.Destroy()
datasource.Destroy()

teşekkürler Dan! Farklı bir yaklaşım izledim ve QGIS-eklentim zaten işlevsel (raster verilerinin uzamsal sorguları ile ilgili). Bölmek yerine, altta yatan raster alt kümesi oluşturdum. Blogumda bir kullanım durumu bulabilirsiniz ( tinyurl.com/cy6hs9q ). Vektör özelliklerini bölmek ve geçici olarak kaydetmek istiyorsanız, cevabınız orijinal soruyu çözer.
Curlew

5

Katmanlardan okuma ve yazma konusunda biraz şansım oldu. Özellikle, çoklu çizgiler içeren bir şekil dosyası katmanı okuyacak ve her özelliğin geometrisini metin dosyalarına (eski bir model için girdi olarak kullanılan) çıktılayacak kodum var.

name     = layer.name()
provider = layer.dataProvider()
feat     = QgsFeature()

# Now we can loop through all the defined features
while provider.nextFeature(feat):

    # Get layer attributes               
    attrs = feat.attributeMap()
    for (k,attr) in attrs.iteritems():
        if k == 0:
            attrOne = attr.toString()
        elif k == 1:
            attrTwo = attr.toString()
        ...

    # Gets the geometry of the feature
    geom = feat.geometry()

    # Get the coordinates of the whole line [or use asPoint()]                    
    line = geom.asPolyline()
        # all points in the line
        for point in line:
            lat = point[0]
            lon = point[1]
            # Add these to a QgsGeometry
            your_Own_QgsGeometry.add...

Bu, katmanlarınızın her bir özelliğini almanın yararlı olabileceği anlaşılıyor.

Başka bir katmana yazmak buradan çok karmaşık olmamalıdır. Böyle bir şey teoride çalışmalıdır:

# New layer name
filename = "myNewLayer.shp"

# define fields for feature attributes
fields   = { 0 : QgsField("attrOne", QVariant.String),
             1 : QgsField("attrTwo", QVariant.String),
             2 : QgsField("...", QVariant.Int) }

# Create coordinate reference system as WGS84
crs    = QgsCoordinateReferenceSystem(4326, QgsCoordinateReferenceSystem.PostgisCrsId)

# Create the vector layer
writer = QgsVectorFileWriter(filename, "CP1250", fields, QGis.WKBLineString, crs)

# Create some features
feat = QgsFeature()
feat.addAttribute(0, QVariant(runway))
feat.addAttribute(1, QVariant(arriveDepart))
feat.addAttribute(2, QVariant(subTrack))

# Add your geometry
feat.setGeometry(your_Own_QgsGeometry)

# Add the features
writer.addFeature(feat)

# Add it to QGIS project
self.iface.addVectorLayer(filename, "MyLayerName", "ogr")

Buradan her bir özelliğin verilerini alabilir ve yeni bir katmana yeni özellikler yazabilirsiniz.

Dan


Hey teşekkürler. Şekillerime nitelikler yazmak isterseniz, kodunuzun bazı bölümleri yararlı olacaktır. Ancak yukarıda belirttiğim gibi ben sadece gdal kullanıyorum (özellikle gdal.RasterizeFunction) ve birisi bir QgsVectorLayer nesnesini gdal nesnesine dönüştürmeyi bilmedikçe ve tersi, bu soru hala çözülmemiştir.
Curlew

Bunu QGIS ile yapmanız gerektiğini söylemediniz. ilk örneğiniz düz vanilya ogr gibi görünüyor.
DavidF

QGIS bunu yapmak istiyorum (i bir QGIS eklentisi için bir işlev olarak gerekir), ama QGIS.core modülleri dayanmadan. Bu yüzden düz ogr çözüm gerekir. Dan başka bir yazıda bu kodun bir QGIS eklentisi olduğunu belirtti çünkü yanıtladı.
Curlew
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.