Розщеплення файлу форм на одну функцію в Python за допомогою GDAL?


15

чи можна розділити файл форми на особливість у python? (найкраще було б рішення, де я можу тимчасово зберегти отримані векторні об'єкти в пам'ять, а не на диск).

Причина: я хочу використовувати функцію gdal rasterizeLayer з кількома різними підмножинами shapefile. Для функції потрібен об'єкт osgeo.ogr.Layer.


гаразд, я спробував трохи навколо, і це могло працювати наступним чином. Ви можете отримати геометрію об’єктів шару gdal за функцією наступним чином.

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

Тепер мені просто потрібно знати, як створити об'єкт osgeo.ogr.layer на основі цієї геометрії.


Для уточнення. Мені потрібна функція в простому коді ogr / gdal! Це, здається, викликає інтерес і для інших людей, і я все ще хочу рішення без будь-яких вторинних модулів (хоча будь-яке рішення, що надходить звідси, буде використовуватися у вільному доступному плагіні qgis).

Відповіді:


7

Гаразд, друга спроба відповісти на ваше запитання чистим рішенням GDAL.

По-перше, GDAL (бібліотека абстракції геопросторових даних) спочатку була лише бібліотекою для роботи з растровими геопросторовими даними, тоді як окрема бібліотека OGR призначена для роботи з векторними даними. Однак дві бібліотеки тепер частково об'єднані і загалом завантажуються та встановлюються разом під комбінованою назвою GDAL. Тож рішення дійсно підпадає під ОГР. Ви маєте це у своєму початковому коді, так що, мабуть, ви це знали, але це важлива відмінність, яку слід пам’ятати, шукаючи поради та підказки.

Щоб читати дані з векторного шару, ви добре використовуєте початковий код:

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

Нам потрібно створити нову функцію, перш ніж ми зможемо записати її у файл форми (або будь-який інший набір векторних даних). Щоб створити нову функцію, нам спочатку потрібно: - Геометрія - визначення функції, яке, ймовірно, включатиме визначення полів. Використовуйте конструктор Geometry ogr.Geometry () для створення порожнього об’єкта Geometry. Визначте, що таке геометрія по-різному для кожного типу (точка, лінія, багатокутник тощо). Так, наприклад:

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

або

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

Для визначення поля

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

Тепер ви можете створити свій векторний шар. У цьому випадку квадратний багатокутник:

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

дякую Ден! Я застосував інший підхід, і мій QGIS-плагін вже функціонує (щодо просторових запитів растрових даних). Замість розбиття я створив підмножину базового растру. Ви можете знайти випадок використання в моєму блозі ( tinyurl.com/cy6hs9q ). Ваша відповідь вирішує початкове запитання, якщо я хочу розділити та тимчасово зберегти векторні функції.
Curlew

5

Мені пощастило читати і писати на шари. Зокрема, у мене є код, який буде читати шар формату, що містить полілінії та виводить геометрію кожної функції до текстових файлів (використовується як вхід для старої моделі).

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...

Здається, це може бути корисним для отримання кожної функції у ваших шарів.

Написання на інший шар не повинно бути надто складним звідси. Щось подібне повинно працювати теоретично:

# 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")

Звідси ви маєте змогу отримувати дані про кожну функцію та писати нові функції на новий шар.

Ден


ей, спасибі Частини вашого коду будуть корисні, якщо я хочу написати атрибути моїх фігур. Однак, як я вже згадував вище, я використовую лише gdal (конкретно, gdal.RasterizeFunction), і якщо хтось не знає, як перетворити об'єкт QgsVectorLayer в об’єкт gdal і навпаки, це питання все ще не вирішено.
Curlew

Ви не згадали, що вам потрібно це робити з QGIS. ваш початковий приклад представляється простою ванільною огр.
DavidF

Я хочу це зробити в QGIS (мені це потрібно як функція для плагіну QGIS), але не покладаючись на модулі QGIS.core. Тому мені потрібне рішення в простому огр. Ден відповів, бо в іншому дописі я згадав, що цей код призначений для плагіну QGIS.
Curlew
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.