Saltar al contenido

¿Hacer que el campo de la tabla de atributos de QGIS sea automático?

Solución:

¡Interesante pregunta! No conozco ninguna otra forma de lograr lo que desea, pero usando PyQGIS.

Lea el código a continuación. Tiene algunos textos en él: 'lines', 'length', 'startX', 'startY', 'endX', 'endY'. Puede ajustar esos nombres en el script para que funcione con sus datos. El primero es el nombre de la capa, mientras que el resto corresponde a los nombres de los campos. Supongo que su capa de línea tiene esos campos (después de todo, desea que los valores se escriban allí).

Una vez que haya ajustado el nombre de su capa y los nombres de los campos que desea que se actualicen automáticamente, copie y pegue el script en la consola QGIS Python.

Si todo va bien, debería poder ver que los valores de campo se actualizan automáticamente en dos escenarios: 1) Cuando se agregan nuevas características y 2) Cuando se modifican las geometrías.

# Initialize required variables
myLayer = QgsMapLayerRegistry.instance().mapLayersByName( 'lines' )[0]
lengthField = myLayer.fieldNameIndex( 'length' )
startXField = myLayer.fieldNameIndex( 'startX' )
startYField = myLayer.fieldNameIndex( 'startY' )
endXField = myLayer.fieldNameIndex( 'endX' )
endYField = myLayer.fieldNameIndex( 'endY' )

# Slot, updates field values
def updateFeatureAttrs( fId, geom=None ):
    f = myLayer.getFeatures( QgsFeatureRequest( fId ) ).next()    
    if not geom:
        geom = f.geometry() 
    myLayer.changeAttributeValue( fId, lengthField, geom.length() )
    myLayer.changeAttributeValue( fId, startXField, geom.vertexAt( 0 )[0] )
    myLayer.changeAttributeValue( fId, startYField, geom.vertexAt( 0 )[1] )
    myLayer.changeAttributeValue( fId, endXField, geom.asPolyline()[-1][0] )
    myLayer.changeAttributeValue( fId, endYField, geom.asPolyline()[-1][1] )

# Update feature attributes when new features are added or geometry changes
myLayer.featureAdded.connect( updateFeatureAttrs )
myLayer.geometryChanged.connect( updateFeatureAttrs )

Así es como funciona:

Actualizaciones automáticas de campos en QGIS

Si tiene algún problema mientras ejecuta el script, agregue un comentario debajo de esta respuesta.

Puede resultarle útil tener esta funcionalidad ya disponible cuando abra su proyecto QGIS. Si ese es el caso, dígame, podría publicar instrucciones para hacerlo.


EDITAR:

Para que esta funcionalidad esté disponible cada vez que abra su proyecto QGIS (es decir, un .qgs archivo que contiene, entre otros, su capa de línea) debe seguir estos pasos:

  1. Ir a QGIS->Project->Project Properties->Macros, comprobar el Python macros opción, y reemplace todo el código con este (ajuste los valores que indican los nombres de su capa y campo):

    from qgis.core import QgsMapLayerRegistry, QgsFeatureRequest
    def openProject():    
        # Initialize required variables
        myLayer = QgsMapLayerRegistry.instance().mapLayersByName( 'lines' )[0]
    
        # Update feature attributes when new features are added or geometry changes
        myLayer.featureAdded.connect( updateFeatureAttrs )
        myLayer.geometryChanged.connect( updateFeatureAttrs )
    
    # Slot, updates field values
    def updateFeatureAttrs( fId, geom=None ):
        myLayer = QgsMapLayerRegistry.instance().mapLayersByName( 'lines' )[0]
        lengthField = myLayer.fieldNameIndex( 'length' )
        startXField = myLayer.fieldNameIndex( 'startX' )
        startYField = myLayer.fieldNameIndex( 'startY' )
        endXField = myLayer.fieldNameIndex( 'endX' )
        endYField = myLayer.fieldNameIndex( 'endY' )
        f = myLayer.getFeatures( QgsFeatureRequest( fId ) ).next()    
        if not geom:
            geom = f.geometry() 
        myLayer.changeAttributeValue( fId, lengthField, geom.length() )
        myLayer.changeAttributeValue( fId, startXField, geom.vertexAt( 0 )[0] )
        myLayer.changeAttributeValue( fId, startYField, geom.vertexAt( 0 )[1] )
        myLayer.changeAttributeValue( fId, endXField, geom.asPolyline()[-1][0] )
        myLayer.changeAttributeValue( fId, endYField, geom.asPolyline()[-1][1] )
    
    def saveProject():
        pass
    
    def closeProject():
        pass
    
  2. Asegúrese de habilitar macros en su proyecto, de esta manera: Settings->Options->General->Enable macros: Always.

  3. Guarde su proyecto QGIS.

Ahora, cada vez que abres el .qgs archivo que acaba de guardar, los atributos de su capa de línea se actualizarán automáticamente cuando agregue una nueva característica o modifique una geometría (es decir, ya no es necesario copiar nada en la consola QGIS Python).


2da EDICIÓN:

Acabo de publicar un complemento llamado AutoFields para ayudar a las personas a resolver este tipo de problemas. Incluso hice un video que muestra cómo resolver su problema, puede verlo en:

Documentación de AutoFields: http://geotux.tuxfamily.org/index.php/en/geo-blogs/item/333-autofields-plugin-for-qgis

Si solo necesita estos campos dentro de QGIS, puede utilizar campos virtuales. Estos permiten usar una expresión (como $length) que depende de otros valores o de la geometría.

Abra la calculadora de campo, agregue un nuevo campo con la longitud del nombre, marque la casilla de verificación “Campo virtual” e ingrese $length como expresión (o algo más para los otros campos).

Sin embargo, estos no se guardarán en el archivo de Excel.

Si desea mantener un archivo de Excel sincronizado con un archivo shp para geometría e incluir campos derivados en el archivo de Excel, existe un complemento llamado ShpSync que conoce este concepto y actualiza los campos automáticamente cuando se cambian, agregan o eliminan características.

Para QGIS 3 Ve a la Layers Properties => Attributes Form => elija su campo con valores de geometría (en ejemplo, area) => tipo $area en el Defaults value caja y marca Apply default value on update. Esto también podría ser útil: $perimeter, $y, $x, $id

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *