¡Interesante pregunta! No conozco ninguna otra forma de lograr lo que quieres, pero usando PyQGIS.
Lee el código a continuación. Tiene algunos textos en que: 'lines'
, 'length'
, 'startX'
, 'startY'
, 'endX'
, 'endY'
. Puede ajustar esos nombres en el script para que funcione en sus datos. El primero es su nombre de capa, mientras que el resto corresponde a los nombres de campo. 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 actualizar 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:
Si tiene algún problema al ejecutar el script, agregue un comentario debajo de esta respuesta.
Puede ser útil para usted 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 contenga, entre otros, su capa de línea), debe seguir estos pasos:
Vaya a QGIS->Project->Project Properties->Macros
, marque la Python macros
opción y reemplace todo el código con este (ajuste los valores que indican los nombres de sus capas y campos):
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
Asegúrese de habilitar las macros en su proyecto, de esta manera: Settings->Options->General->Enable macros: Always
.
Guarde su proyecto QGIS.
Ahora, cada vez que abra 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:
https://vimeo.com/germap/autofields-geometric-properties
Documentación de AutoFields: http://geotux.tuxfamily.org/index.php/en/geo-blogs/item/333-autofields-plugin-for-qgis