Skip to content

QGIS开发教程

说明

QGIS二次开发的方式包括:Python命令行、代码编辑器和Python脚本等。

一、Python命令行

Python命令行

Python Console面板可分为:1.顶部工具栏;2.控制台;3.命令输入窗口。下面以调用Buffer为例,说明一下Python Console的使用。

1. 查看帮助文档

在顶部工具栏点击Help按钮,即可查看相关的帮助文档,相关的帮助文档有:

1. 引入依赖

在命令行中使用Processing需要先输入代码from qgis import processing引入依赖。

2. 查看所有可用工具

可在命令行中输入如下代码查看所有可用工具。

python
for alg in QgsApplication.processingRegistry().algorithms():
    print(alg.id(), "->", alg.displayName())

运行后结果如下。

list-tools

3. 查看帮助

在命令行中输入processing.algorithmHelp("native:buffer")可查看Buffer的详细帮助,输出内容如下。

txt
This algorithm computes a buffer area for all the features in an input layer, using a fixed or dynamic distance.

The segments parameter controls the number of line segments to use to approximate a quarter circle when creating rounded offsets.

The end cap style parameter controls how line endings are handled in the buffer.

The join style parameter specifies whether round, miter or beveled joins should be used when offsetting corners in a line.

The miter limit parameter is only applicable for miter join styles, and controls the maximum distance from the offset curve to use when creating a mitered join.


----------------
Input parameters
----------------

INPUT: Input layer

	Parameter type:	QgsProcessingParameterFeatureSource

	Accepted data types:
		- str: layer ID
		- str: layer name
		- str: layer source
		- QgsProcessingFeatureSourceDefinition
		- QgsProperty
		- QgsVectorLayer

DISTANCE: Distance

	Parameter type:	QgsProcessingParameterDistance

	Accepted data types:
		- int
		- float
		- QgsProperty

SEGMENTS: Segments

	The segments parameter controls the number of line segments to use to approximate a quarter circle when creating rounded offsets.

	Parameter type:	QgsProcessingParameterNumber

	Accepted data types:
		- int
		- float
		- QgsProperty

END_CAP_STYLE: End cap style

	Parameter type:	QgsProcessingParameterEnum

	Available values:
		- 0: Round
		- 1: Flat
		- 2: Square

	Accepted data types:
		- int
		- str: as string representation of int, e.g. '1'
		- QgsProperty

JOIN_STYLE: Join style

	Parameter type:	QgsProcessingParameterEnum

	Available values:
		- 0: Round
		- 1: Miter
		- 2: Bevel

	Accepted data types:
		- int
		- str: as string representation of int, e.g. '1'
		- QgsProperty

MITER_LIMIT: Miter limit

	Parameter type:	QgsProcessingParameterNumber

	Accepted data types:
		- int
		- float
		- QgsProperty

DISSOLVE: Dissolve result

	Parameter type:	QgsProcessingParameterBoolean

	Accepted data types:
		- bool
		- int
		- str
		- QgsProperty

OUTPUT: Buffered

	Parameter type:	QgsProcessingParameterFeatureSink

	Accepted data types:
		- str: destination vector file, e.g. 'd:/test.shp'
		- str: 'memory:' to store result in temporary memory layer
		- str: using vector provider ID prefix and destination URI, e.g. 'postgres:…' to store result in PostGIS table
		- QgsProcessingOutputLayerDefinition
		- QgsProperty

----------------
Outputs
----------------

OUTPUT:  <QgsProcessingOutputVectorLayer>
	Buffered

4. 输入数据

Buffer工具中,需要一个数据或者图层作为输入,我们可以通过如下方式指定输入数据。

  • 指定数据文件,layer = 'D:/桌面/capital.geojson'
  • 界面中当前选择的图层,layer = mc.currentLayer()
  • 界面中的图层,layer = mc.layer(0)

说明mc的定义如下代码所示。

python
mc = iface.mapCanvas()

for lyr in mc.layers():
    print(lyr.name())

5. 无界面运行

python
# 计算缓冲区
processing.run("native:buffer", {'INPUT': 'D:/lzugis23/proj/qgis培训/code/qgis-lecture/data/layer-capital.shp', 'DISTANCE': 0.1,'SEGMENTS': 10,'DISSOLVE': True,'END_CAP_STYLE': 0,'JOIN_STYLE': 0,'MITER_LIMIT': 10,'OUTPUT': 'D:/lzugis23/proj/qgis培训/code/qgis-lecture/data/layer-capital-buffer.shp'})

6. 有界面运行

可通过如下命令创建一个可交互的对话框,并打开对话框。

python
my_dialog = processing.createAlgorithmDialog("native:buffer", {'INPUT': 'D:/lzugis23/proj/qgis培训/code/qgis-lecture/data/layer-capital.shp', 'DISTANCE': 0.1,'SEGMENTS': 10,'DISSOLVE': True,'END_CAP_STYLE': 0,'JOIN_STYLE': 0,'MITER_LIMIT': 10,'OUTPUT': 'D:/lzugis23/proj/qgis培训/code/qgis-lecture/data/layer-capital-buffer.shp'});
my_dialog.show();

buffer-dialog

也可通过如下代码直接代开可交互的对话框。

python
# 创建对话框并立即打开
processing.execAlgorithmDialog("native:buffer", {'INPUT': 'D:/lzugis23/proj/qgis培训/code/qgis-lecture/data/layer-capital.shp', 'DISTANCE': 0.1,'SEGMENTS': 10,'DISSOLVE': True,'END_CAP_STYLE': 0,'JOIN_STYLE': 0,'MITER_LIMIT': 10,'OUTPUT': 'D:/lzugis23/proj/qgis培训/code/qgis-lecture/data/layer-capital-buffer.shp'});

二、代码编辑器

点击Python Console工具栏Show Editor即可打开代码编辑器,如下图所示。 code-editor

代码编辑器界面分为顶部工具栏和代码编辑区域,在编辑器中可编辑脚本,编辑完成后,点击Run按钮即可运行。

1. 查看图层属性

通过如下代码可打开数据并查看数据属性。

python
path = "D:/lzugis23/proj/qgis培训/code/qgis-lecture/data/layer-capital.shp"
vlayer = QgsVectorLayer(path, "layer-capital", "ogr")
    
for feature in vlayer.getFeatures():
    print (feature['name'])
    print ('-----------------')

code1

2. 多工具运行

如下代码演示了如何运行多个工具。

python
# 计算缓冲区并计算clip结果
from qgis import processing;

base_path = 'D:/lzugis23/proj/qgis培训/code/qgis-lecture/data/'
input1 = base_path + 'layer-capital.shp'
input2 = base_path + 'layer-college.shp'
output1 = base_path + 'capital-buffer.shp'
output2 = base_path + 'college-buffer.shp'
output3 = base_path + 'clip-result.shp'

processing.run("native:buffer", {
    'INPUT': input1, 
    'DISTANCE': 0.1,
    'SEGMENTS': 10,
    'DISSOLVE': True,
    'END_CAP_STYLE': 0,
    'JOIN_STYLE': 0,
    'MITER_LIMIT': 10,
    'OUTPUT': output1
})
processing.run("native:buffer", {
    'INPUT': input2, 
    'DISTANCE': 0.1,
    'SEGMENTS': 10,
    'DISSOLVE': True,
    'END_CAP_STYLE': 0,
    'JOIN_STYLE': 0,
    'MITER_LIMIT': 10,
    'OUTPUT': output2
})
processing.run("native:clip", {
    'INPUT': output1, 
    'OVERLAY': output2,
    'OUTPUT': output3
})
print('计算完成!');

run-result

3. 打开文件

如下代码演示了不同格式的文件的打开方式。

python
# 打开数据
import os;

# get the path to the shapefile
path_to_airports_layer = "E:\my\qgis-lecture\data\layer-capital.shp"
vlayer = QgsVectorLayer(path_to_airports_layer, "layer-capital", "ogr")

# get the path to the gpkg
path_to_gpkg = os.path.join(QgsApplication.pkgDataPath(), "resources", "data", "world_map.gpkg")
# append the layername part
gpkg_countries_layer = path_to_gpkg + "|layername=countries"
vlayer = iface.addVectorLayer(gpkg_countries_layer , "countries", "ogr")

# POSTGIS
uri = QgsDataSourceUri()
# set host name, port, database name, username and password
uri.setConnection("localhost", "5432", "dbname", "johny", "xxx")
# set database schema, table name, geometry column and optionally
# subset (WHERE clause)
uri.setDataSource("public", "roads", "the_geom", "cityid = 2643", "primary_key_field")
vlayer = QgsVectorLayer(uri.uri(False), "layer name you like", "postgres")

# CSV
uri = "file://{}/testdata/delimited_xy.csv?delimiter={}&xField={}&yField={}".format(os.getcwd(), ";", "x", "y")
vlayer = QgsVectorLayer(uri, "layer name you like", "delimitedtext")

# raster
path_to_tif = "qgis-projects/python_cookbook/data/srtm.tif"
rlayer = QgsRasterLayer(path_to_tif, "SRTM layer name")

if not vlayer.isValid():
    print("Layer failed to load!")
else:
    QgsProject.instance().addMapLayer(vlayer)

如下代码展示了如何打开tif。

python
base_path = 'D:/lzugis23/proj/qgis培训/code/qgis-lecture/data/'

path_to_tif = base_path + "dem.tif"

rlayer = QgsRasterLayer(path_to_tif, "dem")

if not rlayer.isValid():
    print("Layer failed to load!")
else:
    QgsProject.instance().addMapLayer(rlayer)

raster-file

三、Python脚本文件

1. 创建脚本

在工具箱顶部,点击“Python脚本”按钮,点击Create New Script...可创建一个新的Python脚本文件,打开后弹出代码编辑界面。

new-script

点击Create New Script from Template...可创建一个新的Python脚本模板文件,打开后弹出代码编辑界面,编辑器中会自动填入一些初始化的脚本。

new-script-template

如下代码展示了在脚本中计算缓冲区并将结果栅格化。

python
from qgis.PyQt.QtCore import QCoreApplication
from qgis.core import (QgsProcessing,
                       QgsProcessingAlgorithm,
                       QgsProcessingException,
                       QgsProcessingOutputNumber,
                       QgsProcessingParameterDistance,
                       QgsProcessingParameterFeatureSource,
                       QgsProcessingParameterVectorDestination,
                       QgsProcessingParameterRasterDestination)
from qgis import processing


class ExampleProcessingAlgorithm(QgsProcessingAlgorithm):
    """
    This is an example algorithm that takes a vector layer,
    creates some new layers and returns some results.
    """

    def tr(self, string):
        """
        Returns a translatable string with the self.tr() function.
        """
        return QCoreApplication.translate('Processing', string)

    def createInstance(self):
        # Must return a new copy of your algorithm.
        return ExampleProcessingAlgorithm()

    def name(self):
        """
        Returns the unique algorithm name.
        """
        return 'bufferrasterextend'

    def displayName(self):
        """
        Returns the translated algorithm name.
        """
        return self.tr('缓冲计算并栅格化结果')

    def group(self):
        """
        Returns the name of the group this algorithm belongs to.
        """
        return self.tr('My Script')

    def groupId(self):
        """
        Returns the unique ID of the group this algorithm belongs
        to.
        """
        return 'myscripts'

    def shortHelpString(self):
        """
        Returns a localised short help string for the algorithm.
        """
        return self.tr('先进行缓冲区计算,在将结果转换为栅格展示。')

    def initAlgorithm(self, config=None):
        """
        Here we define the inputs and outputs of the algorithm.
        """
        # 'INPUT' is the recommended name for the main input
        # parameter.
        self.addParameter(
            QgsProcessingParameterFeatureSource(
                'INPUT',
                self.tr('输入矢量数据'),
                types=[QgsProcessing.TypeVectorAnyGeometry]
            )
        )
        self.addParameter(
            QgsProcessingParameterVectorDestination(
                'BUFFER_OUTPUT',
                self.tr('输出缓冲区计算结果'),
            )
        )
        # 'OUTPUT' is the recommended name for the main output
        # parameter.
        self.addParameter(
            QgsProcessingParameterRasterDestination(
                'OUTPUT',
                self.tr('输出栅格文件')
            )
        )
        self.addParameter(
            QgsProcessingParameterDistance(
                'BUFFERDIST',
                self.tr('缓冲区半径'),
                defaultValue = 0.1,
                # Make distance units match the INPUT layer units:
                parentParameterName='INPUT'
            )
        )
        self.addParameter(
            QgsProcessingParameterDistance(
                'CELLSIZE',
                self.tr('单元格大小'),
                defaultValue = 0.1,
                parentParameterName='INPUT'
            )
        )
        self.addOutput(
            QgsProcessingOutputNumber(
                'NUMBEROFFEATURES',
                self.tr('Number of features processed')
            )
        )

    def processAlgorithm(self, parameters, context, feedback):
        """
        Here is where the processing itself takes place.
        """
        # First, we get the count of features from the INPUT layer.
        # This layer is defined as a QgsProcessingParameterFeatureSource
        # parameter, so it is retrieved by calling
        # self.parameterAsSource.
        input_featuresource = self.parameterAsSource(parameters,
                                                     'INPUT',
                                                     context)
        numfeatures = input_featuresource.featureCount()

        # Retrieve the buffer distance and raster cell size numeric
        # values. Since these are numeric values, they are retrieved
        # using self.parameterAsDouble.
        bufferdist = self.parameterAsDouble(parameters, 'BUFFERDIST',
                                            context)
        rastercellsize = self.parameterAsDouble(parameters, 'CELLSIZE',
                                                context)
        if feedback.isCanceled():
            return {}
        buffer_result = processing.run(
            'native:buffer',
            {
                # Here we pass on the original parameter values of INPUT
                # and BUFFER_OUTPUT to the buffer algorithm.
                'INPUT': parameters['INPUT'],
                'OUTPUT': parameters['BUFFER_OUTPUT'],
                'DISTANCE': bufferdist,
                'SEGMENTS': 10,
                'DISSOLVE': True,
                'END_CAP_STYLE': 0,
                'JOIN_STYLE': 0,
                'MITER_LIMIT': 10
            },
            # Because the buffer algorithm is being run as a step in
            # another larger algorithm, the is_child_algorithm option
            # should be set to True
            is_child_algorithm=True,
            #
            # It's important to pass on the context and feedback objects to
            # child algorithms, so that they can properly give feedback to
            # users and handle cancelation requests.
            context=context,
            feedback=feedback)

        # Check for cancelation
        if feedback.isCanceled():
            return {}

        # Run the separate rasterization algorithm using the buffer result
        # as an input.
        rasterized_result = processing.run(
            'qgis:rasterize',
            {
                # Here we pass the 'OUTPUT' value from the buffer's result
                # dictionary off to the rasterize child algorithm.
                'LAYER': buffer_result['OUTPUT'],
                'EXTENT': buffer_result['OUTPUT'],
                'MAP_UNITS_PER_PIXEL': rastercellsize,
                # Use the original parameter value.
                'OUTPUT': parameters['OUTPUT']
            },
            is_child_algorithm=True,
            context=context,
            feedback=feedback)

        if feedback.isCanceled():
            return {}

        # Return the results
        return {'OUTPUT': rasterized_result['OUTPUT'],
                'BUFFER_OUTPUT': buffer_result['OUTPUT'],
                'NUMBEROFFEATURES': numfeatures}

点击“Run”按钮,运行该算法,打开如下界面。

run-script

2. 标准函数

如上代码所示,脚本中的标准函数及说明如下:

  • createInstance (必须)

如下图所示,必须返回一个算法新实例。如果更改了类的名称,请确保在此处返回的值与类名称匹配!

create-instance

  • name (必须)

返回一个用来标识算法的名称。

  • displayName (必须)

如下图所示,返回在界面上展示的算法的名称。

displayname

  • group

如下图所示,返回该算法所属的组。

group

  • groupId

返回算法的唯一分组ID。

  • shortHelpString

返回算法的简单说明与操作帮助。

  • initAlgorithm (必须)

如下代码所示,在此处定义算法的输入与输出。

python
def initAlgorithm(self, config=None):
    # 'INPUT' is the recommended name for the main input
    # parameter.
    self.addParameter(
        QgsProcessingParameterFeatureSource(
            'INPUT',
            self.tr('输入矢量数据'),
            types=[QgsProcessing.TypeVectorAnyGeometry]
        )
    )
    self.addParameter(
        QgsProcessingParameterVectorDestination(
            'BUFFER_OUTPUT',
            self.tr('输出缓冲区计算结果'),
        )
    )
    # 'OUTPUT' is the recommended name for the main output
    # parameter.
    self.addParameter(
        QgsProcessingParameterRasterDestination(
            'OUTPUT',
            self.tr('输出栅格文件')
        )
    )
    self.addParameter(
        QgsProcessingParameterDistance(
            'BUFFERDIST',
            self.tr('缓冲区半径'),
            defaultValue = 0.1,
            # Make distance units match the INPUT layer units:
            parentParameterName='INPUT'
        )
    )
    self.addParameter(
        QgsProcessingParameterDistance(
            'CELLSIZE',
            self.tr('单元格大小'),
            defaultValue = 0.1,
            parentParameterName='INPUT'
        )
    )
    self.addOutput(
        QgsProcessingOutputNumber(
            'NUMBEROFFEATURES',
            self.tr('Number of features processed')
        )
    )
  • processAlgorithm (必须) 定义算法执行逻辑。调用processing.run执行工具箱,最后返回输出与结果。
python
return {
    'OUTPUT': rasterized_result['OUTPUT'],
    'BUFFER_OUTPUT': buffer_result['OUTPUT'],
    'NUMBEROFFEATURES': numfeatures
}

执行后结果如下所示:

script-run

3. @alg装饰器

如下代码演示了如何使用@alg装饰器编写脚本文件。

python
from qgis import processing
from qgis.processing import alg
from qgis.core import QgsProject

@alg(name='bufferrasteralg', label='缓冲区计算并栅格化输出结果',
     group='myscripts', group_label='My scripts')
# 'INPUT' is the recommended name for the main input parameter
@alg.input(type=alg.SOURCE, name='INPUT', label='输入矢量图层')
@alg.input(type=alg.RASTER_LAYER_DEST, name='OUTPUT', label='栅格图层输出')
@alg.input(type=alg.VECTOR_LAYER_DEST, name='BUFFER_OUTPUT', label='缓冲结果输出')
@alg.input(type=alg.DISTANCE, name='BUFFERDIST', label='缓冲距离', default=0.1)
@alg.input(type=alg.DISTANCE, name='CELLSIZE', label='栅格单元格大小', default=0.1)
# 'OUTPUT' is the recommended name for the main output parameter
@alg.output(type=alg.NUMBER, name='NUMBEROFFEATURES', label='要素数量')

def bufferrasteralg(instance, parameters, context, feedback, inputs):
    """
    先进行缓冲区计算,在将结果转换为栅格展示。
    """
    input_featuresource = instance.parameterAsSource(parameters,
                                                     'INPUT', context)
    numfeatures = input_featuresource.featureCount()
    bufferdist = instance.parameterAsDouble(parameters, 'BUFFERDIST',
                                            context)
    rastercellsize = instance.parameterAsDouble(parameters, 'CELLSIZE',
                                                context)
    if feedback.isCanceled():
        return {}
    buffer_result = processing.run('native:buffer',
                               {'INPUT': parameters['INPUT'],
                                'OUTPUT': parameters['BUFFER_OUTPUT'],
                                'DISTANCE': bufferdist,
                                'SEGMENTS': 10,
                                'DISSOLVE': True,
                                'END_CAP_STYLE': 0,
                                'JOIN_STYLE': 0,
                                'MITER_LIMIT': 10
                                },
                               is_child_algorithm=True,
                               context=context,
                               feedback=feedback)
    if feedback.isCanceled():
        return {}
    rasterized_result = processing.run('qgis:rasterize',
                               {'LAYER': buffer_result['OUTPUT'],
                                'EXTENT': buffer_result['OUTPUT'],
                                'MAP_UNITS_PER_PIXEL': rastercellsize,
                                'OUTPUT': parameters['OUTPUT']
                               },
                               is_child_algorithm=True, context=context,
                               feedback=feedback)
    if feedback.isCanceled():
        return {}
    return {'OUTPUT': rasterized_result['OUTPUT'],
            'BUFFER_OUTPUT': buffer_result['OUTPUT'],
            'NUMBEROFFEATURES': numfeatures}

输入类型

Class

Alg constant

Description

QgsProcessingParameterAnnotationLayer

alg.ANNOTATION_LAYER

An annotation layer

QgsProcessingParameterAuthConfig

alg.AUTH_CFG

Allows users to select from available authentication configurations or create new authentication configurations

QgsProcessingParameterBand

alg.BAND

A band of a raster layer

QgsProcessingParameterBoolean

alg.BOOL

A boolean value

QgsProcessingParameterColor

alg.COLOR

A color

QgsProcessingParameterCoordinateOperation

alg.COORDINATE_OPERATION

A coordinate operation (for CRS transformations)

QgsProcessingParameterCrs

alg.CRS

A Coordinate Reference System

QgsProcessingParameterDatabaseSchema

alg.DATABASE_SCHEMA

A database schema

QgsProcessingParameterDatabaseTable

alg.DATABASE_TABLE

A database table

QgsProcessingParameterDateTime

alg.DATETIME

A datetime (or a pure date or time)

QgsProcessingParameterDistance

alg.DISTANCE

A double numeric parameter for distance values

QgsProcessingParameterEnum

alg.ENUM

An enumeration, allowing for selection from a set of predefined values

QgsProcessingParameterExpression

alg.EXPRESSION

An expression

QgsProcessingParameterExtent

alg.EXTENT

A spatial extent defined by xmin, xmax, ymin, ymax

QgsProcessingParameterField

alg.FIELD

A field in the attribute table of a vector layer

QgsProcessingParameterFile

alg.FILE

A filename of an existing file

QgsProcessingParameterFileDestination

alg.FILE_DEST

A filename for a newly created output file

QgsProcessingParameterFolderDestination

alg.FOLDER_DEST

A folder (destination folder)

QgsProcessingParameterGeometry

alg.GEOMETRY

A geometry

QgsProcessingParameterNumber

alg.INT

An integer

QgsProcessingParameterLayout

alg.LAYOUT

A layout

QgsProcessingParameterLayoutItem

alg.LAYOUT_ITEM

A layout item

QgsProcessingParameterMapLayer

alg.MAPLAYER

A map layer

QgsProcessingParameterMapTheme

alg.MAP_THEME

A project map theme

QgsProcessingParameterMatrix

alg.MATRIX

A matrix

QgsProcessingParameterMeshLayer

alg.MESH_LAYER

A mesh layer

QgsProcessingParameterMultipleLayers

alg.MULTILAYER

A set of layers

QgsProcessingParameterNumber

alg.NUMBER

A numerical value

QgsProcessingParameterPoint

alg.POINT

A point

QgsProcessingParameterPointCloudLayer

alg.POINT_CLOUD_LAYER

A point cloud layer

QgsProcessingParameterProviderConnection

alg.PROVIDER_CONNECTION

An available connection for a database provider

QgsProcessingParameterRange

alg.RANGE

A number range

QgsProcessingParameterRasterLayer

alg.RASTER_LAYER

A raster layer

QgsProcessingParameterRasterDestination

alg.RASTER_LAYER_DEST

A raster layer

QgsProcessingParameterScale

alg.SCALE

A map scale

QgsProcessingParameterFeatureSink

alg.SINK

A feature sink

QgsProcessingParameterFeatureSource

alg.SOURCE

A feature source

QgsProcessingParameterString

alg.STRING

A text string

QgsProcessingParameterVectorLayer

alg.VECTOR_LAYER

A vector layer

QgsProcessingParameterVectorDestination

alg.VECTOR_LAYER_DEST

A vector layer

输出类型

Class

Alg constant

Description

QgsProcessingOutputBoolean

alg.BOOL

A boolean value

QgsProcessingOutputNumber

alg.DISTANCE

A double numeric parameter for distance values

QgsProcessingOutputFile

alg.FILE

A filename of an existing file

QgsProcessingOutputFolder

alg.FOLDER

A folder

QgsProcessingOutputHtml

alg.HTML

HTML

QgsProcessingOutputNumber

alg.INT

A integer

QgsProcessingOutputLayerDefinition

alg.LAYERDEF

A layer definition

QgsProcessingOutputMapLayer

alg.MAPLAYER

A map layer

QgsProcessingOutputMultipleLayers

alg.MULTILAYER

A set of layers

QgsProcessingOutputNumber

alg.NUMBER

A numerical value

QgsProcessingOutputRasterLayer

alg.RASTER_LAYER

A raster layer

QgsProcessingOutputString

alg.STRING

A text string

QgsProcessingOutputVectorLayer

alg.VECTOR_LAYER

A vector layer