Re: [QGIS-Developer] Digitizing with Edit Menu

2023-05-02 Thread Jacky Volpes via QGIS-Developer

Hello,

Have you tried this following code? Using 
iface.mapCanvas().mapTool().pointsZM() is good for me with any 
digitizing tool, while drawing.



# Measurement object (adapt with crs/transform context/ellipsoid)
da = QgsDistanceArea()
da.setSourceCrs(QgsProject.instance().crs(), 
QgsProject.instance().transformContext())

# If distance measurement must use ellipsoid
da.setEllipsoid(QgsProject.instance().ellipsoid())

# This is a demonstration function to adapt with your needs
def showArea(current_point):
    if not isinstance(iface.mapCanvas().mapTool(), 
QgsMapToolDigitizeFeature):

    return

    # Snapping
    snapped_point = 
iface.mapCanvas().snappingUtils().snapToMap(current_point).point()

    if not snapped_point.isEmpty():
    current_point = snapped_point

    # Coordinates of currently drawn points in map coordinates
    points = [QgsPointXY(point) for point in 
iface.mapCanvas().mapTool().pointsZM()]

    points.append(current_point)

    # Get area
    print(da.measurePolygon(points))

# Must be handled correctly in the final code, but here is for testing
iface.mapCanvas().xyCoordinates.connect(showArea)



Le 29/04/2023 à 01:45, Catania, Luke A ERDC-RDE-GRL-VA CIV via 
QGIS-Developer 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@lists.osgeo.org
List info:https://lists.osgeo.org/mailman/listinfo/qgis-developer
Unsubscribe:https://lists.osgeo.org/mailman/listinfo/qgis-developer


--
Jacky Volpes

Ingénieur SIG - Oslandia
___
QGIS-Developer mailing list
QGIS-Developer@lists.osgeo.org
List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer


Re: [QGIS-Developer] Digitizing with Edit Menu

2023-05-02 Thread Yoann Quenach de Quivillic via QGIS-Developer
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  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@lists.osgeo.org
> List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
> Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer
>
___
QGIS-Developer mailing list
QGIS-Developer@lists.osgeo.org
List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer