31
31
from qgis .PyQt .QtCore import QVariant
32
32
from qgis .PyQt .QtGui import QIcon
33
33
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 ,
35
41
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 )
38
52
from qgis .analysis import (QgsVectorLayerDirector ,
39
53
QgsNetworkDistanceStrategy ,
40
54
QgsNetworkSpeedStrategy ,
44
58
from qgis .utils import iface
45
59
46
60
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
56
61
57
62
pluginPath = os .path .split (os .path .split (os .path .dirname (__file__ ))[0 ])[0 ]
58
63
59
64
60
65
class ShortestPathPointToLayer (QgisAlgorithm ):
61
66
62
- INPUT_VECTOR = 'INPUT_VECTOR '
67
+ INPUT = 'INPUT '
63
68
START_POINT = 'START_POINT'
64
69
END_POINTS = 'END_POINTS'
65
70
STRATEGY = 'STRATEGY'
@@ -71,7 +76,7 @@ class ShortestPathPointToLayer(QgisAlgorithm):
71
76
SPEED_FIELD = 'SPEED_FIELD'
72
77
DEFAULT_SPEED = 'DEFAULT_SPEED'
73
78
TOLERANCE = 'TOLERANCE'
74
- OUTPUT_LAYER = 'OUTPUT_LAYER '
79
+ OUTPUT = 'OUTPUT '
75
80
76
81
def icon (self ):
77
82
return QIcon (os .path .join (pluginPath , 'images' , 'networkanalysis.svg' ))
@@ -92,58 +97,59 @@ def initAlgorithm(self, config=None):
92
97
self .tr ('Fastest' )
93
98
]
94
99
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 ))
107
112
108
113
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 ))
139
145
140
146
for p in params :
141
147
p .setFlags (p .flags () | QgsProcessingParameterDefinition .FlagAdvanced )
142
148
self .addParameter (p )
143
149
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 ))
147
153
148
154
def name (self ):
149
155
return 'shortestpathpointtolayer'
@@ -152,21 +158,19 @@ def displayName(self):
152
158
return self .tr ('Shortest path (point to layer)' )
153
159
154
160
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 )
170
174
171
175
fields = QgsFields ()
172
176
fields .append (QgsField ('start' , QVariant .String , '' , 254 , 0 ))
@@ -176,17 +180,14 @@ def processAlgorithm(self, parameters, context, feedback):
176
180
feat = QgsFeature ()
177
181
feat .setFields (fields )
178
182
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 ())
184
185
185
186
directionField = - 1
186
- if directionFieldName is not None :
187
+ if directionFieldName :
187
188
directionField = layer .fields ().lookupField (directionFieldName )
188
189
speedField = - 1
189
- if speedFieldName is not None :
190
+ if speedFieldName :
190
191
speedField = layer .fields ().lookupField (speedFieldName )
191
192
192
193
director = QgsVectorLayerDirector (layer ,
@@ -214,12 +215,16 @@ def processAlgorithm(self, parameters, context, feedback):
214
215
feedback .pushInfo (self .tr ('Loading end points...' ))
215
216
request = QgsFeatureRequest ()
216
217
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
219
220
220
221
points = [startPoint ]
221
- for f in features :
222
+ for current , f in enumerate (features ):
223
+ if feedback .isCanceled ():
224
+ break
225
+
222
226
points .append (f .geometry ().asPoint ())
227
+ feedback .setProgress (int (current * total ))
223
228
224
229
feedback .pushInfo (self .tr ('Building graph...' ))
225
230
snappedPoints = director .makeGraph (builder , points )
@@ -231,7 +236,7 @@ def processAlgorithm(self, parameters, context, feedback):
231
236
tree , cost = QgsGraphAnalyzer .dijkstra (graph , idxStart , 0 )
232
237
route = []
233
238
234
- total = 100.0 / count if count else 1
239
+ total = 100.0 / source . featureCount () if source . featureCount () else 1
235
240
for i in range (1 , count + 1 ):
236
241
idxEnd = graph .findVertex (snappedPoints [i ])
237
242
@@ -256,10 +261,10 @@ def processAlgorithm(self, parameters, context, feedback):
256
261
feat ['start' ] = startPoint .toString ()
257
262
feat ['end' ] = points [i ].toString ()
258
263
feat ['cost' ] = cost / multiplier
259
- writer .addFeature (feat , QgsFeatureSink .FastInsert )
264
+ sink .addFeature (feat , QgsFeatureSink .FastInsert )
260
265
261
266
route [:] = []
262
267
263
268
feedback .setProgress (int (i * total ))
264
269
265
- del writer
270
+ return { self . OUTPUT : dest_id }
0 commit comments