处理算法迭代调用失败

问题描述 投票:0回答:0

我为QGIS 3.x编写了一个处理脚本,它本身在for循环中调用本机处理函数(qgis:shortestpathpointtolayer)。

from qgis.PyQt.QtCore import QCoreApplication
from qgis.core import (QgsProcessing,
                       QgsFeatureRequest,
                       QgsExpression,
                       QgsProcessingContext,
                       QgsProcessingException,
                       QgsProcessingAlgorithm,
                       QgsProcessingParameterVectorLayer,
                       QgsProcessingFeatureSourceDefinition)
from qgis import processing


class findDownstreamPathAlgorithm(QgsProcessingAlgorithm):
    """
    This is an algorithm that calculates downstream paths on
    a simplified network.

    """

    INPUT_NETWORK = 'INPUT_NETWORK'
    INPUT_VALVES = 'INPUT_VALVES'

    def tr(self, string):
        return QCoreApplication.translate('Processing', string)

    def createInstance(self):
        return findDownstreamPathAlgorithm()

    def name(self):
        return 'iterateclusters'

    def displayName(self):
        return self.tr('Iterate clusters')

    def group(self):
        return self.tr('Thvilum')

    def groupId(self):
        return 'lukkelister'

    def shortHelpString(self):
        return self.tr("Iterate clusters in a simplified network")

    def initAlgorithm(self, config=None):

        self.addParameter(
            QgsProcessingParameterVectorLayer(
                self.INPUT_NETWORK,
                self.tr('Netværkslag'),
                [QgsProcessing.SourceType.TypeVectorLine]
            )
        )

        self.addParameter(
            QgsProcessingParameterVectorLayer(
                self.INPUT_VALVES,
                self.tr('Ventillag'),
                [QgsProcessing.SourceType.TypeVectorPoint]
            )
        )

    def processAlgorithm(self, parameters, context, feedback):

        # Retrieve the feature sources
        network = self.parameterAsVectorLayer(
            parameters,
            self.INPUT_NETWORK,
            context
        )

        valves = self.parameterAsVectorLayer(
            parameters,
            self.INPUT_VALVES,
            context
        )

        if network is None:
            raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT_NETWORK))

        if valves is None:
            raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT_VALVES))

        # Store inlets from valves layer in separate scractch layer
        inlets = valves.materialize(QgsFeatureRequest(QgsExpression("situation = 'IsInlet'")))

        # Collect clusters to evaluate
        clusterList = []
        for feat in network.getFeatures():
            clusterList.append(feat["cluster"])
 
        # Remove duplicates and sort list
        clusterList = sorted(set(clusterList))
        if len(clusterList) > 0:
            total = 100.0 / len(clusterList)
        else:
            total = 0

        isCanceled = False
        for current, cluster in enumerate(clusterList):
            # Update the progress bar
            feedback.setProgress(int(current * total))
            
            valves.selectByExpression("cluster = {} and situation = 'Flow'".format(cluster))
            for feat in valves.selectedFeatures():
                # Stop the algorithm if cancel button has been clicked
                if feedback.isCanceled():
                    isCanceled = True
                    break

                vertex_id = feat["vertexId"]
                valve_geom = feat.geometry()
                network.selectByExpression("cluster != {}".format(cluster))

                parameters = {
                    'DEFAULT_DIRECTION' : 2,
                    'DEFAULT_SPEED' : 50,
                    'DIRECTION_FIELD' : '',
                    'END_POINTS' : inlets,
                    'INPUT' : QgsProcessingFeatureSourceDefinition( network.id(), selectedFeaturesOnly=True),
                    'OUTPUT' : 'TEMPORARY_OUTPUT',
                    #'OUTPUT_NON_ROUTABLE' : 'TEMPORARY_OUTPUT',
                    'SPEED_FIELD' : '',
                    'START_POINT' : valve_geom,
                    'STRATEGY' : 0,
                    'TOLERANCE' : 0,
                    'VALUE_BACKWARD' : '',
                    'VALUE_BOTH' : '',
                    'VALUE_FORWARD' : ''
                    }
            
                result = processing.run("qgis:shortestpathpointtolayer", parameters, context=context, feedback=feedback, is_child_algorithm=True)
                shortest_path = QgsProcessingContext.takeResultLayer(context, result['OUTPUT'])
                
                # Do something with the path
                    
                del shortest_path
                    
            if isCanceled:
                break


        return {self.INPUT_NETWORK: network}

在 QGIS 3.28.4 上运行此脚本时,它会运行几次迭代,然后引发异常(访问冲突),并具有以下描述:

Python 堆栈跟踪 Windows 致命异常:访问冲突

线程 0x00005d8c(最近调用优先): 文件“C:\PROGRA~1/QGIS32~2.4/apps/qgis-ltr/./python/plugins\processing\gui\AlgorithmExecutor.py”,第 72 行执行 结果,ok = alg.run(参数,上下文,反馈,{},False) 文件“C:\PROGRA~1/QGIS32~2.4/apps/qgis-ltr/./python/plugins\processin

processing qgis pyqgis
© www.soinside.com 2019 - 2024. All rights reserved.