Existe uma maneira de selecionar um atributo de uma camada de polígono e inserir o valor no campo virtual de uma camada de pontos usando "dentro" na calculadora de campos?
CASE
WHEN within($geometry, geometry_polygon) THEN attribute_polygon
END
Existe uma maneira de selecionar um atributo de uma camada de polígono e inserir o valor no campo virtual de uma camada de pontos usando "dentro" na calculadora de campos?
CASE
WHEN within($geometry, geometry_polygon) THEN attribute_polygon
END
Respostas:
Junções espaciais estão disponíveis na calculadora de campo após a instalação do plug-in refFunctions.
geomwithin(targetLayer,targetField)
Fora da caixa, a calculadora de campo não suporta junções espaciais nas camadas de recurso. Mas, se você der uma olhada na postagem de NathanW no editor de funções para expressões qgis, poderá concluir que podemos criar um script para nossa própria interação de dados.
O script a seguir permitirá que você expresse o que procura. Ele funciona iterando todos os recursos da camada de polígono e, se houver uma junção espacial, faça referência aos dados tabulares da coluna especificada:
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
Abaixo está um exemplo de uma camada de polígono que você pode ter. Também criei uma camada de pontos correspondente que você verá na imagem final.
Observe que, se você quiser usar uma coluna separada, altere o segundo argumento para corresponder ao nome da coluna no conjunto de dados do polígono. Por exemplo, você poderia usar a coluna 'AreaNumber', mas precisaria corresponder ao tipo da coluna nas configurações da calculadora de campo.
Você pode ver que o valor padrão da coluna foi aplicado onde não há junção espacial e os outros corresponderam aos dados corretos. Observe que o script que eu forneci entrará apenas na primeira partida. Você precisaria criar alguma outra lógica comercial se seus polígonos estivessem sobrepostos.
Isso pode ser feito em Calculator campo com a função aggregate()
. Na camada de ponto, crie um novo campo com a expressão da calculadora de campo como esta:
aggregate(
layer:= 'polygon_layer_name',
aggregate:='concatenate',
expression:=joining_field_name,
concatenator:=', ',
filter:=intersects($geometry, geometry(@parent))
)
Onde o layer
nome da camada de polígono é escrito como string, aggreagate
é a função agregada (pode ser usada também como soma etc.), o expression
campo a partir dos valores será obtido, a concatenator
junção da cadeia de caracteres (deve ser definida, mesmo nesse caso) e a filter
filtragem de recursos com base na expressão (neste caso, intercepta a geometria da camada com a geometria da camada pai).
Para mais informações, consulte Agregar a documentação do QGIS .
Para atualizações automáticas, podem ser usados campos virtuais ou você pode definir a expressão como Valor padrão nas configurações de Formulário de atributos em Propriedades da camada ( documentação de configuração de formulário de atributo ).
geometry(@parent)
) são suportadas apenas a partir do QGIS 3. Caso alguém que esteja lendo isso ainda esteja usando 2,18 ...