Gibt es eine Möglichkeit, ein Attribut aus einer Polygonebene auszuwählen und den Wert mit "inside" im Feldrechner in ein virtuelles Feld einer Punktebene einzufügen?
CASE
WHEN within($geometry, geometry_polygon) THEN attribute_polygon
END
Gibt es eine Möglichkeit, ein Attribut aus einer Polygonebene auszuwählen und den Wert mit "inside" im Feldrechner in ein virtuelles Feld einer Punktebene einzufügen?
CASE
WHEN within($geometry, geometry_polygon) THEN attribute_polygon
END
Antworten:
Der Feldrechner unterstützt standardmäßig keine räumlichen Verknüpfungen zwischen Feature-Layern. Wenn Sie sich jedoch den Beitrag von NathanW im Funktionseditor für QGIS-Ausdrücke ansehen, können Sie feststellen, dass wir unsere eigene Dateninteraktion skripten können.
Mit dem folgenden Skript können Sie ausdrücken, wonach Sie suchen. Es funktioniert, indem alle Features auf der Polygonebene durchlaufen werden. Wenn eine räumliche Verknüpfung vorhanden ist, verweisen Sie auf Tabellendaten aus der angegebenen Spalte:
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
Unten sehen Sie ein Beispiel für einen Polygon-Layer, den Sie möglicherweise haben. Ich habe auch eine entsprechende Punktebene erstellt, die Sie im endgültigen Bild sehen werden.
Hinweis: Wenn Sie eine separate Spalte verwenden möchten, müssen Sie das zweite Argument so ändern, dass es mit dem Spaltennamen im Polygon-Dataset übereinstimmt. Beispiel: Sie könnten die Spalte 'AreaNumber' verwenden, müssten jedoch dem Spaltentyp in den Einstellungen des Feldrechners entsprechen.
Sie können sehen, dass der Standardspaltenwert angewendet wurde, wenn keine räumliche Verknüpfung vorhanden ist und die anderen mit den korrekten Daten übereinstimmen. Beachten Sie, dass das Skript, das ich gegeben habe, nur beim ersten Spiel beitritt. Sie müssten eine andere Geschäftslogik erstellen, wenn sich Ihre Polygone überschneiden.
Dies kann im Feldrechner mit Funktion durchgeführt werden aggregate()
. Erstellen Sie in der Punktebene ein neues Feld mit dem folgenden Ausdruck für den Feldrechner:
aggregate(
layer:= 'polygon_layer_name',
aggregate:='concatenate',
expression:=joining_field_name,
concatenator:=', ',
filter:=intersects($geometry, geometry(@parent))
)
Wo layer
ist Polygon-Layer-Name wie Zeichenfolge geschrieben, aggreagate
ist Aggregatfunktion (kann auch Summe usw. verwendet werden), expression
wird Feld aus Werten genommen, concatenator
wird Zeichenfolge zusammengefügt (muss auch in diesem Fall gesetzt werden) und filter
basiert auf Filterfunktionen on expression (schneidet in diesem Fall die Ebenengeometrie mit der Geometrie der übergeordneten Ebene).
Weitere Informationen finden Sie in der Dokumentation zu Aggregates QGIS .
Für automatische Aktualisierungen können virtuelle Felder verwendet werden oder Sie können den Ausdruck als Standardwert in den Formulareinstellungen für Attribute in den Layereigenschaften festlegen ( Dokumentation zu den Formulareinstellungen für Attribute ).
geometry(@parent)
) erst ab QGIS 3 unterstützt werden. Nur für den Fall, dass jemand, der dies liest, immer noch 2.18 verwendet ...