Интересный вопрос! Я не знаю ни одного другого способа достижения того, чего вы хотите, кроме использования 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