QGIS kullanarak başka bir vektör çokgen katmanı ile çakışan>% 90'ın üzerinde programlı olarak çokgen bulmak?


9

Örnek katmanlar

Nasıl başka bir vektör tarafından>% 90 ile örtüşen bir vektör çokgenler ayıklamak için python kullanmayı anlamaya çalışıyorum. Daha sonra sadece bu çokgenleri gösterecek bir vektör / haritaya sahip olmak istiyorum. Örnek resim katmanlarımı göstermektedir. % 90'dan fazla kırmızı olan tüm gri çokgenleri istiyorum.

Bunu tüm python (veya benzer şekilde otomatik yöntemler) üzerinden yapmam gerekiyor. Aynı şekilde işlemek için ~ 1000 haritam var.


Bir bindirme 'birliği' yapmak istiyorsunuz ( bazı temel bilgiler için infogeoblog.wordpress.com/2013/01/08/geo-processing-in-qgis adresine bakın ), ardından her orijinal çokgen için 'giriş' istatistiklerini ve 'çıkış' istatistiklerini hesaplayın kaplama yüzdesini belirlemek için gis.stackexchange.com/questions/43037/… ... ipucu: bir alan ölçümüne ihtiyacınız var gis.stackexchange.com/questions/23355/…
Michael Stimson

İpuçları için teşekkürler. Bu sadece denediğim yaklaşımla aynı. Sendikayı python konsolu üzerinden yeterince kolay yapabilirim. Alan özelliği değerlerine zaten eklenmiş. Emin olmadığım bir sonraki adım. % 90 çokgenleri tanımlayabilmem / seçebilmem / seçebilmem için 'giriş' ve 'çıkış' istatistiklerini hesaplamak için python'u nasıl kullanabilirim?
dnormous

Bence piton olmadan bu mümkün. Mutlak bir python'a mı ihtiyacınız var yoksa sanal katmanlara sahip bir çözüm sizin için iyi mi?
Pierma

'Giriş' alanları her iki çokgenden özniteliklere sahip olacak, 'çıkış' alanları yalnızca bir çokgen kümesinden özniteliklere sahip olacak. Her iki alan istatistik kümesini alın ve orijinal çokgenlere tekrar katılın, 'in', 'out' ve kapsama alanı ekleyin, 'in' ve 'out' değerlerini alanların toplamından hesaplayın ve ardından 'in' yüzdeyi hesaplamak için orijinal alan (veya '+' çıkış ').
Michael Stimson

1
Pierma - Çokgenleri bulmak için otomatik bir yönteme ihtiyacım var.
1616'da

Yanıtlar:


3

Sonraki kod QGIS Python Konsolunda çalışıyor. Çokgenleri olan ve>% 90'ı kırmızı alanlarla örtüşen bir bellek katmanı oluşturur.

mapcanvas = iface.mapCanvas()

layers = mapcanvas.layers()

#for polygon_intersects
feats_lyr1 = [ feat for feat in layers[0].getFeatures() ]

#for xwRcl
feats_lyr2 = [ feat for feat in layers[1].getFeatures() ]

selected_feats = []

for i, feat1 in enumerate(feats_lyr1):
    area1 = 0
    area2 = 0
    for j, feat2 in enumerate(feats_lyr2):
        if feat1.geometry().intersects(feat2.geometry()):
            area = feat1.geometry().intersection(feat2.geometry()).area()
            print i, j, area, feat2.attribute('class')
            if feat2.attribute('class') == 1:
                area1 += area
            else:
                area2 += area
    crit = area1/(area1 + area2)
    print crit
    if crit > 0.9:
        selected_feats.append(feat1)

epsg = layers[0].crs().postgisSrid()

uri = "Polygon?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"

mem_layer = QgsVectorLayer(uri,
                           "mem_layer",
                           "memory")

prov = mem_layer.dataProvider()

for i, feat in enumerate(selected_feats):
    feat.setAttributes([i])

prov.addFeatures(selected_feats)

QgsMapLayerRegistry.instance().addMapLayer(mem_layer)

Bu iki vektör katmanı ile kodu denedim:

resim açıklamasını buraya girin

QGIS Python Konsolunda kodu çalıştırdıktan sonra, destekleyici sonuçlar için i, j ilgili özellikler, kavşak alanları, polygons_intersects'teki alanın niteliği ( gri alanlar için 1 ve gri alanlar için 2) ve çakışan kriter yazdırıldı .

0 0 9454207.56892 1
0 1 17429206.7906 2
0 2 10326705.2376 2
0 4 40775341.6814 1
0 5 26342803.0964 2
0 7 11875753.3216 2
0.432253120382
1 6 1198411.02558 2
1 7 1545489.96614 2
1 10 27511427.9909 1
0.90930850584
2 7 750262.940888 2
2 8 12012343.5859 1
0.941213972294
3 6 23321277.5158 2
0.0

Oluşturulan bellek katmanı (yeşil özellikler) bir sonraki resimde görülebilir. Beklendiği gibi oldu.

resim açıklamasını buraya girin


6

Burada python gerektirmeyen bir çözüm.

Şunun gibi bir sorgu ile yeni bir sanal katman ekleyin:

WITH r AS (
SELECT 
    Basins800.rowid AS idGray, 
    area(Basins800.geometry) AS areaGray, 
    area(Intersection(Basins800.geometry, Severity.geometry)) AS aeraInter, 
    Basins800.geometry AS geomGray 
  FROM Basins800, Severity
)

SELECT *, areaInterSum/areaGray  AS overlap , geomGray 
    FROM (
        SELECT 
           idGray, 
           areaGray, 
           sum(areaInter) AS areaInterSum, 
           geomGray 
        FROM r 
        GROUP BY idGray) 
     WHERE areaInterSum/areaGray > 0.9

İle :

  • Basins800 sizin katman olarak gri çokgenler ile filtre

  • Önem derecesi: kırmızı katmanınız çakışıyor.

Sonuç, üst üste binme yüzdesini içeren yeni bir alanla, yalnızca% 90'dan fazla> tüm gri parsellerin kırmızı çokgenlerle örtüştüğü yeni bir katman olacaktır.

resim açıklamasını buraya girin

Umarım bu işe yarar. Gerekirse sorguya daha fazla ayrıntı ekleyebilirim.

Not: Verileriniz çok küçük çokgenler içerir (tarama işleminizden gelir ve bir tarama pikseline karşılık gelir (resimde 4 çokgen görebiliriz, ancak 25 küçük çokgen daha vardır). iki katmandan her özellik çifti için bir özellik oluşturur).


'Sanal katman oluştur' düğmesi aracılığıyla sorguyu çalıştırdığımda bir hata alıyorum. CREATE TEMP VIEW _tview üzerinde sorgu yürütme hatası AS WITH r AS (".... burada kodun geri kalanı ... ardından:" 1 - near "WITH": sözdizimi hatası "QGIS için oldukça yeniyim. programlama yoluyla bu sanal katman oluşturmak teşekkürler yardımınız için?!
dnormous

İşte shapefiles indirmek için bir bağlantı: bağlantı
dnormous

Maalesef, gri ve gri arasında kötü bir kopya (yaklaşık İngilizcem için özür dilerim). Sorguyu düzenledim. Şimdi çalışmalı. Katmanı neden programla oluşturmak istiyorsunuz? Sanal katmanın avantajları, tahribatsız olmasıdır ve verilerinizi (gri veya kırmızı çokgenler) düzenlerseniz, sanal katman otomatik olarak güncellenir.
Pierma

Bu, sürecin sadece küçük bir parçası. Bu haritaların ~ 1000'i var, bu yüzden işlemi otomatikleştirmek son derece yararlı olacaktır.
1616'da

Hala aynı hatayı alıyorum -> "1 - yakın" WITH ": sözdizimi hatası". Her katman için yerel adları grayLayer ve redLayer için ekledim. Yerel ad kullanmam gereken şey mi? yani: gri katman "Basins_800" olarak etiketli, bu yüzden "Basins_800.geometry" gibi bir kod var
4

2

Gördükten sonra bağlantıyı için Önem ve Basins800 shapefiles, ben gerekli Geoprocess anlayabildim. Kodu değiştirdim:

QGIS kullanarak başka bir vektör çokgen katmanı ile çakışan>% 90'ın üzerinde programlı olarak çokgen bulmak?

bunu almak için:

mapcanvas = iface.mapCanvas()

layers = mapcanvas.layers()

#for Severity
feats_lyr1 = [ feat for feat in layers[0].getFeatures() ]

#for Basins800
feats_lyr2 = [ feat for feat in layers[1].getFeatures() ]

selected_feats = []

print "processing..."

for i, feat1 in enumerate(feats_lyr1):
    for j, feat2 in enumerate(feats_lyr2):
        if feat1.geometry().intersects(feat2.geometry()):
            area1 = feat1.geometry().intersection(feat2.geometry()).area()
            area2 = feat1.geometry().area()
            print i, j, area1, area2
    crit = area1/area2
    print crit
    if crit > 0.9:
        selected_feats.append(feat1)

epsg = layers[0].crs().postgisSrid()

uri = "Polygon?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"

mem_layer = QgsVectorLayer(uri,
                           "mem_layer",
                           "memory")

prov = mem_layer.dataProvider()

for i, feat in enumerate(selected_feats):
    feat.setAttributes([i])

prov.addFeatures(selected_feats)

QgsMapLayerRegistry.instance().addMapLayer(mem_layer)

Kodu çalıştırdıktan sonra, QGIS Python Konsolunda bu şekil dosyaları ile birkaç dakika içinde Pierma ile benzer bir sonuç aldım ; burada bellek katmanının 31 özelliği vardı (29 çokgenden farklı).

resim açıklamasını buraya girin

Sonuçlar için hata ayıklamayacağım çünkü 1901 * 3528 = 6706728 özellikler için etkileşimler var. Ancak, kod umut verici görünüyor.

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.