Thursday 28 July 2016

qgis - Handle add new feature event and/or access feature before commit?


Is it possible with PyQGIS to catch "add new feature" event before commiting changes on the layer? or at least to access new features before commit.



Answer



The QgsVectorLayer has quite a number of signals that will may suite your needs. Documentation for 1.8 and master on these links.



Note there are minor changes to the API between 1.8 and master, and it appears that the python bindings have a few issues that are still unresolved.


This sample code defines a couple of listeners, then attaches them to a memory layer. If you start editing the layer you will see each signal triggers a line in the message log.


This code is (mostly) compatible with 1.8 and master and is intended to be pasted into the python console.


from PyQt4.QtGui import *

def logLayerModified( onlyGeometry = None ):
QgsMessageLog.logMessage( "layer modified" )
QApplication.beep()

def logFeatureAdded(fid):

QgsMessageLog.logMessage( "feature added, id = " + str(fid) )
QApplication.beep()

def logEditingStarted():
QgsMessageLog.logMessage( "editing started" )
QApplication.beep()

def logCommittedFeaturesAdded( layerId, addedFeatures ):
message = layerId + " has features added: "
for feature in addedFeatures:

message += str( feature.id() ) + ", "
QgsMessageLog.logMessage( message )
QApplication.beep()

layer = QgsVectorLayer( "Point", "Layer Signal Demo", "memory" )
QgsMapLayerRegistry.instance().addMapLayers( [layer] )

layer.layerModified.connect( logLayerModified )
layer.featureAdded.connect( logFeatureAdded )
layer.editingStarted.connect( logEditingStarted )

layer.committedFeaturesAdded.connect( logCommittedFeaturesAdded )

EDIT: Even with an incomplete set of signals you can probably get the access you require by performing you own analysis.


I have a naive implementation here that will slow down for large feature counts. Depending on your needs you may be able to optimize by reducing the amount of data being handled during the cross referencing. You may get speed gains by omitting the geometry or full attribute table from the query until you have identified the features you are interested in.


Note that this is designed for 1.8, feature iteration has changed significantly for master.


from PyQt4.QtGui import *

def layerModified( onlyGeometry = None ):
global establishedFeatureIds
newFeatureIds = []

layer.select()
feature = QgsFeature()
while layer.nextFeature( feature ):
id = feature.id()
if not id in establishedFeatureIds:
newFeatureIds.append( id )
message = "New features: "
for id in newFeatureIds:
message += str(id) + ", "
QgsMessageLog.logMessage( message )


def editingStarted():
global establishedFeatureIds
establishedFeatureIds = []
layer.select()
feature = QgsFeature()
while layer.nextFeature( feature ):
establishedFeatureIds.append( feature.id() )

layer = qgis.utils.iface.activeLayer()

if layer is None:
layer = QgsVectorLayer( "Point", "Cross-reference Demo", "memory" )
QgsMapLayerRegistry.instance().addMapLayers( [layer] )

layer.layerModified.connect( layerModified )
layer.editingStarted.connect( editingStarted )

No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...