Skip to content
Permalink
Browse files

[processing] restore Shortest path from point to layer

  • Loading branch information
alexbruy committed Jul 17, 2017
1 parent c5ed539 commit 494ceff3b48ae2e9bcbc5d8010fe6c99db2955cb
@@ -90,7 +90,7 @@
# 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 @@ def getAlgs(self):
SaveSelectedFeatures(),
SelectByAttribute(),
SelectByExpression(),
ShortestPathPointToLayer(),
ShortestPathPointToPoint(),
SimplifyGeometries(),
Slope(),
@@ -31,10 +31,24 @@
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.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 @@ def initAlgorithm(self, config=None):
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 @@ def displayName(self):
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)

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)
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.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 @@ def processAlgorithm(self, parameters, context, feedback):
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 @@ def processAlgorithm(self, parameters, context, feedback):
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 @@ def processAlgorithm(self, parameters, context, feedback):
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 @@ def processAlgorithm(self, parameters, context, feedback):
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}

0 comments on commit 494ceff

Please sign in to comment.
You can’t perform that action at this time.