From c5ed53942c36a61ad01c1831660c8d19824cd89f Mon Sep 17 00:00:00 2001 From: Alexander Bruy Date: Sun, 16 Jul 2017 11:26:44 +0300 Subject: [PATCH 1/9] [processing] restore Shortest path from point to point --- .../algs/qgis/QGISAlgorithmProvider.py | 11 +- .../algs/qgis/ShortestPathPointToPoint.py | 174 +++++++++--------- 2 files changed, 89 insertions(+), 96 deletions(-) diff --git a/python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py b/python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py index b0f76cd820a..3b57c9dc0ae 100644 --- a/python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py +++ b/python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py @@ -87,6 +87,11 @@ from .Ruggedness import Ruggedness from .SaveSelectedFeatures import SaveSelectedFeatures from .SelectByAttribute import SelectByAttribute from .SelectByExpression import SelectByExpression +# from .ServiceAreaFromLayer import ServiceAreaFromLayer +# from .ServiceAreaFromPoint import ServiceAreaFromPoint +# from .ShortestPathLayerToPoint import ShortestPathLayerToPoint +# from .ShortestPathPointToLayer import ShortestPathPointToLayer +from .ShortestPathPointToPoint import ShortestPathPointToPoint from .SimplifyGeometries import SimplifyGeometries from .Slope import Slope from .Smooth import Smooth @@ -158,11 +163,6 @@ from .ZonalStatistics import ZonalStatistics # from .ExtractSpecificNodes import ExtractSpecificNodes # from .GeometryByExpression import GeometryByExpression # from .RasterCalculator import RasterCalculator -# from .ShortestPathPointToPoint import ShortestPathPointToPoint -# from .ShortestPathPointToLayer import ShortestPathPointToLayer -# from .ShortestPathLayerToPoint import ShortestPathLayerToPoint -# from .ServiceAreaFromPoint import ServiceAreaFromPoint -# from .ServiceAreaFromLayer import ServiceAreaFromLayer # from .TruncateTable import TruncateTable # from .Polygonize import Polygonize # from .ExecuteSQL import ExecuteSQL @@ -274,6 +274,7 @@ class QGISAlgorithmProvider(QgsProcessingProvider): SaveSelectedFeatures(), SelectByAttribute(), SelectByExpression(), + ShortestPathPointToPoint(), SimplifyGeometries(), Slope(), Smooth(), diff --git a/python/plugins/processing/algs/qgis/ShortestPathPointToPoint.py b/python/plugins/processing/algs/qgis/ShortestPathPointToPoint.py index 2dc4cdb0527..179d4a7af94 100644 --- a/python/plugins/processing/algs/qgis/ShortestPathPointToPoint.py +++ b/python/plugins/processing/algs/qgis/ShortestPathPointToPoint.py @@ -36,11 +36,19 @@ from qgis.core import (QgsWkbTypes, QgsFeature, QgsFeatureSink, QgsGeometry, - QgsPointXY, QgsFields, QgsField, - QgsProcessingParameterDefinition, - QgsProcessingUtils) + QgsProcessing, + QgsProcessingException, + QgsProcessingOutputNumber, + QgsProcessingParameterEnum, + QgsProcessingParameterPoint, + QgsProcessingParameterField, + QgsProcessingParameterNumber, + QgsProcessingParameterString, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterVectorLayer, + QgsProcessingParameterDefinition) from qgis.analysis import (QgsVectorLayerDirector, QgsNetworkDistanceStrategy, QgsNetworkSpeedStrategy, @@ -50,25 +58,13 @@ from qgis.analysis import (QgsVectorLayerDirector, from qgis.utils import iface from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm -from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException -from processing.core.parameters import (ParameterVector, - ParameterPoint, - ParameterNumber, - ParameterString, - ParameterTableField, - ParameterSelection - ) -from processing.core.outputs import (OutputNumber, - OutputVector - ) -from processing.tools import dataobjects pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0] class ShortestPathPointToPoint(QgisAlgorithm): - INPUT_VECTOR = 'INPUT_VECTOR' + INPUT = 'INPUT' START_POINT = 'START_POINT' END_POINT = 'END_POINT' STRATEGY = 'STRATEGY' @@ -81,7 +77,7 @@ class ShortestPathPointToPoint(QgisAlgorithm): DEFAULT_SPEED = 'DEFAULT_SPEED' TOLERANCE = 'TOLERANCE' TRAVEL_COST = 'TRAVEL_COST' - OUTPUT_LAYER = 'OUTPUT_LAYER' + OUTPUT = 'OUTPUT' def icon(self): return QIcon(os.path.join(pluginPath, 'images', 'networkanalysis.svg')) @@ -102,59 +98,60 @@ class ShortestPathPointToPoint(QgisAlgorithm): self.tr('Fastest') ] - self.addParameter(ParameterVector(self.INPUT_VECTOR, - self.tr('Vector layer representing network'), - [dataobjects.TYPE_VECTOR_LINE])) - self.addParameter(ParameterPoint(self.START_POINT, - self.tr('Start 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(QgsProcessingParameterPoint(self.START_POINT, + self.tr('Start point'))) + 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(OutputNumber(self.TRAVEL_COST, - self.tr('Travel cost'))) - self.addOutput(OutputVector(self.OUTPUT_LAYER, - self.tr('Shortest path'), - datatype=[dataobjects.TYPE_VECTOR_LINE])) + self.addOutput(QgsProcessingOutputNumber(self.TRAVEL_COST, + self.tr('Travel cost'))) + self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, + self.tr('Shortest path'), + QgsProcessing.TypeVectorLine)) def name(self): return 'shortestpathpointtopoint' @@ -163,40 +160,33 @@ class ShortestPathPointToPoint(QgisAlgorithm): return self.tr('Shortest path (point to point)') def processAlgorithm(self, parameters, context, feedback): - layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_VECTOR), context) - startPoint = self.getParameterValue(self.START_POINT) - endPoint = self.getParameterValue(self.END_POINT) - strategy = self.getParameterValue(self.STRATEGY) + layer = self.parameterAsVectorLayer(parameters, self.INPUT, context) + startPoint = self.parameterAsPoint(parameters, self.START_POINT, 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)) fields.append(QgsField('end', QVariant.String, '', 254, 0)) fields.append(QgsField('cost', QVariant.Double, '', 20, 7)) - writer = self.getOutputFromName( - self.OUTPUT_LAYER).getVectorWriter(fields, QgsWkbTypes.LineString, layer.crs(), context) - - tmp = startPoint.split(',') - startPoint = QgsPointXY(float(tmp[0]), float(tmp[1])) - 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 directionField: directionField = layer.fields().lookupField(directionFieldName) speedField = -1 - if speedFieldName is not None: + if speedFieldName: speedField = layer.fields().lookupField(speedFieldName) director = QgsVectorLayerDirector(layer, @@ -230,7 +220,7 @@ class ShortestPathPointToPoint(QgisAlgorithm): tree, cost = QgsGraphAnalyzer.dijkstra(graph, idxStart, 0) if tree[idxEnd] == -1: - raise GeoAlgorithmExecutionException( + raise QgsProcessingException( self.tr('There is no route from start point to end point.')) route = [] @@ -244,8 +234,6 @@ class ShortestPathPointToPoint(QgisAlgorithm): route.append(snappedPoints[0]) route.reverse() - self.setOutputValue(self.TRAVEL_COST, cost / multiplier) - feedback.pushInfo(self.tr('Writing results...')) geom = QgsGeometry.fromPolyline(route) feat = QgsFeature() @@ -254,5 +242,9 @@ class ShortestPathPointToPoint(QgisAlgorithm): feat['end'] = endPoint.toString() feat['cost'] = cost / multiplier feat.setGeometry(geom) - writer.addFeature(feat, QgsFeatureSink.FastInsert) - del writer + sink.addFeature(feat, QgsFeatureSink.FastInsert) + + results = {} + results[self.TRAVEL_COST] = cost / multiplier + results[self.OUTPUT] = dest_id + return results From 494ceff3b48ae2e9bcbc5d8010fe6c99db2955cb Mon Sep 17 00:00:00 2001 From: Alexander Bruy Date: Sun, 16 Jul 2017 11:31:11 +0300 Subject: [PATCH 2/9] [processing] restore Shortest path from point to layer --- .../algs/qgis/QGISAlgorithmProvider.py | 3 +- .../algs/qgis/ShortestPathPointToLayer.py | 177 +++++++++--------- 2 files changed, 93 insertions(+), 87 deletions(-) diff --git a/python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py b/python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py index 3b57c9dc0ae..dfc6305dfdc 100644 --- a/python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py +++ b/python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py @@ -90,7 +90,7 @@ from .SelectByExpression import SelectByExpression # from .ServiceAreaFromLayer import ServiceAreaFromLayer # from .ServiceAreaFromPoint import ServiceAreaFromPoint # from .ShortestPathLayerToPoint import ShortestPathLayerToPoint -# from .ShortestPathPointToLayer import ShortestPathPointToLayer +from .ShortestPathPointToLayer import ShortestPathPointToLayer from .ShortestPathPointToPoint import ShortestPathPointToPoint from .SimplifyGeometries import SimplifyGeometries from .Slope import Slope @@ -274,6 +274,7 @@ class QGISAlgorithmProvider(QgsProcessingProvider): SaveSelectedFeatures(), SelectByAttribute(), SelectByExpression(), + ShortestPathPointToLayer(), ShortestPathPointToPoint(), SimplifyGeometries(), Slope(), diff --git a/python/plugins/processing/algs/qgis/ShortestPathPointToLayer.py b/python/plugins/processing/algs/qgis/ShortestPathPointToLayer.py index 06a72639427..c46bb84e259 100644 --- a/python/plugins/processing/algs/qgis/ShortestPathPointToLayer.py +++ b/python/plugins/processing/algs/qgis/ShortestPathPointToLayer.py @@ -31,10 +31,24 @@ from collections import OrderedDict from qgis.PyQt.QtCore import QVariant from qgis.PyQt.QtGui import QIcon -from qgis.core import (QgsWkbTypes, QgsUnitTypes, QgsFeatureSink, QgsFeature, QgsGeometry, QgsPointXY, QgsFields, QgsField, QgsFeatureRequest, +from qgis.core import (QgsWkbTypes, + QgsUnitTypes, + QgsFeature, + QgsFeatureSink, + QgsGeometry, + QgsFields, + QgsField, QgsMessageLog, - QgsProcessingParameterDefinition, - QgsProcessingUtils) + QgsProcessing, + QgsProcessingParameterEnum, + QgsProcessingParameterPoint, + QgsProcessingParameterField, + QgsProcessingParameterNumber, + QgsProcessingParameterString, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterVectorLayer, + QgsProcessingParameterDefinition) from qgis.analysis import (QgsVectorLayerDirector, QgsNetworkDistanceStrategy, QgsNetworkSpeedStrategy, @@ -44,22 +58,13 @@ 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 ShortestPathPointToLayer(QgisAlgorithm): - INPUT_VECTOR = 'INPUT_VECTOR' + INPUT = 'INPUT' START_POINT = 'START_POINT' END_POINTS = 'END_POINTS' STRATEGY = 'STRATEGY' @@ -71,7 +76,7 @@ class ShortestPathPointToLayer(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')) @@ -92,58 +97,59 @@ class ShortestPathPointToLayer(QgisAlgorithm): self.tr('Fastest') ] - self.addParameter(ParameterVector(self.INPUT_VECTOR, - self.tr('Vector layer representing network'), - [dataobjects.TYPE_VECTOR_LINE])) - self.addParameter(ParameterPoint(self.START_POINT, - self.tr('Start point'))) - self.addParameter(ParameterVector(self.END_POINTS, - self.tr('Vector layer with end points'), - [dataobjects.TYPE_VECTOR_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(QgsProcessingParameterPoint(self.START_POINT, + self.tr('Start point'))) + self.addParameter(QgsProcessingParameterFeatureSource(self.END_POINTS, + self.tr('Vector layer with end points'), + [QgsProcessing.TypeVectorPoint])) + 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 'shortestpathpointtolayer' @@ -152,21 +158,19 @@ class ShortestPathPointToLayer(QgisAlgorithm): return self.tr('Shortest path (point to layer)') def processAlgorithm(self, parameters, context, feedback): - layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_VECTOR), context) - startPoint = self.getParameterValue(self.START_POINT) - endPoints = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.END_POINTS), context) - strategy = self.getParameterValue(self.STRATEGY) + layer = self.parameterAsVectorLayer(parameters, self.INPUT, context) + startPoint = self.parameterAsPoint(parameters, self.START_POINT, context) + endPoints = self.parameterAsSource(parameters, self.END_POINTS, 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)) @@ -176,17 +180,14 @@ class ShortestPathPointToLayer(QgisAlgorithm): feat = QgsFeature() feat.setFields(fields) - writer = self.getOutputFromName( - self.OUTPUT_LAYER).getVectorWriter(fields, QgsWkbTypes.LineString, layer.crs(), context) - - tmp = startPoint.split(',') - startPoint = 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, @@ -214,12 +215,16 @@ class ShortestPathPointToLayer(QgisAlgorithm): feedback.pushInfo(self.tr('Loading end points...')) request = QgsFeatureRequest() request.setFlags(request.flags() ^ QgsFeatureRequest.SubsetOfAttributes) - features = QgsProcessingUtils.getFeatures(endPoints, context, request) - count = QgsProcessingUtils.featureCount(endPoints, context) + features = source.getFeatures(request) + total = 100.0 / source.featureCount() if source.featureCount() else 0 points = [startPoint] - 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) @@ -231,7 +236,7 @@ class ShortestPathPointToLayer(QgisAlgorithm): tree, cost = QgsGraphAnalyzer.dijkstra(graph, idxStart, 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): idxEnd = graph.findVertex(snappedPoints[i]) @@ -256,10 +261,10 @@ class ShortestPathPointToLayer(QgisAlgorithm): feat['start'] = startPoint.toString() feat['end'] = points[i].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} From 1e795960b6d4f0f0f8836770a146b0494bf2e14e Mon Sep 17 00:00:00 2001 From: Alexander Bruy Date: Sun, 16 Jul 2017 11:33:34 +0300 Subject: [PATCH 3/9] [processing] restore Shortest path from layer to point --- .../algs/qgis/QGISAlgorithmProvider.py | 3 +- .../algs/qgis/ShortestPathLayerToPoint.py | 173 +++++++++--------- 2 files changed, 87 insertions(+), 89 deletions(-) diff --git a/python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py b/python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py index dfc6305dfdc..83ce8145ffa 100644 --- a/python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py +++ b/python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py @@ -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(), diff --git a/python/plugins/processing/algs/qgis/ShortestPathLayerToPoint.py b/python/plugins/processing/algs/qgis/ShortestPathLayerToPoint.py index 87948058ed5..5f97db978d1 100644 --- a/python/plugins/processing/algs/qgis/ShortestPathLayerToPoint.py +++ b/python/plugins/processing/algs/qgis/ShortestPathLayerToPoint.py @@ -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} From abd14e8b9405c009d3a1753e61e72475bac21890 Mon Sep 17 00:00:00 2001 From: Alexander Bruy Date: Sun, 16 Jul 2017 11:44:11 +0300 Subject: [PATCH 4/9] [processing] restore Service area from point --- .../algs/qgis/QGISAlgorithmProvider.py | 3 +- .../algs/qgis/ServiceAreaFromPoint.py | 183 +++++++++--------- 2 files changed, 92 insertions(+), 94 deletions(-) diff --git a/python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py b/python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py index 83ce8145ffa..f6c6fda95cb 100644 --- a/python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py +++ b/python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py @@ -88,7 +88,7 @@ from .SaveSelectedFeatures import SaveSelectedFeatures from .SelectByAttribute import SelectByAttribute from .SelectByExpression import SelectByExpression # from .ServiceAreaFromLayer import ServiceAreaFromLayer -# from .ServiceAreaFromPoint import ServiceAreaFromPoint +from .ServiceAreaFromPoint import ServiceAreaFromPoint from .ShortestPathLayerToPoint import ShortestPathLayerToPoint from .ShortestPathPointToLayer import ShortestPathPointToLayer from .ShortestPathPointToPoint import ShortestPathPointToPoint @@ -274,6 +274,7 @@ class QGISAlgorithmProvider(QgsProcessingProvider): SaveSelectedFeatures(), SelectByAttribute(), SelectByExpression(), + ServiceAreaFromPoint(), ShortestPathLayerToPoint(), ShortestPathPointToLayer(), ShortestPathPointToPoint(), diff --git a/python/plugins/processing/algs/qgis/ServiceAreaFromPoint.py b/python/plugins/processing/algs/qgis/ServiceAreaFromPoint.py index 79e001a7e8c..166b1725a12 100644 --- a/python/plugins/processing/algs/qgis/ServiceAreaFromPoint.py +++ b/python/plugins/processing/algs/qgis/ServiceAreaFromPoint.py @@ -36,11 +36,18 @@ from qgis.core import (QgsWkbTypes, QgsFeature, QgsFeatureSink, QgsGeometry, - QgsPointXY, - QgsField, QgsFields, - QgsProcessingParameterDefinition, - QgsProcessingUtils) + QgsField, + QgsProcessing, + QgsProcessingParameterEnum, + QgsProcessingParameterPoint, + QgsProcessingParameterField, + QgsProcessingParameterNumber, + QgsProcessingParameterString, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterVectorLayer, + QgsProcessingParameterDefinition) from qgis.analysis import (QgsVectorLayerDirector, QgsNetworkDistanceStrategy, QgsNetworkSpeedStrategy, @@ -50,22 +57,13 @@ 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 ServiceAreaFromPoint(QgisAlgorithm): - INPUT_VECTOR = 'INPUT_VECTOR' + INPUT = 'INPUT' START_POINT = 'START_POINT' STRATEGY = 'STRATEGY' TRAVEL_COST = 'TRAVEL_COST' @@ -99,61 +97,63 @@ class ServiceAreaFromPoint(QgisAlgorithm): self.tr('Fastest') ] - self.addParameter(ParameterVector(self.INPUT_VECTOR, - self.tr('Vector layer representing network'), - [dataobjects.TYPE_VECTOR_LINE])) - self.addParameter(ParameterPoint(self.START_POINT, - self.tr('Start point'))) - self.addParameter(ParameterSelection(self.STRATEGY, - self.tr('Path type to calculate'), - self.STRATEGIES, - default=0)) - self.addParameter(ParameterNumber(self.TRAVEL_COST, - self.tr('Travel cost (distance for "Shortest", time for "Fastest")'), - 0.0, 99999999.999999, 0.0)) + self.addParameter(QgsProcessingParameterVectorLayer(self.INPUT, + self.tr('Vector layer representing network'), + [QgsProcessing.TypeVectorLine])) + self.addParameter(QgsProcessingParameterPoint(self.START_POINT, + self.tr('Start point'))) + self.addParameter(QgsProcessingParameterEnum(self.STRATEGY, + self.tr('Path type to calculate'), + self.STRATEGIES, + defaultValue=0)) + self.addParameter(QgsProcessingParameterNumber(self.TRAVEL_COST, + self.tr('Travel cost (distance for "Shortest", time for "Fastest")'), + QgsProcessingParameterNumber.Double, + 0.0, False, 0, 99999999.99)) 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_POINTS, - self.tr('Service area (boundary nodes)'), - datatype=[dataobjects.TYPE_VECTOR_POINT])) - self.addOutput(OutputVector(self.OUTPUT_POLYGON, - self.tr('Service area (convex hull)'), - datatype=[dataobjects.TYPE_VECTOR_POLYGON])) + self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT_POINTS, + self.tr('Service area (boundary nodes)'), + QgsProcessing.TypeVectorPoint)) + self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT_POLYGON, + self.tr('Service area (convex hull)'), + QgsProcessing.TypeVectorPolygon)) def name(self): return 'serviceareafrompoint' @@ -162,30 +162,25 @@ class ServiceAreaFromPoint(QgisAlgorithm): return self.tr('Service area (from point)') def processAlgorithm(self, parameters, context, feedback): - layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_VECTOR), context) - startPoint = self.getParameterValue(self.START_POINT) - strategy = self.getParameterValue(self.STRATEGY) - travelCost = self.getParameterValue(self.TRAVEL_COST) + layer = self.parameterAsVectorLayer(parameters, self.INPUT, context) + startPoint = self.parameterAsPoint(parameters, self.START_POINT, context) + strategy = self.parameterAsEnum(parameters, self.STRATEGY, context) + travelCost = self.parameterAsDouble(parameters, self.TRAVEL_COST, 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) - - tmp = startPoint.split(',') - startPoint = QgsPointXY(float(tmp[0]), float(tmp[1])) + 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) 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, @@ -241,38 +236,40 @@ class ServiceAreaFromPoint(QgisAlgorithm): geomUpper = QgsGeometry.fromMultiPoint(upperBoundary) geomLower = QgsGeometry.fromMultiPoint(lowerBoundary) - writer = self.getOutputFromName( - self.OUTPUT_POINTS).getVectorWriter(fields, QgsWkbTypes.MultiPoint, layer.crs(), context) + (sinkPoints, pointsId) = self.parameterAsSink(parameters, self.OUTPUT_POINTS, context, + fields, QgsWkbTypes.MultiPoint, layer.crs()) feat.setGeometry(geomUpper) feat['type'] = 'upper' feat['start'] = startPoint.toString() - writer.addFeature(feat, QgsFeatureSink.FastInsert) + sinkPoints.addFeature(feat, QgsFeatureSink.FastInsert) feat.setGeometry(geomLower) feat['type'] = 'lower' feat['start'] = startPoint.toString() - writer.addFeature(feat, QgsFeatureSink.FastInsert) - - del writer + sinkPoints.addFeature(feat, QgsFeatureSink.FastInsert) upperBoundary.append(startPoint) lowerBoundary.append(startPoint) geomUpper = QgsGeometry.fromMultiPoint(upperBoundary) geomLower = QgsGeometry.fromMultiPoint(lowerBoundary) - writer = self.getOutputFromName( - self.OUTPUT_POLYGON).getVectorWriter(fields, QgsWkbTypes.Polygon, layer.crs(), context) - + (sinkPoygon, polygonId) = self.parameterAsSink(parameters, self.OUTPUT_POLYGON, context, + fields, QgsWkbTypes.Polygon, layer.crs()) geom = geomUpper.convexHull() feat.setGeometry(geom) feat['type'] = 'upper' feat['start'] = startPoint.toString() - writer.addFeature(feat, QgsFeatureSink.FastInsert) + sinkPoygon.addFeature(feat, QgsFeatureSink.FastInsert) geom = geomLower.convexHull() feat.setGeometry(geom) feat['type'] = 'lower' feat['start'] = startPoint.toString() - writer.addFeature(feat, QgsFeatureSink.FastInsert) - del writer + sinkPoygon.addFeature(feat, QgsFeatureSink.FastInsert) + + results = {} + results[self.OUTPUT_POINTS] = pointsId + results[self.OUTPUT_POLYGON] = polygonId + + return results From 5af177e963f3d45a458dfd6209488090e91224e3 Mon Sep 17 00:00:00 2001 From: Alexander Bruy Date: Sun, 16 Jul 2017 11:51:51 +0300 Subject: [PATCH 5/9] [processing] restore Service area from layer --- .../algs/qgis/QGISAlgorithmProvider.py | 3 +- .../algs/qgis/ServiceAreaFromLayer.py | 189 +++++++++--------- .../algs/qgis/ServiceAreaFromPoint.py | 1 - 3 files changed, 102 insertions(+), 91 deletions(-) diff --git a/python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py b/python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py index f6c6fda95cb..fde3c1757c7 100644 --- a/python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py +++ b/python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py @@ -87,7 +87,7 @@ from .Ruggedness import Ruggedness from .SaveSelectedFeatures import SaveSelectedFeatures from .SelectByAttribute import SelectByAttribute from .SelectByExpression import SelectByExpression -# from .ServiceAreaFromLayer import ServiceAreaFromLayer +from .ServiceAreaFromLayer import ServiceAreaFromLayer from .ServiceAreaFromPoint import ServiceAreaFromPoint from .ShortestPathLayerToPoint import ShortestPathLayerToPoint from .ShortestPathPointToLayer import ShortestPathPointToLayer @@ -274,6 +274,7 @@ class QGISAlgorithmProvider(QgsProcessingProvider): SaveSelectedFeatures(), SelectByAttribute(), SelectByExpression(), + ServiceAreaFromLayer(), ServiceAreaFromPoint(), ShortestPathLayerToPoint(), ShortestPathPointToLayer(), diff --git a/python/plugins/processing/algs/qgis/ServiceAreaFromLayer.py b/python/plugins/processing/algs/qgis/ServiceAreaFromLayer.py index c37f874f32b..51976f2b961 100644 --- a/python/plugins/processing/algs/qgis/ServiceAreaFromLayer.py +++ b/python/plugins/processing/algs/qgis/ServiceAreaFromLayer.py @@ -36,10 +36,17 @@ from qgis.core import (QgsWkbTypes, QgsFeature, QgsFeatureSink, QgsGeometry, - QgsField, QgsFields, - QgsFeatureRequest, - QgsProcessingUtils, + QgsField, + QgsProcessing, + QgsProcessingParameterEnum, + QgsProcessingParameterPoint, + QgsProcessingParameterField, + QgsProcessingParameterNumber, + QgsProcessingParameterString, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterVectorLayer, QgsProcessingParameterDefinition) from qgis.analysis import (QgsVectorLayerDirector, QgsNetworkDistanceStrategy, @@ -50,21 +57,13 @@ from qgis.analysis import (QgsVectorLayerDirector, from qgis.utils import iface from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm -from processing.core.parameters import (ParameterVector, - 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 ServiceAreaFromLayer(QgisAlgorithm): - INPUT_VECTOR = 'INPUT_VECTOR' + INPUT = 'INPUT' START_POINTS = 'START_POINTS' STRATEGY = 'STRATEGY' TRAVEL_COST = 'TRAVEL_COST' @@ -98,62 +97,64 @@ class ServiceAreaFromLayer(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(ParameterSelection(self.STRATEGY, - self.tr('Path type to calculate'), - self.STRATEGIES, - default=0)) - self.addParameter(ParameterNumber(self.TRAVEL_COST, - self.tr('Travel cost (distance for "Shortest", time for "Fastest")'), - 0.0, 99999999.999999, 0.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(QgsProcessingParameterEnum(self.STRATEGY, + self.tr('Path type to calculate'), + self.STRATEGIES, + defaultValue=0)) + self.addParameter(QgsProcessingParameterNumber(self.TRAVEL_COST, + self.tr('Travel cost (distance for "Shortest", time for "Fastest")'), + QgsProcessingParameterNumber.Double, + 0.0, False, 0, 99999999.99)) 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_POINTS, - self.tr('Service area (boundary nodes)'), - datatype=[dataobjects.TYPE_VECTOR_POINT])) - self.addOutput(OutputVector(self.OUTPUT_POLYGON, - self.tr('Service area (convex hull)'), - datatype=[dataobjects.TYPE_VECTOR_POLYGON])) + self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT_POINTS, + self.tr('Service area (boundary nodes)'), + QgsProcessing.TypeVectorPoint)) + self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT_POLYGON, + self.tr('Service area (convex hull)'), + QgsProcessing.TypeVectorPolygon)) def name(self): return 'serviceareafromlayer' @@ -162,21 +163,19 @@ class ServiceAreaFromLayer(QgisAlgorithm): return self.tr('Service area (from layer)') def processAlgorithm(self, parameters, context, feedback): - layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_VECTOR), context) - startPoints = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.START_POINTS), context) - strategy = self.getParameterValue(self.STRATEGY) - travelCost = self.getParameterValue(self.TRAVEL_COST) + layer = self.parameterAsVectorLayer(parameters, self.INPUT, context) + startPoints = self.parameterAsSource(parameters, self.START_POINTS, context) + strategy = self.parameterAsEnum(parameters, self.STRATEGY, context) + travelCost = self.parameterAsDouble(parameters, self.TRAVEL_COST, 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('type', QVariant.String, '', 254, 0)) @@ -185,17 +184,17 @@ class ServiceAreaFromLayer(QgisAlgorithm): feat = QgsFeature() feat.setFields(fields) - writerPoints = self.getOutputFromName( - self.OUTPUT_POINTS).getVectorWriter(fields, QgsWkbTypes.MultiPoint, layer.crs(), context) + (sinkPoints, pointsId) = self.parameterAsSink(parameters, self.OUTPUT_POINTS, context, + fields, QgsWkbTypes.MultiPoint, layer.crs()) - writerPolygons = self.getOutputFromName( - self.OUTPUT_POLYGON).getVectorWriter(fields, QgsWkbTypes.Polygon, layer.crs(), context) + (sinkPoygon, polygonId) = self.parameterAsSink(parameters, self.OUTPUT_POLYGON, context, + fields, QgsWkbTypes.Polygon, 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,10 +221,16 @@ class ServiceAreaFromLayer(QgisAlgorithm): feedback.pushInfo(self.tr('Loading start points...')) request = QgsFeatureRequest() request.setFlags(request.flags() ^ QgsFeatureRequest.SubsetOfAttributes) - features = QgsProcessingUtils.getFeatures(startPoints, context, request) + features = source.getFeatures(request) + total = 100.0 / source.featureCount() if source.featureCount() else 0 + points = [] - 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,6 +243,9 @@ class ServiceAreaFromLayer(QgisAlgorithm): lowerBoundary = [] total = 100.0 / len(snappedPoints) if snappedPoints else 1 for i, p in enumerate(snappedPoints): + if feedback.isCanceled(): + break + idxStart = graph.findVertex(snappedPoints[i]) origPoint = points[i].toString() @@ -258,12 +266,12 @@ class ServiceAreaFromLayer(QgisAlgorithm): feat.setGeometry(geomUpper) feat['type'] = 'upper' feat['start'] = origPoint - writerPoints.addFeature(feat, QgsFeatureSink.FastInsert) + sinkPoints.addFeature(feat, QgsFeatureSink.FastInsert) feat.setGeometry(geomLower) feat['type'] = 'lower' feat['start'] = origPoint - writerPoints.addFeature(feat, QgsFeatureSink.FastInsert) + sinkPoints.addFeature(feat, QgsFeatureSink.FastInsert) upperBoundary.append(origPoint) lowerBoundary.append(origPoint) @@ -274,13 +282,13 @@ class ServiceAreaFromLayer(QgisAlgorithm): feat.setGeometry(geom) feat['type'] = 'upper' feat['start'] = origPoint - writerPolygons.addFeature(feat, QgsFeatureSink.FastInsert) + sinkPolygons.addFeature(feat, QgsFeatureSink.FastInsert) geom = geomLower.convexHull() feat.setGeometry(geom) feat['type'] = 'lower' feat['start'] = origPoint - writerPolygons.addFeature(feat, QgsFeatureSink.FastInsert) + sinkPolygons.addFeature(feat, QgsFeatureSink.FastInsert) vertices[:] = [] upperBoundary[:] = [] @@ -288,5 +296,8 @@ class ServiceAreaFromLayer(QgisAlgorithm): feedback.setProgress(int(i * total)) - del writerPoints - del writerPolygons + results = {} + results[self.OUTPUT_POINTS] = pointsId + results[self.OUTPUT_POLYGON] = polygonId + + return results diff --git a/python/plugins/processing/algs/qgis/ServiceAreaFromPoint.py b/python/plugins/processing/algs/qgis/ServiceAreaFromPoint.py index 166b1725a12..fd077aac5ca 100644 --- a/python/plugins/processing/algs/qgis/ServiceAreaFromPoint.py +++ b/python/plugins/processing/algs/qgis/ServiceAreaFromPoint.py @@ -44,7 +44,6 @@ from qgis.core import (QgsWkbTypes, QgsProcessingParameterField, QgsProcessingParameterNumber, QgsProcessingParameterString, - QgsProcessingParameterFeatureSource, QgsProcessingParameterFeatureSink, QgsProcessingParameterVectorLayer, QgsProcessingParameterDefinition) From 95de3a414a96975ea778c1646acdd435229b2683 Mon Sep 17 00:00:00 2001 From: Alexander Bruy Date: Sun, 16 Jul 2017 11:52:52 +0300 Subject: [PATCH 6/9] [processing] add cancellation support where possible --- .../plugins/processing/algs/qgis/ShortestPathLayerToPoint.py | 3 +++ .../plugins/processing/algs/qgis/ShortestPathPointToLayer.py | 3 +++ 2 files changed, 6 insertions(+) diff --git a/python/plugins/processing/algs/qgis/ShortestPathLayerToPoint.py b/python/plugins/processing/algs/qgis/ShortestPathLayerToPoint.py index 5f97db978d1..43306285e20 100644 --- a/python/plugins/processing/algs/qgis/ShortestPathLayerToPoint.py +++ b/python/plugins/processing/algs/qgis/ShortestPathLayerToPoint.py @@ -237,6 +237,9 @@ class ShortestPathLayerToPoint(QgisAlgorithm): total = 100.0 / source.featureCount() if source.featureCount() else 1 for i in range(1, count + 1): + if feedback.isCanceled(): + break + idxStart = graph.findVertex(snappedPoints[i]) tree, cost = QgsGraphAnalyzer.dijkstra(graph, idxStart, 0) diff --git a/python/plugins/processing/algs/qgis/ShortestPathPointToLayer.py b/python/plugins/processing/algs/qgis/ShortestPathPointToLayer.py index c46bb84e259..dabd6ae9a72 100644 --- a/python/plugins/processing/algs/qgis/ShortestPathPointToLayer.py +++ b/python/plugins/processing/algs/qgis/ShortestPathPointToLayer.py @@ -238,6 +238,9 @@ class ShortestPathPointToLayer(QgisAlgorithm): total = 100.0 / source.featureCount() if source.featureCount() else 1 for i in range(1, count + 1): + if feedback.isCanceled(): + break + idxEnd = graph.findVertex(snappedPoints[i]) if tree[idxEnd] == -1: From bee568364361f93e4e35d3b1f54517845f2a77d3 Mon Sep 17 00:00:00 2001 From: Alexander Bruy Date: Sun, 16 Jul 2017 13:29:09 +0300 Subject: [PATCH 7/9] [processing] allow diferent CRS for point layers and network layer --- python/plugins/processing/algs/qgis/ServiceAreaFromLayer.py | 1 + python/plugins/processing/algs/qgis/ShortestPathLayerToPoint.py | 1 + python/plugins/processing/algs/qgis/ShortestPathPointToLayer.py | 1 + 3 files changed, 3 insertions(+) diff --git a/python/plugins/processing/algs/qgis/ServiceAreaFromLayer.py b/python/plugins/processing/algs/qgis/ServiceAreaFromLayer.py index 51976f2b961..1c484d20680 100644 --- a/python/plugins/processing/algs/qgis/ServiceAreaFromLayer.py +++ b/python/plugins/processing/algs/qgis/ServiceAreaFromLayer.py @@ -221,6 +221,7 @@ class ServiceAreaFromLayer(QgisAlgorithm): feedback.pushInfo(self.tr('Loading start points...')) request = QgsFeatureRequest() request.setFlags(request.flags() ^ QgsFeatureRequest.SubsetOfAttributes) + request.setDestinationCrs(layer.crs()) features = source.getFeatures(request) total = 100.0 / source.featureCount() if source.featureCount() else 0 diff --git a/python/plugins/processing/algs/qgis/ShortestPathLayerToPoint.py b/python/plugins/processing/algs/qgis/ShortestPathLayerToPoint.py index 43306285e20..0fd2bddb0aa 100644 --- a/python/plugins/processing/algs/qgis/ShortestPathLayerToPoint.py +++ b/python/plugins/processing/algs/qgis/ShortestPathLayerToPoint.py @@ -215,6 +215,7 @@ class ShortestPathLayerToPoint(QgisAlgorithm): feedback.pushInfo(self.tr('Loading start points...')) request = QgsFeatureRequest() request.setFlags(request.flags() ^ QgsFeatureRequest.SubsetOfAttributes) + request.setDestinationCrs(layer.crs()) features = source.getFeatures(request) total = 100.0 / source.featureCount() if source.featureCount() else 0 diff --git a/python/plugins/processing/algs/qgis/ShortestPathPointToLayer.py b/python/plugins/processing/algs/qgis/ShortestPathPointToLayer.py index dabd6ae9a72..a084f859be0 100644 --- a/python/plugins/processing/algs/qgis/ShortestPathPointToLayer.py +++ b/python/plugins/processing/algs/qgis/ShortestPathPointToLayer.py @@ -215,6 +215,7 @@ class ShortestPathPointToLayer(QgisAlgorithm): feedback.pushInfo(self.tr('Loading end points...')) request = QgsFeatureRequest() request.setFlags(request.flags() ^ QgsFeatureRequest.SubsetOfAttributes) + request.setDestinationCrs(layer.crs()) features = source.getFeatures(request) total = 100.0 / source.featureCount() if source.featureCount() else 0 From 4a6ceffc543750be890066e705298eb72c2b265f Mon Sep 17 00:00:00 2001 From: Alexander Bruy Date: Sun, 16 Jul 2017 13:39:49 +0300 Subject: [PATCH 8/9] [processing] make service area outputs optional --- .../algs/qgis/ServiceAreaFromLayer.py | 78 ++++++++++--------- .../algs/qgis/ServiceAreaFromPoint.py | 71 +++++++++-------- 2 files changed, 80 insertions(+), 69 deletions(-) diff --git a/python/plugins/processing/algs/qgis/ServiceAreaFromLayer.py b/python/plugins/processing/algs/qgis/ServiceAreaFromLayer.py index 1c484d20680..330d96172bf 100644 --- a/python/plugins/processing/algs/qgis/ServiceAreaFromLayer.py +++ b/python/plugins/processing/algs/qgis/ServiceAreaFromLayer.py @@ -151,10 +151,12 @@ class ServiceAreaFromLayer(QgisAlgorithm): self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT_POINTS, self.tr('Service area (boundary nodes)'), - QgsProcessing.TypeVectorPoint)) + QgsProcessing.TypeVectorPoint, + optional=True)) self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT_POLYGON, self.tr('Service area (convex hull)'), - QgsProcessing.TypeVectorPolygon)) + QgsProcessing.TypeVectorPolygon, + optional=True)) def name(self): return 'serviceareafromlayer' @@ -184,12 +186,6 @@ class ServiceAreaFromLayer(QgisAlgorithm): feat = QgsFeature() feat.setFields(fields) - (sinkPoints, pointsId) = self.parameterAsSink(parameters, self.OUTPUT_POINTS, context, - fields, QgsWkbTypes.MultiPoint, layer.crs()) - - (sinkPoygon, polygonId) = self.parameterAsSink(parameters, self.OUTPUT_POLYGON, context, - fields, QgsWkbTypes.Polygon, layer.crs()) - directionField = -1 if directionFieldName: directionField = layer.fields().lookupField(directionFieldName) @@ -239,6 +235,18 @@ class ServiceAreaFromLayer(QgisAlgorithm): feedback.pushInfo(self.tr('Calculating service areas...')) graph = builder.graph() + results = {} + (sinkPoints, pointsId) = self.parameterAsSink(parameters, self.OUTPUT_POINTS, context, + fields, QgsWkbTypes.MultiPoint, layer.crs()) + + (sinkPolygon, polygonId) = self.parameterAsSink(parameters, self.OUTPUT_POLYGON, context, + fields, QgsWkbTypes.Polygon, layer.crs()) + + if sinkPoints: + results[self.OUTPUT_POINTS] = pointsId + if sinkPolygon: + results[self.OUTPUT_POLYGON] = polygonId + vertices = [] upperBoundary = [] lowerBoundary = [] @@ -261,35 +269,37 @@ class ServiceAreaFromLayer(QgisAlgorithm): upperBoundary.append(graph.vertex(graph.edge(tree[j]).inVertex()).point()) lowerBoundary.append(graph.vertex(graph.edge(tree[j]).outVertex()).point()) - geomUpper = QgsGeometry.fromMultiPoint(upperBoundary) - geomLower = QgsGeometry.fromMultiPoint(lowerBoundary) + if sinkPoints: + geomUpper = QgsGeometry.fromMultiPoint(upperBoundary) + geomLower = QgsGeometry.fromMultiPoint(lowerBoundary) - feat.setGeometry(geomUpper) - feat['type'] = 'upper' - feat['start'] = origPoint - sinkPoints.addFeature(feat, QgsFeatureSink.FastInsert) + feat.setGeometry(geomUpper) + feat['type'] = 'upper' + feat['start'] = origPoint + sinkPoints.addFeature(feat, QgsFeatureSink.FastInsert) - feat.setGeometry(geomLower) - feat['type'] = 'lower' - feat['start'] = origPoint - sinkPoints.addFeature(feat, QgsFeatureSink.FastInsert) + feat.setGeometry(geomLower) + feat['type'] = 'lower' + feat['start'] = origPoint + sinkPoints.addFeature(feat, QgsFeatureSink.FastInsert) - upperBoundary.append(origPoint) - lowerBoundary.append(origPoint) - geomUpper = QgsGeometry.fromMultiPoint(upperBoundary) - geomLower = QgsGeometry.fromMultiPoint(lowerBoundary) + if sinkPolygon: + upperBoundary.append(origPoint) + lowerBoundary.append(origPoint) + geomUpper = QgsGeometry.fromMultiPoint(upperBoundary) + geomLower = QgsGeometry.fromMultiPoint(lowerBoundary) - geom = geomUpper.convexHull() - feat.setGeometry(geom) - feat['type'] = 'upper' - feat['start'] = origPoint - sinkPolygons.addFeature(feat, QgsFeatureSink.FastInsert) + geom = geomUpper.convexHull() + feat.setGeometry(geom) + feat['type'] = 'upper' + feat['start'] = origPoint + sinkPolygon.addFeature(feat, QgsFeatureSink.FastInsert) - geom = geomLower.convexHull() - feat.setGeometry(geom) - feat['type'] = 'lower' - feat['start'] = origPoint - sinkPolygons.addFeature(feat, QgsFeatureSink.FastInsert) + geom = geomLower.convexHull() + feat.setGeometry(geom) + feat['type'] = 'lower' + feat['start'] = origPoint + sinkPolygon.addFeature(feat, QgsFeatureSink.FastInsert) vertices[:] = [] upperBoundary[:] = [] @@ -297,8 +307,4 @@ class ServiceAreaFromLayer(QgisAlgorithm): feedback.setProgress(int(i * total)) - results = {} - results[self.OUTPUT_POINTS] = pointsId - results[self.OUTPUT_POLYGON] = polygonId - return results diff --git a/python/plugins/processing/algs/qgis/ServiceAreaFromPoint.py b/python/plugins/processing/algs/qgis/ServiceAreaFromPoint.py index fd077aac5ca..822affd8edc 100644 --- a/python/plugins/processing/algs/qgis/ServiceAreaFromPoint.py +++ b/python/plugins/processing/algs/qgis/ServiceAreaFromPoint.py @@ -149,10 +149,12 @@ class ServiceAreaFromPoint(QgisAlgorithm): self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT_POINTS, self.tr('Service area (boundary nodes)'), - QgsProcessing.TypeVectorPoint)) + QgsProcessing.TypeVectorPoint, + optional=True)) self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT_POLYGON, self.tr('Service area (convex hull)'), - QgsProcessing.TypeVectorPolygon)) + QgsProcessing.TypeVectorPolygon, + optional=True)) def name(self): return 'serviceareafrompoint' @@ -238,37 +240,40 @@ class ServiceAreaFromPoint(QgisAlgorithm): (sinkPoints, pointsId) = self.parameterAsSink(parameters, self.OUTPUT_POINTS, context, fields, QgsWkbTypes.MultiPoint, layer.crs()) - feat.setGeometry(geomUpper) - feat['type'] = 'upper' - feat['start'] = startPoint.toString() - sinkPoints.addFeature(feat, QgsFeatureSink.FastInsert) - - feat.setGeometry(geomLower) - feat['type'] = 'lower' - feat['start'] = startPoint.toString() - sinkPoints.addFeature(feat, QgsFeatureSink.FastInsert) - - upperBoundary.append(startPoint) - lowerBoundary.append(startPoint) - geomUpper = QgsGeometry.fromMultiPoint(upperBoundary) - geomLower = QgsGeometry.fromMultiPoint(lowerBoundary) - - (sinkPoygon, polygonId) = self.parameterAsSink(parameters, self.OUTPUT_POLYGON, context, - fields, QgsWkbTypes.Polygon, layer.crs()) - geom = geomUpper.convexHull() - feat.setGeometry(geom) - feat['type'] = 'upper' - feat['start'] = startPoint.toString() - sinkPoygon.addFeature(feat, QgsFeatureSink.FastInsert) - - geom = geomLower.convexHull() - feat.setGeometry(geom) - feat['type'] = 'lower' - feat['start'] = startPoint.toString() - sinkPoygon.addFeature(feat, QgsFeatureSink.FastInsert) - + (sinkPolygon, polygonId) = self.parameterAsSink(parameters, self.OUTPUT_POLYGON, context, + fields, QgsWkbTypes.Polygon, layer.crs()) results = {} - results[self.OUTPUT_POINTS] = pointsId - results[self.OUTPUT_POLYGON] = polygonId + if sinkPoints: + feat.setGeometry(geomUpper) + feat['type'] = 'upper' + feat['start'] = startPoint.toString() + sinkPoints.addFeature(feat, QgsFeatureSink.FastInsert) + + feat.setGeometry(geomLower) + feat['type'] = 'lower' + feat['start'] = startPoint.toString() + sinkPoints.addFeature(feat, QgsFeatureSink.FastInsert) + + upperBoundary.append(startPoint) + lowerBoundary.append(startPoint) + geomUpper = QgsGeometry.fromMultiPoint(upperBoundary) + geomLower = QgsGeometry.fromMultiPoint(lowerBoundary) + + results[self.OUTPUT_POINTS] = pointsId + + if sinkPolygon: + geom = geomUpper.convexHull() + feat.setGeometry(geom) + feat['type'] = 'upper' + feat['start'] = startPoint.toString() + sinkPolygon.addFeature(feat, QgsFeatureSink.FastInsert) + + geom = geomLower.convexHull() + feat.setGeometry(geom) + feat['type'] = 'lower' + feat['start'] = startPoint.toString() + sinkPolygon.addFeature(feat, QgsFeatureSink.FastInsert) + + results[self.OUTPUT_POLYGON] = polygonId return results From f3f74a9ddf1801cfbb80a00106ac35ad0ceca1d4 Mon Sep 17 00:00:00 2001 From: Alexander Bruy Date: Mon, 17 Jul 2017 11:32:12 +0300 Subject: [PATCH 9/9] [processing] adapt network analysis algorithms to latest API changes --- .../algs/qgis/ServiceAreaFromLayer.py | 27 +++++++++--------- .../algs/qgis/ServiceAreaFromPoint.py | 22 +++++++-------- .../algs/qgis/ShortestPathLayerToPoint.py | 28 +++++++++---------- .../algs/qgis/ShortestPathPointToLayer.py | 28 +++++++++---------- .../algs/qgis/ShortestPathPointToPoint.py | 20 ++++++------- 5 files changed, 62 insertions(+), 63 deletions(-) diff --git a/python/plugins/processing/algs/qgis/ServiceAreaFromLayer.py b/python/plugins/processing/algs/qgis/ServiceAreaFromLayer.py index 330d96172bf..fff40f24acb 100644 --- a/python/plugins/processing/algs/qgis/ServiceAreaFromLayer.py +++ b/python/plugins/processing/algs/qgis/ServiceAreaFromLayer.py @@ -46,7 +46,6 @@ from qgis.core import (QgsWkbTypes, QgsProcessingParameterString, QgsProcessingParameterFeatureSource, QgsProcessingParameterFeatureSink, - QgsProcessingParameterVectorLayer, QgsProcessingParameterDefinition) from qgis.analysis import (QgsVectorLayerDirector, QgsNetworkDistanceStrategy, @@ -97,9 +96,9 @@ class ServiceAreaFromLayer(QgisAlgorithm): self.tr('Fastest') ] - self.addParameter(QgsProcessingParameterVectorLayer(self.INPUT, - self.tr('Vector layer representing network'), - [QgsProcessing.TypeVectorLine])) + self.addParameter(QgsProcessingParameterFeatureSource(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])) @@ -165,7 +164,7 @@ class ServiceAreaFromLayer(QgisAlgorithm): return self.tr('Service area (from layer)') def processAlgorithm(self, parameters, context, feedback): - layer = self.parameterAsVectorLayer(parameters, self.INPUT, context) + network = self.parameterAsSource(parameters, self.INPUT, context) startPoints = self.parameterAsSource(parameters, self.START_POINTS, context) strategy = self.parameterAsEnum(parameters, self.STRATEGY, context) travelCost = self.parameterAsDouble(parameters, self.TRAVEL_COST, context) @@ -188,12 +187,12 @@ class ServiceAreaFromLayer(QgisAlgorithm): directionField = -1 if directionFieldName: - directionField = layer.fields().lookupField(directionFieldName) + directionField = network.fields().lookupField(directionFieldName) speedField = -1 if speedFieldName: - speedField = layer.fields().lookupField(speedFieldName) + speedField = network.fields().lookupField(speedFieldName) - director = QgsVectorLayerDirector(layer, + director = QgsVectorLayerDirector(network, directionField, forwardValue, backwardValue, @@ -217,9 +216,9 @@ class ServiceAreaFromLayer(QgisAlgorithm): feedback.pushInfo(self.tr('Loading start points...')) request = QgsFeatureRequest() request.setFlags(request.flags() ^ QgsFeatureRequest.SubsetOfAttributes) - request.setDestinationCrs(layer.crs()) - features = source.getFeatures(request) - total = 100.0 / source.featureCount() if source.featureCount() else 0 + request.setDestinationCrs(network.sourceCrs()) + features = startPoints.getFeatures(request) + total = 100.0 / startPoints.featureCount() if startPoints.featureCount() else 0 points = [] for current, f in enumerate(features): @@ -230,17 +229,17 @@ class ServiceAreaFromLayer(QgisAlgorithm): feedback.setProgress(int(current * total)) feedback.pushInfo(self.tr('Building graph...')) - snappedPoints = director.makeGraph(builder, points) + snappedPoints = director.makeGraph(builder, points, feedback) feedback.pushInfo(self.tr('Calculating service areas...')) graph = builder.graph() results = {} (sinkPoints, pointsId) = self.parameterAsSink(parameters, self.OUTPUT_POINTS, context, - fields, QgsWkbTypes.MultiPoint, layer.crs()) + fields, QgsWkbTypes.MultiPoint, network.sourceCrs()) (sinkPolygon, polygonId) = self.parameterAsSink(parameters, self.OUTPUT_POLYGON, context, - fields, QgsWkbTypes.Polygon, layer.crs()) + fields, QgsWkbTypes.Polygon, network.sourceCrs()) if sinkPoints: results[self.OUTPUT_POINTS] = pointsId diff --git a/python/plugins/processing/algs/qgis/ServiceAreaFromPoint.py b/python/plugins/processing/algs/qgis/ServiceAreaFromPoint.py index 822affd8edc..edb559067e2 100644 --- a/python/plugins/processing/algs/qgis/ServiceAreaFromPoint.py +++ b/python/plugins/processing/algs/qgis/ServiceAreaFromPoint.py @@ -45,7 +45,7 @@ from qgis.core import (QgsWkbTypes, QgsProcessingParameterNumber, QgsProcessingParameterString, QgsProcessingParameterFeatureSink, - QgsProcessingParameterVectorLayer, + QgsProcessingParameterFeatureSource, QgsProcessingParameterDefinition) from qgis.analysis import (QgsVectorLayerDirector, QgsNetworkDistanceStrategy, @@ -96,9 +96,9 @@ class ServiceAreaFromPoint(QgisAlgorithm): self.tr('Fastest') ] - self.addParameter(QgsProcessingParameterVectorLayer(self.INPUT, - self.tr('Vector layer representing network'), - [QgsProcessing.TypeVectorLine])) + self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT, + self.tr('Vector layer representing network'), + [QgsProcessing.TypeVectorLine])) self.addParameter(QgsProcessingParameterPoint(self.START_POINT, self.tr('Start point'))) self.addParameter(QgsProcessingParameterEnum(self.STRATEGY, @@ -163,7 +163,7 @@ class ServiceAreaFromPoint(QgisAlgorithm): return self.tr('Service area (from point)') def processAlgorithm(self, parameters, context, feedback): - layer = self.parameterAsVectorLayer(parameters, self.INPUT, context) + network = self.parameterAsSource(parameters, self.INPUT, context) startPoint = self.parameterAsPoint(parameters, self.START_POINT, context) strategy = self.parameterAsEnum(parameters, self.STRATEGY, context) travelCost = self.parameterAsDouble(parameters, self.TRAVEL_COST, context) @@ -179,12 +179,12 @@ class ServiceAreaFromPoint(QgisAlgorithm): directionField = -1 if directionFieldName: - directionField = layer.fields().lookupField(directionFieldName) + directionField = network.fields().lookupField(directionFieldName) speedField = -1 if speedFieldName: - speedField = layer.fields().lookupField(speedFieldName) + speedField = network.fields().lookupField(speedFieldName) - director = QgsVectorLayerDirector(layer, + director = QgsVectorLayerDirector(network, directionField, forwardValue, backwardValue, @@ -205,7 +205,7 @@ class ServiceAreaFromPoint(QgisAlgorithm): True, tolerance) feedback.pushInfo(self.tr('Building graph...')) - snappedPoints = director.makeGraph(builder, [startPoint]) + snappedPoints = director.makeGraph(builder, [startPoint], feedback) feedback.pushInfo(self.tr('Calculating service area...')) graph = builder.graph() @@ -238,10 +238,10 @@ class ServiceAreaFromPoint(QgisAlgorithm): geomLower = QgsGeometry.fromMultiPoint(lowerBoundary) (sinkPoints, pointsId) = self.parameterAsSink(parameters, self.OUTPUT_POINTS, context, - fields, QgsWkbTypes.MultiPoint, layer.crs()) + fields, QgsWkbTypes.MultiPoint, network.sourceCrs()) (sinkPolygon, polygonId) = self.parameterAsSink(parameters, self.OUTPUT_POLYGON, context, - fields, QgsWkbTypes.Polygon, layer.crs()) + fields, QgsWkbTypes.Polygon, network.sourceCrs()) results = {} if sinkPoints: feat.setGeometry(geomUpper) diff --git a/python/plugins/processing/algs/qgis/ShortestPathLayerToPoint.py b/python/plugins/processing/algs/qgis/ShortestPathLayerToPoint.py index 0fd2bddb0aa..88881dedac4 100644 --- a/python/plugins/processing/algs/qgis/ShortestPathLayerToPoint.py +++ b/python/plugins/processing/algs/qgis/ShortestPathLayerToPoint.py @@ -47,7 +47,6 @@ from qgis.core import (QgsWkbTypes, QgsProcessingParameterString, QgsProcessingParameterFeatureSource, QgsProcessingParameterFeatureSink, - QgsProcessingParameterVectorLayer, QgsProcessingParameterDefinition) from qgis.analysis import (QgsVectorLayerDirector, QgsNetworkDistanceStrategy, @@ -97,9 +96,9 @@ class ShortestPathLayerToPoint(QgisAlgorithm): self.tr('Fastest') ] - self.addParameter(QgsProcessingParameterVectorLayer(self.INPUT, - self.tr('Vector layer representing network'), - [QgsProcessing.TypeVectorLine])) + self.addParameter(QgsProcessingParameterFeatureSource(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])) @@ -158,7 +157,7 @@ class ShortestPathLayerToPoint(QgisAlgorithm): return self.tr('Shortest path (layer to point)') def processAlgorithm(self, parameters, context, feedback): - layer = self.parameterAsVectorLayer(parameters, self.INPUT, context) + network = self.parameterAsSource(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) @@ -181,16 +180,16 @@ class ShortestPathLayerToPoint(QgisAlgorithm): feat.setFields(fields) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, - fields, QgsWkbTypes.LineString, layer.crs()) + fields, QgsWkbTypes.LineString, network.sourceCrs()) directionField = -1 if directionFieldName: - directionField = layer.fields().lookupField(directionFieldName) + directionField = network.fields().lookupField(directionFieldName) speedField = -1 if speedFieldName: - speedField = layer.fields().lookupField(speedFieldName) + speedField = network.fields().lookupField(speedFieldName) - director = QgsVectorLayerDirector(layer, + director = QgsVectorLayerDirector(network, directionField, forwardValue, backwardValue, @@ -215,9 +214,9 @@ class ShortestPathLayerToPoint(QgisAlgorithm): feedback.pushInfo(self.tr('Loading start points...')) request = QgsFeatureRequest() request.setFlags(request.flags() ^ QgsFeatureRequest.SubsetOfAttributes) - request.setDestinationCrs(layer.crs()) - features = source.getFeatures(request) - total = 100.0 / source.featureCount() if source.featureCount() else 0 + request.setDestinationCrs(network.sourceCrs()) + features = startPoints.getFeatures(request) + total = 100.0 / startPoints.featureCount() if startPoints.featureCount() else 0 points = [endPoint] for current, f in enumerate(features): @@ -228,7 +227,7 @@ class ShortestPathLayerToPoint(QgisAlgorithm): feedback.setProgress(int(current * total)) feedback.pushInfo(self.tr('Building graph...')) - snappedPoints = director.makeGraph(builder, points) + snappedPoints = director.makeGraph(builder, points, feedback) feedback.pushInfo(self.tr('Calculating shortest paths...')) graph = builder.graph() @@ -236,7 +235,8 @@ class ShortestPathLayerToPoint(QgisAlgorithm): idxEnd = graph.findVertex(snappedPoints[0]) route = [] - total = 100.0 / source.featureCount() if source.featureCount() else 1 + nPoints = len(snappedPoints) + total = 100.0 / nPoints if nPoints else 1 for i in range(1, count + 1): if feedback.isCanceled(): break diff --git a/python/plugins/processing/algs/qgis/ShortestPathPointToLayer.py b/python/plugins/processing/algs/qgis/ShortestPathPointToLayer.py index a084f859be0..9964ea40d03 100644 --- a/python/plugins/processing/algs/qgis/ShortestPathPointToLayer.py +++ b/python/plugins/processing/algs/qgis/ShortestPathPointToLayer.py @@ -47,7 +47,6 @@ from qgis.core import (QgsWkbTypes, QgsProcessingParameterString, QgsProcessingParameterFeatureSource, QgsProcessingParameterFeatureSink, - QgsProcessingParameterVectorLayer, QgsProcessingParameterDefinition) from qgis.analysis import (QgsVectorLayerDirector, QgsNetworkDistanceStrategy, @@ -97,9 +96,9 @@ class ShortestPathPointToLayer(QgisAlgorithm): self.tr('Fastest') ] - self.addParameter(QgsProcessingParameterVectorLayer(self.INPUT, - self.tr('Vector layer representing network'), - [QgsProcessing.TypeVectorLine])) + self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT, + self.tr('Vector layer representing network'), + [QgsProcessing.TypeVectorLine])) self.addParameter(QgsProcessingParameterPoint(self.START_POINT, self.tr('Start point'))) self.addParameter(QgsProcessingParameterFeatureSource(self.END_POINTS, @@ -158,7 +157,7 @@ class ShortestPathPointToLayer(QgisAlgorithm): return self.tr('Shortest path (point to layer)') def processAlgorithm(self, parameters, context, feedback): - layer = self.parameterAsVectorLayer(parameters, self.INPUT, context) + network = self.parameterAsSource(parameters, self.INPUT, context) startPoint = self.parameterAsPoint(parameters, self.START_POINT, context) endPoints = self.parameterAsSource(parameters, self.END_POINTS, context) strategy = self.parameterAsEnum(parameters, self.STRATEGY, context) @@ -181,16 +180,16 @@ class ShortestPathPointToLayer(QgisAlgorithm): feat.setFields(fields) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, - fields, QgsWkbTypes.LineString, layer.crs()) + fields, QgsWkbTypes.LineString, network.sourceCrs()) directionField = -1 if directionFieldName: - directionField = layer.fields().lookupField(directionFieldName) + directionField = network.fields().lookupField(directionFieldName) speedField = -1 if speedFieldName: - speedField = layer.fields().lookupField(speedFieldName) + speedField = network.fields().lookupField(speedFieldName) - director = QgsVectorLayerDirector(layer, + director = QgsVectorLayerDirector(network, directionField, forwardValue, backwardValue, @@ -215,9 +214,9 @@ class ShortestPathPointToLayer(QgisAlgorithm): feedback.pushInfo(self.tr('Loading end points...')) request = QgsFeatureRequest() request.setFlags(request.flags() ^ QgsFeatureRequest.SubsetOfAttributes) - request.setDestinationCrs(layer.crs()) - features = source.getFeatures(request) - total = 100.0 / source.featureCount() if source.featureCount() else 0 + request.setDestinationCrs(network.sourceCrs()) + features = endPoints.getFeatures(request) + total = 100.0 / endPoints.featureCount() if endPoints.featureCount() else 0 points = [startPoint] for current, f in enumerate(features): @@ -228,7 +227,7 @@ class ShortestPathPointToLayer(QgisAlgorithm): feedback.setProgress(int(current * total)) feedback.pushInfo(self.tr('Building graph...')) - snappedPoints = director.makeGraph(builder, points) + snappedPoints = director.makeGraph(builder, points, feedback) feedback.pushInfo(self.tr('Calculating shortest paths...')) graph = builder.graph() @@ -237,7 +236,8 @@ class ShortestPathPointToLayer(QgisAlgorithm): tree, cost = QgsGraphAnalyzer.dijkstra(graph, idxStart, 0) route = [] - total = 100.0 / source.featureCount() if source.featureCount() else 1 + nPoints = len(snappedPoints) + total = 100.0 / nPoints if nPoints else 1 for i in range(1, count + 1): if feedback.isCanceled(): break diff --git a/python/plugins/processing/algs/qgis/ShortestPathPointToPoint.py b/python/plugins/processing/algs/qgis/ShortestPathPointToPoint.py index 179d4a7af94..6a7862b8455 100644 --- a/python/plugins/processing/algs/qgis/ShortestPathPointToPoint.py +++ b/python/plugins/processing/algs/qgis/ShortestPathPointToPoint.py @@ -46,8 +46,8 @@ from qgis.core import (QgsWkbTypes, QgsProcessingParameterField, QgsProcessingParameterNumber, QgsProcessingParameterString, + QgsProcessingParameterFeatureSource, QgsProcessingParameterFeatureSink, - QgsProcessingParameterVectorLayer, QgsProcessingParameterDefinition) from qgis.analysis import (QgsVectorLayerDirector, QgsNetworkDistanceStrategy, @@ -98,9 +98,9 @@ class ShortestPathPointToPoint(QgisAlgorithm): self.tr('Fastest') ] - self.addParameter(QgsProcessingParameterVectorLayer(self.INPUT, - self.tr('Vector layer representing network'), - [QgsProcessing.TypeVectorLine])) + self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT, + self.tr('Vector layer representing network'), + [QgsProcessing.TypeVectorLine])) self.addParameter(QgsProcessingParameterPoint(self.START_POINT, self.tr('Start point'))) self.addParameter(QgsProcessingParameterPoint(self.END_POINT, @@ -160,7 +160,7 @@ class ShortestPathPointToPoint(QgisAlgorithm): return self.tr('Shortest path (point to point)') def processAlgorithm(self, parameters, context, feedback): - layer = self.parameterAsVectorLayer(parameters, self.INPUT, context) + network = self.parameterAsSource(parameters, self.INPUT, context) startPoint = self.parameterAsPoint(parameters, self.START_POINT, context) endPoint = self.parameterAsPoint(parameters, self.END_POINT, context) strategy = self.parameterAsEnum(parameters, self.STRATEGY, context) @@ -180,16 +180,16 @@ class ShortestPathPointToPoint(QgisAlgorithm): fields.append(QgsField('cost', QVariant.Double, '', 20, 7)) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, - fields, QgsWkbTypes.LineString, layer.crs()) + fields, QgsWkbTypes.LineString, network.sourceCrs()) directionField = -1 if directionField: - directionField = layer.fields().lookupField(directionFieldName) + directionField = network.fields().lookupField(directionFieldName) speedField = -1 if speedFieldName: - speedField = layer.fields().lookupField(speedFieldName) + speedField = network.fields().lookupField(speedFieldName) - director = QgsVectorLayerDirector(layer, + director = QgsVectorLayerDirector(network, directionField, forwardValue, backwardValue, @@ -211,7 +211,7 @@ class ShortestPathPointToPoint(QgisAlgorithm): True, tolerance) feedback.pushInfo(self.tr('Building graph...')) - snappedPoints = director.makeGraph(builder, [startPoint, endPoint]) + snappedPoints = director.makeGraph(builder, [startPoint, endPoint], feedback) feedback.pushInfo(self.tr('Calculating shortest path...')) graph = builder.graph()