Skip to content

Commit 017f6a5

Browse files
committedApr 6, 2018
[processing] Fixes for Service Area algorithms
- Output interpolated points when travel cost falls mid-way along an edge - Output all intermediate reachable points also - Make outputting upper/lower bound points optional, and non-default. Now by default we just output all definitely reachable points and the interpolated points along edges which correspond to the travel cost. This allows the output to be used to correctly generate service areas e.g. by concave/convex polygons and all reachable nodes will be included in the area. - Allow algorithm to optionally output a line layer (and make the point layer optional too, and default to just the line layer output) containing all reachable line segments (including interpolated segments of lines when the travel cost sits midway along that edge). This output is more easily understandably for users. (cherry-picked from ccb72eb)
1 parent d93862c commit 017f6a5

23 files changed

+480
-76
lines changed
 

‎python/analysis/network/qgsgraphanalyzer.sip.in

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ Solve shortest path problem using Dijkstra algorithm
3030
:param source: source graph
3131
:param startVertexIdx: index of the start vertex
3232
:param criterionNum: index of the optimization strategy
33-
:param resultTree: array that represents shortest path tree. resultTree[ vertexIndex ] == inboundingArcIndex if vertex reachable, otherwise resultTree[ vertexIndex ] == -1
33+
:param resultTree: array that represents shortest path tree. resultTree[ vertexIndex ] == inboundingArcIndex if vertex reachable, otherwise resultTree[ vertexIndex ] == -1.
34+
Note that the startVertexIdx will also have a value of -1 and may need special handling by callers.
3435
:param resultCost: array of the paths costs
3536
%End
3637

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

Lines changed: 111 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,12 @@
3737
QgsFeatureSink,
3838
QgsFeatureRequest,
3939
QgsGeometry,
40+
QgsGeometryUtils,
4041
QgsFields,
4142
QgsPointXY,
4243
QgsField,
4344
QgsProcessing,
45+
QgsProcessingParameterBoolean,
4446
QgsProcessingParameterEnum,
4547
QgsProcessingParameterPoint,
4648
QgsProcessingParameterField,
@@ -75,7 +77,9 @@ class ServiceAreaFromLayer(QgisAlgorithm):
7577
SPEED_FIELD = 'SPEED_FIELD'
7678
DEFAULT_SPEED = 'DEFAULT_SPEED'
7779
TOLERANCE = 'TOLERANCE'
80+
INCLUDE_BOUNDS = 'INCLUDE_BOUNDS'
7881
OUTPUT = 'OUTPUT'
82+
OUTPUT_LINES = 'OUTPUT_LINES'
7983

8084
def icon(self):
8185
return QIcon(os.path.join(pluginPath, 'images', 'networkanalysis.svg'))
@@ -146,14 +150,24 @@ def initAlgorithm(self, config=None):
146150
self.tr('Topology tolerance'),
147151
QgsProcessingParameterNumber.Double,
148152
0.0, False, 0, 99999999.99))
149-
153+
params.append(QgsProcessingParameterBoolean(self.INCLUDE_BOUNDS,
154+
self.tr('Include upper/lower bound points'),
155+
defaultValue=False))
150156
for p in params:
151157
p.setFlags(p.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
152158
self.addParameter(p)
153159

154-
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT,
155-
self.tr('Service area (boundary nodes)'),
156-
QgsProcessing.TypeVectorPoint))
160+
lines_output = QgsProcessingParameterFeatureSink(self.OUTPUT_LINES,
161+
self.tr('Service area (lines)'),
162+
QgsProcessing.TypeVectorLine, optional=True)
163+
lines_output.setCreateByDefault(True)
164+
self.addParameter(lines_output)
165+
166+
nodes_output = QgsProcessingParameterFeatureSink(self.OUTPUT,
167+
self.tr('Service area (boundary nodes)'),
168+
QgsProcessing.TypeVectorPoint, optional=True)
169+
nodes_output.setCreateByDefault(False)
170+
self.addParameter(nodes_output)
157171

158172
def name(self):
159173
return 'serviceareafromlayer'
@@ -176,6 +190,10 @@ def processAlgorithm(self, parameters, context, feedback):
176190
defaultSpeed = self.parameterAsDouble(parameters, self.DEFAULT_SPEED, context)
177191
tolerance = self.parameterAsDouble(parameters, self.TOLERANCE, context)
178192

193+
include_bounds = True # default to true to maintain 3.0 API
194+
if self.INCLUDE_BOUNDS in parameters:
195+
include_bounds = self.parameterAsBool(parameters, self.INCLUDE_BOUNDS, context)
196+
179197
fields = startPoints.fields()
180198
fields.append(QgsField('type', QVariant.String, '', 254, 0))
181199
fields.append(QgsField('start', QVariant.String, '', 254, 0))
@@ -240,12 +258,11 @@ def processAlgorithm(self, parameters, context, feedback):
240258
feedback.pushInfo(QCoreApplication.translate('ServiceAreaFromLayer', 'Calculating service areas…'))
241259
graph = builder.graph()
242260

243-
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
244-
fields, QgsWkbTypes.MultiPoint, network.sourceCrs())
261+
(point_sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
262+
fields, QgsWkbTypes.MultiPoint, network.sourceCrs())
263+
(line_sink, line_dest_id) = self.parameterAsSink(parameters, self.OUTPUT_LINES, context,
264+
fields, QgsWkbTypes.MultiLineString, network.sourceCrs())
245265

246-
vertices = []
247-
upperBoundary = []
248-
lowerBoundary = []
249266
total = 100.0 / len(snappedPoints) if snappedPoints else 1
250267
for i, p in enumerate(snappedPoints):
251268
if feedback.isCanceled():
@@ -255,35 +272,92 @@ def processAlgorithm(self, parameters, context, feedback):
255272
origPoint = points[i].toString()
256273

257274
tree, cost = QgsGraphAnalyzer.dijkstra(graph, idxStart, 0)
258-
for j, v in enumerate(cost):
259-
if v > travelCost and tree[j] != -1:
260-
vertexId = graph.edge(tree[j]).fromVertex()
261-
if cost[vertexId] <= travelCost:
262-
vertices.append(j)
263-
264-
for j in vertices:
265-
upperBoundary.append(graph.vertex(graph.edge(tree[j]).toVertex()).point())
266-
lowerBoundary.append(graph.vertex(graph.edge(tree[j]).fromVertex()).point())
267-
268-
geomUpper = QgsGeometry.fromMultiPointXY(upperBoundary)
269-
geomLower = QgsGeometry.fromMultiPointXY(lowerBoundary)
270-
271-
feat.setGeometry(geomUpper)
272-
273-
attrs = source_attributes[i]
274-
attrs.extend(['upper', origPoint])
275-
feat.setAttributes(attrs)
276-
sink.addFeature(feat, QgsFeatureSink.FastInsert)
277-
278-
feat.setGeometry(geomLower)
279-
attrs[-2] = 'lower'
280-
feat.setAttributes(attrs)
281-
sink.addFeature(feat, QgsFeatureSink.FastInsert)
282275

283-
vertices[:] = []
284-
upperBoundary[:] = []
285-
lowerBoundary[:] = []
276+
vertices = set()
277+
area_points = []
278+
lines = []
279+
for vertex, start_vertex_cost in enumerate(cost):
280+
inbound_edge_index = tree[vertex]
281+
if inbound_edge_index == -1 and vertex != idxStart:
282+
# unreachable vertex
283+
continue
284+
285+
if start_vertex_cost > travelCost:
286+
# vertex is too expensive, discard
287+
continue
288+
289+
vertices.add(vertex)
290+
start_point = graph.vertex(vertex).point()
291+
292+
# find all edges coming from this vertex
293+
for edge_id in graph.vertex(vertex).outgoingEdges():
294+
edge = graph.edge(edge_id)
295+
end_vertex_cost = start_vertex_cost + edge.cost(0)
296+
end_point = graph.vertex(edge.toVertex()).point()
297+
if end_vertex_cost <= travelCost:
298+
# end vertex is cheap enough to include
299+
vertices.add(edge.toVertex())
300+
lines.append([start_point, end_point])
301+
else:
302+
# travelCost sits somewhere on this edge, interpolate position
303+
interpolated_end_point = QgsGeometryUtils.interpolatePointOnLineByValue(start_point.x(), start_point.y(), start_vertex_cost,
304+
end_point.x(), end_point.y(), end_vertex_cost, travelCost)
305+
area_points.append(interpolated_end_point)
306+
lines.append([start_point, interpolated_end_point])
307+
308+
for v in vertices:
309+
area_points.append(graph.vertex(v).point())
310+
311+
feat = QgsFeature()
312+
if point_sink is not None:
313+
geomPoints = QgsGeometry.fromMultiPointXY(area_points)
314+
feat.setGeometry(geomPoints)
315+
attrs = source_attributes[i]
316+
attrs.extend(['within', origPoint])
317+
feat.setAttributes(attrs)
318+
point_sink.addFeature(feat, QgsFeatureSink.FastInsert)
319+
320+
if include_bounds:
321+
upperBoundary = []
322+
lowerBoundary = []
323+
324+
vertices = []
325+
for vertex, c in enumerate(cost):
326+
if c > travelCost and tree[vertex] != -1:
327+
vertexId = graph.edge(tree[vertex]).fromVertex()
328+
if cost[vertexId] <= travelCost:
329+
vertices.append(vertex)
330+
331+
for v in vertices:
332+
upperBoundary.append(graph.vertex(graph.edge(tree[v]).toVertex()).point())
333+
lowerBoundary.append(graph.vertex(graph.edge(tree[v]).fromVertex()).point())
334+
335+
geomUpper = QgsGeometry.fromMultiPointXY(upperBoundary)
336+
geomLower = QgsGeometry.fromMultiPointXY(lowerBoundary)
337+
338+
feat.setGeometry(geomUpper)
339+
attrs[-2] = 'upper'
340+
feat.setAttributes(attrs)
341+
point_sink.addFeature(feat, QgsFeatureSink.FastInsert)
342+
343+
feat.setGeometry(geomLower)
344+
attrs[-2] = 'lower'
345+
feat.setAttributes(attrs)
346+
point_sink.addFeature(feat, QgsFeatureSink.FastInsert)
347+
348+
if line_sink is not None:
349+
geom_lines = QgsGeometry.fromMultiPolylineXY(lines)
350+
feat.setGeometry(geom_lines)
351+
attrs = source_attributes[i]
352+
attrs.extend(['lines', origPoint])
353+
feat.setAttributes(attrs)
354+
line_sink.addFeature(feat, QgsFeatureSink.FastInsert)
286355

287356
feedback.setProgress(int(i * total))
288357

289-
return {self.OUTPUT: dest_id}
358+
results = {}
359+
if point_sink is not None:
360+
results[self.OUTPUT] = dest_id
361+
if line_sink is not None:
362+
results[self.OUTPUT_LINES] = line_dest_id
363+
return results

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

Lines changed: 108 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,11 @@
3636
QgsFeature,
3737
QgsFeatureSink,
3838
QgsGeometry,
39+
QgsGeometryUtils,
3940
QgsFields,
4041
QgsField,
4142
QgsProcessing,
43+
QgsProcessingParameterBoolean,
4244
QgsProcessingParameterEnum,
4345
QgsProcessingParameterPoint,
4446
QgsProcessingParameterField,
@@ -73,7 +75,9 @@ class ServiceAreaFromPoint(QgisAlgorithm):
7375
SPEED_FIELD = 'SPEED_FIELD'
7476
DEFAULT_SPEED = 'DEFAULT_SPEED'
7577
TOLERANCE = 'TOLERANCE'
78+
INCLUDE_BOUNDS = 'INCLUDE_BOUNDS'
7679
OUTPUT = 'OUTPUT'
80+
OUTPUT_LINES = 'OUTPUT_LINES'
7781

7882
def icon(self):
7983
return QIcon(os.path.join(pluginPath, 'images', 'networkanalysis.svg'))
@@ -143,14 +147,25 @@ def initAlgorithm(self, config=None):
143147
self.tr('Topology tolerance'),
144148
QgsProcessingParameterNumber.Double,
145149
0.0, False, 0, 99999999.99))
150+
params.append(QgsProcessingParameterBoolean(self.INCLUDE_BOUNDS,
151+
self.tr('Include upper/lower bound points'),
152+
defaultValue=False))
146153

147154
for p in params:
148155
p.setFlags(p.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
149156
self.addParameter(p)
150157

151-
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT,
152-
self.tr('Service area (boundary nodes)'),
153-
QgsProcessing.TypeVectorPoint))
158+
lines_output = QgsProcessingParameterFeatureSink(self.OUTPUT_LINES,
159+
self.tr('Service area (lines)'),
160+
QgsProcessing.TypeVectorLine, optional=True)
161+
lines_output.setCreateByDefault(True)
162+
self.addParameter(lines_output)
163+
164+
nodes_output = QgsProcessingParameterFeatureSink(self.OUTPUT,
165+
self.tr('Service area (boundary nodes)'),
166+
QgsProcessing.TypeVectorPoint, optional=True)
167+
nodes_output.setCreateByDefault(False)
168+
self.addParameter(nodes_output)
154169

155170
def name(self):
156171
return 'serviceareafrompoint'
@@ -173,6 +188,10 @@ def processAlgorithm(self, parameters, context, feedback):
173188
defaultSpeed = self.parameterAsDouble(parameters, self.DEFAULT_SPEED, context)
174189
tolerance = self.parameterAsDouble(parameters, self.TOLERANCE, context)
175190

191+
include_bounds = True # default to true to maintain 3.0 API
192+
if self.INCLUDE_BOUNDS in parameters:
193+
include_bounds = self.parameterAsBool(parameters, self.INCLUDE_BOUNDS, context)
194+
176195
directionField = -1
177196
if directionFieldName:
178197
directionField = network.fields().lookupField(directionFieldName)
@@ -208,18 +227,41 @@ def processAlgorithm(self, parameters, context, feedback):
208227
idxStart = graph.findVertex(snappedPoints[0])
209228

210229
tree, cost = QgsGraphAnalyzer.dijkstra(graph, idxStart, 0)
211-
vertices = []
212-
for i, v in enumerate(cost):
213-
if v > travelCost and tree[i] != -1:
214-
vertexId = graph.edge(tree[i]).fromVertex()
215-
if cost[vertexId] <= travelCost:
216-
vertices.append(i)
217-
218-
upperBoundary = []
219-
lowerBoundary = []
230+
vertices = set()
231+
points = []
232+
lines = []
233+
234+
for vertex, start_vertex_cost in enumerate(cost):
235+
inbound_edge_index = tree[vertex]
236+
if inbound_edge_index == -1 and vertex != idxStart:
237+
# unreachable vertex
238+
continue
239+
240+
if start_vertex_cost > travelCost:
241+
# vertex is too expensive, discard
242+
continue
243+
244+
vertices.add(vertex)
245+
start_point = graph.vertex(vertex).point()
246+
247+
# find all edges coming from this vertex
248+
for edge_id in graph.vertex(vertex).outgoingEdges():
249+
edge = graph.edge(edge_id)
250+
end_vertex_cost = start_vertex_cost + edge.cost(0)
251+
end_point = graph.vertex(edge.toVertex()).point()
252+
if end_vertex_cost <= travelCost:
253+
# end vertex is cheap enough to include
254+
vertices.add(edge.toVertex())
255+
lines.append([start_point, end_point])
256+
else:
257+
# travelCost sits somewhere on this edge, interpolate position
258+
interpolated_end_point = QgsGeometryUtils.interpolatePointOnLineByValue(start_point.x(), start_point.y(), start_vertex_cost,
259+
end_point.x(), end_point.y(), end_vertex_cost, travelCost)
260+
points.append(interpolated_end_point)
261+
lines.append([start_point, interpolated_end_point])
262+
220263
for i in vertices:
221-
upperBoundary.append(graph.vertex(graph.edge(tree[i]).toVertex()).point())
222-
lowerBoundary.append(graph.vertex(graph.edge(tree[i]).fromVertex()).point())
264+
points.append(graph.vertex(i).point())
223265

224266
feedback.pushInfo(QCoreApplication.translate('ServiceAreaFromPoint', 'Writing results…'))
225267

@@ -230,25 +272,55 @@ def processAlgorithm(self, parameters, context, feedback):
230272
feat = QgsFeature()
231273
feat.setFields(fields)
232274

233-
geomUpper = QgsGeometry.fromMultiPointXY(upperBoundary)
234-
geomLower = QgsGeometry.fromMultiPointXY(lowerBoundary)
235-
236-
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
237-
fields, QgsWkbTypes.MultiPoint, network.sourceCrs())
238-
239-
feat.setGeometry(geomUpper)
240-
feat['type'] = 'upper'
241-
feat['start'] = startPoint.toString()
242-
sink.addFeature(feat, QgsFeatureSink.FastInsert)
243-
244-
feat.setGeometry(geomLower)
245-
feat['type'] = 'lower'
246-
feat['start'] = startPoint.toString()
247-
sink.addFeature(feat, QgsFeatureSink.FastInsert)
248-
249-
upperBoundary.append(startPoint)
250-
lowerBoundary.append(startPoint)
251-
geomUpper = QgsGeometry.fromMultiPointXY(upperBoundary)
252-
geomLower = QgsGeometry.fromMultiPointXY(lowerBoundary)
253-
254-
return {self.OUTPUT: dest_id}
275+
(point_sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
276+
fields, QgsWkbTypes.MultiPoint, network.sourceCrs())
277+
278+
results = {}
279+
280+
if point_sink is not None:
281+
results[self.OUTPUT] = dest_id
282+
geomPoints = QgsGeometry.fromMultiPointXY(points)
283+
feat.setGeometry(geomPoints)
284+
feat['type'] = 'within'
285+
feat['start'] = startPoint.toString()
286+
point_sink.addFeature(feat, QgsFeatureSink.FastInsert)
287+
288+
if include_bounds:
289+
upperBoundary = []
290+
lowerBoundary = []
291+
292+
vertices = []
293+
for i, v in enumerate(cost):
294+
if v > travelCost and tree[i] != -1:
295+
vertexId = graph.edge(tree[i]).fromVertex()
296+
if cost[vertexId] <= travelCost:
297+
vertices.append(i)
298+
299+
for i in vertices:
300+
upperBoundary.append(graph.vertex(graph.edge(tree[i]).toVertex()).point())
301+
lowerBoundary.append(graph.vertex(graph.edge(tree[i]).fromVertex()).point())
302+
303+
geomUpper = QgsGeometry.fromMultiPointXY(upperBoundary)
304+
geomLower = QgsGeometry.fromMultiPointXY(lowerBoundary)
305+
306+
feat.setGeometry(geomUpper)
307+
feat['type'] = 'upper'
308+
feat['start'] = startPoint.toString()
309+
point_sink.addFeature(feat, QgsFeatureSink.FastInsert)
310+
311+
feat.setGeometry(geomLower)
312+
feat['type'] = 'lower'
313+
feat['start'] = startPoint.toString()
314+
point_sink.addFeature(feat, QgsFeatureSink.FastInsert)
315+
316+
(line_sink, line_dest_id) = self.parameterAsSink(parameters, self.OUTPUT_LINES, context,
317+
fields, QgsWkbTypes.MultiLineString, network.sourceCrs())
318+
if line_sink is not None:
319+
results[self.OUTPUT_LINES] = line_dest_id
320+
geom_lines = QgsGeometry.fromMultiPolylineXY(lines)
321+
feat.setGeometry(geom_lines)
322+
feat['type'] = 'lines'
323+
feat['start'] = startPoint.toString()
324+
line_sink.addFeature(feat, QgsFeatureSink.FastInsert)
325+
326+
return results

‎python/plugins/processing/tests/testdata/expected/service_area.gml

Lines changed: 8 additions & 1 deletion
Large diffs are not rendered by default.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
PROJCS["WGS_1984_UTM_Zone_33S",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",15],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",10000000],UNIT["Meter",1]]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
PROJCS["WGS 84 / UTM zone 33S",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",15],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",10000000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","32733"]]
Binary file not shown.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
PROJCS["WGS_1984_UTM_Zone_33S",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",15],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",10000000],UNIT["Meter",1]]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
PROJCS["WGS 84 / UTM zone 33S",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",15],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",10000000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","32733"]]
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<ogr:FeatureCollection
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://ogr.maptools.org/ service_area_lines.xsd"
5+
xmlns:ogr="http://ogr.maptools.org/"
6+
xmlns:gml="http://www.opengis.net/gml">
7+
<gml:boundedBy>
8+
<gml:Box>
9+
<gml:coord><gml:X>1003314.095851715</gml:X><gml:Y>6222106.12154613</gml:Y></gml:coord>
10+
<gml:coord><gml:X>1003967.800308236</gml:X><gml:Y>6222690.130282185</gml:Y></gml:coord>
11+
</gml:Box>
12+
</gml:boundedBy>
13+
14+
<gml:featureMember>
15+
<ogr:service_area_lines fid="service_area_lines.0">
16+
<ogr:geometryProperty><gml:MultiLineString srsName="EPSG:32733"><gml:lineStringMember><gml:LineString><gml:coordinates>1003318.51056419,6222558.84948158 1003323.47521749,6222559.42305579</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003318.51056419,6222558.84948158 1003322.48706454,6222561.87672396</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003318.51056419,6222558.84948158 1003314.09585172,6222556.50703782</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003416.77290022,6222570.20188393 1003318.51056419,6222558.84948158</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003416.77290022,6222570.20188393 1003430.63468333,6222565.77529146</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003430.63468333,6222565.77529146 1003416.77290022,6222570.20188393</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003430.63468333,6222565.77529146 1003461.44609399,6222555.86616133</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003430.63468333,6222565.77529146 1003403.86741564,6222623.83109929</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003461.44609399,6222555.86616133 1003430.63468333,6222565.77529146</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003461.44609399,6222555.86616133 1003536.86501513,6222502.0742548</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003536.86501513,6222502.0742548 1003461.44609399,6222555.86616133</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003536.86501513,6222502.0742548 1003555.31281829,6222483.13439712</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003555.31281829,6222483.13439712 1003536.86501513,6222502.0742548</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003555.31281829,6222483.13439712 1003602.8338769,6222436.67874613</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003555.31281829,6222483.13439712 1003736.7650073,6222682.94730863</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003602.8338769,6222436.67874613 1003555.31281829,6222483.13439712</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003602.8338769,6222436.67874613 1003647.3751082,6222401.82100567</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003602.8338769,6222436.67874613 1003483.81137232,6222286.60579404</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003647.3751082,6222401.82100567 1003602.8338769,6222436.67874613</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003647.3751082,6222401.82100567 1003653.19070942,6222396.08507509</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003647.3751082,6222401.82100567 1003696.4437017,6222455.04866221</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003692.73332615,6222357.0841711 1003653.19070942,6222396.08507509</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003692.73332615,6222357.0841711 1003745.40906699,6222317.55884368</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003745.40906699,6222317.55884368 1003692.73332615,6222357.0841711</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003745.40906699,6222317.55884368 1003883.50731708,6222232.58074336</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003745.40906699,6222317.55884368 1003596.67006395,6222145.79506248</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003883.50731708,6222232.58074336 1003783.39573872,6222294.18392619</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003883.50731708,6222232.58074336 1003964.66165518,6222154.64186961</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003964.66165518,6222154.64186961 1003961.03504388,6222158.12478879</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003964.66165518,6222154.64186961 1003967.80030824,6222150.713519</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003403.86741564,6222623.83109929 1003360.47539199,6222590.79663107</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003403.86741564,6222623.83109929 1003440.28158698,6222664.4285805</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003403.86741564,6222623.83109929 1003426.7015651,6222574.30587287</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003394.25380049,6222340.63979273 1003373.83959122,6222318.82341122</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003394.25380049,6222340.63979273 1003413.414808,6222363.56471269</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003394.25380049,6222340.63979273 1003416.23997955,6222320.4085397</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003441.51556356,6222297.15044041 1003394.25380049,6222340.63979273</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003441.51556356,6222297.15044041 1003465.11136422,6222304.2892544</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003465.11136422,6222304.2892544 1003441.51556356,6222297.15044041</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003465.11136422,6222304.2892544 1003483.26027016,6222288.61783917</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003483.26027016,6222288.61783917 1003465.11136422,6222304.2892544</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003483.26027016,6222288.61783917 1003483.81137232,6222286.60579404</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003483.81137232,6222286.60579404 1003483.26027016,6222288.61783917</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003483.81137232,6222286.60579404 1003573.80211768,6222400.07321656</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003483.81137232,6222286.60579404 1003472.3070191,6222272.11630568</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003472.3070191,6222272.11630568 1003483.81137232,6222286.60579404</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003472.3070191,6222272.11630568 1003406.90500878,6222189.64158806</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003472.3070191,6222272.11630568 1003560.92830067,6222182.0996092</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003406.90500878,6222189.64158806 1003419.99086281,6222206.14340675</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003406.90500878,6222189.64158806 1003422.43926795,6222175.42060347</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003406.90500878,6222189.64158806 1003392.71936137,6222205.2080979</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003596.67006395,6222145.79506248 1003559.85075068,6222183.1941261</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003596.67006395,6222145.79506248 1003631.02591393,6222185.46919353</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003596.67006395,6222145.79506248 1003562.31361325,6222106.12154613</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003696.4437017,6222455.04866221 1003647.3751082,6222401.82100567</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003696.4437017,6222455.04866221 1003745.10253898,6222507.54062578</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003696.4437017,6222455.04866221 1003730.70401858,6222428.97077802</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003745.10253898,6222507.54062578 1003696.4437017,6222455.04866221</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003745.10253898,6222507.54062578 1003852.72754463,6222623.65770678</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003745.10253898,6222507.54062578 1003776.08011855,6222475.56747746</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003852.72754463,6222623.65770678 1003791.11900533,6222557.18798903</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003852.72754463,6222623.65770678 1003914.33323318,6222690.13028219</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003852.72754463,6222623.65770678 1003784.38305434,6222683.17969849</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003852.72754463,6222623.65770678 1003921.7483249,6222564.92109632</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003776.08011855,6222475.56747746 1003745.10253898,6222507.54062578</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003776.08011855,6222475.56747746 1003730.70401858,6222428.97077802</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003730.70401858,6222428.97077802 1003776.08011855,6222475.56747746</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003730.70401858,6222428.97077802 1003696.4437017,6222455.04866221</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003653.19070942,6222396.08507509 1003647.3751082,6222401.82100567</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>1003653.19070942,6222396.08507509 1003692.73332615,6222357.0841711</gml:coordinates></gml:LineString></gml:lineStringMember></gml:MultiLineString></ogr:geometryProperty>
17+
<ogr:type>lines</ogr:type>
18+
<ogr:start>1003654.80653, 6222397.72334</ogr:start>
19+
</ogr:service_area_lines>
20+
</gml:featureMember>
21+
</ogr:FeatureCollection>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<xs:schema targetNamespace="http://ogr.maptools.org/" xmlns:ogr="http://ogr.maptools.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" elementFormDefault="qualified" version="1.0">
3+
<xs:import namespace="http://www.opengis.net/gml" schemaLocation="http://schemas.opengis.net/gml/2.1.2/feature.xsd"/>
4+
<xs:element name="FeatureCollection" type="ogr:FeatureCollectionType" substitutionGroup="gml:_FeatureCollection"/>
5+
<xs:complexType name="FeatureCollectionType">
6+
<xs:complexContent>
7+
<xs:extension base="gml:AbstractFeatureCollectionType">
8+
<xs:attribute name="lockId" type="xs:string" use="optional"/>
9+
<xs:attribute name="scope" type="xs:string" use="optional"/>
10+
</xs:extension>
11+
</xs:complexContent>
12+
</xs:complexType>
13+
<xs:element name="service_area_lines" type="ogr:service_area_lines_Type" substitutionGroup="gml:_Feature"/>
14+
<xs:complexType name="service_area_lines_Type">
15+
<xs:complexContent>
16+
<xs:extension base="gml:AbstractFeatureType">
17+
<xs:sequence>
18+
<xs:element name="geometryProperty" type="gml:MultiLineStringPropertyType" nillable="true" minOccurs="0" maxOccurs="1"/>
19+
<xs:element name="type" nillable="true" minOccurs="0" maxOccurs="1">
20+
<xs:simpleType>
21+
<xs:restriction base="xs:string">
22+
<xs:maxLength value="254"/>
23+
</xs:restriction>
24+
</xs:simpleType>
25+
</xs:element>
26+
<xs:element name="start" nillable="true" minOccurs="0" maxOccurs="1">
27+
<xs:simpleType>
28+
<xs:restriction base="xs:string">
29+
<xs:maxLength value="254"/>
30+
</xs:restriction>
31+
</xs:simpleType>
32+
</xs:element>
33+
</xs:sequence>
34+
</xs:extension>
35+
</xs:complexContent>
36+
</xs:complexType>
37+
</xs:schema>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<ogr:FeatureCollection
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://ogr.maptools.org/ service_area_no_bounds.xsd"
5+
xmlns:ogr="http://ogr.maptools.org/"
6+
xmlns:gml="http://www.opengis.net/gml">
7+
<gml:boundedBy>
8+
<gml:Box>
9+
<gml:coord><gml:X>1001909.22669746</gml:X><gml:Y>6221326.986762793</gml:Y></gml:coord>
10+
<gml:coord><gml:X>1003019.60535174</gml:X><gml:Y>6222370.250298364</gml:Y></gml:coord>
11+
</gml:Box>
12+
</gml:boundedBy>
13+
14+
<gml:featureMember>
15+
<ogr:service_area_no_bounds fid="service_area_no_bounds.0">
16+
<ogr:geometryProperty><gml:MultiPoint srsName="EPSG:32733"><gml:pointMember><gml:Point><gml:coordinates>1001909.22669746,6221447.42709256</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1001952.34123543,6221487.30242746</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1001953.43051079,6221448.67450212</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002032.5709223,6221550.81242615</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002969.05030799,6221676.74220288</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002829.94223561,6222321.00857048</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1003004.11226582,6222163.11646885</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002963.52384506,6222257.45803232</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1003019.60535174,6222304.92785896</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002967.72944989,6222310.07412497</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002200.16938687,6221990.04883096</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002131.79656056,6222131.1616001</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002094.78459206,6222017.32991103</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002062.09347554,6221990.71518684</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1001967.62712745,6221918.33750879</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1001980.19825308,6222000.74280752</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002050.07703423,6221904.36892203</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1001968.4230433,6221742.68709309</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002428.50365906,6222266.9106148</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002338.00077012,6222370.25029836</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002477.4573779,6221349.03103474</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002210.48174146,6221405.95790523</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002325.82583316,6221391.57557966</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002739.97402922,6222338.5362528</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002709.22816052,6222314.30504549</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002736.08018519,6222311.40511801</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002897.23102887,6221326.98676279</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002788.41696794,6221470.76830883</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002786.2954101,6221332.83431321</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002904.54858627,6221469.12457386</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002648.98946836,6222212.9852206</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002901.19905976,6222006.39009319</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002888.74299755,6221990.93761268</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002679.03257324,6221723.1246628</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002842.33788343,6222175.19744855</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002076.31366647,6221866.90361533</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002045.66496862,6221837.84991727</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002448.62305961,6222244.85108956</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002382.21032908,6222317.66803566</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002464.2146579,6221876.53459619</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002131.61040283,6221796.62965213</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002302.22841804,6221576.64258306</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002310.58466849,6221563.42200322</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002207.17904492,6221977.8210857</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002275.1898604,6221455.19588041</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002226.82368085,6221517.62843522</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002532.83636772,6221785.38136521</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002421.46534272,6221674.17571725</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002526.28363451,6221554.70249994</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002485.75145034,6221954.55074419</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002621.6858386,6222058.82241101</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002529.45107897,6222163.92536965</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1001930.78353526,6221467.36521594</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1001968.37489204,6221502.13083684</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002137.81278244,6221630.62018051</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002215.13556068,6221689.25446887</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002288.4678461,6221744.85964495</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002334.20638747,6221779.49098284</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002425.63766482,6221848.74446543</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002462.62346654,6221875.38780442</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002518.06990805,6221915.34875741</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002626.85249869,6221993.7562202</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002657.33259138,6222018.20620536</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002781.74783802,6222107.45193255</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002852.18578258,6222162.74032983</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002903.48249244,6222204.64725757</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002916.58033846,6222216.16749784</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002945.17950103,6222241.31856099</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002991.11072264,6222281.72914386</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002643.23398503,6221648.43442531</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002623.85396603,6221672.14481097</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002624.53430232,6222242.61769963</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002724.17727046,6222326.95840711</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002684.54187821,6222169.9061412</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002845.50542017,6221400.90692838</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002893.44547534,6221999.89357485</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002813.21865203,6221847.09999962</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002779.14071154,6222255.13883114</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002161.08326842,6222058.23120113</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002125.77638469,6222042.5574598</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002015.92985521,6221953.13030737</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002509.88988421,6222183.56835463</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002380.76911747,6222089.85859496</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002284.1421556,6222019.72274182</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002233.59814873,6221951.11952203</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002200.84267254,6221919.96191528</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates>1002141.64083448,6221887.81776555</gml:coordinates></gml:Point></gml:pointMember></gml:MultiPoint></ogr:geometryProperty>
17+
<ogr:type>within</ogr:type>
18+
<ogr:start>1002465.00896, 6221875.43249</ogr:start>
19+
</ogr:service_area_no_bounds>
20+
</gml:featureMember>
21+
</ogr:FeatureCollection>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<xs:schema targetNamespace="http://ogr.maptools.org/" xmlns:ogr="http://ogr.maptools.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" elementFormDefault="qualified" version="1.0">
3+
<xs:import namespace="http://www.opengis.net/gml" schemaLocation="http://schemas.opengis.net/gml/2.1.2/feature.xsd"/>
4+
<xs:element name="FeatureCollection" type="ogr:FeatureCollectionType" substitutionGroup="gml:_FeatureCollection"/>
5+
<xs:complexType name="FeatureCollectionType">
6+
<xs:complexContent>
7+
<xs:extension base="gml:AbstractFeatureCollectionType">
8+
<xs:attribute name="lockId" type="xs:string" use="optional"/>
9+
<xs:attribute name="scope" type="xs:string" use="optional"/>
10+
</xs:extension>
11+
</xs:complexContent>
12+
</xs:complexType>
13+
<xs:element name="service_area_no_bounds" type="ogr:service_area_no_bounds_Type" substitutionGroup="gml:_Feature"/>
14+
<xs:complexType name="service_area_no_bounds_Type">
15+
<xs:complexContent>
16+
<xs:extension base="gml:AbstractFeatureType">
17+
<xs:sequence>
18+
<xs:element name="geometryProperty" type="gml:MultiPointPropertyType" nillable="true" minOccurs="0" maxOccurs="1"/>
19+
<xs:element name="type" nillable="true" minOccurs="0" maxOccurs="1">
20+
<xs:simpleType>
21+
<xs:restriction base="xs:string">
22+
<xs:maxLength value="254"/>
23+
</xs:restriction>
24+
</xs:simpleType>
25+
</xs:element>
26+
<xs:element name="start" nillable="true" minOccurs="0" maxOccurs="1">
27+
<xs:simpleType>
28+
<xs:restriction base="xs:string">
29+
<xs:maxLength value="254"/>
30+
</xs:restriction>
31+
</xs:simpleType>
32+
</xs:element>
33+
</xs:sequence>
34+
</xs:extension>
35+
</xs:complexContent>
36+
</xs:complexType>
37+
</xs:schema>

‎python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2954,6 +2954,66 @@ tests:
29542954
start: skip
29552955
end: skip
29562956

2957+
- algorithm: qgis:serviceareafrompoint
2958+
name: Service area (from point, shortest, no bounds)
2959+
params:
2960+
DEFAULT_DIRECTION: 2
2961+
DEFAULT_SPEED: 5.0
2962+
INCLUDE_BOUNDS: false
2963+
INPUT:
2964+
name: roads.gml
2965+
type: vector
2966+
START_POINT: 1002465.0089601517,6221875.432489508
2967+
STRATEGY: 0
2968+
TOLERANCE: 0.0
2969+
TRAVEL_COST: 700.0
2970+
VALUE_BACKWARD: ''
2971+
VALUE_BOTH: ''
2972+
VALUE_FORWARD: ''
2973+
results:
2974+
OUTPUT:
2975+
name: expected/service_area_no_bounds.gml
2976+
type: vector
2977+
compare:
2978+
ignore_crs_check: true
2979+
geometry:
2980+
precision: 2
2981+
fields:
2982+
cost:
2983+
precision: 2
2984+
start: skip
2985+
end: skip
2986+
2987+
- algorithm: qgis:serviceareafrompoint
2988+
name: Service area from point, output lines
2989+
params:
2990+
DEFAULT_DIRECTION: 2
2991+
DEFAULT_SPEED: 5.0
2992+
INCLUDE_BOUNDS: false
2993+
INPUT:
2994+
name: roads.gml
2995+
type: vector
2996+
START_POINT: 1003654.8065293541,6222397.723338357 [EPSG:32733]
2997+
STRATEGY: 0
2998+
TOLERANCE: 0.0
2999+
TRAVEL_COST: 400.0
3000+
VALUE_BACKWARD: ''
3001+
VALUE_BOTH: ''
3002+
VALUE_FORWARD: ''
3003+
results:
3004+
OUTPUT_LINES:
3005+
name: expected/service_area_lines.gml
3006+
type: vector
3007+
compare:
3008+
ignore_crs_check: true
3009+
geometry:
3010+
precision: 2
3011+
fields:
3012+
cost:
3013+
precision: 2
3014+
start: skip
3015+
end: skip
3016+
29573017
- algorithm: qgis:serviceareafromlayer
29583018
name: Service area from layer
29593019
params:
@@ -2988,6 +3048,75 @@ tests:
29883048
- d
29893049
- type
29903050

3051+
- algorithm: qgis:serviceareafromlayer
3052+
name: Service area from layer no bounds
3053+
params:
3054+
DEFAULT_DIRECTION: 2
3055+
DEFAULT_SPEED: 5.0
3056+
INCLUDE_BOUNDS: false
3057+
INPUT:
3058+
name: roads.gml
3059+
type: vector
3060+
START_POINTS:
3061+
name: custom/route_points.gml
3062+
type: vector
3063+
STRATEGY: 0
3064+
TOLERANCE: 0.0
3065+
TRAVEL_COST: 700.0
3066+
VALUE_BACKWARD: ''
3067+
VALUE_BOTH: ''
3068+
VALUE_FORWARD: ''
3069+
results:
3070+
OUTPUT:
3071+
name: expected/service_area_from_layer_no_bounds.shp
3072+
type: vector
3073+
compare:
3074+
ignore_crs_check: true
3075+
geometry:
3076+
precision: 2
3077+
fields:
3078+
cost:
3079+
precision: 2
3080+
start: skip
3081+
end: skip
3082+
pk:
3083+
- d
3084+
- type
3085+
3086+
- algorithm: qgis:serviceareafromlayer
3087+
name: Service area from layer (lines)
3088+
params:
3089+
DEFAULT_DIRECTION: 2
3090+
DEFAULT_SPEED: 5.0
3091+
INCLUDE_BOUNDS: false
3092+
INPUT:
3093+
name: roads.gml
3094+
type: vector
3095+
START_POINTS:
3096+
name: custom/route_points.gml
3097+
type: vector
3098+
STRATEGY: 0
3099+
TOLERANCE: 0.0
3100+
TRAVEL_COST: 500.0
3101+
VALUE_BACKWARD: ''
3102+
VALUE_BOTH: ''
3103+
VALUE_FORWARD: ''
3104+
results:
3105+
OUTPUT_LINES:
3106+
name: expected/service_area_from_layer_lines.shp
3107+
type: vector
3108+
compare:
3109+
ignore_crs_check: true
3110+
geometry:
3111+
precision: 2
3112+
fields:
3113+
cost:
3114+
precision: 2
3115+
start: skip
3116+
end: skip
3117+
pk:
3118+
- d
3119+
- type
29913120

29923121
- algorithm: qgis:createattributeindex
29933122
name: Create attribute index

‎src/analysis/network/qgsgraphanalyzer.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ class ANALYSIS_EXPORT QgsGraphAnalyzer
3838
* \param source source graph
3939
* \param startVertexIdx index of the start vertex
4040
* \param criterionNum index of the optimization strategy
41-
* \param resultTree array that represents shortest path tree. resultTree[ vertexIndex ] == inboundingArcIndex if vertex reachable, otherwise resultTree[ vertexIndex ] == -1
41+
* \param resultTree array that represents shortest path tree. resultTree[ vertexIndex ] == inboundingArcIndex if vertex reachable, otherwise resultTree[ vertexIndex ] == -1.
42+
* Note that the startVertexIdx will also have a value of -1 and may need special handling by callers.
4243
* \param resultCost array of the paths costs
4344
*/
4445
static void SIP_PYALTERNATIVETYPE( SIP_PYLIST ) dijkstra( const QgsGraph *source, int startVertexIdx, int criterionNum, QVector<int> *resultTree = nullptr, QVector<double> *resultCost = nullptr );

0 commit comments

Comments
 (0)
Please sign in to comment.