mirror of
				https://github.com/qgis/QGIS.git
				synced 2025-11-04 00:04:25 -05:00 
			
		
		
		
	[processing] restore Shortest path from layer to point
This commit is contained in:
		
							parent
							
								
									494ceff3b4
								
							
						
					
					
						commit
						1e795960b6
					
				@ -89,7 +89,7 @@ from .SelectByAttribute import SelectByAttribute
 | 
			
		||||
from .SelectByExpression import SelectByExpression
 | 
			
		||||
# from .ServiceAreaFromLayer import ServiceAreaFromLayer
 | 
			
		||||
# from .ServiceAreaFromPoint import ServiceAreaFromPoint
 | 
			
		||||
# from .ShortestPathLayerToPoint import ShortestPathLayerToPoint
 | 
			
		||||
from .ShortestPathLayerToPoint import ShortestPathLayerToPoint
 | 
			
		||||
from .ShortestPathPointToLayer import ShortestPathPointToLayer
 | 
			
		||||
from .ShortestPathPointToPoint import ShortestPathPointToPoint
 | 
			
		||||
from .SimplifyGeometries import SimplifyGeometries
 | 
			
		||||
@ -274,6 +274,7 @@ class QGISAlgorithmProvider(QgsProcessingProvider):
 | 
			
		||||
                SaveSelectedFeatures(),
 | 
			
		||||
                SelectByAttribute(),
 | 
			
		||||
                SelectByExpression(),
 | 
			
		||||
                ShortestPathLayerToPoint(),
 | 
			
		||||
                ShortestPathPointToLayer(),
 | 
			
		||||
                ShortestPathPointToPoint(),
 | 
			
		||||
                SimplifyGeometries(),
 | 
			
		||||
 | 
			
		||||
@ -36,13 +36,19 @@ from qgis.core import (QgsWkbTypes,
 | 
			
		||||
                       QgsFeature,
 | 
			
		||||
                       QgsFeatureSink,
 | 
			
		||||
                       QgsGeometry,
 | 
			
		||||
                       QgsPointXY,
 | 
			
		||||
                       QgsFields,
 | 
			
		||||
                       QgsField,
 | 
			
		||||
                       QgsFeatureRequest,
 | 
			
		||||
                       QgsMessageLog,
 | 
			
		||||
                       QgsProcessingParameterDefinition,
 | 
			
		||||
                       QgsProcessingUtils)
 | 
			
		||||
                       QgsProcessing,
 | 
			
		||||
                       QgsProcessingParameterEnum,
 | 
			
		||||
                       QgsProcessingParameterPoint,
 | 
			
		||||
                       QgsProcessingParameterField,
 | 
			
		||||
                       QgsProcessingParameterNumber,
 | 
			
		||||
                       QgsProcessingParameterString,
 | 
			
		||||
                       QgsProcessingParameterFeatureSource,
 | 
			
		||||
                       QgsProcessingParameterFeatureSink,
 | 
			
		||||
                       QgsProcessingParameterVectorLayer,
 | 
			
		||||
                       QgsProcessingParameterDefinition)
 | 
			
		||||
from qgis.analysis import (QgsVectorLayerDirector,
 | 
			
		||||
                           QgsNetworkDistanceStrategy,
 | 
			
		||||
                           QgsNetworkSpeedStrategy,
 | 
			
		||||
@ -52,23 +58,14 @@ from qgis.analysis import (QgsVectorLayerDirector,
 | 
			
		||||
from qgis.utils import iface
 | 
			
		||||
 | 
			
		||||
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
 | 
			
		||||
from processing.core.parameters import (ParameterVector,
 | 
			
		||||
                                        ParameterPoint,
 | 
			
		||||
                                        ParameterNumber,
 | 
			
		||||
                                        ParameterString,
 | 
			
		||||
                                        ParameterTableField,
 | 
			
		||||
                                        ParameterSelection
 | 
			
		||||
                                        )
 | 
			
		||||
from processing.core.outputs import OutputVector
 | 
			
		||||
from processing.tools import dataobjects
 | 
			
		||||
 | 
			
		||||
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ShortestPathLayerToPoint(QgisAlgorithm):
 | 
			
		||||
 | 
			
		||||
    INPUT_VECTOR = 'INPUT_VECTOR'
 | 
			
		||||
    START_POINTS = 'START_POINT'
 | 
			
		||||
    INPUT = 'INPUT'
 | 
			
		||||
    START_POINTS = 'START_POINTS'
 | 
			
		||||
    END_POINT = 'END_POINT'
 | 
			
		||||
    STRATEGY = 'STRATEGY'
 | 
			
		||||
    DIRECTION_FIELD = 'DIRECTION_FIELD'
 | 
			
		||||
@ -79,7 +76,7 @@ class ShortestPathLayerToPoint(QgisAlgorithm):
 | 
			
		||||
    SPEED_FIELD = 'SPEED_FIELD'
 | 
			
		||||
    DEFAULT_SPEED = 'DEFAULT_SPEED'
 | 
			
		||||
    TOLERANCE = 'TOLERANCE'
 | 
			
		||||
    OUTPUT_LAYER = 'OUTPUT_LAYER'
 | 
			
		||||
    OUTPUT = 'OUTPUT'
 | 
			
		||||
 | 
			
		||||
    def icon(self):
 | 
			
		||||
        return QIcon(os.path.join(pluginPath, 'images', 'networkanalysis.svg'))
 | 
			
		||||
@ -100,58 +97,59 @@ class ShortestPathLayerToPoint(QgisAlgorithm):
 | 
			
		||||
                           self.tr('Fastest')
 | 
			
		||||
                           ]
 | 
			
		||||
 | 
			
		||||
        self.addParameter(ParameterVector(self.INPUT_VECTOR,
 | 
			
		||||
                                          self.tr('Vector layer representing network'),
 | 
			
		||||
                                          [dataobjects.TYPE_VECTOR_LINE]))
 | 
			
		||||
        self.addParameter(ParameterVector(self.START_POINTS,
 | 
			
		||||
                                          self.tr('Vector layer with start points'),
 | 
			
		||||
                                          [dataobjects.TYPE_VECTOR_POINT]))
 | 
			
		||||
        self.addParameter(ParameterPoint(self.END_POINT,
 | 
			
		||||
                                         self.tr('End point')))
 | 
			
		||||
        self.addParameter(ParameterSelection(self.STRATEGY,
 | 
			
		||||
                                             self.tr('Path type to calculate'),
 | 
			
		||||
                                             self.STRATEGIES,
 | 
			
		||||
                                             default=0))
 | 
			
		||||
        self.addParameter(QgsProcessingParameterVectorLayer(self.INPUT,
 | 
			
		||||
                                                            self.tr('Vector layer representing network'),
 | 
			
		||||
                                                            [QgsProcessing.TypeVectorLine]))
 | 
			
		||||
        self.addParameter(QgsProcessingParameterFeatureSource(self.START_POINTS,
 | 
			
		||||
                                                              self.tr('Vector layer with start points'),
 | 
			
		||||
                                                              [QgsProcessing.TypeVectorPoint]))
 | 
			
		||||
        self.addParameter(QgsProcessingParameterPoint(self.END_POINT,
 | 
			
		||||
                                                      self.tr('End point')))
 | 
			
		||||
        self.addParameter(QgsProcessingParameterEnum(self.STRATEGY,
 | 
			
		||||
                                                     self.tr('Path type to calculate'),
 | 
			
		||||
                                                     self.STRATEGIES,
 | 
			
		||||
                                                     defaultValue=0))
 | 
			
		||||
 | 
			
		||||
        params = []
 | 
			
		||||
        params.append(ParameterTableField(self.DIRECTION_FIELD,
 | 
			
		||||
                                          self.tr('Direction field'),
 | 
			
		||||
                                          self.INPUT_VECTOR,
 | 
			
		||||
                                          optional=True))
 | 
			
		||||
        params.append(ParameterString(self.VALUE_FORWARD,
 | 
			
		||||
                                      self.tr('Value for forward direction'),
 | 
			
		||||
                                      '',
 | 
			
		||||
                                      optional=True))
 | 
			
		||||
        params.append(ParameterString(self.VALUE_BACKWARD,
 | 
			
		||||
                                      self.tr('Value for backward direction'),
 | 
			
		||||
                                      '',
 | 
			
		||||
                                      optional=True))
 | 
			
		||||
        params.append(ParameterString(self.VALUE_BOTH,
 | 
			
		||||
                                      self.tr('Value for both directions'),
 | 
			
		||||
                                      '',
 | 
			
		||||
                                      optional=True))
 | 
			
		||||
        params.append(ParameterSelection(self.DEFAULT_DIRECTION,
 | 
			
		||||
                                         self.tr('Default direction'),
 | 
			
		||||
                                         list(self.DIRECTIONS.keys()),
 | 
			
		||||
                                         default=2))
 | 
			
		||||
        params.append(ParameterTableField(self.SPEED_FIELD,
 | 
			
		||||
                                          self.tr('Speed field'),
 | 
			
		||||
                                          self.INPUT_VECTOR,
 | 
			
		||||
                                          optional=True))
 | 
			
		||||
        params.append(ParameterNumber(self.DEFAULT_SPEED,
 | 
			
		||||
                                      self.tr('Default speed (km/h)'),
 | 
			
		||||
                                      0.0, 99999999.999999, 5.0))
 | 
			
		||||
        params.append(ParameterNumber(self.TOLERANCE,
 | 
			
		||||
                                      self.tr('Topology tolerance'),
 | 
			
		||||
                                      0.0, 99999999.999999, 0.0))
 | 
			
		||||
        params.append(QgsProcessingParameterField(self.DIRECTION_FIELD,
 | 
			
		||||
                                                  self.tr('Direction field'),
 | 
			
		||||
                                                  None,
 | 
			
		||||
                                                  self.INPUT,
 | 
			
		||||
                                                  optional=True))
 | 
			
		||||
        params.append(QgsProcessingParameterString(self.VALUE_FORWARD,
 | 
			
		||||
                                                   self.tr('Value for forward direction'),
 | 
			
		||||
                                                   optional=True))
 | 
			
		||||
        params.append(QgsProcessingParameterString(self.VALUE_BACKWARD,
 | 
			
		||||
                                                   self.tr('Value for backward direction'),
 | 
			
		||||
                                                   optional=True))
 | 
			
		||||
        params.append(QgsProcessingParameterString(self.VALUE_BOTH,
 | 
			
		||||
                                                   self.tr('Value for both directions'),
 | 
			
		||||
                                                   optional=True))
 | 
			
		||||
        params.append(QgsProcessingParameterEnum(self.DEFAULT_DIRECTION,
 | 
			
		||||
                                                 self.tr('Default direction'),
 | 
			
		||||
                                                 list(self.DIRECTIONS.keys()),
 | 
			
		||||
                                                 defaultValue=2))
 | 
			
		||||
        params.append(QgsProcessingParameterField(self.SPEED_FIELD,
 | 
			
		||||
                                                  self.tr('Speed field'),
 | 
			
		||||
                                                  None,
 | 
			
		||||
                                                  self.INPUT,
 | 
			
		||||
                                                  optional=True))
 | 
			
		||||
        params.append(QgsProcessingParameterNumber(self.DEFAULT_SPEED,
 | 
			
		||||
                                                   self.tr('Default speed (km/h)'),
 | 
			
		||||
                                                   QgsProcessingParameterNumber.Double,
 | 
			
		||||
                                                   5.0, False, 0, 99999999.99))
 | 
			
		||||
        params.append(QgsProcessingParameterNumber(self.TOLERANCE,
 | 
			
		||||
                                                   self.tr('Topology tolerance'),
 | 
			
		||||
                                                   QgsProcessingParameterNumber.Double,
 | 
			
		||||
                                                   0.0, False, 0, 99999999.99))
 | 
			
		||||
 | 
			
		||||
        for p in params:
 | 
			
		||||
            p.setFlags(p.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
 | 
			
		||||
            self.addParameter(p)
 | 
			
		||||
 | 
			
		||||
        self.addOutput(OutputVector(self.OUTPUT_LAYER,
 | 
			
		||||
                                    self.tr('Shortest path'),
 | 
			
		||||
                                    datatype=[dataobjects.TYPE_VECTOR_LINE]))
 | 
			
		||||
        self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT,
 | 
			
		||||
                                                            self.tr('Shortest path'),
 | 
			
		||||
                                                            QgsProcessing.TypeVectorLine))
 | 
			
		||||
 | 
			
		||||
    def name(self):
 | 
			
		||||
        return 'shortestpathlayertopoint'
 | 
			
		||||
@ -160,21 +158,19 @@ class ShortestPathLayerToPoint(QgisAlgorithm):
 | 
			
		||||
        return self.tr('Shortest path (layer to point)')
 | 
			
		||||
 | 
			
		||||
    def processAlgorithm(self, parameters, context, feedback):
 | 
			
		||||
        layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_VECTOR), context)
 | 
			
		||||
        startPoints = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.START_POINTS), context)
 | 
			
		||||
        endPoint = self.getParameterValue(self.END_POINT)
 | 
			
		||||
        strategy = self.getParameterValue(self.STRATEGY)
 | 
			
		||||
        layer = self.parameterAsVectorLayer(parameters, self.INPUT, context)
 | 
			
		||||
        startPoints = self.parameterAsSource(parameters, self.START_POINTS, context)
 | 
			
		||||
        endPoint = self.parameterAsPoint(parameters, self.END_POINT, context)
 | 
			
		||||
        strategy = self.parameterAsEnum(parameters, self.STRATEGY, context)
 | 
			
		||||
 | 
			
		||||
        directionFieldName = self.getParameterValue(self.DIRECTION_FIELD)
 | 
			
		||||
        forwardValue = self.getParameterValue(self.VALUE_FORWARD)
 | 
			
		||||
        backwardValue = self.getParameterValue(self.VALUE_BACKWARD)
 | 
			
		||||
        bothValue = self.getParameterValue(self.VALUE_BOTH)
 | 
			
		||||
        defaultDirection = self.getParameterValue(self.DEFAULT_DIRECTION)
 | 
			
		||||
        bothValue = self.getParameterValue(self.VALUE_BOTH)
 | 
			
		||||
        defaultDirection = self.getParameterValue(self.DEFAULT_DIRECTION)
 | 
			
		||||
        speedFieldName = self.getParameterValue(self.SPEED_FIELD)
 | 
			
		||||
        defaultSpeed = self.getParameterValue(self.DEFAULT_SPEED)
 | 
			
		||||
        tolerance = self.getParameterValue(self.TOLERANCE)
 | 
			
		||||
        directionFieldName = self.parameterAsString(parameters, self.DIRECTION_FIELD, context)
 | 
			
		||||
        forwardValue = self.parameterAsString(parameters, self.VALUE_FORWARD, context)
 | 
			
		||||
        backwardValue = self.parameterAsString(parameters, self.VALUE_BACKWARD, context)
 | 
			
		||||
        bothValue = self.parameterAsString(parameters, self.VALUE_BOTH, context)
 | 
			
		||||
        defaultDirection = self.parameterAsEnum(parameters, self.DEFAULT_DIRECTION, context)
 | 
			
		||||
        speedFieldName = self.parameterAsString(parameters, self.SPEED_FIELD, context)
 | 
			
		||||
        defaultSpeed = self.parameterAsDouble(parameters, self.DEFAULT_SPEED, context)
 | 
			
		||||
        tolerance = self.parameterAsDouble(parameters, self.TOLERANCE, context)
 | 
			
		||||
 | 
			
		||||
        fields = QgsFields()
 | 
			
		||||
        fields.append(QgsField('start', QVariant.String, '', 254, 0))
 | 
			
		||||
@ -184,17 +180,14 @@ class ShortestPathLayerToPoint(QgisAlgorithm):
 | 
			
		||||
        feat = QgsFeature()
 | 
			
		||||
        feat.setFields(fields)
 | 
			
		||||
 | 
			
		||||
        writer = self.getOutputFromName(
 | 
			
		||||
            self.OUTPUT_LAYER).getVectorWriter(fields, QgsWkbTypes.LineString, layer.crs(), context)
 | 
			
		||||
 | 
			
		||||
        tmp = endPoint.split(',')
 | 
			
		||||
        endPoint = QgsPointXY(float(tmp[0]), float(tmp[1]))
 | 
			
		||||
        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
 | 
			
		||||
                                               fields, QgsWkbTypes.LineString, layer.crs())
 | 
			
		||||
 | 
			
		||||
        directionField = -1
 | 
			
		||||
        if directionFieldName is not None:
 | 
			
		||||
        if directionFieldName:
 | 
			
		||||
            directionField = layer.fields().lookupField(directionFieldName)
 | 
			
		||||
        speedField = -1
 | 
			
		||||
        if speedFieldName is not None:
 | 
			
		||||
        if speedFieldName:
 | 
			
		||||
            speedField = layer.fields().lookupField(speedFieldName)
 | 
			
		||||
 | 
			
		||||
        director = QgsVectorLayerDirector(layer,
 | 
			
		||||
@ -222,12 +215,16 @@ class ShortestPathLayerToPoint(QgisAlgorithm):
 | 
			
		||||
        feedback.pushInfo(self.tr('Loading start points...'))
 | 
			
		||||
        request = QgsFeatureRequest()
 | 
			
		||||
        request.setFlags(request.flags() ^ QgsFeatureRequest.SubsetOfAttributes)
 | 
			
		||||
        features = QgsProcessingUtils.getFeatures(startPoints, context, request)
 | 
			
		||||
        count = QgsProcessingUtils.featureCount(startPoints, context)
 | 
			
		||||
        features = source.getFeatures(request)
 | 
			
		||||
        total = 100.0 / source.featureCount() if source.featureCount() else 0
 | 
			
		||||
 | 
			
		||||
        points = [endPoint]
 | 
			
		||||
        for f in features:
 | 
			
		||||
        for current, f in enumerate(features):
 | 
			
		||||
            if feedback.isCanceled():
 | 
			
		||||
                break
 | 
			
		||||
 | 
			
		||||
            points.append(f.geometry().asPoint())
 | 
			
		||||
            feedback.setProgress(int(current * total))
 | 
			
		||||
 | 
			
		||||
        feedback.pushInfo(self.tr('Building graph...'))
 | 
			
		||||
        snappedPoints = director.makeGraph(builder, points)
 | 
			
		||||
@ -238,7 +235,7 @@ class ShortestPathLayerToPoint(QgisAlgorithm):
 | 
			
		||||
        idxEnd = graph.findVertex(snappedPoints[0])
 | 
			
		||||
        route = []
 | 
			
		||||
 | 
			
		||||
        total = 100.0 / count if count else 1
 | 
			
		||||
        total = 100.0 / source.featureCount() if source.featureCount() else 1
 | 
			
		||||
        for i in range(1, count + 1):
 | 
			
		||||
            idxStart = graph.findVertex(snappedPoints[i])
 | 
			
		||||
            tree, cost = QgsGraphAnalyzer.dijkstra(graph, idxStart, 0)
 | 
			
		||||
@ -264,10 +261,10 @@ class ShortestPathLayerToPoint(QgisAlgorithm):
 | 
			
		||||
            feat['start'] = points[i].toString()
 | 
			
		||||
            feat['end'] = endPoint.toString()
 | 
			
		||||
            feat['cost'] = cost / multiplier
 | 
			
		||||
            writer.addFeature(feat, QgsFeatureSink.FastInsert)
 | 
			
		||||
            sink.addFeature(feat, QgsFeatureSink.FastInsert)
 | 
			
		||||
 | 
			
		||||
            route[:] = []
 | 
			
		||||
 | 
			
		||||
            feedback.setProgress(int(i * total))
 | 
			
		||||
 | 
			
		||||
        del writer
 | 
			
		||||
        return {self.OUTPUT: dest_id}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user