python脚本编写_【PyQGIS】编写用于处理框架(QGIS3)的Python脚本
可以編寫可通過QGIS中的Python控制臺運行的獨立pyqgis腳本。進行一些調整,即可使您的獨立腳本通過處理框架運行。這具有幾個優(yōu)點。首先,獲取用戶輸入和寫入輸出文件要容易得多,因為Processing Framework為這些提供了標準化的用戶界面。其次,將腳本放入“處理工具箱”中還可以使其成為任何“處理模型”的一部分,或作為具有多個輸入的批處理作業(yè)運行。本教程將展示如何編寫自定義python腳本,該腳本可以作為QGIS中Processing框架的一部分。
注意
在QGIS3中徹底修改了Processing API。請參考本指南以獲取最佳做法和提示。
任務概述
我們的腳本將根據(jù)用戶選擇的字段執(zhí)行溶解操作。它還將為溶解的特征求和另一個字段的值。在示例中,我們將基于CONTINENT屬性分解世界shapefile并求和POP_EST字段以計算溶解區(qū)域中的總人口。
獲取數(shù)據(jù)
我們將使用?自然地球的Admin 0-國家數(shù)據(jù)集。
下載Admin 0-國家shapefile。。
資料來源[NATURALEARTH]
為了方便起見,您可以直接從下面下載包含以上圖層的地理包:
ne_global.gpkg
程序
在“ QGIS瀏覽器面板”中,找到保存下載數(shù)據(jù)的目錄。展開
zip或gpkg?條目,然后選擇ne_10m_admin_0_countries圖層。將圖層拖到畫布上。轉到處理?工具箱。單擊工具欄中的“腳本”按鈕,然后選擇“從模板創(chuàng)建新腳本”。
該模板包含處理框架將其識別為處理腳本并管理輸入/輸出所需的所有樣板代碼。讓我們開始根據(jù)需要定制示例模板。首先將類名從更改
ExampleProcessingAlgorithm為DissolveProcessingAlgorithm。此名稱也需要在createInstance方法中更新。在該類中添加一個文檔字符串,以解釋該算法的作用。向下滾動時,您將看到為腳本分配名稱,組,描述等的方法。更改返回值的名稱的方法是
dissolve_with_sum,顯示名的方法,組方法和的groupId方法?。將shortHelpString方法的返回值更改為將顯示給用戶的描述。單擊保存按鈕。Dissolve?with?Sumscripts命名腳本
dissolve_with_sum并將其保存在配置文件?默認?處理?腳本文件夾下的默認位置。現(xiàn)在,我們將定義腳本的輸入。模板已經包含
INPUT矢量層和OUTPUT層的定義。我們將添加2個新輸入,允許用戶選擇DISSOLVE_FIELD和SUM_FIELD。在該initAlgorithm方法的頂部和下面的代碼中添加一個新的導入。單擊運行按鈕以預覽更改。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))
您將看到帶有新定義的輸入的“用總和溶解”對話框。選擇
ne_10m_admin_0_countries圖層作為Input layer`。由于溶解字段和求和字段都是基于輸入層進行過濾的,因此它們將被輸入層中的現(xiàn)有字段預先填充。單擊關閉按鈕。現(xiàn)在,我們定義了用于在該
processAlgorithm方法中處理數(shù)據(jù)的自定義邏輯。該方法通過了名為的字典parameters。它包含用戶已選擇的輸入。有一些幫助程序方法,使您可以接受這些輸入并創(chuàng)建適當?shù)膶ο蟆N覀兪紫仁褂?code>parameterAsSource和parameterAsString方法獲得輸入。接下來,我們要創(chuàng)建一個特征接收器,在其中寫入輸出。QGIS3有一個新的類QgsFeatureSink,它是創(chuàng)建可以接受新功能的對象的首選方法。輸出僅需要2個字段-一個用于溶解字段的值,另一個用于所選字段的總和。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)在,我們將準備輸入功能,并創(chuàng)建一個字典來保存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)
接下來,我們將
native:dissolve在輸入層上調用內置處理算法以生成分解的幾何圖形。一旦有了可溶的幾何形狀,我們便會遍歷可溶算法的輸出,并創(chuàng)建要添加到輸出中的新特征。最后,我們返回dest_idFeatureSink作為輸出。現(xiàn)在腳本已準備就緒。單擊運行按鈕。
注意
請注意,使用parameters[self.INPUT]可以直接從參數(shù)字典中獲取輸入層,而無需將其定義為源。由于我們將輸入對象傳遞給算法而不進行任何操作,因此沒有必要將其定義為源。
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}在“用總和溶解”對話框中,選擇
ne_10m_admin_0_countries作為“輸入”層,CONTINENT“溶解”字段和POP_EST“總和”字段。點擊運行。處理完成后,單擊“關閉”按鈕,然后切換到QGIS主窗口。
您將看到每個大陸具有一個要素的已分解輸出層,以及該大陸各個國家的總人口合計。
編寫處理腳本的另一個優(yōu)點是,處理框架中的方法知道圖層選擇,并自動過濾輸入以僅使用所選功能。發(fā)生這種情況是因為我們將輸入定義為
QgsProcessingParameterFeatureSource。特征源允許使用包含矢量要素的任何對象,而不僅僅是矢量圖層,因此,當圖層中有選定要素并要求Processing使用選定要素時,輸入將作為QgsProcessingFeatureSource包含選定要素的對象傳遞到腳本中而不是完整的矢量層。這是此功能的快速演示。假設我們只想溶解某些大洲。讓我們使用“表達式”工具的“選擇”功能來創(chuàng)建選擇。輸入以下表達式以選擇北美和南美的要素,然后單擊“選擇”。
"CONTINENT" = 'North America' OR "CONTINENT" = 'South America'
您將看到以黃色突出顯示的所選功能。找到該
dissolve_with_sum腳本,然后雙擊以運行它。在“用總和溶解”對話框中,選擇
ne_10m_admin_0_countries作為輸入層。這次,請確保選中“僅所選功能”框。選擇SUBREGION作為“溶解”字段和POP_EST“求和”字段。處理完成后,單擊“關閉”,然后切換回QGIS主窗口。您會注意到一個新圖層,其中僅溶解了選定的要素。單擊“標識”按鈕,然后單擊某個功能以檢查并驗證腳本是否正常運行。
# -*- 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
點擊下方“閱讀原文”查看更多
總結
以上是生活随笔為你收集整理的python脚本编写_【PyQGIS】编写用于处理框架(QGIS3)的Python脚本的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 是我三观不正吗?为什么张馨予演个莫愁大家
- 下一篇: golang int64转string_