python脚本编写_【PyQGIS】编写用于处理框架(QGIS3)的Python脚本
可以編寫(xiě)可通過(guò)QGIS中的Python控制臺(tái)運(yùn)行的獨(dú)立pyqgis腳本。進(jìn)行一些調(diào)整,即可使您的獨(dú)立腳本通過(guò)處理框架運(yùn)行。這具有幾個(gè)優(yōu)點(diǎn)。首先,獲取用戶輸入和寫(xiě)入輸出文件要容易得多,因?yàn)镻rocessing Framework為這些提供了標(biāo)準(zhǔn)化的用戶界面。其次,將腳本放入“處理工具箱”中還可以使其成為任何“處理模型”的一部分,或作為具有多個(gè)輸入的批處理作業(yè)運(yùn)行。本教程將展示如何編寫(xiě)自定義python腳本,該腳本可以作為QGIS中Processing框架的一部分。
注意
在QGIS3中徹底修改了Processing API。請(qǐng)參考本指南以獲取最佳做法和提示。
任務(wù)概述
我們的腳本將根據(jù)用戶選擇的字段執(zhí)行溶解操作。它還將為溶解的特征求和另一個(gè)字段的值。在示例中,我們將基于CONTINENT屬性分解世界shapefile并求和POP_EST字段以計(jì)算溶解區(qū)域中的總?cè)丝凇?/p>
獲取數(shù)據(jù)
我們將使用?自然地球的Admin 0-國(guó)家數(shù)據(jù)集。
下載Admin 0-國(guó)家shapefile。。
資料來(lái)源[NATURALEARTH]
為了方便起見(jiàn),您可以直接從下面下載包含以上圖層的地理包:
ne_global.gpkg
程序
在“ QGIS瀏覽器面板”中,找到保存下載數(shù)據(jù)的目錄。展開(kāi)
zip或gpkg?條目,然后選擇ne_10m_admin_0_countries圖層。將圖層拖到畫(huà)布上。轉(zhuǎn)到處理?工具箱。單擊工具欄中的“腳本”按鈕,然后選擇“從模板創(chuàng)建新腳本”。
該模板包含處理框架將其識(shí)別為處理腳本并管理輸入/輸出所需的所有樣板代碼。讓我們開(kāi)始根據(jù)需要定制示例模板。首先將類名從更改
ExampleProcessingAlgorithm為DissolveProcessingAlgorithm。此名稱也需要在createInstance方法中更新。在該類中添加一個(gè)文檔字符串,以解釋該算法的作用。向下滾動(dòng)時(shí),您將看到為腳本分配名稱,組,描述等的方法。更改返回值的名稱的方法是
dissolve_with_sum,顯示名的方法,組方法和的groupId方法?。將shortHelpString方法的返回值更改為將顯示給用戶的描述。單擊保存按鈕。Dissolve?with?Sumscripts命名腳本
dissolve_with_sum并將其保存在配置文件?默認(rèn)?處理?腳本文件夾下的默認(rèn)位置。現(xiàn)在,我們將定義腳本的輸入。模板已經(jīng)包含
INPUT矢量層和OUTPUT層的定義。我們將添加2個(gè)新輸入,允許用戶選擇DISSOLVE_FIELD和SUM_FIELD。在該initAlgorithm方法的頂部和下面的代碼中添加一個(gè)新的導(dǎo)入。單擊運(yùn)行按鈕以預(yù)覽更改。from qgis.core import QgsProcessingParameterFieldself.addParameter( QgsProcessingParameterField( self.DISSOLVE_FIELD, 'Choose Dissolve Field', '', self.INPUT))self.addParameter( QgsProcessingParameterField( self.SUM_FIELD, 'Choose Sum Field', '', self.INPUT))
您將看到帶有新定義的輸入的“用總和溶解”對(duì)話框。選擇
ne_10m_admin_0_countries圖層作為Input layer`。由于溶解字段和求和字段都是基于輸入層進(jìn)行過(guò)濾的,因此它們將被輸入層中的現(xiàn)有字段預(yù)先填充。單擊關(guān)閉按鈕。現(xiàn)在,我們定義了用于在該
processAlgorithm方法中處理數(shù)據(jù)的自定義邏輯。該方法通過(guò)了名為的字典parameters。它包含用戶已選擇的輸入。有一些幫助程序方法,使您可以接受這些輸入并創(chuàng)建適當(dāng)?shù)膶?duì)象。我們首先使用parameterAsSource和parameterAsString方法獲得輸入。接下來(lái),我們要?jiǎng)?chuàng)建一個(gè)特征接收器,在其中寫(xiě)入輸出。QGIS3有一個(gè)新的類QgsFeatureSink,它是創(chuàng)建可以接受新功能的對(duì)象的首選方法。輸出僅需要2個(gè)字段-一個(gè)用于溶解字段的值,另一個(gè)用于所選字段的總和。from PyQt5.QtCore import QVariantfrom qgis.core import QgsField, QgsFieldssource = self.parameterAsSource( parameters, self.INPUT, context)dissolve_field = self.parameterAsString( parameters, self.DISSOLVE_FIELD, context)sum_field = self.parameterAsString( parameters, self.SUM_FIELD, context)fields = QgsFields()fields.append(QgsField(dissolve_field, QVariant.String))fields.append(QgsField('SUM_' + sum_field, QVariant.Double))(sink, dest_id) = self.parameterAsSink( parameters, self.OUTPUT, context, fields, source.wkbType(), source.sourceCrs())
現(xiàn)在,我們將準(zhǔn)備輸入功能,并創(chuàng)建一個(gè)字典來(lái)保存dissolve_field中的唯一值和sum_field中的值之和。注意使用
feedback.pushInfo()方法與用戶交流狀態(tài)。feedback.pushInfo('Extracting unique values from dissolve_field and computing sum')features = source.getFeatures()unique_values = set(f[dissolve_field] for f in features)# Get Indices of dissolve field and sum fielddissolveIdx = source.fields().indexFromName(dissolve_field)sumIdx = source.fields().indexFromName(sum_field)# Find all unique values for the given dissolve_field and# sum the corresponding values from the sum_fieldsum_unique_values = {}attrs = [{dissolve_field: f[dissolveIdx], sum_field: f[sumIdx]} for f in source.getFeatures()]for unique_value in unique_values: val_list = [ f_attr[sum_field] for f_attr in attrs if f_attr[dissolve_field] == unique_value] sum_unique_values[unique_value] = sum(val_list)
接下來(lái),我們將
native:dissolve在輸入層上調(diào)用內(nèi)置處理算法以生成分解的幾何圖形。一旦有了可溶的幾何形狀,我們便會(huì)遍歷可溶算法的輸出,并創(chuàng)建要添加到輸出中的新特征。最后,我們返回dest_idFeatureSink作為輸出。現(xiàn)在腳本已準(zhǔn)備就緒。單擊運(yùn)行按鈕。
注意
請(qǐng)注意,使用parameters[self.INPUT]可以直接從參數(shù)字典中獲取輸入層,而無(wú)需將其定義為源。由于我們將輸入對(duì)象傳遞給算法而不進(jìn)行任何操作,因此沒(méi)有必要將其定義為源。
from qgis.core import QgsFeature# Running the processing dissolve algorithmfeedback.pushInfo('Dissolving features')dissolved_layer = processing.run("native:dissolve", { 'INPUT': parameters[self.INPUT], 'FIELD': dissolve_field, 'OUTPUT': 'memory:' }, context=context, feedback=feedback)['OUTPUT']# Read the dissolved layer and create output featuresfor f in dissolved_layer.getFeatures(): new_feature = QgsFeature() # Set geometry to dissolved geometry new_feature.setGeometry(f.geometry()) # Set attributes from sum_unique_values dictionary that we had computed new_feature.setAttributes([f[dissolve_field], sum_unique_values[f[dissolve_field]]]) sink.addFeature(new_feature, QgsFeatureSink.FastInsert)return {self.OUTPUT: dest_id}在“用總和溶解”對(duì)話框中,選擇
ne_10m_admin_0_countries作為“輸入”層,CONTINENT“溶解”字段和POP_EST“總和”字段。點(diǎn)擊運(yùn)行。處理完成后,單擊“關(guān)閉”按鈕,然后切換到QGIS主窗口。
您將看到每個(gè)大陸具有一個(gè)要素的已分解輸出層,以及該大陸各個(gè)國(guó)家的總?cè)丝诤嫌?jì)。
編寫(xiě)處理腳本的另一個(gè)優(yōu)點(diǎn)是,處理框架中的方法知道圖層選擇,并自動(dòng)過(guò)濾輸入以僅使用所選功能。發(fā)生這種情況是因?yàn)槲覀儗⑤斎攵x為
QgsProcessingParameterFeatureSource。特征源允許使用包含矢量要素的任何對(duì)象,而不僅僅是矢量圖層,因此,當(dāng)圖層中有選定要素并要求Processing使用選定要素時(shí),輸入將作為QgsProcessingFeatureSource包含選定要素的對(duì)象傳遞到腳本中而不是完整的矢量層。這是此功能的快速演示。假設(shè)我們只想溶解某些大洲。讓我們使用“表達(dá)式”工具的“選擇”功能來(lái)創(chuàng)建選擇。輸入以下表達(dá)式以選擇北美和南美的要素,然后單擊“選擇”。
"CONTINENT" = 'North America' OR "CONTINENT" = 'South America'
您將看到以黃色突出顯示的所選功能。找到該
dissolve_with_sum腳本,然后雙擊以運(yùn)行它。在“用總和溶解”對(duì)話框中,選擇
ne_10m_admin_0_countries作為輸入層。這次,請(qǐng)確保選中“僅所選功能”框。選擇SUBREGION作為“溶解”字段和POP_EST“求和”字段。處理完成后,單擊“關(guān)閉”,然后切換回QGIS主窗口。您會(huì)注意到一個(gè)新圖層,其中僅溶解了選定的要素。單擊“標(biāo)識(shí)”按鈕,然后單擊某個(gè)功能以檢查并驗(yàn)證腳本是否正常運(yùn)行。
# -*- coding: utf-8 -*-"""**************************************************************************** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ****************************************************************************"""from PyQt5.QtCore import QCoreApplication, QVariantfrom qgis.core import (QgsProcessing, QgsFeatureSink, QgsFeature, QgsField, QgsFields, QgsProcessingException, QgsProcessingAlgorithm, QgsProcessingParameterFeatureSource, QgsProcessingParameterFeatureSink, QgsProcessingParameterField, )import processingclass DissolveProcessingAlgorithm(QgsProcessingAlgorithm): """ Dissolve algorithm that dissolves features based on selected attribute and summarizes the selected field by cumputing the sum of dissolved features. """ INPUT = 'INPUT' OUTPUT = 'OUTPUT' DISSOLVE_FIELD = 'dissolve_field' SUM_FIELD = 'sum_field' def tr(self, string): """ Returns a translatable string with the self.tr() function. """ return QCoreApplication.translate('Processing', string) def createInstance(self): return DissolveProcessingAlgorithm() def name(self): """ Returns the algorithm name, used for identifying the algorithm. This string should be fixed for the algorithm, and must not be localised. The name should be unique within each provider. Names should contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ return 'dissolve_with_sum' def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ return self.tr('Dissolve with Sum') def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ return self.tr('scripts') def groupId(self): """ Returns the unique ID of the group this algorithm belongs to. This string should be fixed for the algorithm, and must not be localised. The group id should be unique within each provider. Group id should contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ return 'scripts' def shortHelpString(self): """ Returns a localised short helper string for the algorithm. This string should provide a basic description about what the algorithm does and the parameters and outputs associated with it.. """ return self.tr("Dissolves selected features and creates and sums values of features that were dissolved") def initAlgorithm(self, config=None): """ Here we define the inputs and output of the algorithm, along with some other properties. """ # We add the input vector features source. It can have any kind of # geometry. self.addParameter( QgsProcessingParameterFeatureSource( self.INPUT, self.tr('Input layer'), [QgsProcessing.TypeVectorAnyGeometry] ) ) self.addParameter( QgsProcessingParameterField( self.DISSOLVE_FIELD, 'Choose Dissolve Field', '', self.INPUT)) self.addParameter( QgsProcessingParameterField( self.SUM_FIELD, 'Choose Sum Field', '', self.INPUT)) # We add a feature sink in which to store our processed features (this # usually takes the form of a newly created vector layer when the # algorithm is run in QGIS). self.addParameter( QgsProcessingParameterFeatureSink( self.OUTPUT, self.tr('Output layer') ) ) def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ source = self.parameterAsSource( parameters, self.INPUT, context ) dissolve_field = self.parameterAsString( parameters, self.DISSOLVE_FIELD, context) sum_field = self.parameterAsString( parameters, self.SUM_FIELD, context) fields = QgsFields() fields.append(QgsField(dissolve_field, QVariant.String)) fields.append(QgsField('SUM_' + sum_field, QVariant.Double)) (sink, dest_id) = self.parameterAsSink( parameters, self.OUTPUT, context, fields, source.wkbType(), source.sourceCrs()) # Create a dictionary to hold the unique values from the # dissolve_field and the sum of the values from the sum_field feedback.pushInfo('Extracting unique values from dissolve_field and computing sum') features = source.getFeatures() unique_values = set(f[dissolve_field] for f in features) # Get Indices of dissolve field and sum field dissolveIdx = source.fields().indexFromName(dissolve_field) sumIdx = source.fields().indexFromName(sum_field) # Find all unique values for the given dissolve_field and # sum the corresponding values from the sum_field sum_unique_values = {} attrs = [{dissolve_field: f[dissolveIdx], sum_field: f[sumIdx]} for f in source.getFeatures()] for unique_value in unique_values: val_list = [ f_attr[sum_field] for f_attr in attrs if f_attr[dissolve_field] == unique_value] sum_unique_values[unique_value] = sum(val_list) # Running the processing dissolve algorithm feedback.pushInfo('Dissolving features') dissolved_layer = processing.run("native:dissolve", { 'INPUT': parameters[self.INPUT], 'FIELD': dissolve_field, 'OUTPUT': 'memory:' }, context=context, feedback=feedback)['OUTPUT'] # Read the dissolved layer and create output features for f in dissolved_layer.getFeatures(): new_feature = QgsFeature() # Set geometry to dissolved geometry new_feature.setGeometry(f.geometry()) # Set attributes from sum_unique_values dictionary that we had computed new_feature.setAttributes([f[dissolve_field], sum_unique_values[f[dissolve_field]]]) sink.addFeature(new_feature, QgsFeatureSink.FastInsert) return {self.OUTPUT: dest_id}END
點(diǎn)擊下方“閱讀原文”查看更多
總結(jié)
以上是生活随笔為你收集整理的python脚本编写_【PyQGIS】编写用于处理框架(QGIS3)的Python脚本的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 是我三观不正吗?为什么张馨予演个莫愁大家
- 下一篇: golang int64转string_