PyQGIS / Python kullanarak başka bir katmanın özelliğiyle kesişirken bir özelliği böl?


12

Bir bariyer (mavi çizgi) geçtiğinde iki çokgene bölmek istiyorum bir tampon katman (yeşil çokgen) var. "SplitGeometry" yöntemini kullanmaya çalışıyorum, ama sadece işe alamadım. Kodum şu ana kadar:

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) 

Sonuç için 1 (hata) ve newGeometries için boş bir liste döndürür. Herhangi bir yardım büyük beğeni topluyor.

resim açıklamasını buraya girin


Yanıtlar:


7

Bunun için bir çokgeni bir çizgiyle kesiştiği yerde kesen nesnenin reshapeGeometryişlevini kullanabilirsiniz QgsGeometry.

Aşağıdakiler, arabellek çokgenlerini çizgilerle kesişecek ve bölünmüş çokgen özelliklerini bir bellek katmanına (QGIS 2.0 sözdizimi) ekleyecektir:

# 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
Bu harika çalışıyor. Önce diğer çözümü denedim ve bu yüzden çalıştı ve ur ans okumadan önce bunun için ödül verdi. Bu çözüm kesinlikle mükemmel ve benim senaryom için daha uygun. bunun için üzgünüm: /
Alex

Hehe, sorun değil! Yardım etmekten memnunum!
Jake

Cevabınızı onaylıyorum çünkü mükemmel çalışıyor, benimki ise sadece bir yaklaşım. @PeyMan Ödül için teşekkürler, ama ödül değeri sona erdiğinde benimki dışında cevap yoktu. Daha iyi çözümler her zaman bekleriz.
Antonio Falciano

speicifc katmanının tüm çokgenini bölmenin bir yolu var mı?
Muhammed Faizan Han

Tek bir katmanım var ve onları kodlama yoluyla bölmek istediğim çokgen var
Muhammad Faizan Khan

2

SQLite ve SpatiaLite ile derlenen GDAL> = 1.10.0 ile iyi bir yaklaşım, katmanlarınızı (örneğin poligon.shp ve line.shp ) bir OGR VRT dosyasına (örn. Layers.vrt ) sarmaktan oluşur :

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

* buffer_line * katmanını elde eden line.shp etrafında çok küçük bir tampon (örneğin 1 mikron) olması için. Ardından, SpatiaLite kullanarak bu geometrilere simetrik fark ve fark uygulayabiliriz:

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

Açıkçası, tüm bu şeyler bir Python betiğinden mükemmel bir şekilde yürütülebilir:

os.system("some_command with args")

Bu yardımcı olur umarım!


Jeometri, bilinmeyen bir istisna hatası veriyor.Peki çokgen ve çoklu çizgi arasındaki kesişmeyi kontrol etmenin başka yolu var mı?
kullanici99

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.