Bir şekil dosyasındaki çokgen diğerinin çokgen içindeki yüzdesi


13

Ben bir acemi, bu açık / özür dilerim zaten sorulmuş ve cevap ama hiçbir şey bulamadım.

İki şekil dosyaları var: 1. İngiltere'de 500 küçük bölgeleri olan bir LSOA sınırı olarak bilinen bir ilçe için bir idari sınır katmanı 2. bir sel bölgesi.

İdeal olarak, küçük LSOA bölgelerinden hangisinin sel bölgesi içinde ≥% 50 olduğunu bulmak ve 500 LSOA bölgesinin her biri için evet / hayır veya 1/0 ile sonuçlanmak istiyorum.

Ama bunu nasıl yapacağımı bilmiyorum. İki şekil dosyasına katılabileceğimi düşündüm, ancak aralarında ortak bir özellik yok. Daha sonra, sel bölgesinde hangi LSOA'nın bulunduğunu gösteren ve bana göre gösterilen Özelliğe Göre Katıl Özelliği işlevini kullanabileceğimi düşündüm, ancak neredeyse hepsi bu (bkz. Resim 2).

Bu bir SQL sorunu olduğunu düşünüyorum ama bilmiyorum. QGIS'te yeniyim ve hiç PostgreSQL kullanmadım.

Herhangi bir yardım büyük mutluluk duyacağız. Güzel insanların bana yardım etmek için ihtiyaç duydukları bilgileri sağlayabilirim.

resim açıklamasını buraya girin

resim açıklamasını buraya girin

Yanıtlar:


12

Bu, QGIS'de bulunan coğrafi işlem araçlarını kullanan nispeten basit bir görevdir.

  1. LSOA bölgelerinizin alanını hesaplayın.

    • LSOA katmanı öznitelik tablosunu açın.
    • Düzenleme modunu etkinleştirin.
    • Alan hesap makinesini açın.
    • "$ Area" ifadesi ile "Ondalık sayı (gerçek)" türünde yeni bir alan oluşturun.
    • Düzenleme modunu devre dışı bırakın (düzenlemeleri kaydedin).
  2. Taşkın bölgesi katmanını tek bir çok parçalı özelliğe birleştirin.

    • Vector > Geometry Tools > Singleparts to Multipart.
    • Benzersiz Kimlik alanı için "--- Tümünü birleştir ---" seçeneğini belirleyin.
  3. LSOA bölge katmanını çok parçalı sel bölgesi katmanıyla kesiştirin.

    • Vector > Geoprocessing Tools > Intersect.
    • Giriş katmanı LSOA bölgeleridir, kesişen katman taşkın bölgeleridir.
  4. Ortaya çıkan katman, sel alanları katmanıyla örtüşen LSOA bölgelerinin (LSOA bölgeleri katmanındaki özniteliklerle) parçaları olacaktır. Taşkın bölgesi içindeki her LSOA bölgesinin oranını hesaplamak için:

    • Kesişen özelliklerin alanını hesaplayın (1. adımdaki gibi), ardından
    • Orijinal (toplam) alanı kesişen alana bölerek başka bir alan ekleyin. Sonuç, 0 ile 1 arasında bir ondalık sayıdır. Yüzde vermek için 100 ile çarpın.
  5. Her iki katmanın paylaştığı benzersiz kimliği kullanarak orijinal LSOA katmanını kesişen katmana birleştirin.

  6. Birleştirilen katmanı yeni bir şekil dosyası olarak dışa aktarın.

  7. Çoğaltılan öznitelikleri silin.

Et voilà!

Adım # 2 olmadan, her LSOA özelliği için her farklı taşkın bölgesi özelliği için ayrı bir özellik oluşturulacaktır. Her LSOA bölgesi için yalnızca toplam kapsama alanı ile ilgileniyorsanız, bu muhtemelen istediğiniz bir şey değildir. Fluvial / tidal / pluvial sel arasında ayrım yapmak istiyorsanız (ve sel bölgesi verileri bunu destekliyorsa), singlepart s'yi "IDPE" alanını Unique ID alanı olarak belirten multipart'a dönüştürebilirsiniz.


Yardımın için teşekkürler! Çok takdir etmek. Ancak, bazı sorunlar yaşıyorum. Adımları takip ettim. Adım 3, Kesişim, tamamlanması 10 saat sürdü ve tamamlandığında boş bir şekil dosyasıydı : i.imgur.com/QIM6Gtg.png Kaçırdığım bir şey var mı? İşlemi tamamlamaya ve 4. adımı yapmaya çalıştım, ancak kesişim alanını hesaplayacak veri yok.
KJGarbutt

Daha önce sel katmanlarıyla kesişme yapmakta sorunlar yaşadım. Özellikleri büyük ve karmaşıktır. Geçmişte bu şekilde çalıştığım yol, onları daha küçük özelliklere ayırmaktır, böylece uzamsal dizin daha fazla iş yapabilir. Bunu yapmak için, taşkın katmanıyla ( Vector > Research Tools > Vector Grid... Output grid as polygons) aynı ölçüde bir vektör ızgarası oluşturun , ardından ızgarayı taşkın katmanıyla kesiştirin. Daha sonra 3. adımda sel katmanı yerine çıktıyı kullanın. Katmanın boş olmasının nedeninin çökmesinden kaynaklandığını tahmin ediyorum.
Snorfalorpagus

Tekrar teşekkürler. Şimdi tek sorun, vektör ızgarasını her oluşturmaya çalıştığımda QGIS'in çökmesi. Buradan tavsiyelere uydum ama her seferinde çöküyor. Parametreleri birden çok kez değiştirdim ve tüm proje dosyamı açmak yerine sadece taşkın bölgesi şekil dosyasını kullanarak denedim ve her seferinde başarısız oldu. Herhangi bir fikir? ! Ekran görüntüsü burada .
KJGarbutt

Belirttiğiniz X ve Y parametreleri çok küçük. 1000 x 1000 gibi bir şey deneyin. Bunu birden çok kez yapabilirsiniz, yani önce 5000 x 5000 yapın, 500 x 500 oluşturmak için çıktıyı kullanın. İlgili cevaba buradan bakın: gis.stackexchange.com/a/66319/12420
Snorfalorpagus

Neredeyse senin yardımınla çatladım! Ancak, kesişen katmanla orijinal LSOA katmanına katıldığımda çok fazla veri kaybediyorum. Bence vektör ızgara karelerinin bazıları aynı LSOA alanına düştüğünden ve her biri ile aynı LSOA koduna sahip olduğu için. Böylece, birleştirme yaptığımda her LSOA alanı için 2+ yüzde rakamları ile sonuçlanıyorum ve bunlardan sadece bir tanesini alıyorum. Aynı LSOA'ya sahip her vektör ızgarası karesi için her bir yüzdeyi toplamanın bir yolu var mı?
KJGarbutt

6

Uzamsal ve bazı uzamsal SQL işlevlerini kullanabilirsiniz.

Select t1.geometry, t1.ID, area(t1.geometry), area(t2.geometry) ...... (anything you need to have in the table results)

(area(intersection(t1.geometry,t2.geometry))) as "Commun_AREA"

, ("Commun_AREA"*100/(area(t1.geometry))) as "Percent_AREA"

From lsoa as t1, flood_zone as t2

Where Intersects( t1.geometry,t2.geometry ) = 1

3

Bu, verilen cevaplardan çok daha kolay yapılabilecek bir şey gibi görünüyor. Şahsen basit bir python betiği kullanırdım:

floodName = "the layer name here"
boundryName = "the layer name here"
fieldName = "the name of the field to contain the output 1/0"
minCoverage = 0.5 # the minimum amount of area covered to write 1
updateMap = [] # this will store values to be written    

# get layers
floodLayer = QgsMapLayerRegistry.instance().mapLayersByName(floodName)[0]
boundryLayer = QgsMapLayerRegistry.instance().mapLayersByName(boundryName)[0]
fieldIndex = boundryLayer.dataProvider().fieldNameIndex(fieldName)    

# iterate through boundries
for b in boundryLayer.getFeatures():
    # get only flood features that intersect with this feature's bounding box
    # this will make the script go way faster than it would otherwise
    request = QgsFeatureRequest().setFilterRect(b.geometry().boundingBox())
    floodGeom = geometry()
    floodFeat = QgsFeature()
    iter = floodLayer.getFeatures(request)
    iter.nextFeature(feat)
    while iter.nextFeature(feat):
        floodGeom = floodGeom.combine(feat.geometry())
    intersectGeom = b.geometry().intersection(feat.geometry())
    if intersectGeom.area() > minCoverage * b.geometry().area():
        updateMap[b.id()] = {fieldIndex : 1}
    else:
        updateMap[b.id()] = {fieldIndex : 0}

boundryLayer.dataProvider().changeAttributeValues(updateMap)

bu, her sınır katmanının sınırlayıcı kutusuyla kesişen taşkın poligonlarını değerlendirir, böylece çalıştırılması oldukça hızlı olmalıdır, daha sonra mevcut katmandaki yalnızca bir alanı günceller (tamamen yeni bir katman oluşturma ve eski değerleri kopyalama karmaşık bir işlem yerine) sonra silme)


2

Adım 3'te "Kesişim" yöntemini kullanarak Snorfalorpagus'un talimatlarını takip eden KJ ile aynı problemi yaşadım Hesaplamak biraz zaman aldı ve neyle kaldığım boştu.

QGIS içinde Intersect yerine "Clip" yöntemini kullanmak dışında aynı adımları izlemeye çalıştım - yani, örneğinizde kalan alanın sel bölgesi tarafından kaplanmayan kısımları olurdu. Bu bir nedenle işe yaramış gibi görünüyordu ve bir önceki adımdan "Alan" alan hesaplamasını ve her bir poligonun geri kalan kısımlarında yeni bir "Alan" hesaplamasını, her alanın% OLMADIĞINI anlamak için kullanabildim diğer Çokgen katmanı ile kaplanmıştır.

Bu teknik olarak istediğin tersi. Ama oradan ne elde etmek 1'den her değerin çıkarılmasından sadece bir meselesi olduğunu taşkın sınırının içindedir.

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.