35 votos

¿Cómo referirse a otra capa en la calculadora de campo?

¿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

enter image description here

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.

29voto

latusaki Puntos 153

Para las versiones de QGIS 3.16 y superiores

Desde QGIS 3.16 la funcionalidad del "refFunctions plugin" se convirtió en núcleo . La función actual correspondiente es la overlay_within() .

Para versiones de QGIS inferiores a QGIS 3.16

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.

0 votos

Los plug-ins son mucho más sencillos que utilizar un script personalizado. Gracias.

1 votos

Geomwithin('targetLayer','targetField').

23voto

nagytech Puntos 2872

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

Ejemplo de capa poligonal

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.

enter image description here

Uso de expresiones

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.

enter image description here

Resultado

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.

enter image description here

0 votos

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.

0 votos

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.

0 votos

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?

20voto

Oto Kaláb Puntos 121

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 ).

enter image description here

4 votos

Cabe señalar que las funciones espaciales (con geometry() ) sólo se admiten a partir de QGIS 3. Por si alguien que esté leyendo esto todavía utiliza la versión 2.18...

0 votos

Gracias, señor. Funciona de maravilla.

3voto

ARUNBALAN NV Puntos 101

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.

0 votos

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.

0 votos

Gracias por tu inspiración :) Tal vez debería actualizar la respuesta anterior... hmmm

0 votos

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.com

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.

Powered by:

X