[QGIS-Developer] Rotating selected features programmatically

Jacky Volpes jacky.volpes at oslandia.com
Tue Aug 6 07:06:02 PDT 2024


Hi Luke,

 >  and only rotates the inner most one.

Like I guessed, it's because element_layer_rotated() commits and ends 
the edition of the layer (and disconnects signal) as soon as the first 
feature geometry has been changed, so all other change won't follow.

Here is a way to wait for every selected feature to be rotated (feel 
free to adapt):



def element_layer_rotated(self):
         """When the rotate action is triggered it seems to ignore the 
ElementPlacementTool events, so in order to end the edit session
         we need to detect a geometryChanged event after the rotation is 
complete.
         """

# Do nothing if all the selected features have not been rotated
         if set(self.vector_layer.selectedFeatureIds()) != 
set(self.vector_layer.editBuffer().changedGeometries().keys()):
                 return

QgsMessageLog.logMessage(f"Element Layer Rotated: 
{self.vector_layer.name()}", "ElementPlacementTool", Qgis.Info)

         # Disconnect from the signal so we can just commit the changes.
         
self.vector_layer.editBuffer().geometryChanged.disconnect(self.element_layer_rotated)

         # Save changes and end edit mode
         self.vector_layer.commitChanges()
         self.vector_layer.endEditCommand()
         self.deactivate()


Regards,

--
Jacky Volpes

Ingénieur développeur SIG - Oslandia

Le 05/08/2024 à 19:44, Catania, Luke A ERDC-RDE-GRL-VA CIV a écrit :
>
> So I found that I could use a selectAll() method on the layer directly 
> rather than use the processing tool, but when I call the trigger on 
> the rotate action it unselects all the features and only rotates the 
> inner most one.
>
> *From:*QGIS-Developer <qgis-developer-bounces at lists.osgeo.org> *On 
> Behalf Of *Catania, Luke A ERDC-RDE-GRL-VA CIV via QGIS-Developer
> *Sent:* Monday, August 5, 2024 1:22 PM
> *To:* Jacky Volpes <jacky.volpes at oslandia.com>; 'qgis-developer' 
> <qgis-developer at lists.osgeo.org>
> *Subject:* Re: [QGIS-Developer] Rotating selected features 
> programmatically
>
> Well.  Now for some reason my select by expression tool is not 
> selecting any features, so need to figure out why that is happening 
> before implementing this change. I did not make any changes that I can 
> see that would have caused this.
>
> *From:*Jacky Volpes <jacky.volpes at oslandia.com>
> *Sent:* Monday, August 5, 2024 5:14 AM
> *To:* Catania, Luke A ERDC-RDE-GRL-VA CIV 
> <Luke.A.Catania at erdc.dren.mil>; 'qgis-developer' 
> <qgis-developer at lists.osgeo.org>
> *Subject:* Re: [QGIS-Developer] Rotating selected features 
> programmatically
>
> Hi Luke,
>
> My guess is that when more than one feature is selected, and the 
> rotation is ended, geometryChanged signal is emitted for each rotated 
> feature.
>
> element_layer_rotated() is run when the first geometryChanged signal 
> is emitted, and is disconnected, and the layer is saved, and the other 
> geometryChanged signals don't trigger anything.
>
> NB: self.vector_layer.editBuffer().geometryChanged.disconnect() is 
> risky, if other slots are connected, prefer 
> self.vector_layer.editBuffer().geometryChanged.disconnect(self.element_layer_rotated)
>
> Regards,
>
> --
> Jacky Volpes
> Ingénieur développeur SIG - Oslandia
>
> Le 01/08/2024 à 20:29, Catania, Luke A ERDC-RDE-GRL-VA CIV a écrit :
>
>     def rotateFeature(self):
>
>             """Find the rotate feature action in QGIS toolbar and
>     trigger it so the user can rotate the element.
>
>             """
>
>             # We want to detect when the rotation is complete with a
>     geometryChanged signal so we can commit the changes and
>
>             # end the edit session.
>
>     self.vector_layer.editBuffer().geometryChanged.connect(self.element_layer_rotated)
>
>             # Get all actions so we can search for the
>     mActionRotateFeature action.
>
>             actions = iface.mainWindow().findChildren(QAction)
>
>             action = [x for x in actions if
>     x.objectName()=='mActionRotateFeature'][0]
>
>             expression = '"Element_Nb" = '
>
>             expression = expression + "\'" + f'{self.element_number}'
>     + "\'"
>
>     QgsMessageLog.logMessage(f"expression: {expression}",
>     "StandoffLayers", Qgis.Info)
>
>     processing.run("qgis:selectbyexpression",
>
>                            {'INPUT':self.vector_layer,
>
>                             'EXPRESSION': expression,
>
>                             'METHOD':0
>
>                             }
>
>             )
>
>             # Inititates rotate feature action allowing to select a
>     snap to value.
>
>             action.trigger()
>
>             QgsMessageLog.logMessage(f"Rotate Feature Action
>     Triggered", "ElementPlacementTool", Qgis.Info)
>
>     def element_layer_rotated(self):
>
>             """When the rotate action is triggered it seems to ignore
>     the ElementPlacementTool events, so in order to end the edit session
>
>             we need to detect a geometryChanged event after the
>     rotation is complete.
>
>             """
>
>     QgsMessageLog.logMessage(f"Element Layer Rotated:
>     {self.vector_layer.name()}", "ElementPlacementTool", Qgis.Info)
>
>             # Disconnect from the signal so we can just commit the
>     changes.
>
>     self.vector_layer.editBuffer().geometryChanged.disconnect()
>
>             # Save changes and end edit mode
>
>             self.vector_layer.commitChanges()
>
>     self.vector_layer.endEditCommand()
>
>             self.deactivate()
>
>     *From:*Jacky Volpes <jacky.volpes at oslandia.com>
>     <mailto:jacky.volpes at oslandia.com>
>     *Sent:* Thursday, August 1, 2024 8:26 AM
>     *To:* Catania, Luke A ERDC-RDE-GRL-VA CIV
>     <Luke.A.Catania at erdc.dren.mil>
>     <mailto:Luke.A.Catania at erdc.dren.mil>; 'qgis-developer'
>     <qgis-developer at lists.osgeo.org>
>     <mailto:qgis-developer at lists.osgeo.org>
>     *Subject:* Re: [QGIS-Developer] Rotating selected features
>     programmatically
>
>     Hi Luke,
>
>     Please provide a PyQGIS code snippet to reproduce. It will be more
>     convenient to comment and suggest modifications.
>     Thanks,
>
>     --
>
>     Jacky Volpes
>
>       
>
>     Ingénieur développeur SIG - Oslandia
>
>
>     Le 26/07/2024 à 22:06, Catania, Luke A ERDC-RDE-GRL-VA CIV via
>     QGIS-Developer a écrit :
>
>         I am using the select by expression tool through python to
>         select my features and then I trigger rotation through python
>         I see both selected features rotating, but when I click to end
>         the rotation, it only rotated one of the features and left the
>         other one as is.  If I do this through the QGIS using the
>         selection by expression in the selection toolbar and the
>         rotate in the advanced digitizing tool bar rotating both
>         features works fine.
>
>         Any Ideas?
>
>         Luke
>
>
>
>         _______________________________________________
>
>         QGIS-Developer mailing list
>
>         QGIS-Developer at lists.osgeo.org
>
>         List info:Blockedhttps://lists.osgeo.org/mailman/listinfo/qgis-developerBlocked  <Blockedhttps://lists.osgeo.org/mailman/listinfo/qgis-developerBlocked>
>
>         Unsubscribe:Blockedhttps://lists.osgeo.org/mailman/listinfo/qgis-developerBlocked  <Blockedhttps://lists.osgeo.org/mailman/listinfo/qgis-developerBlocked>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/qgis-developer/attachments/20240806/8f6fd73c/attachment-0001.htm>


More information about the QGIS-Developer mailing list