Skip to content

Commit 5000f9a

Browse files
authored
Merge pull request #5488 from nyalldawson/network
[processing] Fix some issues with network analysis shortest path algs
2 parents 9a1cd9d + 05ad0bc commit 5000f9a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1189
-374
lines changed

doc/api_break.dox

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,13 +1379,34 @@ QgsGraduatedSymbolRenderer {#qgis_api_break_3_0_QgsGraduatedSymbolRendere
13791379
- sizeScaleFieldChanged() and scaleMethodChanged() were removed. These settings are no longer exposed in the widget's GUI.
13801380

13811381

1382+
QgsGraph {#qgis_api_break_3_0_QgsGraph}
1383+
--------
1384+
1385+
- addEdge now explicitly takes the fromVertex as first argument, and toVertex as second argument. The original
1386+
API design was unclear due to the reversed methods in QgsGraphEdge and QgsGraphVertex.
1387+
1388+
13821389
QgsGraphBuilderInterface {#qgis_api_break_3_0_QgsGraphBuilderInterface}
13831390
------------------------
13841391

13851392
- destinationCrs() now returns a copy instead of a reference to the CRS. This has no effect on PyQGIS code, but c++
13861393
plugins calling this method will need to be updated.
13871394

13881395

1396+
QgsGraphEdge {#qgis_api_break_3_0_QgsGraphEdge}
1397+
------------
1398+
1399+
- outVertex() was renamed as toVertex() (yes, the original name was the opposite of the returned value!)
1400+
- inVertex() was renamed as fromVertex() (yes, the original name was the opposite of the returned value!)
1401+
1402+
1403+
QgsGraphVertex {#qgis_api_break_3_0_QgsGraphVertex}
1404+
--------------
1405+
1406+
- outEdges() was renamed as incomingEdges() (yes, the original name was the opposite of the returned value!)
1407+
- inEdges() was renamed as outgoingEdges() (yes, the original name was the opposite of the returned value!)
1408+
1409+
13891410
QgsEditorWidgetRegistry {#qgis_api_break_3_0_QgsEditorWidgetRegistry}
13901411
-----------------------
13911412

@@ -1777,6 +1798,13 @@ QgsNetworkAccessManager {#qgis_api_break_3_0_QgsNetworkAccessManager}
17771798
- deleteReply() was removed. Use abort() and deleteLayer() on the reply directly.
17781799
- requestSent signal was removed. This is no longer emitted.
17791800

1801+
1802+
QgsNetworkStrategy {#qgis_api_break_3_0_QgsNetworkStrategy}
1803+
------------------
1804+
1805+
- requiredAttributes() now returns a set of attributes, instead of a list
1806+
1807+
17801808
QgsNewVectorLayerDialog {#qgis_api_break_3_0_QgsNewVectorLayerDialog}
17811809
-----------------------
17821810

python/analysis/network/qgsgraph.sip

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,17 @@ class QgsGraphEdge
4141
:rtype: list of QVariant
4242
%End
4343

44-
int outVertex() const;
44+
int toVertex() const;
4545
%Docstring
46-
Returns index of the outgoing vertex
46+
Returns the index of the vertex at the end of this edge.
47+
.. seealso:: fromVertex()
4748
:rtype: int
4849
%End
4950

50-
int inVertex() const;
51+
int fromVertex() const;
5152
%Docstring
52-
Returns index of the incoming vertex
53+
Returns the index of the vertex at the start of this edge.
54+
.. seealso:: toVertex()
5355
:rtype: int
5456
%End
5557

@@ -62,6 +64,7 @@ class QgsGraphVertex
6264
{
6365
%Docstring
6466
This class implements a graph vertex
67+
.. versionadded:: 3.0
6568
%End
6669

6770
%TypeHeaderCode
@@ -80,21 +83,23 @@ class QgsGraphVertex
8083
This constructor initializes QgsGraphVertex object and associates a vertex with a point
8184
%End
8285

83-
QgsGraphEdgeIds outEdges() const;
86+
QgsGraphEdgeIds incomingEdges() const;
8487
%Docstring
85-
Returns outgoing edges ids
88+
Returns the incoming edge ids, i.e. edges which end at this node.
89+
.. seealso:: outgoingEdges()
8690
:rtype: QgsGraphEdgeIds
8791
%End
8892

89-
QgsGraphEdgeIds inEdges() const;
93+
QgsGraphEdgeIds outgoingEdges() const;
9094
%Docstring
91-
Return incoming edges ids
95+
Returns outgoing edge ids, i.e. edges which start at this node.
96+
.. seealso:: incomingEdges()
9297
:rtype: QgsGraphEdgeIds
9398
%End
9499

95100
QgsPointXY point() const;
96101
%Docstring
97-
Returns point associated with graph vertex
102+
Returns point associated with graph vertex.
98103
:rtype: QgsPointXY
99104
%End
100105

@@ -105,6 +110,7 @@ class QgsGraph
105110
{
106111
%Docstring
107112
Mathematical graph representation
113+
.. versionadded:: 3.0
108114
%End
109115

110116
%TypeHeaderCode
@@ -124,9 +130,10 @@ class QgsGraph
124130
:rtype: int
125131
%End
126132

127-
int addEdge( int outVertexIdx, int inVertexIdx, const QVector< QVariant > &strategies );
133+
int addEdge( int fromVertexIdx, int toVertexIdx, const QVector< QVariant > &strategies );
128134
%Docstring
129-
Add an edge to the graph
135+
Add an edge to the graph, going from the ``fromVertexIdx``
136+
to ``toVertexIdx``.
130137
:rtype: int
131138
%End
132139

python/analysis/network/qgsgraphbuilder.sip

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,14 @@ class QgsGraphBuilder : QgsGraphBuilderInterface
3030
~QgsGraphBuilder();
3131

3232
virtual void addVertex( int id, const QgsPointXY &pt );
33+
3334
%Docstring
3435
MANDATORY BUILDER PROPERTY DECLARATION
3536
%End
3637

3738
virtual void addEdge( int pt1id, const QgsPointXY &pt1, int pt2id, const QgsPointXY &pt2, const QVector< QVariant > &prop );
3839

40+
3941
QgsGraph *graph() /Factory/;
4042
%Docstring
4143
Returns generated QgsGraph

python/analysis/network/qgsnetworkspeedstrategy.sip

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,8 @@ class QgsNetworkSpeedStrategy : QgsNetworkStrategy
2828

2929
virtual QVariant cost( double distance, const QgsFeature &f ) const;
3030

31-
%Docstring
32-
Returns edge cost
33-
:rtype: QVariant
34-
%End
35-
36-
virtual QgsAttributeList requiredAttributes() const;
31+
virtual QSet< int > requiredAttributes() const;
3732

38-
%Docstring
39-
Returns list of the source layer attributes needed for cost calculation.
40-
This method called by QgsGraphDirector.
41-
:rtype: QgsAttributeList
42-
%End
4333

4434
};
4535

python/analysis/network/qgsnetworkstrategy.sip

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,11 @@ class QgsNetworkStrategy
4545

4646
virtual ~QgsNetworkStrategy();
4747

48-
virtual QgsAttributeList requiredAttributes() const;
48+
virtual QSet< int > requiredAttributes() const;
4949
%Docstring
50-
Returns list of the source layer attributes needed for cost calculation.
51-
This method called by QgsGraphDirector.
52-
:return: list of required attributes
53-
:rtype: QgsAttributeList
50+
Returns a list of the source layer attributes needed for cost calculation.
51+
This is method called by QgsGraphDirector.
52+
:rtype: set of int
5453
%End
5554

5655
virtual QVariant cost( double distance, const QgsFeature &f ) const = 0;

python/plugins/processing/algs/qgis/ServiceAreaFromLayer.py

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
QgsFeatureRequest,
3939
QgsGeometry,
4040
QgsFields,
41+
QgsPointXY,
4142
QgsField,
4243
QgsProcessing,
4344
QgsProcessingParameterEnum,
@@ -88,8 +89,8 @@ def __init__(self):
8889
def initAlgorithm(self, config=None):
8990
self.DIRECTIONS = OrderedDict([
9091
(self.tr('Forward direction'), QgsVectorLayerDirector.DirectionForward),
91-
(self.tr('Backward direction'), QgsVectorLayerDirector.DirectionForward),
92-
(self.tr('Both directions'), QgsVectorLayerDirector.DirectionForward)])
92+
(self.tr('Backward direction'), QgsVectorLayerDirector.DirectionBackward),
93+
(self.tr('Both directions'), QgsVectorLayerDirector.DirectionBoth)])
9394

9495
self.STRATEGIES = [self.tr('Shortest'),
9596
self.tr('Fastest')
@@ -172,7 +173,7 @@ def processAlgorithm(self, parameters, context, feedback):
172173
defaultSpeed = self.parameterAsDouble(parameters, self.DEFAULT_SPEED, context)
173174
tolerance = self.parameterAsDouble(parameters, self.TOLERANCE, context)
174175

175-
fields = QgsFields()
176+
fields = startPoints.fields()
176177
fields.append(QgsField('type', QVariant.String, '', 254, 0))
177178
fields.append(QgsField('start', QVariant.String, '', 254, 0))
178179

@@ -209,17 +210,25 @@ def processAlgorithm(self, parameters, context, feedback):
209210

210211
feedback.pushInfo(self.tr('Loading start points...'))
211212
request = QgsFeatureRequest()
212-
request.setFlags(request.flags() ^ QgsFeatureRequest.SubsetOfAttributes)
213213
request.setDestinationCrs(network.sourceCrs())
214214
features = startPoints.getFeatures(request)
215215
total = 100.0 / startPoints.featureCount() if startPoints.featureCount() else 0
216216

217217
points = []
218+
source_attributes = {}
219+
i = 0
218220
for current, f in enumerate(features):
219221
if feedback.isCanceled():
220222
break
221223

222-
points.append(f.geometry().asPoint())
224+
if not f.hasGeometry():
225+
continue
226+
227+
for p in f.geometry().vertices():
228+
points.append(QgsPointXY(p))
229+
source_attributes[i] = f.attributes()
230+
i += 1
231+
223232
feedback.setProgress(int(current * total))
224233

225234
feedback.pushInfo(self.tr('Building graph...'))
@@ -245,25 +254,27 @@ def processAlgorithm(self, parameters, context, feedback):
245254
tree, cost = QgsGraphAnalyzer.dijkstra(graph, idxStart, 0)
246255
for j, v in enumerate(cost):
247256
if v > travelCost and tree[j] != -1:
248-
vertexId = graph.edge(tree[j]).outVertex()
257+
vertexId = graph.edge(tree[j]).fromVertex()
249258
if cost[vertexId] <= travelCost:
250259
vertices.append(j)
251260

252261
for j in vertices:
253-
upperBoundary.append(graph.vertex(graph.edge(tree[j]).inVertex()).point())
254-
lowerBoundary.append(graph.vertex(graph.edge(tree[j]).outVertex()).point())
262+
upperBoundary.append(graph.vertex(graph.edge(tree[j]).toVertex()).point())
263+
lowerBoundary.append(graph.vertex(graph.edge(tree[j]).fromVertex()).point())
255264

256265
geomUpper = QgsGeometry.fromMultiPointXY(upperBoundary)
257266
geomLower = QgsGeometry.fromMultiPointXY(lowerBoundary)
258267

259268
feat.setGeometry(geomUpper)
260-
feat['type'] = 'upper'
261-
feat['start'] = origPoint
269+
270+
attrs = source_attributes[i]
271+
attrs.extend(['upper', origPoint])
272+
feat.setAttributes(attrs)
262273
sink.addFeature(feat, QgsFeatureSink.FastInsert)
263274

264275
feat.setGeometry(geomLower)
265-
feat['type'] = 'lower'
266-
feat['start'] = origPoint
276+
attrs[-2] = 'lower'
277+
feat.setAttributes(attrs)
267278
sink.addFeature(feat, QgsFeatureSink.FastInsert)
268279

269280
vertices[:] = []

python/plugins/processing/algs/qgis/ServiceAreaFromPoint.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ def __init__(self):
8787
def initAlgorithm(self, config=None):
8888
self.DIRECTIONS = OrderedDict([
8989
(self.tr('Forward direction'), QgsVectorLayerDirector.DirectionForward),
90-
(self.tr('Backward direction'), QgsVectorLayerDirector.DirectionForward),
91-
(self.tr('Both directions'), QgsVectorLayerDirector.DirectionForward)])
90+
(self.tr('Backward direction'), QgsVectorLayerDirector.DirectionBackward),
91+
(self.tr('Both directions'), QgsVectorLayerDirector.DirectionBoth)])
9292

9393
self.STRATEGIES = [self.tr('Shortest'),
9494
self.tr('Fastest')
@@ -208,15 +208,15 @@ def processAlgorithm(self, parameters, context, feedback):
208208
vertices = []
209209
for i, v in enumerate(cost):
210210
if v > travelCost and tree[i] != -1:
211-
vertexId = graph.edge(tree[i]).outVertex()
211+
vertexId = graph.edge(tree[i]).fromVertex()
212212
if cost[vertexId] <= travelCost:
213213
vertices.append(i)
214214

215215
upperBoundary = []
216216
lowerBoundary = []
217217
for i in vertices:
218-
upperBoundary.append(graph.vertex(graph.edge(tree[i]).inVertex()).point())
219-
lowerBoundary.append(graph.vertex(graph.edge(tree[i]).outVertex()).point())
218+
upperBoundary.append(graph.vertex(graph.edge(tree[i]).toVertex()).point())
219+
lowerBoundary.append(graph.vertex(graph.edge(tree[i]).fromVertex()).point())
220220

221221
feedback.pushInfo(self.tr('Writing results...'))
222222

0 commit comments

Comments
 (0)