¿Hay alguna forma de seleccionar un atributo de una capa de polígono e insertar el valor en un campo virtual de una capa de punto usando "dentro" en la calculadora de campo?
CASE
WHEN within($geometry, geometry_polygon) THEN attribute_polygon
END
¿Hay alguna forma de seleccionar un atributo de una capa de polígono e insertar el valor en un campo virtual de una capa de punto usando "dentro" en la calculadora de campo?
CASE
WHEN within($geometry, geometry_polygon) THEN attribute_polygon
END
Desde QGIS 3.16 la funcionalidad del "refFunctions plugin" se convirtió en núcleo . La función actual correspondiente es la overlay_within()
.
Las uniones espaciales están disponibles en la Calculadora de campo después de instalar la aplicación "Plugin "refFunctions .
geomwithin(targetLayer, targetField)
Tenlo en cuenta:
Este plugin está obsoleto.
La calculadora de campo no admite uniones espaciales entre capas de características. Pero, si usted echa un vistazo a NathanW's post en el editor de funciones para expresiones qgis podrás ver que podemos programar nuestra propia interacción de datos.
El siguiente script le permitirá expresar lo que busca. Funciona iterando a través de todas las características de la capa de polígonos y si hay una unión espacial, entonces referencia los datos tabulares de la columna 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
A continuación se muestra un ejemplo de una capa poligonal que usted podría tener. También he creado una capa de puntos correspondiente que verás en la imagen final.
Tenga en cuenta que si desea utilizar una columna distinta, debe cambiar el segundo argumento para que coincida con el nombre de la columna en el conjunto de datos de polígonos. Por ejemplo, podría utilizar la columna 'AreaNumber', pero tendría que coincidir con el tipo de columna en la configuración de la calculadora de campos.
Puede ver que el valor por defecto de la columna se ha aplicado donde no hay unión espacial, y los otros han coincidido con los datos correctos. Tenga en cuenta que la secuencia de comandos que he dado sólo se unen en el primero partido. Tendría que crear otra lógica de negocio si sus polígonos estuvieran superpuestos.
Muchas gracias, tu script funciona bien utilizando 'geom' en lugar de 'geometry' en la primera sentencia 'if'. Unir geometrías de esta forma puede ser bastante útil, por ejemplo, para crear etiquetas múltiples en polígonos.
Lo siento, no sé cómo se me ha podido pasar. Espero que no haya problemas de rendimiento; sólo lo he probado con un subconjunto muy pequeño de registros.
Con sólo más de 100 puntos, QGIS tiene problemas de rendimiento. Añadir una nueva característica de punto es realmente un dolor incluso si no hay ninguna característica de punto mostrada en el lienzo real. Por otra parte cuando se hace zoom QGIS se acelera. He probado `CASE WHEN scale<10000THENspatialJoinLookupI(′Polygons′,′AreaName′,′None′, geometry) END' pero no funciona. ¿Hay algo que pueda hacer para mejorar el rendimiento?
Puede hacerse en Calculadora de campo con función aggregate()
. En la capa de puntos cree un nuevo campo con una expresión de calculadora de campo como esta:
aggregate(
layer:= 'polygon_layer_name',
aggregate:='concatenate',
expression:=joining_field_name,
concatenator:=', ',
filter:=intersects($geometry, geometry())
)
Dónde layer
es el nombre de la capa poligonal escrito como una cadena, aggreagate
es una función agregada (también se puede utilizar suma, etc.), expression
es campo de valores se tomarán, concatenator
es una cadena de caracteres de unión (tiene que estar configurada, incluso en este caso) y filter
es filtrar características basándose en la expresión (en este caso interesa la geometría de la capa con la geometría de la capa padre).
Más información Documentación sobre agregados QGIS .
Para las actualizaciones automáticas se puede utilizar campos virtuales o puede establecer la expresión como Valor por defecto en Formulario de atributos ajustes en Propiedades de las capas ( Documentación sobre la configuración de formularios de atributos ).
Una pequeña actualización de Mar Lunar la respuesta.
Desde QGIS 3.16 donde refFunctions en el núcleo es posible utilizar el overlay_within()
función.
De hecho Esta respuesta debería subir, ya que puede inducir a error leer que, por defecto, esto no es posible o sólo como una solución. Los tiempos han cambiado. Así que vota esta pequeña pero importante respuesta.
Tengo una capa de puntos en la que he creado dos campos, uno con la función agregar y otro con la función superponer. Algo raro pasa con la función agregar: ralentiza QGIS considerablemente. En propiedades de la capa > formularios de atributos > click izquierdo en el campo con la función de agregación tarda como un segundo o dos en abrirse. Todos los demás campos se abren inmediatamente. Lo mismo ocurre al añadir un nuevo punto: la ventana emergente para rellenar los campos tarda más tiempo con el "campo agregado" presente.
I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.
1 votos
¿Por qué no utilizar para ello el complemento "Herramienta de muestreo de puntos"?
0 votos
Porque necesito actualizaciones dinámicas al crear nuevos puntos o mover puntos existentes.
0 votos
Sería mejor que programaras esta interacción en lugar de confiar en herramientas estándar.
0 votos
Desgraciadamente no tengo experiencia en scripts.
1 votos
@LunarSea He escrito un ejemplo a continuación para que lo sigas, pero puede que tengas que ajustarlo a tus necesidades.