Freehand Raster Georeferencer plugin updated for QGIS 3
A few weeks ago, I updated my Freehand Raster Georeferencer plugin for the newly released QGIS 3. I also included a few fixes for some issues as well as new features such as uniform scaling, a new “Georeference with 2 Points” tool (contributed by a user) or taking into account an existing world file. Those changes were backported to the plugin version for QGIS 2 so there should not be any difference between the QGIS 2 and 3 versions. See the updated doc for information.
QGIS 3 was released at the end of February and included quite a few changes when it came to plugin development:
- The most obvious change was that the version of Python used for plugins is now Python 3. My code was pretty much compatible, except that I had to switch to relative imports and drop the u from strings. I used the standard 2to3 tool to check the code.
- The second most obvious change was the switch to PyQt 5 (instead of PyQt 4). Again, there were not a lot to changes: Basically, update the imported PyQt modules, as well as change the packages for widgets, now in
PyQt5.QtWidgets
instead ofPyQt4.QtGui
. I also had to rebuild the .py fils from the .ui with the pyuic5 tool. - I also had to update the metadata with the new QGIS 3 version (
qgisMinimumVersion=3.0
). I was not sure when I published the plugin for QGIS 3 if the QGIS 2 version would be kept available for users still on QGIS 2, but there was no problem: The QGIS plugin manager shows the latest published version of the plugin compatible with either QGIS 2 or 3, depending on which one is used. - Finally there were a lot of API changes. The project has released a list of backwards incompatible changes to help and mostly it was pretty clear what needed to be changed. Here are some more details on a few points:
- The plugin is based around a QgsPluginLayer and I had to add 2 new classes that were not necessary in QGIS 2: one subclass of QgsDataProvider that needs to be returned by the
dataProvider()
method of my plugin layer + one subclass of QgsMapLayerRenderer that needs to be returned by thecreateMapRenderer()
method.- Checking the visiblity of a QgsMapLayer used to be done with something like
iface.legendInterface().isLayerVisible(layer)
. The QgsLegendInterface class has been removed and replaced by a layer tree API. Now, I am not sure if that is the best way but I performed the checking of the visibility of the map layer withiface.layerTreeView().layerTreeModel().rootGroup().findLayer(layer).itemVisibilityChecked()
The QGIS project has released a tool and some instructions for migrating plugins.
- Checking the visiblity of a QgsMapLayer used to be done with something like
- The plugin is based around a QgsPluginLayer and I had to add 2 new classes that were not necessary in QGIS 2: one subclass of QgsDataProvider that needs to be returned by the