Câu hỏi thú vị! Tôi không biết về bất kỳ cách nào khác để đạt được những gì bạn muốn, nhưng sử dụng PyQGIS.
Đọc mã dưới đây. Nó có một số văn bản trong đó: 'lines'
, 'length'
, 'startX'
, 'startY'
, 'endX'
, 'endY'
. Bạn có thể điều chỉnh các tên đó trong tập lệnh để nó hoạt động trên dữ liệu của bạn. Cái đầu tiên là tên lớp của bạn, trong khi phần còn lại tương ứng với tên trường. Tôi giả sử lớp dòng của bạn có các trường đó (sau tất cả, bạn muốn các giá trị được viết ở đó).
Khi bạn đã điều chỉnh tên lớp của mình và tên của các trường bạn muốn được cập nhật tự động, hãy sao chép và dán tập lệnh vào bảng điều khiển QGIS Python.
Nếu mọi thứ đều ổn, bạn sẽ có thể thấy các giá trị trường được tự động cập nhật theo hai kịch bản: 1) Khi các tính năng mới được thêm vào và 2) Khi hình học được sửa đổi.
# 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 )
Đây là cách nó hoạt động:
Nếu bạn có bất kỳ vấn đề nào trong khi chạy tập lệnh, hãy thêm một bình luận bên dưới câu trả lời này.
Bạn có thể có sẵn chức năng này khi bạn mở dự án QGIS. Nếu đó là trường hợp, cho tôi biết, tôi có thể gửi hướng dẫn để làm điều đó.
BIÊN TẬP:
Để chức năng này có sẵn mỗi khi bạn mở dự án QGIS (nghĩa là một .qgs
tệp chứa, trong số các tệp khác, lớp dòng của bạn), bạn cần phải làm theo các bước sau:
Đi đến QGIS->Project->Project Properties->Macros
, kiểm tra Python macros
tùy chọn và thay thế toàn bộ mã bằng mã này (điều chỉnh các giá trị cho biết tên lớp và trường của bạn):
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
Hãy chắc chắn rằng bạn bật macro trên dự án của bạn, theo cách này : Settings->Options->General->Enable macros: Always
.
Lưu dự án QGIS của bạn.
Bây giờ, mỗi khi bạn mở .qgs
tệp bạn vừa lưu, các thuộc tính của lớp dòng của bạn sẽ được cập nhật tự động khi bạn thêm một tính năng mới hoặc sửa đổi hình học (nghĩa là không cần phải sao chép bất cứ điều gì vào Bảng điều khiển Python của QGIS nữa).
EDIT thứ 2:
Tôi vừa xuất bản một plugin có tên AutoFields để giúp mọi người giải quyết loại vấn đề này. Tôi thậm chí đã làm một video cho thấy làm thế nào để giải quyết vấn đề của bạn, bạn có thể xem nó tại:
https://vimeo.com/germap/autofields-geometric-properies
Tài liệu về AutoFields: http : //geotux.tuxf Family.org/index.php/en/geo-bloss/item/333-autofields-plugin-for-qgis