Alan hesap makinesinde başka bir katmana nasıl başvurulur?


26

Çokgen katmanından bir öznitelik seçmenin ve alan hesap makinesinde "içinde" kullanarak bir nokta katmanının sanal alanına eklemenin bir yolu var mı?

CASE
 WHEN within($geometry, geometry_polygon) THEN attribute_polygon
END

görüntü tanımını buraya girin


1
Neden bunun için 'Nokta örnekleme aracı' eklentisini kullanmıyorsun?
Jakob

Çünkü yeni noktalar oluştururken veya mevcut noktaları taşırken dinamik güncellemelere ihtiyacım var.
Ay Denizi

Kutu dışı araçlara güvenmek yerine bu etkileşimi kodlamaktan daha iyi olurdu.
nagytech

Ne yazık ki, hiçbir komut dosyası deneyimiim yok.
Lunar Sea,

@LunarSea İzlemeniz için aşağıda bir örnek yazdım, ancak gereksinimlerinize uyacak şekilde ince ayar yapmanız gerekebilir.
nagytech

Yanıtlar:


22

RefFunctions eklentisini kurduktan sonra alan hesaplamasında spatial birleşimler mevcut.

geomwithin(targetLayer,targetField)

Eklentiler, özel bir komut dosyası kullanmaktan çok daha kolaydır. Teşekkürler!
jpmc26

geomwithin ( 'targetLayer', 'targetField').
Raja

19

Kutudan çıkan alan hesap makinesi özellik katmanları arasındaki uzamsal birleşmeleri desteklemez. Ancak, NathanW'nin qgis ifadeleri için fonksiyon düzenleyicideki yazısına bakarsanız, kendi veri etkileşimimizi kodlayabileceğimizi ortaya çıkarabilirsiniz.

Aşağıdaki komut dosyası neyin peşinde olduğunuzu ifade etmenizi sağlayacaktır. Çokgen katmanındaki tüm özellikler boyunca yinelenerek çalışır ve uzamsal birleştirme varsa, o zaman belirtilen sütundan tablo verilerini referans alın:

from qgis.core import *
from qgis.gui import *
from qgis.utils import iface

allfeatures = None
index = QgsSpatialIndex()
indexMade = 0
refLayer = None

@qgsfunction(args="auto", group='Custom')
def spatialJoinLookup(layerName, refColumn, defaultValue, geom, feature, parent):

    if geom is None:
        return defaultValue

    # globals so we don't create the index, refLayer more than once
    global allfeatures
    global index
    global indexMade
    global refLayer

    # Get the reference layer
    if refLayer is None:
        for layer in iface.mapCanvas().layers():
            if layerName == layer.name():
                refLayer = layer
                break
    if refLayer is None:
        raise Exception("Layer [" + layerName + "] not found")

    # Create the index if not exists
    if indexMade == 0:
        index = QgsSpatialIndex()
        allAttrs = layer.pendingAllAttributesList()
        layer.select(allAttrs)
        allfeatures = {feature.id(): feature for (feature) in refLayer.getFeatures()}
        for f in allfeatures.values():
            index.insertFeature(f)
        indexMade = 1

    # Use spatail index to find intersect 
    fid = None
    ids = index.intersects(geom.boundingBox())
    for id in ids:
        fid = id
        break # Only get the first match.
    if fid is not None:
        return allfeatures[fid].attribute(refColumn)

    # Default
    return defaultValue

Poligon Katmanı Örneği

Aşağıda sahip olabileceğiniz çokgen bir katman örneği verilmiştir. Ayrıca, son resimde göreceğiniz karşılık gelen bir nokta katmanı oluşturdum.

görüntü tanımını buraya girin

İfade Kullanımı

Ayrı bir sütun kullanmak istiyorsanız, ikinci argümanı çokgen veri kümesindeki sütun adıyla eşleştirmek için değiştirmeniz gerektiğini unutmayın. Örneğin, 'AreaNumber' sütununu kullanabilirsiniz, ancak alan hesap makinesi ayarlarındaki sütun türüyle eşleşmesi gerekir.

görüntü tanımını buraya girin

Sonuç

Mekansal birleşim olmadığında varsayılan sütun değerinin uygulandığını ve diğerinin doğru verileri eşleştiğini görebilirsiniz. Verdiğim komut dosyasının yalnızca ilk eşleşmeye katılacağını unutmayın . Çokgenlerinizin üst üste gelmesi durumunda başka bir işletme mantığı yaratmanız gerekir.

görüntü tanımını buraya girin


Çok teşekkürler, betiğiniz ilk 'if' ifadesinde 'geometri' yerine 'geom' kullanarak çalışıyor. Geometrilerin bu şekilde birleştirilmesi, örneğin çokgenler üzerinde birden fazla etiket oluşturmak için oldukça yararlı olabilir.
Ay Denizi

Üzgünüm, bunu nasıl özlediğimi bilmiyorum. Umarım performans sorunu yoktur - yalnızca çok küçük bir kayıt alt kümesiyle denedim.
nagytech

Sadece 100+ puan özelliğine sahip olmak, QGIS performans sorunları ile mücadele ediyor. Yeni bir nokta özelliği eklemek, acutal tuvalinde görüntülenen hiçbir nokta özelliği olmasa da gerçekten bir acıdır. Aksi takdirde, QGIS yakınlaştırıldığında hızlanır. Ben $ ölçek <10000 sonra spatialJoinLookupI ('Çokgenler', 'AlanAdı', 'Yok', $ geometri) SONUYLA OLDUĞUMU 'CASE'i denedik ama işe yaramadı. Performansı arttırmak için yapabileceğim bir şey var mı?
Lunar Sea

@LunarSea Bir uzamsal dizin kullanmak için işlevi güncelledik. Oldukça hızlı olmalı.
nagytech

Yardımın için teşekkürler. Mekansal katılım şimdi çok daha hızlı ama maalesef bir şey düzgün çalışmıyor. Bir ve aynı poligondaki noktalar için farklı sonuçlar alıyorum.
Lunar Sea

8

Fonksiyonlu Alan Hesaplayıcıda yapılabilir aggregate(). Point katmanında şöyle bir alan hesap makinesi ifadesi ile yeni alan oluşturun:

aggregate(
layer:= 'polygon_layer_name',
aggregate:='concatenate',
expression:=joining_field_name,
concatenator:=', ',
filter:=intersects($geometry, geometry(@parent))
)

Nerede layerpoligon katman adı dizesi gibi yazılır, aggreagate(vb özetlemek de kullanılabilir) toplama işlevi olduğunu expressiondeğerlerinden alan, alınacak olan concatenatorkarakter dizesini katılıyor (hatta bu durumda, set olmak zorunda) ve filteresaslı özellikler filtrelediğini ifadesinde (bu durumda katman geometrisini üst katman geometrisi ile ilişkilendirir).

Daha fazla bilgi için, Toplama QGIS belgelerine bakın .

Otomatik güncellemeler için kullanılabilecek sanal alanlar ya gibi ifadeyi ayarlayabilirsiniz Varsayılan değer içinde Öznitelikler'in Form ayarları Katman Özellikleri ( Özellik formu ayar belgelerine ).

görüntü tanımını buraya girin


2
Mekansal işlevlerin (birlikte geometry(@parent)) yalnızca QGIS 3'ten itibaren desteklendiğine dikkat edilmelidir . Sadece bunu okuyan birinin hala 2.18 kullanıyor olması durumunda ...
she_weeds,

Teşekkür ederim. ÇALIŞIYOR bir cazibe gibi.
spatialthoughts
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.