[QGIS-Developer] Digitizing with Edit Menu
Yoann Quenach de Quivillic
yoann.quenach at gmail.com
Mon May 1 13:17:18 PDT 2023
In that case, you could try the following to get the temp geometry being
drawn on the map.
*Note that this is kind of hackish, may not work for every tool, and might
break at any QGIS update*.
def getTempGeom():
# Iter over map canvas items, starting from the end (most recent)
for item in iface.mapCanvas().items()[::-1]:
# If it is a valid QgsGeometryRubberBand, return its geometry
if isinstance(item, QgsGeometryRubberBand):
geom = item.geometry()
if geom.area() > 0:
return geom
# If it is a valid QgsRubberBand, return its geometry
if isinstance(item, QgsRubberBand):
geom = item.asGeometry()
if geom.area() > 0:
return geom
In your eventFilter, you could just use getTempGeom, perform the area
computation, and display a tooltip with the current area.
Le lun. 1 mai 2023 à 18:00, Catania, Luke A ERDC-RDE-GRL-VA CIV <
Luke.A.Catania at erdc.dren.mil> a écrit :
> Thanks for taking the time to code that. I originally coded with the
> featureAdded method. When I first found it I was pretty happy with the
> solution, but then since the user does not get informed until after they
> draw the shape and it is already added to the layer and so the feature then
> needs to be deleted so they can try again. This can go a few iterations.
>
>
>
> The previous version of the software I am working on which did not use
> QGIS but custom developed using R and Leaflet had this dynamic cursor that
> indicated the size and users miss that, so then I came across the
> eventFilter and applied that to the map canvas and while still using the
> shapes from the edit menu basically used the mouse location to handle
> dynamically updating the cursor the a QLabel calculating the area bases on
> the shape being drawn. It added more code, but out trainers are excited
> about this new feature..
>
>
>
>
>
>
>
> *From:* Yoann Quenach de Quivillic <yoann.quenach at gmail.com>
> *Sent:* Sunday, April 30, 2023 5:48 PM
> *To:* Catania, Luke A ERDC-RDE-GRL-VA CIV <Luke.A.Catania at erdc.dren.mil>
> *Cc:* qgis-developer at lists.osgeo.org
> *Subject:* Re: [QGIS-Developer] Digitizing with Edit Menu
>
>
>
> 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:
> Blockedhttps://lists.osgeo.org/mailman/listinfo/qgis-developerBlocked
> Unsubscribe:
> Blockedhttps://lists.osgeo.org/mailman/listinfo/qgis-developerBlocked
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/qgis-developer/attachments/20230501/7cc052ed/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/20230501/7cc052ed/attachment-0003.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image002.png
Type: image/png
Size: 728686 bytes
Desc: not available
URL: <http://lists.osgeo.org/pipermail/qgis-developer/attachments/20230501/7cc052ed/attachment-0004.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image003.png
Type: image/png
Size: 855843 bytes
Desc: not available
URL: <http://lists.osgeo.org/pipermail/qgis-developer/attachments/20230501/7cc052ed/attachment-0005.png>
More information about the QGIS-Developer
mailing list