[QGIS-Developer] Digitizing with Edit Menu

Yoann Quenach de Quivillic yoann.quenach at gmail.com
Sun Apr 30 14:48:05 PDT 2023


Have you considered listening to the featureAdded signal instead?
The digitizing shape (aka rubberband) you see while digitizing is not
really accessible. In fact, it isn't guaranteed to be the geometry of the
feature being created. It could even not exist at all ; this is all
dependent on the current QgsMapTool used.

Rather than monitoring clicks, or accessing the rubberband, you could
listen to the featureAdded signal. This signal is emitted when a new
feature is added to the layer. You can then perform your check (e;g area
validation), and delete the feature if the check fails. It won't even
appear on screen.

Here is a possible implementation. Note that I split the AreaValidator into
three classes for genericity, but you could merge these three classes in a
single one.

LayerConnector : this is used to automatically connect all map layers to a
function
FeatureValidator: Specialization, connects all QgsVectorLayer featureAdded
signal to a function that takes the layer and the feature being added as
parameters
AreaValidator: Contains the actual area computation, and possible deletion
of the feature


class LayerConnector(QObject):
    """Generic class to connect to all QgsMapLayer"""

    def __init__(self):
        super().__init__()
        QgsProject.instance().layerWasAdded.connect(self.connect_layer)
        self.connect_layers()

    def __del__(self):
        QgsProject.instance().layerWasAdded.disconnect(self.connect_layer)
        self.disconnect_layers()

    def connect_layers(self):
        print("Connecting")
        for layer in QgsProject.instance().mapLayers().values():
            self.connect_layer(layer)

    def disconnect_layers(self):
        print("DisConnecting")
        for layer in QgsProject.instance().mapLayers().values():
            self.disconnect_layer(layer)

    def connect_layer(self, layer):
        pass

    def disconnect_layer(self, layer):
        pass


class FeatureValidator(LayerConnector):
    """Connect all QgsVectorLayer to a process_feature method when a
feature is added"""

    def connect_layer(self, layer):
        if not isinstance(layer, QgsVectorLayer):
            return
        layer.featureAdded.connect(self.on_feature_added)

    def disconnect_layer(self, layer):
        if not isinstance(layer, QgsVectorLayer):
            return
        layer.featureAdded.disconnect(self.on_feature_added)

    def on_feature_added(self, id):
        layer = self.sender()
        feat = layer.getFeature(id)
        self.process_feature(layer, feat)

    def process_feature(self, layer, feature):
        print(f"Feature {feature.id()} added to layer {layer.name()}")


class AreaValidator(FeatureValidator):
    def __init__(self, max_area):
        super().__init__()
        self.max_area = max_area

    def process_feature(self, layer, feature):
        geom = feature.geometry()
        if not geom:
            return

        # Here you should handle CRS transformation
        # before computing the feature area
        area = geom.area()

        if area > self.max_area:
            iface.messageBar().pushWarning("Cannot add feature", f"Area too
big : {round(area, 2)}")
            layer.deleteFeature(feature.id())


validator = AreaValidator(500)

Le dim. 30 avr. 2023 à 18:42, Catania, Luke A ERDC-RDE-GRL-VA CIV via
QGIS-Developer <qgis-developer at lists.osgeo.org> a écrit :

> When you digitize a shape using the Edit menu in QGIS is the shape
> accessible?  I am looking to get he area of the shape as it is drawn.  I
> have added an event filter to my code to capture the coordinates and
> calculate it by creating a QgsGeometry, but my code is getting complicated
> as there are many shapes that a user can draw from this menu so if I can
> get access to this shape if it is temporary in memory, then I can just
> calculate the area on the shape and not have to capture all the positions
> of the mouse when clicked and moved.
>
>
>
> _______________________________________________
> QGIS-Developer mailing list
> QGIS-Developer at lists.osgeo.org
> List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
> Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/qgis-developer/attachments/20230430/d417ed2c/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image001.png
Type: image/png
Size: 82922 bytes
Desc: not available
URL: <http://lists.osgeo.org/pipermail/qgis-developer/attachments/20230430/d417ed2c/attachment-0001.png>


More information about the QGIS-Developer mailing list