Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/tools/import/osm/osmTaxiStop.py
169679 views
1
#!/usr/bin/env python
2
# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
# Copyright (C) 2020-2025 German Aerospace Center (DLR) and others.
4
# This program and the accompanying materials are made available under the
5
# terms of the Eclipse Public License 2.0 which is available at
6
# https://www.eclipse.org/legal/epl-2.0/
7
# This Source Code may also be made available under the following Secondary
8
# Licenses when the conditions for such availability set forth in the Eclipse
9
# Public License 2.0 are satisfied: GNU General Public License, version 2
10
# or later which is available at
11
# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13
14
# @file osmTaxiStop.py
15
# @author Michael Behrisch
16
# @date 2020-10-30
17
18
from __future__ import absolute_import
19
from __future__ import print_function
20
21
import os
22
import sys
23
import random
24
import argparse
25
if 'SUMO_HOME' in os.environ:
26
sys.path.append(os.path.join(os.environ["SUMO_HOME"], "tools"))
27
import sumolib # noqa
28
import osmBuild # noqa
29
30
31
VEHICLE_LENGTH = 7.5
32
33
34
def parseArgs(args=None):
35
op = sumolib.options.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
36
op.add_argument("-s", "--osm-file", category="input", required=True, type=op.file,
37
help="read OSM file from FILE (mandatory)", metavar="FILE")
38
op.add_argument("-n", "--net-file", category="input", type=op.net_file,
39
help="read SUMO net from FILE", metavar="FILE")
40
op.add_argument("-o", "--output-file", category="output", required=True, type=op.file,
41
help="write stopping places to the output FILE", metavar="FILE",
42
default="stopping_places.add.xml")
43
op.add_argument("-f", "--fleet-file", category="output", type=op.file,
44
help="write taxi fleet to the output FILE", metavar="FILE")
45
op.add_argument("--fleet-size", type=float, metavar="NUM", category="input",
46
help="relative (0 < NUM < 1) or absolute number of vehicles (NUM >= 1) to generate")
47
op.add_argument("-a", "--amenity", category="input", help="amenity type to read", default="taxi")
48
op.add_argument("-t", "--type", category="output", help="stopping place type", default="chargingStation")
49
op.add_argument("-r", "--radius", category="input", type=float, help="radius for edge finding", default=20.)
50
op.add_argument("-l", "--length", category="input", type=float,
51
help="(minimum) length of the stopping place", default=20.)
52
op.add_argument("--vclass", category="input", help="which vehicle class should be allowed", default="passenger")
53
return op.parse_args(args)
54
55
56
def main(options):
57
if options.net_file is None:
58
osmBuild.build(["-f", options.osm_file])
59
net = sumolib.net.readNet("osm.net.xml")
60
else:
61
net = sumolib.net.readNet(options.net_file)
62
count = 0
63
fleet_out = sumolib.openz(options.fleet_file, "w") if options.fleet_file else None
64
if fleet_out:
65
places = []
66
sumolib.xml.writeHeader(fleet_out, root="additional", options=options)
67
print(u""" <vType id="taxi" vClass="taxi">
68
<param key="has.taxi.device" value="true"/>
69
</vType>""", file=fleet_out)
70
with sumolib.openz(options.output_file, "w") as output:
71
sumolib.xml.writeHeader(output, root="additional", options=options)
72
for n in sumolib.xml.parse(options.osm_file, "node"):
73
name = None
74
bestLane = None
75
point = None
76
length = options.length
77
if n.tag:
78
for t in n.tag:
79
if t.k == "capacity":
80
try:
81
length = max(int(t.v) * VEHICLE_LENGTH, length)
82
except ValueError:
83
pass
84
if t.k == "name":
85
name = t.v
86
if t.k == "amenity" and t.v == options.amenity:
87
point = net.convertLonLat2XY(float(n.lon), float(n.lat))
88
candidates = net.getNeighboringLanes(*point, r=options.radius, includeJunctions=False)
89
for lane, _ in sorted(candidates, key=lambda i: i[1]):
90
if lane.getLength() > options.length and lane.allows(options.vclass):
91
bestLane = lane
92
break
93
if bestLane:
94
pos = sumolib.geomhelper.polygonOffsetWithMinimumDistanceToPoint(point, bestLane.getShape())
95
endPos = min(bestLane.getLength(), max(length, pos + length / 2))
96
nameAttr = 'name="%s" ' % name if name else ""
97
stopID = "%s_%s" % (options.type, count)
98
print(u' <%s id="%s" %slane="%s" startPos="%.2f" endPos="%.2f"/>' %
99
(options.type, stopID, nameAttr, bestLane.getID(), max(0, endPos - length), endPos),
100
file=output)
101
if fleet_out:
102
places += int(length / VEHICLE_LENGTH) * [stopID]
103
count += 1
104
print(u"</additional>", file=output)
105
if fleet_out:
106
if options.fleet_size:
107
fleet_size = int(len(places) * options.fleet_size) if options.fleet_size < 1 else int(options.fleet_size)
108
random.seed(42)
109
random.shuffle(places)
110
places = places[:fleet_size]
111
for idx, stopID in enumerate(places):
112
print(u' <trip id="taxi_%s_%s" type="taxi" depart="begin">' % (stopID, idx), end=u'', file=fleet_out)
113
print(u'<stop busStop="%s" triggered="person"/></trip>' % stopID, file=fleet_out)
114
print(u"</additional>", file=fleet_out)
115
fleet_out.close()
116
117
118
if __name__ == "__main__":
119
main(parseArgs())
120
121