Skip to content

Commit 494ceff

Browse files
committedJul 17, 2017
[processing] restore Shortest path from point to layer
1 parent c5ed539 commit 494ceff

File tree

2 files changed

+94
-88
lines changed

2 files changed

+94
-88
lines changed
 

‎python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@
9090
# from .ServiceAreaFromLayer import ServiceAreaFromLayer
9191
# from .ServiceAreaFromPoint import ServiceAreaFromPoint
9292
# from .ShortestPathLayerToPoint import ShortestPathLayerToPoint
93-
# from .ShortestPathPointToLayer import ShortestPathPointToLayer
93+
from .ShortestPathPointToLayer import ShortestPathPointToLayer
9494
from .ShortestPathPointToPoint import ShortestPathPointToPoint
9595
from .SimplifyGeometries import SimplifyGeometries
9696
from .Slope import Slope
@@ -274,6 +274,7 @@ def getAlgs(self):
274274
SaveSelectedFeatures(),
275275
SelectByAttribute(),
276276
SelectByExpression(),
277+
ShortestPathPointToLayer(),
277278
ShortestPathPointToPoint(),
278279
SimplifyGeometries(),
279280
Slope(),

‎python/plugins/processing/algs/qgis/ShortestPathPointToLayer.py

Lines changed: 92 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,24 @@
3131
from qgis.PyQt.QtCore import QVariant
3232
from qgis.PyQt.QtGui import QIcon
3333

34-
from qgis.core import (QgsWkbTypes, QgsUnitTypes, QgsFeatureSink, QgsFeature, QgsGeometry, QgsPointXY, QgsFields, QgsField, QgsFeatureRequest,
34+
from qgis.core import (QgsWkbTypes,
35+
QgsUnitTypes,
36+
QgsFeature,
37+
QgsFeatureSink,
38+
QgsGeometry,
39+
QgsFields,
40+
QgsField,
3541
QgsMessageLog,
36-
QgsProcessingParameterDefinition,
37-
QgsProcessingUtils)
42+
QgsProcessing,
43+
QgsProcessingParameterEnum,
44+
QgsProcessingParameterPoint,
45+
QgsProcessingParameterField,
46+
QgsProcessingParameterNumber,
47+
QgsProcessingParameterString,
48+
QgsProcessingParameterFeatureSource,
49+
QgsProcessingParameterFeatureSink,
50+
QgsProcessingParameterVectorLayer,
51+
QgsProcessingParameterDefinition)
3852
from qgis.analysis import (QgsVectorLayerDirector,
3953
QgsNetworkDistanceStrategy,
4054
QgsNetworkSpeedStrategy,
@@ -44,22 +58,13 @@
4458
from qgis.utils import iface
4559

4660
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
47-
from processing.core.parameters import (ParameterVector,
48-
ParameterPoint,
49-
ParameterNumber,
50-
ParameterString,
51-
ParameterTableField,
52-
ParameterSelection
53-
)
54-
from processing.core.outputs import OutputVector
55-
from processing.tools import dataobjects
5661

5762
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
5863

5964

6065
class ShortestPathPointToLayer(QgisAlgorithm):
6166

62-
INPUT_VECTOR = 'INPUT_VECTOR'
67+
INPUT = 'INPUT'
6368
START_POINT = 'START_POINT'
6469
END_POINTS = 'END_POINTS'
6570
STRATEGY = 'STRATEGY'
@@ -71,7 +76,7 @@ class ShortestPathPointToLayer(QgisAlgorithm):
7176
SPEED_FIELD = 'SPEED_FIELD'
7277
DEFAULT_SPEED = 'DEFAULT_SPEED'
7378
TOLERANCE = 'TOLERANCE'
74-
OUTPUT_LAYER = 'OUTPUT_LAYER'
79+
OUTPUT = 'OUTPUT'
7580

7681
def icon(self):
7782
return QIcon(os.path.join(pluginPath, 'images', 'networkanalysis.svg'))
@@ -92,58 +97,59 @@ def initAlgorithm(self, config=None):
9297
self.tr('Fastest')
9398
]
9499

95-
self.addParameter(ParameterVector(self.INPUT_VECTOR,
96-
self.tr('Vector layer representing network'),
97-
[dataobjects.TYPE_VECTOR_LINE]))
98-
self.addParameter(ParameterPoint(self.START_POINT,
99-
self.tr('Start point')))
100-
self.addParameter(ParameterVector(self.END_POINTS,
101-
self.tr('Vector layer with end points'),
102-
[dataobjects.TYPE_VECTOR_POINT]))
103-
self.addParameter(ParameterSelection(self.STRATEGY,
104-
self.tr('Path type to calculate'),
105-
self.STRATEGIES,
106-
default=0))
100+
self.addParameter(QgsProcessingParameterVectorLayer(self.INPUT,
101+
self.tr('Vector layer representing network'),
102+
[QgsProcessing.TypeVectorLine]))
103+
self.addParameter(QgsProcessingParameterPoint(self.START_POINT,
104+
self.tr('Start point')))
105+
self.addParameter(QgsProcessingParameterFeatureSource(self.END_POINTS,
106+
self.tr('Vector layer with end points'),
107+
[QgsProcessing.TypeVectorPoint]))
108+
self.addParameter(QgsProcessingParameterEnum(self.STRATEGY,
109+
self.tr('Path type to calculate'),
110+
self.STRATEGIES,
111+
defaultValue=0))
107112

108113
params = []
109-
params.append(ParameterTableField(self.DIRECTION_FIELD,
110-
self.tr('Direction field'),
111-
self.INPUT_VECTOR,
112-
optional=True))
113-
params.append(ParameterString(self.VALUE_FORWARD,
114-
self.tr('Value for forward direction'),
115-
'',
116-
optional=True))
117-
params.append(ParameterString(self.VALUE_BACKWARD,
118-
self.tr('Value for backward direction'),
119-
'',
120-
optional=True))
121-
params.append(ParameterString(self.VALUE_BOTH,
122-
self.tr('Value for both directions'),
123-
'',
124-
optional=True))
125-
params.append(ParameterSelection(self.DEFAULT_DIRECTION,
126-
self.tr('Default direction'),
127-
list(self.DIRECTIONS.keys()),
128-
default=2))
129-
params.append(ParameterTableField(self.SPEED_FIELD,
130-
self.tr('Speed field'),
131-
self.INPUT_VECTOR,
132-
optional=True))
133-
params.append(ParameterNumber(self.DEFAULT_SPEED,
134-
self.tr('Default speed (km/h)'),
135-
0.0, 99999999.999999, 5.0))
136-
params.append(ParameterNumber(self.TOLERANCE,
137-
self.tr('Topology tolerance'),
138-
0.0, 99999999.999999, 0.0))
114+
params.append(QgsProcessingParameterField(self.DIRECTION_FIELD,
115+
self.tr('Direction field'),
116+
None,
117+
self.INPUT,
118+
optional=True))
119+
params.append(QgsProcessingParameterString(self.VALUE_FORWARD,
120+
self.tr('Value for forward direction'),
121+
optional=True))
122+
params.append(QgsProcessingParameterString(self.VALUE_BACKWARD,
123+
self.tr('Value for backward direction'),
124+
optional=True))
125+
params.append(QgsProcessingParameterString(self.VALUE_BOTH,
126+
self.tr('Value for both directions'),
127+
optional=True))
128+
params.append(QgsProcessingParameterEnum(self.DEFAULT_DIRECTION,
129+
self.tr('Default direction'),
130+
list(self.DIRECTIONS.keys()),
131+
defaultValue=2))
132+
params.append(QgsProcessingParameterField(self.SPEED_FIELD,
133+
self.tr('Speed field'),
134+
None,
135+
self.INPUT,
136+
optional=True))
137+
params.append(QgsProcessingParameterNumber(self.DEFAULT_SPEED,
138+
self.tr('Default speed (km/h)'),
139+
QgsProcessingParameterNumber.Double,
140+
5.0, False, 0, 99999999.99))
141+
params.append(QgsProcessingParameterNumber(self.TOLERANCE,
142+
self.tr('Topology tolerance'),
143+
QgsProcessingParameterNumber.Double,
144+
0.0, False, 0, 99999999.99))
139145

140146
for p in params:
141147
p.setFlags(p.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
142148
self.addParameter(p)
143149

144-
self.addOutput(OutputVector(self.OUTPUT_LAYER,
145-
self.tr('Shortest path'),
146-
datatype=[dataobjects.TYPE_VECTOR_LINE]))
150+
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT,
151+
self.tr('Shortest path'),
152+
QgsProcessing.TypeVectorLine))
147153

148154
def name(self):
149155
return 'shortestpathpointtolayer'
@@ -152,21 +158,19 @@ def displayName(self):
152158
return self.tr('Shortest path (point to layer)')
153159

154160
def processAlgorithm(self, parameters, context, feedback):
155-
layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_VECTOR), context)
156-
startPoint = self.getParameterValue(self.START_POINT)
157-
endPoints = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.END_POINTS), context)
158-
strategy = self.getParameterValue(self.STRATEGY)
159-
160-
directionFieldName = self.getParameterValue(self.DIRECTION_FIELD)
161-
forwardValue = self.getParameterValue(self.VALUE_FORWARD)
162-
backwardValue = self.getParameterValue(self.VALUE_BACKWARD)
163-
bothValue = self.getParameterValue(self.VALUE_BOTH)
164-
defaultDirection = self.getParameterValue(self.DEFAULT_DIRECTION)
165-
bothValue = self.getParameterValue(self.VALUE_BOTH)
166-
defaultDirection = self.getParameterValue(self.DEFAULT_DIRECTION)
167-
speedFieldName = self.getParameterValue(self.SPEED_FIELD)
168-
defaultSpeed = self.getParameterValue(self.DEFAULT_SPEED)
169-
tolerance = self.getParameterValue(self.TOLERANCE)
161+
layer = self.parameterAsVectorLayer(parameters, self.INPUT, context)
162+
startPoint = self.parameterAsPoint(parameters, self.START_POINT, context)
163+
endPoints = self.parameterAsSource(parameters, self.END_POINTS, context)
164+
strategy = self.parameterAsEnum(parameters, self.STRATEGY, context)
165+
166+
directionFieldName = self.parameterAsString(parameters, self.DIRECTION_FIELD, context)
167+
forwardValue = self.parameterAsString(parameters, self.VALUE_FORWARD, context)
168+
backwardValue = self.parameterAsString(parameters, self.VALUE_BACKWARD, context)
169+
bothValue = self.parameterAsString(parameters, self.VALUE_BOTH, context)
170+
defaultDirection = self.parameterAsEnum(parameters, self.DEFAULT_DIRECTION, context)
171+
speedFieldName = self.parameterAsString(parameters, self.SPEED_FIELD, context)
172+
defaultSpeed = self.parameterAsDouble(parameters, self.DEFAULT_SPEED, context)
173+
tolerance = self.parameterAsDouble(parameters, self.TOLERANCE, context)
170174

171175
fields = QgsFields()
172176
fields.append(QgsField('start', QVariant.String, '', 254, 0))
@@ -176,17 +180,14 @@ def processAlgorithm(self, parameters, context, feedback):
176180
feat = QgsFeature()
177181
feat.setFields(fields)
178182

179-
writer = self.getOutputFromName(
180-
self.OUTPUT_LAYER).getVectorWriter(fields, QgsWkbTypes.LineString, layer.crs(), context)
181-
182-
tmp = startPoint.split(',')
183-
startPoint = QgsPointXY(float(tmp[0]), float(tmp[1]))
183+
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
184+
fields, QgsWkbTypes.LineString, layer.crs())
184185

185186
directionField = -1
186-
if directionFieldName is not None:
187+
if directionFieldName:
187188
directionField = layer.fields().lookupField(directionFieldName)
188189
speedField = -1
189-
if speedFieldName is not None:
190+
if speedFieldName:
190191
speedField = layer.fields().lookupField(speedFieldName)
191192

192193
director = QgsVectorLayerDirector(layer,
@@ -214,12 +215,16 @@ def processAlgorithm(self, parameters, context, feedback):
214215
feedback.pushInfo(self.tr('Loading end points...'))
215216
request = QgsFeatureRequest()
216217
request.setFlags(request.flags() ^ QgsFeatureRequest.SubsetOfAttributes)
217-
features = QgsProcessingUtils.getFeatures(endPoints, context, request)
218-
count = QgsProcessingUtils.featureCount(endPoints, context)
218+
features = source.getFeatures(request)
219+
total = 100.0 / source.featureCount() if source.featureCount() else 0
219220

220221
points = [startPoint]
221-
for f in features:
222+
for current, f in enumerate(features):
223+
if feedback.isCanceled():
224+
break
225+
222226
points.append(f.geometry().asPoint())
227+
feedback.setProgress(int(current * total))
223228

224229
feedback.pushInfo(self.tr('Building graph...'))
225230
snappedPoints = director.makeGraph(builder, points)
@@ -231,7 +236,7 @@ def processAlgorithm(self, parameters, context, feedback):
231236
tree, cost = QgsGraphAnalyzer.dijkstra(graph, idxStart, 0)
232237
route = []
233238

234-
total = 100.0 / count if count else 1
239+
total = 100.0 / source.featureCount() if source.featureCount() else 1
235240
for i in range(1, count + 1):
236241
idxEnd = graph.findVertex(snappedPoints[i])
237242

@@ -256,10 +261,10 @@ def processAlgorithm(self, parameters, context, feedback):
256261
feat['start'] = startPoint.toString()
257262
feat['end'] = points[i].toString()
258263
feat['cost'] = cost / multiplier
259-
writer.addFeature(feat, QgsFeatureSink.FastInsert)
264+
sink.addFeature(feat, QgsFeatureSink.FastInsert)
260265

261266
route[:] = []
262267

263268
feedback.setProgress(int(i * total))
264269

265-
del writer
270+
return {self.OUTPUT: dest_id}

0 commit comments

Comments
 (0)
Please sign in to comment.