He creado un modelo gráfico de QGIS utilizando el modelador gráfico incorporado. Mi modelo se supone que pide al usuario una capa de entrada, una capa de superposición y campos de la capa de superposición.
A continuación, el modelo debe calcular la media ponderada por área de esos campos para cada característica de la capa de entrada. El resultado será una capa de entrada con campos adicionales para cada promedio ponderado por área.
Me he dado cuenta de que el campo de entrada no se puede utilizar en el modelador gráfico y tengo que convertirlo en un script de python para realizar esta tarea. Aquí añado el script. Lo que estoy teniendo problemas es con la forma de utilizar la entrada del usuario en mis cálculos de campo y nombres de campo.
from qgis.core import QgsProcessing
from qgis.core import QgsProcessingAlgorithm
from qgis.core import QgsProcessingMultiStepFeedback
from qgis.core import QgsProcessingParameterVectorLayer
from qgis.core import QgsProcessingParameterField
from qgis.core import QgsProcessingParameterFeatureSink
import processing
class FutureLuHsg(QgsProcessingAlgorithm):
def initAlgorithm(self, config=None):
self.addParameter(QgsProcessingParameterVectorLayer('luhsgexisting', 'LU HSG', types=[QgsProcessing.TypeVectorPolygon], defaultValue=None))
self.addParameter(QgsProcessingParameterVectorLayer('parcels', 'Parcels', types=[QgsProcessing.TypeVectorPolygon], defaultValue=None))
self.addParameter(QgsProcessingParameterField('fieldtoaverage1', 'Field to Average', type=QgsProcessingParameterField.Numeric, parentLayerParameterName='luhsgexisting', allowMultiple=True, defaultValue=None))
self.addParameter(QgsProcessingParameterFeatureSink('Joined', 'Joined', optional=True, type=QgsProcessing.TypeVectorAnyGeometry, createByDefault=True, defaultValue=None))
self.addParameter(QgsProcessingParameterFeatureSink('Final', 'Final', type=QgsProcessing.TypeVectorAnyGeometry, createByDefault=True, defaultValue=None))
self.addParameter(QgsProcessingParameterFeatureSink('Stats', 'Stats', type=QgsProcessing.TypeVectorAnyGeometry, createByDefault=True, defaultValue=None))
def processAlgorithm(self, parameters, context, model_feedback):
# Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the
# overall progress through the model
feedback = QgsProcessingMultiStepFeedback(6, model_feedback)
results = {}
outputs = {}
# Field calculator
alg_params = {
'FIELD_LENGTH': 10,
'FIELD_NAME': 'FID_Parcels',
'FIELD_PRECISION': 3,
'FIELD_TYPE': 1,
'FORMULA': '$id',
'INPUT': parameters['parcels'],
'NEW_FIELD': True,
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
outputs['FieldCalculator'] = processing.run('qgis:fieldcalculator', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
feedback.setCurrentStep(1)
if feedback.isCanceled():
return {}
# Intersection
alg_params = {
'INPUT': outputs['FieldCalculator']['OUTPUT'],
'INPUT_FIELDS': None,
'OVERLAY': parameters['luhsgexisting'],
'OVERLAY_FIELDS': parameters['fieldtoaverage1'],
'OVERLAY_FIELDS_PREFIX': '',
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
outputs['Intersection'] = processing.run('native:intersection', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
feedback.setCurrentStep(2)
if feedback.isCanceled():
return {}
# Field calculator 2
alg_params = {
'FIELD_LENGTH': 10,
'FIELD_NAME': 'Field1*Area',
'FIELD_PRECISION': 2,
'FIELD_TYPE': 0,
'FORMULA': ' \"fieldtoaverage\" * $area',
'INPUT': outputs['Intersection']['OUTPUT'],
'NEW_FIELD': True,
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
outputs['FieldCalculator2'] = processing.run('qgis:fieldcalculator', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
feedback.setCurrentStep(3)
if feedback.isCanceled():
return {}
# Statistics by categories
alg_params = {
'CATEGORIES_FIELD_NAME': 'FID_Parcels',
'INPUT': outputs['FieldCalculator2']['OUTPUT'],
'VALUES_FIELD_NAME': 'Field1*Area',
'OUTPUT': parameters['Stats']
}
outputs['StatisticsByCategories'] = processing.run('qgis:statisticsbycategories', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
results['Stats'] = outputs['StatisticsByCategories']['OUTPUT']
feedback.setCurrentStep(4)
if feedback.isCanceled():
return {}
# Join attributes by field value
alg_params = {
'DISCARD_NONMATCHING': False,
'FIELD': 'FID_Parcels',
'FIELDS_TO_COPY': 'SUM',
'FIELD_2': 'FID_Parcels',
'INPUT': outputs['FieldCalculator']['OUTPUT'],
'INPUT_2': outputs['StatisticsByCategories']['OUTPUT'],
'METHOD': 1,
'PREFIX': 'Stats_',
'OUTPUT': parameters['Joined']
}
outputs['JoinAttributesByFieldValue'] = processing.run('native:joinattributestable', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
results['Joined'] = outputs['JoinAttributesByFieldValue']['OUTPUT']
feedback.setCurrentStep(5)
if feedback.isCanceled():
return {}
# Field calculator 3
alg_params = {
'FIELD_LENGTH': 10,
'FIELD_NAME': 'Field1_Weighted',
'FIELD_PRECISION': 3,
'FIELD_TYPE': 0,
'FORMULA': ' \"Statssum\" / $area',
'INPUT': outputs['JoinAttributesByFieldValue']['OUTPUT'],
'NEW_FIELD': True,
'OUTPUT': parameters['Final']
}
outputs['FieldCalculator3'] = processing.run('qgis:fieldcalculator', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
results['Final'] = outputs['FieldCalculator3']['OUTPUT']
return results
def name(self):
return 'Future LU HSG'
def displayName(self):
return 'Future LU HSG'
def group(self):
return 'QGIS Tools'
def groupId(self):
return 'QGIS Tools'
def createInstance(self):
return FutureLuHsg()