Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/tools/contributed/sumopy/coremodules/scenario/scenario.py
169689 views
1
# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
2
# Copyright (C) 2016-2025 German Aerospace Center (DLR) and others.
3
# SUMOPy module
4
# Copyright (C) 2012-2021 University of Bologna - DICAM
5
# This program and the accompanying materials are made available under the
6
# terms of the Eclipse Public License 2.0 which is available at
7
# https://www.eclipse.org/legal/epl-2.0/
8
# This Source Code may also be made available under the following Secondary
9
# Licenses when the conditions for such availability set forth in the Eclipse
10
# Public License 2.0 are satisfied: GNU General Public License, version 2
11
# or later which is available at
12
# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
13
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
14
15
# @file scenario.py
16
# @author Joerg Schweizer
17
# @date 2012
18
19
20
import numpy as np
21
from coremodules.misc import shapeformat
22
from coremodules.simulation import simulation
23
from coremodules.demand import demand
24
from coremodules.landuse import landuse
25
from coremodules.network import network
26
from agilepy.lib_base.processes import Process
27
import agilepy.lib_base.arrayman as am
28
import agilepy.lib_base.classman as cm
29
import os
30
import sys
31
if __name__ == '__main__':
32
try:
33
FILEDIR = os.path.dirname(os.path.abspath(__file__))
34
except:
35
FILEDIR = os.path.dirname(os.path.abspath(sys.argv[0]))
36
sys.path.append(os.path.join(FILEDIR, "..", ".."))
37
38
# this is default scenario directory
39
DIRPATH_SCENARIO = os.path.join(os.path.expanduser("~"), 'Sumo')
40
# os.path.join(os.getcwd(),'testscenario')
41
42
43
def load_scenario(filepath, logger=None):
44
scen = cm.load_obj(filepath, parent=None)
45
# scenario.set_workdirpath(os.path.dirname(filepath))
46
# this will set rootname and workdir
47
if scen is not None:
48
scen.set_filepath(filepath)
49
# print 'load_scenario', scen.get_rootfilepath(),'workdirpath',scen.workdirpath
50
if logger is not None:
51
scen.set_logger(logger)
52
return scen
53
54
55
class ScenarioCreator(Process):
56
def __init__(self, rootname='myscenario', name_scenario='My Scenario', workdirpath=None, description='', logger=None):
57
58
# init process
59
self._init_common('scenariocreator', name='New Scenario', logger=logger)
60
61
if workdirpath is None:
62
#workdirpath = os.getcwd()
63
workdirpath = os.path.expanduser("~")
64
attrsman = self.get_attrsman()
65
self.rootname = attrsman.add(cm.AttrConf('rootname', rootname,
66
groupnames=['options'],
67
perm='rw',
68
name='Shortname',
69
info='Short name for scenario. This string is used as rootname for all files produced by this scenario. Please avoid special charracters, whitespace, accents etc. ASCII is recommented in order to remain compatible between operating systems.',
70
))
71
72
self.name_scenario = attrsman.add(cm.AttrConf('name_scenario', name_scenario,
73
groupnames=['options'],
74
perm='rw',
75
name='Name',
76
info='Scenario name, used for documentation purposes only.',
77
))
78
79
self.description = attrsman.add(cm.AttrConf('description', description,
80
groupnames=['options'],
81
perm='rw',
82
name='Description',
83
info='Short, free description of Scenario.',
84
))
85
86
self.workdirpath = attrsman.add(cm.AttrConf('workdirpath', workdirpath,
87
groupnames=['options'],
88
perm='rw',
89
name='Workdir',
90
metatype='dirpath',
91
info='Working directory for this scenario.',
92
))
93
94
def do(self):
95
# print 'do',self.newident
96
self._scenario = Scenario(self.rootname,
97
name_scenario=self.name_scenario,
98
description=self.description,
99
parent=None,
100
workdirpath=self.workdirpath,
101
logger=self.get_logger(),
102
)
103
return True
104
105
def get_scenario(self):
106
return self._scenario
107
108
# class OxScenariocreator(ScenarioCreator):
109
# def __init__(self, **kwargs):
110
##
111
# ScenarioCreator.__init__(self,**kwargs)
112
##
113
# nodeshapefilepath, edgeshapefilepath, polyshapefilepath,
114
## attrsman = self.get_attrsman()
115
# self.nodeshapefilepath = attrsman.add(
116
# cm.AttrConf('nodeshapefilepath',kwargs.get('nodeshapefilepath',''),
117
## groupnames = ['options'],
118
# perm='rw',
119
## name = 'Nodes shapefile',
120
## wildcards = 'Shape file (*.shp)|*.shp;*.SHP',
121
## metatype = 'filepaths',
122
## info = """Shapefile path for nodes.""",
123
# ))
124
##
125
# self.edgeshapefilepath = attrsman.add(
126
# cm.AttrConf('edgeshapefilepath',kwargs.get('edgeshapefilepath',''),
127
## groupnames = ['options'],
128
# perm='rw',
129
## name = 'Edge shapefile',
130
## wildcards = 'Shape file (*.shp)|*.shp;*.SHP',
131
## metatype = 'filepaths',
132
## info = """Shapefile path for edges.""",
133
# ))
134
##
135
# self.polyshapefilepath = attrsman.add(
136
# cm.AttrConf('polyshapefilepath',kwargs.get('polyshapefilepath',''),
137
## groupnames = ['options'],
138
# perm='rw',
139
## name = 'Poly shapefile',
140
## wildcards = 'Shape file (*.shp)|*.shp;*.SHP',
141
## metatype = 'filepaths',
142
## info = """Shapefile path for polygons.""",
143
# ))
144
##
145
##
146
# def do(self):
147
# print 'do',self.newident
148
# if ScenarioCreator.do(self):
149
##
150
## scenario = self.get_scenario()
151
# return shapeformat.OxImporter(scenario,
152
## self.nodeshapefilepath, self.edgeshapefilepath, self.polyshapefilepath,
153
## ident = 'oximporter',
154
## name = 'OSMnx importer',
155
## info = 'Import of network imported with the help of osmnx.',
156
## logger =self.get_logger()
157
# ).do()
158
# else:
159
# return False
160
##
161
162
163
class Scenario(cm.BaseObjman):
164
def __init__(self, rootname, name_scenario='myscenario',
165
description='', parent=None,
166
workdirpath=None, **kwargs):
167
168
self._init_objman(ident='scenario', parent=parent,
169
name='Scenario', info='Main scenario instance.',
170
version=0.2,
171
**kwargs)
172
173
attrsman = self.set_attrsman(cm.Attrsman(self))
174
175
if workdirpath is not None:
176
# create a directory if path is given, but does not exist
177
if not os.path.isdir(workdirpath):
178
os.mkdir(workdirpath)
179
else:
180
workdirpath = os.getcwd()
181
#workdirpath = os.path.expanduser("~")
182
183
self.name_scenario = attrsman.add(cm.AttrConf('name_scenario', name_scenario,
184
groupnames=['options'],
185
perm='rw',
186
name='Name',
187
info='Scenario name, used for documentation purposes only.',
188
))
189
190
self.description = attrsman.add(cm.AttrConf('description', description,
191
groupnames=['options'],
192
perm='rw',
193
name='Description',
194
info='Short, free description of Scenario.',
195
))
196
197
self.rootname = attrsman.add(cm.AttrConf('rootname', rootname,
198
groupnames=['options'],
199
perm='r',
200
is_save=True,
201
name='Shortname',
202
info='Short name for scenario. This string is defined when saving the scenario. It is used as rootname for all files produced by this scenario. Please avoid special charracters, whitespace, accents etc. ASCII is recommented in order to remain compatible between operating systems.',
203
))
204
205
self.workdirpath = attrsman.add(cm.AttrConf('workdirpath', workdirpath,
206
groupnames=['options'],
207
perm='r',
208
is_save=True,
209
name='Workdir',
210
metatype='dirpath',
211
info='Working directory for this scenario and can be changed when saving the scenario. Please avoid special charracters, whitespace, accents etc. ASCII is recommented in order to remain compatible between operating systems.',
212
))
213
214
self.net = attrsman.add(cm.ObjConf(network.Network(self)))
215
216
self.landuse = attrsman.add(cm.ObjConf(landuse.Landuse(self, self.net)))
217
218
self.demand = attrsman.add(cm.ObjConf(demand.Demand(self)))
219
# if self.get_version()<0.2:
220
# self.delete('simulation')
221
222
self._init_attributes()
223
224
def _init_attributes(self):
225
print 'Scenario._init_attributes' # ,dir(self)
226
227
attrsman = self.get_attrsman()
228
self.simulation = attrsman.add(cm.ObjConf(simulation.Simulation(self)))
229
self.set_version(0.2)
230
231
# print ' finish Scenario._init_attributes'
232
def set_filepath(self, filepath):
233
"""
234
A new filepath will set the shortname and workdir.
235
"""
236
names = os.path.basename(filepath).split('.')
237
dirname = os.path.dirname(filepath)
238
239
if len(names) >= 3:
240
rootname = '.'.join(names[:-2])
241
elif len(names) <= 2:
242
rootname = names[0]
243
244
self.set_workdirpath(dirname)
245
self.set_rootfilename(rootname)
246
247
def save(self, filepath=None):
248
if filepath is None:
249
filepath = self.get_rootfilepath()+'.obj'
250
self.set_filepath(filepath)
251
cm.save_obj(self, filepath, is_not_save_parent=False)
252
return filepath
253
254
def get_workdirpath(self):
255
return self.workdirpath
256
257
def set_workdirpath(self, workdirpath):
258
self.workdirpath = workdirpath
259
260
def set_rootfilename(self, filename):
261
self.rootname = filename
262
263
def get_rootfilename(self):
264
"""
265
Centralized definition of filename bases.
266
"""
267
return self.rootname
268
269
def get_rootfilepath(self):
270
return os.path.join(self.get_workdirpath(), self.get_rootfilename())
271
272
def import_xml(self, is_clean_nodes=False):
273
"""
274
Try to import xml-type files into scenario.
275
"""
276
277
# print 'import_xml'
278
netfilepath = self.net.get_filepath()
279
280
if os.path.isfile(netfilepath):
281
# convert and import edg,nod,con,tll...
282
self.net.import_netxml(filepath=netfilepath, rootname=self.get_rootfilename())
283
else:
284
# import edg,nod,con,tll...
285
self.net.import_xml(self.get_rootfilename(), self.get_workdirpath(), is_clean_nodes=is_clean_nodes)
286
287
self.landuse.import_polyxml(self.get_rootfilename(), self.get_workdirpath())
288
try:
289
self.demand.import_xml(self.get_rootfilename(), self.get_workdirpath())
290
except:
291
print 'WARNING: import of demand data failed. Please check for inconsistency with trip/route and network edge IDs.'
292
293
def update_netoffset(self, deltaoffset):
294
"""
295
Called when network offset has changed.
296
Children may need to adjust theur coordinates.
297
"""
298
self.landuse.update_netoffset(deltaoffset)
299
self.demand.update_netoffset(deltaoffset)
300
301
302
if __name__ == '__main__':
303
###############################################################################
304
# print 'sys.path',sys.path
305
from agilepy.lib_wx.objpanel import objbrowser
306
from agilepy.lib_base.logger import Logger
307
if len(sys.argv) == 3:
308
rootname = sys.argv[1]
309
dirpath = sys.argv[2]
310
else:
311
rootname = 'facsp2'
312
dirpath = os.path.join(os.path.dirname(__file__), '..', 'network', 'testnet')
313
314
scenario = Scenario(rootname, workdirpath=dirpath, logger=Logger())
315
316
# net.import_nodes(os.path.join('test','facsp2.nod.xml'))
317
# net.import_edges(os.path.join('test','facsp2.edg.xml'))
318
objbrowser(scenario)
319
320