Dividere una funzione quando si interseca con una funzione di un altro livello usando PyQGIS / Python?


12

Ho uno strato buffer (poligono verde) che voglio dividere in due poligoni ogni volta che attraversa una barriera (linea blu). Ho provato a usare il metodo "splitGeometry", ma non riesco proprio a farlo funzionare. Il mio codice finora è questo:

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) 

Che restituisce 1 per risultato (errore) e un elenco vuoto per newGeometries. Qualsiasi aiuto è molto apprezzato.

inserisci qui la descrizione dell'immagine


Risposte:


7

È possibile utilizzare la reshapeGeometryfunzione QgsGeometrydell'oggetto per questo, che taglia un poligono lungo la sua intersezione con una linea.

Quanto segue intersecherà i poligoni del buffer con le linee e aggiungerà le funzioni del poligono diviso a un livello di memoria (sintassi QGIS 2.0):

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


1
Funziona alla grande. Ho provato prima l'altra soluzione e ha funzionato, quindi ho dato la grazia per quello ancora prima di leggere il tuo messaggio. Questa soluzione è assolutamente perfetta e si adatta meglio alla mia sceneggiatura. scusatemi per questo: /
Alex

Hehe, nessun problema! Sono contento che aiuti!
Jake,

Ho votato a favore della tua risposta perché funziona perfettamente, mentre la mia è solo un'approssimazione. @PeyMan Grazie per la generosità, ma non ci sono state risposte tranne la mia quando il valore della grazia è finito. Le soluzioni migliori sono sempre benvenute.
Antonio Falciano,

c'è un modo per dividere tutti i poligoni di un livello specifico?
Muhammad Faizan Khan,

Ho un singolo strato e ci sono più poligoni che voglio dividere attraverso la codifica
Muhammad Faizan Khan

2

Una buona approssimazione con GDAL> = 1.10.0 compilato con SQLite e SpatiaLite consiste nell'avvolgere i livelli (ad es. Poligon.shp e line.shp ) in un file VRT OGR (ad esempio layers.vrt ):

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

per avere un buffer molto piccolo (ad esempio 1 micron) attorno a line.shp ottenendo il livello * buffer_line *. Quindi, possiamo applicare la differenza simmetrica e la differenza su queste geometrie usando SpatiaLite:

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

Ovviamente, tutte queste cose sono perfettamente eseguibili da uno script Python:

os.system("some_command with args")

Spero che sia di aiuto!


@Jake reshapeGeometry sta generando un errore sconosciuto di eccezione. Esiste un altro modo per verificare l'intersezione tra poligono e polilinea?
user99

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.