Domanda interessante! Non sono a conoscenza di altri modi per ottenere ciò che desideri, ma utilizzando PyQGIS.
Leggi il codice qui sotto. Ha alcuni testi in esso: 'lines'
, 'length'
, 'startX'
, 'startY'
, 'endX'
, 'endY'
. Puoi adattare quei nomi nello script affinché funzioni sui tuoi dati. Il primo è il nome del tuo livello, mentre il resto corrisponde ai nomi dei campi. Suppongo che il tuo livello di linea abbia quei campi (dopo tutto, vuoi che i valori vengano scritti lì).
Dopo aver modificato il nome del layer e i nomi dei campi che si desidera vengano aggiornati automaticamente, copiare e incollare lo script nella console di QGIS Python.
Se tutto va bene, dovresti essere in grado di vedere che i valori dei campi vengono aggiornati automaticamente in due scenari: 1) Quando vengono aggiunte nuove funzionalità e 2) Quando le geometrie vengono modificate.
# 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 )
Ecco come funziona:
In caso di problemi durante l'esecuzione dello script, aggiungere un commento sotto questa risposta.
Potrebbe esserti utile avere questa funzionalità già disponibile quando apri il tuo progetto QGIS. In tal caso, dimmi, potrei pubblicare le istruzioni per farlo.
MODIFICARE:
Affinché questa funzionalità sia disponibile ogni volta che apri il tuo progetto QGIS (ovvero un .qgs
file contenente, tra l'altro, il tuo livello di linea) devi seguire questi passaggi:
Vai a QGIS->Project->Project Properties->Macros
, seleziona l' Python macros
opzione e sostituisci l'intero codice con questo (regola i valori che indicano i nomi dei livelli e dei campi):
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
Assicurarsi di abilitare le macro sul vostro progetto, in questo modo: Settings->Options->General->Enable macros: Always
.
Salva il tuo progetto QGIS.
Ora, ogni volta che apri il .qgs
file che hai appena salvato, gli attributi del tuo livello di linea verranno automaticamente aggiornati quando aggiungi una nuova funzione o modifichi una geometria (cioè, non c'è più bisogno di copiare nulla nella QGIS Python Console).
2a modifica:
Ho appena pubblicato un plugin chiamato AutoFields per aiutare le persone a risolvere questo tipo di problemi. Ho anche realizzato un video che mostra come risolvere il tuo problema, puoi guardarlo su:
https://vimeo.com/germap/autofields-geometric-properties
Documentazione di AutoFields: http://geotux.tuxfamily.org/index.php/en/geo-blogs/item/333-autofields-plugin-for-qgis