Pergunta interessante! Não conheço outra maneira de conseguir o que deseja, mas usando o PyQGIS.
Leia o código abaixo. Tem alguns textos em que: 'lines'
, 'length'
, 'startX'
, 'startY'
, 'endX'
, 'endY'
. Você pode ajustar esses nomes no script para que ele funcione nos seus dados. O primeiro é o nome da camada, enquanto o restante corresponde aos nomes dos campos. Presumo que sua camada de linha tenha esses campos (afinal, você deseja que os valores sejam escritos lá).
Depois de ajustar o nome da camada e os nomes dos campos que você deseja atualizar automaticamente, copie e cole o script no console do QGIS Python.
Se tudo correr bem, você poderá ver que os valores do campo são atualizados automaticamente em dois cenários: 1) Quando novos recursos são adicionados e 2) Quando as geometrias são modificadas.
# 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 )
É assim que funciona:
Se você tiver algum problema ao executar o script, adicione um comentário abaixo desta resposta.
Pode ser útil que você já tenha essa funcionalidade disponível ao abrir seu projeto QGIS. Se for esse o caso, diga-me, eu poderia postar instruções para fazer isso.
EDITAR:
Para que essa funcionalidade esteja disponível sempre que você abrir o seu projeto QGIS (ou seja, um .qgs
arquivo que contém, entre outros, sua camada de linha), siga estas etapas:
Vá para QGIS->Project->Project Properties->Macros
, marque a Python macros
opção e substitua o código inteiro por este (ajuste os valores indicando seus nomes de camada e 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
Certifique-se de habilitar as macros no seu projeto, desta forma: Settings->Options->General->Enable macros: Always
.
Salve seu projeto QGIS.
Agora, toda vez que você abrir o .qgs
arquivo que acabou de salvar, os atributos da camada de linha serão atualizados automaticamente quando você adicionar um novo recurso ou modificar uma geometria (ou seja, não será mais necessário copiar nada no QGIS Python Console).
2ª EDIÇÃO:
Acabei de publicar um plugin chamado AutoFields para ajudar as pessoas a resolver esse tipo de problema. Eu até fiz um vídeo mostrando como resolver seu problema, você pode assistir em:
https://vimeo.com/germap/autofields-geometric-properties
Documentação do AutoFields: http://geotux.tuxfamily.org/index.php/en/geo-blogs/item/333-autofields-plugin-for-qgis