Teilen Sie ein Feature, wenn Sie es mit PyQGIS / Python mit einem Feature einer anderen Ebene schneiden?

12

Ich habe eine Pufferebene (grünes Polygon), die ich auf zwei Polygone aufteilen möchte, wenn sie eine Barriere überschreitet (blaue Linie). Ich habe versucht, "splitGeometry" -Methode zu verwenden, aber ich kann es einfach nicht zum Laufen bringen. Mein bisheriger Code lautet:

while ldbuffprovider.nextFeature(feat):
  while barprovider.nextFeature(feat2):
    if feat.geometry().intersects(feat2.geometry()):
        intersection = feat.geometry().intersection(feat2.geometry())
        result, newGeometries, topoTestPoints=feat.geometry().splitGeometry(intersection.asPolyline(),True) 

Dies gibt 1 für das Ergebnis (Fehler) und eine leere Liste für newGeometries zurück. Jede Hilfe wird sehr geschätzt.

Bildbeschreibung hier eingeben

Alex
quelle
1
Vielleicht hilft dir dieser hier: gis.stackexchange.com/questions/66543/erase-method-using-ogr
Michalis Avraam

Antworten:

7

Hierfür können Sie die reshapeGeometryFunktion des QgsGeometryObjekts verwenden, das ein Polygon entlang seines Schnittpunkts mit einer Linie schneidet.

Das Folgende schneidet die Pufferpolygone mit den Linien und fügt die geteilten Polygon-Features einer Speicherebene hinzu (QGIS 2.0-Syntax):

# Get the dataProvider objects for the layers called 'line' and 'buffer'
linepr = QgsMapLayerRegistry.instance().mapLayersByName('line')[0].dataProvider()
bufferpr = QgsMapLayerRegistry.instance().mapLayersByName('buffer')[0].dataProvider()

# Create a memory layer to store the result
resultl = QgsVectorLayer("Polygon", "result", "memory")
resultpr = resultl.dataProvider()
QgsMapLayerRegistry.instance().addMapLayer(resultl)


for feature in bufferpr.getFeatures():
  # Save the original geometry
  geometry = QgsGeometry.fromPolygon(feature.geometry().asPolygon())
  for line in linepr.getFeatures():
    # Intersect the polygon with the line. If they intersect, the feature will contain one half of the split
    t = feature.geometry().reshapeGeometry(line.geometry().asPolyline())
    if (t==0):
      # Create a new feature to hold the other half of the split
      diff = QgsFeature()
      # Calculate the difference between the original geometry and the first half of the split
      diff.setGeometry( geometry.difference(feature.geometry()))
      # Add the two halves of the split to the memory layer
      resultpr.addFeatures([feature])
      resultpr.addFeatures([diff])

Jake
quelle
1
Das funktioniert hervorragend. Ich habe zuerst die andere Lösung ausprobiert und es hat funktioniert, also gab es das Kopfgeld dafür, noch bevor ich ur ans las. Diese Lösung ist absolut perfekt und passt besser zu meinem Skript. Entschuldigung dafür: /
Alex
Hehe, kein Problem! Froh, dass es hilft!
Jake
Ich stimme deiner Antwort zu, weil sie perfekt funktioniert, während meine nur eine Annäherung ist. @PeyMan Danke für die Prämie, aber es gab keine Antworten außer meinen, als der Wert der Prämie endete. Bessere Lösungen sind immer willkommen.
Antonio Falciano
Gibt es eine Möglichkeit, alle Polygone einer bestimmten Ebene zu teilen?
Muhammad Faizan Khan
Ich habe eine einzelne Ebene und es gibt mehrere Polygone, die ich durch Codierung
teilen
2

Eine gute Annäherung mit GDAL> = 1.10.0, die mit SQLite und SpatiaLite kompiliert wurde, besteht darin, Ihre Layer (z. B. poligon.shp und line.shp ) in eine OGR-VRT-Datei (z. B. layers.vrt ) zu packen :

<OGRVRTDataSource>
    <OGRVRTlayer name="buffer_line">
        <SrcDataSource>line.shp</SrcDataSource>
        <SrcSQL dialect="sqlite">SELECT ST_Buffer(geometry,0.000001) from line</SrcSQL>
    </OGRVRTlayer>
    <OGRVRTlayer name="polygon">
        <SrcDataSource>polygon.shp</SrcDataSource>
    </OGRVRTlayer>
</OGRVRTDataSource>

um einen sehr kleinen Puffer (zB 1 Mikron) um line.shp zu haben , der die * buffer_line * Schicht erhält. Dann können wir mit SpatiaLite symmetrische Differenzen und Differenzen auf diese Geometrien anwenden:

ogr2ogr splitted_polygons.shp layers.vrt -dialect sqlite -sql "SELECT ST_Difference(ST_SymDifference(g1.geometry,g2.geometry),g2.geometry) FROM polygon AS g1, buffer_line AS g2" -explodecollections

Offensichtlich ist all dieses Zeug perfekt von einem Python-Skript ausführbar:

os.system("some_command with args")

Hoffe das hilft!

Antonio Falciano
quelle
@Jake reshapeGeometry gibt einen unbekannten Ausnahmefehler aus. Gibt es eine andere Möglichkeit, den Schnittpunkt zwischen Polygon und Polylinie zu überprüfen?
Benutzer99