Este breve tutorial es un complemento a la entrada anterior de mi blog, Introducción a PyQGIS, donde describí cómo empezar a usar PyQGIS desde la consola de Python integrada en la interfaz gráfica de QGIS. Si bien lo recomendable es que mientras desarrollamos un proceso de automatización con PyQGIS usemos la consola integrada para ir viendo visualmente que los resultados que obtenemos son los que deseamos, también es un poco engorroso escribir código desde el editor de esa consola, porque es muy básico y le faltan características como autocompletado, resaltado, revisión de sintaxis y otras herramientas que los IDES modernos ofrecen.

Desde hace pocos años es posible instalar QGIS como una librería más de conda, lo que permite crear ambientes aisalados que incluyan QGIS. De esta forma, es posible desarrollar usando PyQGIS sin afectar la instalación de la aplicación de escritorio de QGIS. Esto es importante, porque si queremos instalar librerías adicionales de análisis de datos, es mucho más seguro hacerlo desde un ambiente aislado, así en caso que haya incompatibilidades entre librerías o que se afecten aquellas de las que depende PyQGIS y esto genere errores, no hay más que crear un nuevo ambiente y empezar otra vez. Si eso ocurriera dentro de la aplicación de escritorio, probablemente tendríamos que desinstalar y volver a instalar QGIS. Antes de que QGIS fuera una librería de conda, no era fácil establecer un ambiente de desarrollo de PyQGIS que no estuviera ligado al intérprete de Python incluido en QGIS. Afortunadamente con conda es tremendamente fácil instalar un ambiente.

Para empezar es necesario contar con Anaconda o Miniconda. Luego desde la terminal de comandos podemos ejecutar de forma secuencial los sigientes comandos:

conda create -n qgis -c conda-forge qgis jupyterlab matplotlib
conda activate qgis
jupyter lab

En la primera línea estamos creando un nuevo ambiente llamado qgis y además le pedimos que instale las librerías qgis, jupyterlab y matplotlib desde el canal de conda-forge. En la segunda línea activamos el ambiente y en la tercera lanzamos Jupyter Lab que es mi IDE preferido para trabajar en análisis datos.

Con esto podemos crear un nuevo notebook y ya podremos ejecutar código de PyQGIS. Así de sencillo. Por ejemplo, usando una versión ligeramente modificada del primer script que usé en mi entrada anterior así lo puedo ejecutar:

import json
import os
import sys
from qgis.core import QgsProject, QgsVectorLayer, QgsProcessingFeatureSourceDefinition, QgsFeatureRequest, QgsVectorFileWriter, QgsApplication, QgsProcessingProvider
from qgis.analysis import QgsNativeAlgorithms
import matplotlib.pyplot as plt

os.environ["QT_QPA_PLATFORM"] = "offscreen" # Esta línea es necesaria para poder iniciar una instancia QgsApplication(), en caso de que sea necesario

QgsApplication.setPrefixPath(None, True)

import processing
from processing.core.Processing import Processing

# Inicia algoritmos
Processing.initialize()

# establece directorio de trabajo
os.chdir('/home/studio-lab-user/sagemaker-studiolab-notebooks/intro_pyqgis')

proyecto = QgsProject.instance()

# carpeta donde están los datos
dir_data = "datos"
nombre_layer_colonias = "colonias_cdmx"
layer_colonias = QgsVectorLayer(f"{dir_data}/colonias_iecm_2019/mgpc_2019.shp", nombre_layer_colonias)
if not proyecto.mapLayersByName(nombre_layer_colonias):
    proyecto.addMapLayer(layer_colonias)

print("Número de capas en el proyecto:", proyecto.count())
print("CRS del proyecto:", proyecto.crs().description())
print("Directorio del proyecto:", proyecto.homePath())

print("Número de filas:", layer_colonias.featureCount())
print("Número de columnas:", len(layer_colonias.fields()))
print("Sistema de coordenadas:", layer_colonias.crs().description())

for f in layer_colonias.fields():
    print(f.name(), f.typeName())
#
feature = layer_colonias.getFeature(10)
print(feature)
print(feature.attributes())
#
geom = feature.geometry()
print(geom.centroid())

coords = json.loads(geom.asJson())["coordinates"][0][0]
coords_centroide = json.loads(geom.centroid().asJson())["coordinates"]
x, y = [[xy[n] for xy in coords] for n in [0, 1]]
ax = plt.subplot()
ax.plot(x, y)
ax.plot([coords_centroide[0]], [coords_centroide[1]], 'bo')
ax.text(x=coords_centroide[0], y=coords_centroide[1], s=feature.attribute("NOMUT"))
Número de capas en el proyecto: 1
CRS del proyecto: 
Directorio del proyecto: 
Número de filas: 1815
Número de columnas: 8
Sistema de coordenadas: WGS 84 / UTM zone 14N
ENT String
CVEDT String
NOMDT String
DTTOLOC String
CVEUT String
NOMUT String
POB2010 String
ID Integer
<qgis._core.QgsFeature object at 0x7f09dd057400>
['9', '2', 'AZCAPOTZALCO', '05', '02-013', 'CUITLÁHUAC 1 Y 2 (U HAB)', '2449', 11]
<QgsGeometry: Point (482445.29628468106966466 2153086.92174857435747981)>
QObject::startTimer: Timers can only be used with threads started with QThread
Text(482445.2962846811, 2153086.9217485744, 'CUITLÁHUAC 1 Y 2 (U HAB)')

Como podemos ver, el resultado es el mismo que el que obtuvimos usando la consola de Python dentro de QGIS.

Para poder correr este script tuve que hacer unas pequeñas modificaciones, la más importante y necesaria para que todo funcione, fue que tuve que agregar la línea:

QgsApplication.setPrefixPath(None, True)

antes de importar la librería processing e inicializar los algoritmos. Usualmente el primer argumento es la ubicación de la carpeta donde está instalado QGIS, aunque en mi caso parece que el sistema lo identifica automáticamente y por eso simplemente puedo poner un None. En cualquier caso, si al intentarlo no te funciona, intenta poniendo la dirección a la carpeta de tu instalación de QGIS, en mi caso sería:

QgsApplication.setPrefixPath('/home/studio-lab-user/.conda/envs/qgis/share/qgis', True)

Otra línea que tuve que agregar fue:

os.chdir('/home/studio-lab-user/sagemaker-studiolab-notebooks/intro_pyqgis')

para establecer el directorio de trabajo principal ya que este notebook lo estoy escribiendo desde el servicio de Amazon SageMaker Studio Lab, que ofrece de forma gratuita (y sin pedir medios de pago ni cuenta de AWS) una máquina virtual de 16GB de RAM y 15GB de almacenamiento persistente. El almacenamiento persistente me permite crear ambientes de conda y las librerías instaladas permanecen siempre, a diferencia de Google Colab (que también es un gran, gran, gran servicio) donde debes instalar las librerías cada vez que inicias una sesión. Que por cierto, en un post de su blog Lerry W nos muestra cómo instalar QGIS dentro de Colab.

Volviendo al código, a continuación ejecutamos un fragmento del script intro_pyqgis_04.py en el que calculamos los centroides de la capa de colonias_cdmx y exportamos los resultados en formato GeoJSON. La diferencia con el publicado anteriormente es que en lugar de añadir la capa resultante al proyecto, ya mejor la exportamos directamente especificando la ruta en el parámetro 'OUTPUT'. Dado que ya no estamos usando la interfaz gráfica, en realidad no tiene mucho sentido añadirla al proyecto para poder visualizarla.

params = {
    'INPUT': QgsProcessingFeatureSourceDefinition(
        nombre_layer_colonias, selectedFeaturesOnly=False,
        featureLimit=-1,
        flags=QgsProcessingFeatureSourceDefinition.FlagOverrideDefaultGeometryCheck,
        geometryCheck=QgsFeatureRequest.GeometrySkipInvalid
    ),
    'ALL_PARTS': False,
    'OUTPUT': f"{dir_data}/centroides_colonias.geojson"
}

try:
    out = processing.run("native:centroids", params)
except:
    out = processing.run("native:centroids", params)
Warning 1: organizePolygons() received an unexpected geometry.  Either a polygon with interior rings, or a polygon with less than 4 points, or a non-Polygon geometry.  Return arguments as a collection.
QObject::startTimer: Timers can only be used with threads started with QThread

Warning: en la celda anterior tuve que introducir un bloque try-except porque, por alguna razón desconocida para mí, al ejecutar una vez la línea processing.run("native:centroids", params) arroja un error, pero después de dos o más ejecuciones funciona sin problema. Hay que tener en cuenta que esta versión de QGIS en conda no es oficialmente soportada por los desarrolladores QGIS y puede que tenga comportamientos un poco distintos que la versión oficial que es la que viene con QGIS.

Y precisamente, como no tenemos la interfaz gráfica de QGIS, no podemos visualizar directamente los resultados. Aún así, nos la podemos arreglar para usar matplotlib y graficar los puntos. Otra opción obvia es GeoPandas.

layer_centroides = QgsVectorLayer(out["OUTPUT"])
geoms = [f.geometry().asPoint() for f in layer_centroides.getFeatures()]
points_x = [p.x() for p in geoms]
points_y = [p.y() for p in geoms]

ax = plt.subplot()
ax.plot(points_x, points_y, 'bo', alpha=0.2)
ax.set_aspect('equal')
ax.figure.set_size_inches(8, 8)
ax.set_title("Colonias de la CDMX")
QObject::startTimer: Timers can only be used with threads started with QThread
Text(0.5, 1.0, 'Colonias de la CDMX')

A mí en particular me gusta mucho trabajar con Jupyter Lab, pero si se prefiere también es posible usar otros editores como PyCharm o VScode ya que estos también tienen soporte para trabajar con ambientes de Conda.

Y hasta aquí llega esta entrada.

Anexo final

Dejo este código que nos permite encontrar el ID de todos los algoritmos disponibles en PyQGIS:

QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms())
for alg in QgsApplication.processingRegistry().algorithms():
    print(alg.id(), "--->", alg.displayName())
Logged warning: Duplicate provider native registered
3d:tessellate ---> Tessellate
gdal:aspect ---> Aspect
gdal:assignprojection ---> Assign projection
gdal:buffervectors ---> Buffer vectors
gdal:buildvirtualraster ---> Build virtual raster
gdal:buildvirtualvector ---> Build virtual vector
gdal:cliprasterbyextent ---> Clip raster by extent
gdal:cliprasterbymasklayer ---> Clip raster by mask layer
gdal:clipvectorbyextent ---> Clip vector by extent
gdal:clipvectorbypolygon ---> Clip vector by mask layer
gdal:colorrelief ---> Color relief
gdal:contour ---> Contour
gdal:contour_polygon ---> Contour Polygons
gdal:convertformat ---> Convert format
gdal:dissolve ---> Dissolve
gdal:executesql ---> Execute SQL
gdal:extractprojection ---> Extract projection
gdal:fillnodata ---> Fill nodata
gdal:gdal2tiles ---> gdal2tiles
gdal:gdal2xyz ---> gdal2xyz
gdal:gdalinfo ---> Raster information
gdal:gridaverage ---> Grid (Moving average)
gdal:griddatametrics ---> Grid (Data metrics)
gdal:gridinversedistance ---> Grid (Inverse distance to a power)
gdal:gridinversedistancenearestneighbor ---> Grid (IDW with nearest neighbor searching)
gdal:gridlinear ---> Grid (Linear)
gdal:gridnearestneighbor ---> Grid (Nearest neighbor)
gdal:hillshade ---> Hillshade
gdal:importvectorintopostgisdatabaseavailableconnections ---> Export to PostgreSQL (available connections)
gdal:importvectorintopostgisdatabasenewconnection ---> Export to PostgreSQL (new connection)
gdal:merge ---> Merge
gdal:nearblack ---> Near black
gdal:offsetcurve ---> Offset curve
gdal:ogrinfo ---> Vector information
gdal:onesidebuffer ---> One side buffer
gdal:overviews ---> Build overviews (pyramids)
gdal:pansharp ---> Pansharpening
gdal:pcttorgb ---> PCT to RGB
gdal:pointsalonglines ---> Points along lines
gdal:polygonize ---> Polygonize (raster to vector)
gdal:proximity ---> Proximity (raster distance)
gdal:rastercalculator ---> Raster calculator
gdal:rasterize ---> Rasterize (vector to raster)
gdal:rasterize_over ---> Rasterize (overwrite with attribute)
gdal:rasterize_over_fixed_value ---> Rasterize (overwrite with fixed value)
gdal:rearrange_bands ---> Rearrange bands
gdal:retile ---> Retile
gdal:rgbtopct ---> RGB to PCT
gdal:roughness ---> Roughness
gdal:sieve ---> Sieve
gdal:slope ---> Slope
gdal:tileindex ---> Tile index
gdal:tpitopographicpositionindex ---> Topographic Position Index (TPI)
gdal:translate ---> Translate (convert format)
gdal:triterrainruggednessindex ---> Terrain Ruggedness Index (TRI)
gdal:viewshed ---> Viewshed
gdal:warpreproject ---> Warp (reproject)
native:addautoincrementalfield ---> Add autoincremental field
native:addfieldtoattributestable ---> Add field to attributes table
native:adduniquevalueindexfield ---> Add unique value index field
native:addxyfields ---> Add X/Y fields to layer
native:affinetransform ---> Affine transform
native:aggregate ---> Aggregate
native:angletonearest ---> Align points to features
native:antimeridiansplit ---> Geodesic line split at antimeridian
native:arrayoffsetlines ---> Array of offset (parallel) lines
native:arraytranslatedfeatures ---> Array of translated features
native:aspect ---> Aspect
native:assignprojection ---> Assign projection
native:atlaslayouttoimage ---> Export atlas layout as image
native:atlaslayouttopdf ---> Export atlas layout as PDF
native:bookmarkstolayer ---> Convert spatial bookmarks to layer
native:boundary ---> Boundary
native:boundingboxes ---> Bounding boxes
native:buffer ---> Buffer
native:bufferbym ---> Variable width buffer (by M value)
native:calculatevectoroverlaps ---> Overlap analysis
native:categorizeusingstyle ---> Create categorized renderer from styles
native:cellstackpercentile ---> Cell stack percentile
native:cellstackpercentrankfromrasterlayer ---> Cell stack percentrank from raster layer
native:cellstackpercentrankfromvalue ---> Cell stack percent rank from value
native:cellstatistics ---> Cell statistics
native:centroids ---> Centroids
native:clip ---> Clip
native:collect ---> Collect geometries
native:combinestyles ---> Combine style databases
native:condition ---> Conditional branch
native:converttocurves ---> Convert to curved geometries
native:convexhull ---> Convex hull
native:countpointsinpolygon ---> Count points in polygon
native:createattributeindex ---> Create attribute index
native:createconstantrasterlayer ---> Create constant raster layer
native:createdirectory ---> Create directory
native:creategrid ---> Create grid
native:createpointslayerfromtable ---> Create points layer from table
native:createrandombinomialrasterlayer ---> Create random raster layer (binomial distribution)
native:createrandomexponentialrasterlayer ---> Create random raster layer (exponential distribution)
native:createrandomgammarasterlayer ---> Create random raster layer (gamma distribution)
native:createrandomgeometricrasterlayer ---> Create random raster layer (geometric distribution)
native:createrandomnegativebinomialrasterlayer ---> Create random raster layer (negative binomial distribution)
native:createrandomnormalrasterlayer ---> Create random raster layer (normal distribution)
native:createrandompoissonrasterlayer ---> Create random raster layer (poisson distribution)
native:createrandomuniformrasterlayer ---> Create random raster layer (uniform distribution)
native:createspatialindex ---> Create spatial index
native:dbscanclustering ---> DBSCAN clustering
native:deletecolumn ---> Drop field(s)
native:deleteduplicategeometries ---> Delete duplicate geometries
native:deleteholes ---> Delete holes
native:densifygeometries ---> Densify by count
native:densifygeometriesgivenaninterval ---> Densify by interval
native:detectvectorchanges ---> Detect dataset changes
native:difference ---> Difference
native:dissolve ---> Dissolve
native:dropgeometries ---> Drop geometries
native:dropmzvalues ---> Drop M/Z values
native:dxfexport ---> Export layers to DXF
native:equaltofrequency ---> Equal to frequency
native:explodehstorefield ---> Explode HStore Field
native:explodelines ---> Explode lines
native:exportlayersinformation ---> Export layer(s) information
native:exportmeshedges ---> Export mesh edges
native:exportmeshfaces ---> Export mesh faces
native:exportmeshongrid ---> Export mesh on grid
native:exportmeshvertices ---> Export mesh vertices
native:exporttospreadsheet ---> Export to spreadsheet
native:extendlines ---> Extend lines
native:extenttolayer ---> Create layer from extent
native:extractbinary ---> Extract binary field
native:extractbyattribute ---> Extract by attribute
native:extractbyexpression ---> Extract by expression
native:extractbyextent ---> Extract/clip by extent
native:extractbylocation ---> Extract by location
native:extractmvalues ---> Extract M values
native:extractspecificvertices ---> Extract specific vertices
native:extractvertices ---> Extract vertices
native:extractzvalues ---> Extract Z values
native:fieldcalculator ---> Field calculator
native:filedownloader ---> Download file
native:fillnodata ---> Fill NoData cells
native:filter ---> Feature filter
native:filterbygeometry ---> Filter by geometry type
native:filterlayersbytype ---> Filter layers by type
native:filterverticesbym ---> Filter vertices by M value
native:filterverticesbyz ---> Filter vertices by Z value
native:fixgeometries ---> Fix geometries
native:flattenrelationships ---> Flatten relationship
native:forcerhr ---> Force right-hand-rule
native:fuzzifyrastergaussianmembership ---> Fuzzify raster (gaussian membership)
native:fuzzifyrasterlargemembership ---> Fuzzify raster (large membership)
native:fuzzifyrasterlinearmembership ---> Fuzzify raster (linear membership)
native:fuzzifyrasternearmembership ---> Fuzzify raster (near membership)
native:fuzzifyrasterpowermembership ---> Fuzzify raster (power membership)
native:fuzzifyrastersmallmembership ---> Fuzzify raster (small membership)
native:generatepointspixelcentroidsinsidepolygons ---> Generate points (pixel centroids) inside polygons
native:geometrybyexpression ---> Geometry by expression
native:greaterthanfrequency ---> Greater than frequency
native:highestpositioninrasterstack ---> Highest position in raster stack
native:hillshade ---> Hillshade
native:hublines ---> Join by lines (hub lines)
native:importphotos ---> Import geotagged photos
native:interpolatepoint ---> Interpolate point on line
native:intersection ---> Intersection
native:joinattributesbylocation ---> Join attributes by location
native:joinattributestable ---> Join attributes by field value
native:joinbynearest ---> Join attributes by nearest
native:kmeansclustering ---> K-means clustering
native:layertobookmarks ---> Convert layer to spatial bookmarks
native:lessthanfrequency ---> Less than frequency
native:linedensity ---> Line density
native:lineintersections ---> Line intersections
native:linesubstring ---> Line substring
native:loadlayer ---> Load layer into project
native:lowestpositioninrasterstack ---> Lowest position in raster stack
native:meancoordinates ---> Mean coordinate(s)
native:mergelines ---> Merge lines
native:mergevectorlayers ---> Merge vector layers
native:meshcontours ---> Export contours
native:meshexportcrosssection ---> Export cross section dataset values on lines from mesh
native:meshexporttimeseries ---> Export time series values from points of a mesh dataset
native:meshrasterize ---> Rasterize mesh dataset
native:minimumenclosingcircle ---> Minimum enclosing circles
native:multiparttosingleparts ---> Multipart to singleparts
native:multiringconstantbuffer ---> Multi-ring buffer (constant distance)
native:nearestneighbouranalysis ---> Nearest neighbour analysis
native:offsetline ---> Offset lines
native:orderbyexpression ---> Order by expression
native:orientedminimumboundingbox ---> Oriented minimum bounding box
native:orthogonalize ---> Orthogonalize
native:package ---> Package layers
native:pixelstopoints ---> Raster pixels to points
native:pixelstopolygons ---> Raster pixels to polygons
native:pointonsurface ---> Point on surface
native:pointsalonglines ---> Points along geometry
native:pointstopath ---> Points to path
native:pointtolayer ---> Create layer from point
native:poleofinaccessibility ---> Pole of inaccessibility
native:polygonfromlayerextent ---> Extract layer extent
native:polygonize ---> Polygonize
native:polygonstolines ---> Polygons to lines
native:postgisexecutesql ---> PostgreSQL execute SQL
native:printlayoutmapextenttolayer ---> Print layout map extent to layer
native:printlayouttoimage ---> Export print layout as image
native:printlayouttopdf ---> Export print layout as PDF
native:projectpointcartesian ---> Project points (Cartesian)
native:promotetomulti ---> Promote to multipart
native:raiseexception ---> Raise exception
native:raisewarning ---> Raise warning
native:randomextract ---> Random extract
native:randompointsinextent ---> Random points in extent
native:randompointsinpolygons ---> Random points in polygons
native:randompointsonlines ---> Random points on lines
native:rasterbooleanand ---> Raster boolean AND
native:rasterize ---> Convert map to raster
native:rasterlayerstatistics ---> Raster layer statistics
native:rasterlayeruniquevaluesreport ---> Raster layer unique values report
native:rasterlayerzonalstats ---> Raster layer zonal statistics
native:rasterlogicalor ---> Raster boolean OR
native:rastersampling ---> Sample raster values
native:rastersurfacevolume ---> Raster surface volume
native:reclassifybylayer ---> Reclassify by layer
native:reclassifybytable ---> Reclassify by table
native:rectanglesovalsdiamonds ---> Rectangles, ovals, diamonds
native:refactorfields ---> Refactor fields
native:removeduplicatesbyattribute ---> Delete duplicates by attribute
native:removeduplicatevertices ---> Remove duplicate vertices
native:removenullgeometries ---> Remove null geometries
native:renamelayer ---> Rename layer
native:renametablefield ---> Rename field
native:repairshapefile ---> Repair Shapefile
native:reprojectlayer ---> Reproject layer
native:rescaleraster ---> Rescale raster
native:retainfields ---> Retain fields
native:reverselinedirection ---> Reverse line direction
native:rotatefeatures ---> Rotate
native:roundrastervalues ---> Round raster
native:ruggednessindex ---> Ruggedness index
native:savefeatures ---> Save vector features to file
native:savelog ---> Save log to file
native:saveselectedfeatures ---> Extract selected features
native:segmentizebymaxangle ---> Segmentize by maximum angle
native:segmentizebymaxdistance ---> Segmentize by maximum distance
native:selectbylocation ---> Select by location
native:serviceareafromlayer ---> Service area (from layer)
native:serviceareafrompoint ---> Service area (from point)
native:setlayerencoding ---> Set layer encoding
native:setlayerstyle ---> Set layer style
native:setmfromraster ---> Set M value from raster
native:setmvalue ---> Set M value
native:setprojectvariable ---> Set project variable
native:setzfromraster ---> Drape (set Z value from raster)
native:setzvalue ---> Set Z value
native:shortestpathlayertopoint ---> Shortest path (layer to point)
native:shortestpathpointtolayer ---> Shortest path (point to layer)
native:shortestpathpointtopoint ---> Shortest path (point to point)
native:shpencodinginfo ---> Extract Shapefile encoding
native:simplifygeometries ---> Simplify
native:singlesidedbuffer ---> Single sided buffer
native:slope ---> Slope
native:smoothgeometry ---> Smooth
native:snapgeometries ---> Snap geometries to layer
native:snappointstogrid ---> Snap points to grid
native:spatialiteexecutesql ---> SpatiaLite execute SQL
native:spatialiteexecutesqlregistered ---> SpatiaLite execute SQL (registered DB)
native:splitfeaturesbycharacter ---> Split features by character
native:splitlinesbylength ---> Split lines by maximum length
native:splitvectorlayer ---> Split vector layer
native:splitwithlines ---> Split with lines
native:stringconcatenation ---> String concatenation
native:stylefromproject ---> Create style database from project
native:subdivide ---> Subdivide
native:sumlinelengths ---> Sum line lengths
native:swapxy ---> Swap X and Y coordinates
native:symmetricaldifference ---> Symmetrical difference
native:taperedbuffer ---> Tapered buffers
native:tinmeshcreation ---> TIN Mesh Creation
native:transect ---> Transect
native:translategeometry ---> Translate
native:truncatetable ---> Truncate table
native:union ---> Union
native:wedgebuffers ---> Create wedge buffers
native:writevectortiles_mbtiles ---> Write Vector Tiles (MBTiles)
native:writevectortiles_xyz ---> Write Vector Tiles (XYZ)
native:zonalhistogram ---> Zonal histogram
native:zonalstatistics ---> Zonal statistics (in place)
native:zonalstatisticsfb ---> Zonal statistics
qgis:advancedpythonfieldcalculator ---> Advanced Python field calculator
qgis:barplot ---> Bar plot
qgis:basicstatisticsforfields ---> Basic statistics for fields
qgis:boxplot ---> Box plot
qgis:checkvalidity ---> Check validity
qgis:climbalongline ---> Climb along line
qgis:concavehull ---> Concave hull (alpha shapes)
qgis:convertgeometrytype ---> Convert geometry type
qgis:definecurrentprojection ---> Define Shapefile projection
qgis:delaunaytriangulation ---> Delaunay triangulation
qgis:distancematrix ---> Distance matrix
qgis:distancetonearesthublinetohub ---> Distance to nearest hub (line to hub)
qgis:distancetonearesthubpoints ---> Distance to nearest hub (points)
qgis:eliminateselectedpolygons ---> Eliminate selected polygons
qgis:executesql ---> Execute SQL
qgis:exportaddgeometrycolumns ---> Add geometry attributes
qgis:findprojection ---> Find projection
qgis:generatepointspixelcentroidsalongline ---> Generate points (pixel centroids) along line
qgis:heatmapkerneldensityestimation ---> Heatmap (Kernel Density Estimation)
qgis:hypsometriccurves ---> Hypsometric curves
qgis:idwinterpolation ---> IDW interpolation
qgis:importintopostgis ---> Export to PostgreSQL
qgis:importintospatialite ---> Export to SpatiaLite
qgis:joinbylocationsummary ---> Join attributes by location (summary)
qgis:keepnbiggestparts ---> Keep N biggest parts
qgis:knearestconcavehull ---> Concave hull (k-nearest neighbor)
qgis:linestopolygons ---> Lines to polygons
qgis:listuniquevalues ---> List unique values
qgis:meanandstandarddeviationplot ---> Mean and standard deviation plot
qgis:minimumboundinggeometry ---> Minimum bounding geometry
qgis:pointsdisplacement ---> Points displacement
qgis:polarplot ---> Polar plot
qgis:postgisexecuteandloadsql ---> PostgreSQL execute and load SQL
qgis:randomextractwithinsubsets ---> Random extract within subsets
qgis:randompointsalongline ---> Random points along line
qgis:randompointsinlayerbounds ---> Random points in layer bounds
qgis:randompointsinsidepolygons ---> Random points inside polygons
qgis:randomselection ---> Random selection
qgis:randomselectionwithinsubsets ---> Random selection within subsets
qgis:rastercalculator ---> Raster calculator
qgis:rasterlayerhistogram ---> Raster layer histogram
qgis:rectanglesovalsdiamondsvariable ---> Rectangles, ovals, diamonds (variable)
qgis:regularpoints ---> Regular points
qgis:relief ---> Relief
qgis:scatter3dplot ---> Vector layer scatterplot 3D
qgis:selectbyattribute ---> Select by attribute
qgis:selectbyexpression ---> Select by expression
qgis:setstyleforrasterlayer ---> Set style for raster layer
qgis:setstyleforvectorlayer ---> Set style for vector layer
qgis:statisticsbycategories ---> Statistics by categories
qgis:texttofloat ---> Text to float
qgis:tilesxyzdirectory ---> Generate XYZ tiles (Directory)
qgis:tilesxyzmbtiles ---> Generate XYZ tiles (MBTiles)
qgis:tininterpolation ---> TIN interpolation
qgis:topologicalcoloring ---> Topological coloring
qgis:variabledistancebuffer ---> Variable distance buffer
qgis:vectorlayerhistogram ---> Vector layer histogram
qgis:vectorlayerscatterplot ---> Vector layer scatterplot
qgis:voronoipolygons ---> Voronoi polygons