Membagi fitur ketika berpotongan dengan fitur lapisan lain menggunakan PyQGIS / Python?

12

Saya memiliki lapisan penyangga (poligon hijau) yang ingin saya bagi menjadi dua poligon setiap kali melewati penghalang (garis biru). Saya telah mencoba menggunakan metode "splitGeometry", tetapi saya tidak bisa membuatnya bekerja. Kode saya sejauh ini adalah ini:

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) 

Yang mengembalikan 1 untuk hasil (kesalahan) dan daftar kosong untuk newGeometries. Setiap bantuan sangat dihargai.

masukkan deskripsi gambar di sini

Alex
sumber
1
Mungkin yang ini akan membantu Anda: gis.stackexchange.com/questions/66543/erase-method-using-ogr
Michalis Avraam

Jawaban:

7

Anda dapat menggunakan reshapeGeometryfungsi QgsGeometryobjek untuk ini, yang memotong poligon sepanjang persimpangan dengan garis.

Berikut ini akan memotong poligon penyangga dengan garis, dan menambahkan fitur poligon terpecah ke lapisan memori (sintaksis 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])

Jake
sumber
1
Ini bekerja dengan sangat baik. Saya mencoba solusi lain terlebih dahulu dan itu berhasil sehingga memberi hadiah untuk itu bahkan sebelum saya membaca ans Anda. Solusi ini sangat sempurna dan sesuai dengan skrip saya lebih baik. maaf untuk itu: /
Alex
Hehe, tidak masalah! Senang membantu!
Jake
Saya mengubah jawaban Anda karena itu berfungsi dengan baik, sedangkan jawaban saya hanya perkiraan. @PeyMan Terima kasih atas hadiahnya, tapi tidak ada jawaban kecuali milikku ketika nilai hadiah itu berakhir. Solusi yang lebih baik selalu diterima.
Antonio Falciano
apakah ada cara untuk membagi semua poligon dari lapisan speicifc?
Muhammad Faizan Khan
Saya punya satu layer dan ada banyak poligon yang saya ingin membaginya melalui coding
Muhammad Faizan Khan
2

Perkiraan yang baik dengan GDAL> = 1.10.0 dikompilasi dengan SQLite dan SpatiaLite terdiri dari membungkus lapisan Anda (mis. Poligon.shp dan line.shp ) dalam file OGR VRT (mis. 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>

untuk memiliki buffer yang sangat kecil (mis. 1 mikron) di sekitar line.shp mendapatkan layer * buffer_line *. Kemudian, kita bisa menerapkan perbedaan dan perbedaan simetris pada geometri ini menggunakan 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

Jelas, semua hal ini dapat dieksekusi dengan sempurna dari skrip Python:

os.system("some_command with args")

Semoga ini membantu!

Antonio Falciano
sumber
@Jake reshapeGeometry melemparkan pengecualian kesalahan yang tidak diketahui. Jadi, apakah ada cara lain untuk memeriksa persimpangan antara poligon dan polyline?
user99