Esiste un modo per selezionare un attributo da un livello poligonale e inserire il valore in un campo virtuale di un livello punto usando "entro" nel calcolatore di campo?
CASE
WHEN within($geometry, geometry_polygon) THEN attribute_polygon
END
Esiste un modo per selezionare un attributo da un livello poligonale e inserire il valore in un campo virtuale di un livello punto usando "entro" nel calcolatore di campo?
CASE
WHEN within($geometry, geometry_polygon) THEN attribute_polygon
END
Risposte:
Immediatamente, il calcolatore di campo non supporta i join spaziali tra i layer delle funzionalità. Ma, se dai un'occhiata al post di NathanW sull'editor di funzioni per le espressioni qgis , sarai in grado di capire che possiamo scrivere la nostra interazione con i dati.
Il seguente script ti consentirà di esprimere ciò che stai cercando. Funziona ripetendo tutte le funzionalità sul layer poligonale e se esiste un join spaziale, fai riferimento ai dati tabulari dalla colonna specificata:
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
Di seguito è riportato un esempio di un livello poligonale che potresti avere. Ho anche creato un layer di punti corrispondente che vedrai nell'immagine finale.
Nota, se si desidera utilizzare una colonna separata, è necessario modificare il secondo argomento in modo che corrisponda al nome della colonna nel set di dati del poligono. Ad esempio, è possibile utilizzare la colonna "AreaNumber", ma dovrebbe corrispondere al tipo di colonna nelle impostazioni della calcolatrice del campo.
Puoi vedere che il valore di colonna predefinito è stato applicato in assenza di join spaziali e che gli altri hanno trovato i dati corretti. Nota che lo script che ho dato si unirà solo alla prima partita. Dovresti creare qualche altra logica aziendale se i tuoi poligoni si sovrapponessero.
Può essere fatto in Field Calculator con la funzione aggregate()
. Nel livello punto creare un nuovo campo con un'espressione calcolatrice di campo come questa:
aggregate(
layer:= 'polygon_layer_name',
aggregate:='concatenate',
expression:=joining_field_name,
concatenator:=', ',
filter:=intersects($geometry, geometry(@parent))
)
Dove il layer
nome del layer poligonale è scritto come una stringa, aggreagate
è una funzione aggregata (può essere utilizzata anche come somma ecc.), Il expression
campo viene prelevato dai valori, concatenator
si unisce la stringa di caratteri (deve essere impostata, anche in questo caso) e filter
si basa sul filtraggio delle funzionalità sull'espressione (in questo caso intercetta la geometria del livello con la geometria del livello principale).
Per ulteriori informazioni, consultare la documentazione relativa agli aggregati QGIS .
Per gli aggiornamenti automatici è possibile utilizzare i campi virtuali oppure è possibile impostare l'espressione come Valore predefinito nelle Impostazioni modulo attributi in Proprietà livello ( Documentazione impostazione modulo attributi ).
geometry(@parent)
) sono supportate solo da QGIS 3 in poi. Nel caso in cui chiunque stia leggendo questo stia ancora usando 2.18 ...