Interesujące pytanie! Nie znam żadnego innego sposobu osiągnięcia tego, co chcesz, ale używając PyQGIS.
Przeczytaj poniższy kod. Ma pewne teksty w niej: 'lines'
, 'length'
, 'startX'
, 'startY'
, 'endX'
, 'endY'
. Możesz dostosować te nazwy w skrypcie, aby działał on na twoich danych. Pierwszy to nazwa warstwy, a reszta odpowiada nazwom pól. Zakładam, że twoja warstwa liniowa ma te pola (w końcu chcesz, żeby tam były zapisane wartości).
Po dostosowaniu nazwy warstwy i nazw pól, które mają być automatycznie aktualizowane, skopiuj i wklej skrypt do konsoli QGIS Python.
Jeśli wszystko pójdzie dobrze, powinieneś zobaczyć, że wartości pól są automatycznie aktualizowane w dwóch scenariuszach: 1) Po dodaniu nowych elementów i 2) Po modyfikacji geometrii.
# 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 )
Tak to działa:
Jeśli masz problem z uruchomieniem skryptu, dodaj komentarz poniżej tej odpowiedzi.
Może się przydać, aby ta funkcja była już dostępna po otwarciu projektu QGIS. Jeśli tak jest, powiedz mi, że mogę zamieścić instrukcje, aby to zrobić.
EDYTOWAĆ:
Aby ta funkcja była dostępna za każdym razem, gdy otwierasz swój projekt QGIS (tj. .qgs
Plik zawierający między innymi warstwę liniową), musisz wykonać następujące kroki:
Przejdź do QGIS->Project->Project Properties->Macros
, zaznacz Python macros
opcję i zastąp cały kod tym kodem (dostosuj wartości wskazujące nazwy warstw i pól):
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
Upewnij się włączyć makra nad projektem, w ten sposób: Settings->Options->General->Enable macros: Always
.
Zapisz swój projekt QGIS.
Teraz za każdym razem, gdy otwierasz .qgs
właśnie zapisany plik, atrybuty warstwy linii będą automatycznie aktualizowane po dodaniu nowej operacji lub modyfikacji geometrii (tj. Nie trzeba już niczego kopiować do konsoli Python QGIS).
2. EDYCJA:
Właśnie opublikowałem wtyczkę o nazwie AutoFields, aby pomóc ludziom rozwiązać tego rodzaju problemy. Zrobiłem nawet film pokazujący, jak rozwiązać twój problem, możesz go obejrzeć na:
https://vimeo.com/germap/autofields-geometric-properties
Dokumentacja AutoFields: http://geotux.tuxfamily.org/index.php/en/geo-blogs/item/333-autofields-plugin-for-qgis