33. Developing QGIS Plugin#
33.1. Quickstart to develop a processing plugin#
Create a plugin template with the QGIS plugin “Plugin Builder”. We will create a processing plugin, where I am just going to use the default GUI given by QGIS to develop the plugin. The plugin will appear in Processing -> Toolbox -> gis3d
Copy and paste the plugin folders to the qgis plugin folders with the following command.
cp -r /where/your/plugin/is /home/your_usr_name/.local/share/QGIS/QGIS3/profiles/default/python/plugins
Open QGIS, the plugin should appear in the processing toolbox window
Repeat 1- 3 as you make changes to your plugin. Download the plugin “Plugin Reloader”. So that you can just reload the plugin without shutting down QGIS.
33.3. How to edit the input layer#
An example script showing how to edit the input layer.
def initAlgorithm(self, config):
....
....
....
self.addParameter(
QgsProcessingParameterFeatureSource(
self.TREE_HEIGHT,
self.tr('Tree Grid Layer'),
[QgsProcessing.TypeVectorAnyGeometry]
)
)
....
....
....
def processAlgorithm(self, parameters, context, feedback):
....
....
....
tree = self.parameterAsVectorLayer(parameters, self.TREE_HEIGHT, context)
tree_data = tree.dataProvider()
tree_data.addAttributes([QgsField(tree_height_name, QVariant.Double)])
tree.updateFields()
tree_features = tree.getFeatures()
tree_fields = tree.fields().names()
tree_height_field_id = tree_fields.index(tree_height_name)
total = 100.0 / tree.featureCount() if tree.featureCount() else 0
for cnt, feature in enumerate(tree_features):
# Stop the algorithm if cancel button has been clicked
if feedback.isCanceled():
break
# Update the progress bar
feedback.setProgress(int(cnt * total))
fid = feature.id()
attrs = {tree_height_field_id: 15.2}
tree_data.changeAttributeValues({fid:attrs})
....
....
....
33.4. How to create a new layer and populate it with new features and attributes#
An example script showing how to create a new sink layer.
def initAlgorithm(self, config):
....
....
....
self.addParameter(QgsProcessingParameterFeatureSource(self.TREE_HEIGHT,
self.tr('Tree Grid Layer'),
[QgsProcessing.TypeVectorAnyGeometry])
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT,
self.tr('Tree Height Layer'),
QgsProcessing.TypeVectorPolygon))
....
....
....
def processAlgorithm(self, parameters, context, feedback):
....
....
....
tree = self.parameterAsSource(parameters, self.TREE_HEIGHT, context) #QgsProcessingFeatureSource
fields = tree.fields()
fields.append(QgsField(tree_height_name, QVariant.Double))
tree_features = tree.getFeatures()
total = 100.0 / tree.featureCount() if tree.featureCount() else 0
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, tree.wkbType(), tree.sourceCrs())
for cnt,feature in enumerate(tree_features):
# Stop the algorithm if cancel button has been clicked
if feedback.isCanceled():
break
# Update the progress bar
feedback.setProgress(int(cnt * total))
feature.setFields(fields)
feature[tree_height_name] = 15.3
sink.addFeature(feature, QgsFeatureSink.FastInsert)
....
....
....
33.5. Submitting your plugin to QGIS plugin repository#
official guide: https://docs.qgis.org/testing/en/docs/pyqgis_developer_cookbook/plugins/releasing.html#plugin-structure
zip your file and make sure you feel in all the mandatory fields in the metadata.txt
get a osgeoid and submit your plugin to https://plugins.qgis.org/plugins/ and wait for approval
create local respository: https://training.gismentors.eu/qgis-plugins/publish_plugin.html
alternatively you can consider setting up a local repository
guidelines: https://plugins.qgis.org/publish/
33.6. Geopandas and laspy#
read and write files with geopandas: https://geopandas.org/en/stable/docs/user_guide/io.html#reading-and-writing-files
laspy specification: https://www.asprs.org/wp-content/uploads/2019/03/LAS_1_4_r14.pdf
33.7. Resources#
QGIS Python API: https://api.qgis.org/api/annotated.html
QGIS python tutorials: https://www.qgistutorials.com/en/docs/3/getting_started_with_pyqgis.html
plugin resources
QGIS documentation: https://docs.qgis.org/testing/en/docs/pyqgis_developer_cookbook/plugins/index.html
Minimal plugin example: wonder-sk/qgis-minimal-plugin
QGIS plugin-CI:
plugin tutorials
building a QGIS plugin: https://www.qgistutorials.com/en/docs/3/building_a_python_plugin.html
building a QGIS processing plugin: https://www.qgistutorials.com/en/docs/3/processing_python_plugin.html
building plugin: https://training.gismentors.eu/qgis-plugins/build_plugin.html
plugin examples
gis3d: chenkianwee/gis3d
shortest path processing algorithm: root676/QNEAT3
cityjson loader: cityjson/cityjson-qgis-plugin
3dcitybuilder: arthurRuf/3dcitybuilder
third party python library:
Multiple layer parameters
Get filepath of parameter layer
tree_info = self.parameterDefinition(self.TREE_HEIGHT).valueAsJsonObject(parameters[self.TREE_HEIGHT], context) -quickapi example