Creating UI

For now, we need two user inputs:

  • Input vector layer

  • Output target directory

Task

In the Qt Designer create two required inputs. Use QgsMapLayerComboBox for layer selection, QgsFileWidget for output dir name.

Use objectName attribute to name the objects: layers, output_dir and submit.

Consider using grid layout and horizontal/vertical spacers.

../_images/plugin-ui-final.svg

Fig. 19 Example of plugin UI design.

The Code

The run() method of the SaveViews class has to do following tasks:

  1. Initialize some initial form inputs

  2. Get the user input data

  3. Call the saving function

 1    def run(self):
 2        """Run method that loads and starts the plugin"""
 3
 4        if not self.pluginIsActive:
 5            self.pluginIsActive = True
 6
 7            #print "** STARTING SaveViews"
 8
 9            # dockwidget may not exist if:
10            #    first run of plugin
11            #    removed on close (see self.onClosePlugin method)
12            if self.dockwidget == None:
13                # Create the dockwidget (after translation) and keep reference
14                self.dockwidget = SaveViewsDockWidget()
15                self.dockwidget.layers.setFilters(QgsMapLayerProxyModel.VectorLayer)
16                self.dockwidget.output_dir.setStorageMode(QgsFileWidget.GetDirectory)
17                self.dockwidget.submit.clicked.connect(self.save_views)
18
19            # connect to provide cleanup on closing of dockwidget
20            self.dockwidget.closingPlugin.connect(self.onClosePlugin)
21
22            # show the dockwidget
23            # TODO: fix to allow choice of dock location
24            self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dockwidget)
25            self.dockwidget.show()

Note, that we had to import QGIS Python modules

1from qgis.PyQt.QtGui import QColor, QPixmap
2from qgis.utils import iface
3from qgis.core import QgsMapLayerProxyModel
4from qgis.gui import QgsFileWidget

Tip

For testing purpose we can hardcode output path

self.dockwidget.output_dir.setFilePath("/tmp/output")

Image save function

Finally, we approach to the heart of the plugin: the save_views() method.

 1    def save_views(self):
 2        """
 3        save graphical output for every row in attribute table
 4        """
 5        layer = self.dockwidget.layers.currentLayer()
 6        
 7        for feature in layer.getFeatures():
 8            layer.selectByIds([feature.id()])
 9            self.iface.mapCanvas().setSelectionColor(QColor("transparent"))
10            box = layer.boundingBoxOfSelected()
11            self.iface.mapCanvas().setExtent(box)
12            pixmap = QPixmap(self.iface.mapCanvas().mapSettings().outputSize().width(),
13                             self.iface.mapCanvas().mapSettings().outputSize().height()
14                             )
15            mapfile = os.path.join(
16                self.dockwidget.output_dir.filePath(),
17                '{0}_{1:03d}.png'.format(layer.name(), feature.id())
18            )
19            self.iface.mapCanvas().saveAsImage(mapfile, pixmap)
20            layer.removeSelection()
21
22        # save also full extend of vector layer                            
23        canvas = self.iface.mapCanvas()
24        canvas.setExtent(layer.extent())
25        pixmap = QPixmap(self.iface.mapCanvas().mapSettings().outputSize().width(),
26                         self.iface.mapCanvas().mapSettings().outputSize().height()
27                         )
28        mapfile = os.path.join(
29            self.dockwidget.output_dir.filePath(),
30            '{}_full.png'.format(layer.name())
31        )
32        self.iface.mapCanvas().saveAsImage(mapfile, pixmap)
../_images/plugin-ui-final2.png

Task

Make sure that the plugin will not fail, if no target directory is selected.

Hint

In case that you want to change plugin icon, modify the icon.png file as you wish.

../_images/save-views-result.png

Fig. 20 Example of image files stored in output directory.

Note

The code can be downloaded from our Github.