Цікаве запитання! Я не знаю жодного іншого способу досягнення того, що ви хочете, але за допомогою PyQGIS.
Прочитайте код нижче. Він має деякі тексти в ньому: 'lines'
, 'length'
, 'startX'
, 'startY'
, 'endX'
, 'endY'
. Ви можете налаштувати ці імена в сценарії, щоб він працював на ваших даних. Перший - це ім'я шару, тоді як решта відповідає назвам полів. Я припускаю, що у вашому шарі рядка є ці поля (адже ви хочете, щоб значення там були записані).
Після налаштування назви шару та імен полів, які потрібно автоматично оновлювати, скопіюйте та вставте сценарій у консоль QGIS Python.
Якщо все піде добре, ви повинні мати можливість бачити, що значення полів автоматично оновлюються у двох сценаріях: 1) Коли нові функції додаються, і 2) Коли геометрії змінені.
# 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 )
Ось як це працює:
Якщо у вас виникли проблеми під час запуску сценарію, додайте коментар під цією відповіддю.
Можливо, вам буде зручно мати цю функціональність уже під час відкриття проекту QGIS. Якщо це так, скажіть, я можу розмістити інструкції, щоб це зробити.
Редагувати:
Щоб ця функціональність була доступною щоразу, коли ви відкриваєте проект QGIS (тобто .qgs
файл, що містить, серед іншого, ваш лінійний шар), вам потрібно виконати наступні кроки:
Перейдіть QGIS->Project->Project Properties->Macros
, перевірте Python macros
параметр і замініть весь код цим (відрегулюйте значення, що вказують на назви шару та поля):
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
Переконайтеся , що ви включити макроси на ваш проект, таким чином: Settings->Options->General->Enable macros: Always
.
Збережіть свій проект QGIS.
Тепер, щоразу, коли ви відкриваєте .qgs
файл, який ви тільки що зберегли, атрибути шару рядка будуть автоматично оновлюватися, коли ви додаєте нову функцію або змінюєте геометрію (тобто більше не потрібно копіювати що-небудь в консоль QGIS Python).
2-е редагування:
Я щойно опублікував плагін під назвою AutoFields, щоб допомогти людям вирішити подібні проблеми. Я навіть зробив відео, в якому показав, як вирішити вашу проблему, ви можете подивитися її за адресою:
https://vimeo.com/germap/autofields-geometric-properties
Документація щодо AutoFields: http://geotux.tuxfamily.org/index.php/en/geo-blogs/item/333-autofields-plugin-for-qgis