有趣的问题!我不知道有什么其他方法可以实现所需的功能,但可以使用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控制台中),线图层的属性都会自动更新。
第二次编辑:
我刚刚发布了一个名为AutoFields的插件,以帮助人们解决此类问题。我什至制作了一段视频,展示如何解决您的问题,您可以在以下位置观看:
https://vimeo.com/germap/autofields-geometric-properties
AutoFields文档:http ://geotux.tuxfamily.org/index.php/en/geo-blogs/item/333-autofields-plugin-for-qgis