Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/tools/contributed/sumopy/coremodules/demand/demandbase.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 demandbase.py
16
# @author Joerg Schweizer
17
# @date 2012
18
19
20
import numpy as np
21
from xml.sax import saxutils, parse, handler
22
import agilepy.lib_base.classman as cm
23
import agilepy.lib_base.arrayman as am
24
import agilepy.lib_base.xmlman as xm
25
from agilepy.lib_base.misc import random_choice, get_inversemap, dict_to_str
26
27
OPTIONMAP_POS_DEPARTURE = {"random": -1, "free": -2,
28
"random_free": -3, "base": -4, "last": -5, "first": -6}
29
OPTIONMAP_POS_ARRIVAL = {"random": -1, "max": -2}
30
OPTIONMAP_SPEED_DEPARTURE = {"random": -1, "max": -2}
31
OPTIONMAP_SPEED_ARRIVAL = {"current": -1}
32
33
OPTIONMAP_LANE_DEPART = {"random": -1, "free": -2,
34
"allowed": -3, "best": -4, "first": -5}
35
36
OPTIONMAP_LANE_ARRIVAL = {"current": -1}
37
38
39
class TripoptionMixin:
40
"""
41
Class mixin wich defines some trip options.
42
To be used with different processes.
43
"""
44
45
def add_posoptions(self):
46
attrsman = self.get_attrsman()
47
48
self.add_option('pos_depart', OPTIONMAP_POS_DEPARTURE['base'],
49
groupnames=['options'],
50
cml='--departpos',
51
name='Departure position',
52
unit='m',
53
info="Departure position of vehicle.\n\nSpecial values:\n"
54
+ dict_to_str(OPTIONMAP_POS_DEPARTURE, intend=2),
55
cmlvaluemap=get_inversemap(OPTIONMAP_POS_DEPARTURE),
56
)
57
58
self.add_option('pos_arrival', OPTIONMAP_POS_ARRIVAL['max'],
59
groupnames=['options'],
60
cml='--arrivalpos',
61
name='Arival position',
62
unit='m',
63
info="Arival position of vehicle.\n\nSpecial values:\n"
64
+ dict_to_str(OPTIONMAP_POS_ARRIVAL, intend=2),
65
cmlvaluemap=get_inversemap(OPTIONMAP_POS_ARRIVAL),
66
)
67
68
def add_speedoptions(self):
69
attrsman = self.get_attrsman()
70
71
self.add_option('speed_depart', OPTIONMAP_SPEED_DEPARTURE['max'],
72
groupnames=['options'],
73
cml='--departspeed',
74
name='Departure speed',
75
unit='m/s',
76
info="Departure speed of vehicle.\n\nSpecial values:\n"
77
+ dict_to_str(OPTIONMAP_SPEED_DEPARTURE, intend=2),
78
cmlvaluemap=get_inversemap(OPTIONMAP_SPEED_DEPARTURE),
79
)
80
81
self.add_option('speed_arrival', OPTIONMAP_SPEED_ARRIVAL['current'],
82
groupnames=['options'],
83
cml='--arrivalspeed',
84
name='Arival speed',
85
unit='m/s',
86
info="Arival speed of vehicle.\n\nSpecial values:\n"
87
+ dict_to_str(OPTIONMAP_SPEED_ARRIVAL, intend=2),
88
cmlvaluemap=get_inversemap(OPTIONMAP_SPEED_ARRIVAL),
89
)
90
91
def add_laneoptions(self):
92
attrsman = self.get_attrsman()
93
94
self.add_option('ind_lane_depart', OPTIONMAP_LANE_DEPART['best'],
95
groupnames=['options'],
96
cml='--departlane',
97
name='Depart lane',
98
info="Departure lane index. 0 is rightmost lane or sidewalk, if existant.\n\nSpecial values:\n"
99
+ dict_to_str(OPTIONMAP_LANE_DEPART, intend=2),
100
cmlvaluemap=get_inversemap(OPTIONMAP_LANE_DEPART),
101
)
102
103
self.add_option('ind_lane_arrival', OPTIONMAP_LANE_ARRIVAL['current'],
104
groupnames=['options'],
105
cml='--arrivallane',
106
name='Arrival lane',
107
info="Arrival lane index. 0 is rightmost lane or sidewalk, if existant.\n\nSpecial values:\n"
108
+ dict_to_str(OPTIONMAP_LANE_ARRIVAL, intend=2),
109
cmlvaluemap=get_inversemap(OPTIONMAP_LANE_ARRIVAL),
110
)
111
112
113
class ModeShares(am.ArrayObjman):
114
"""
115
Utility table with some default mode shares.
116
"""
117
118
def __init__(self, ident, parent, modes, **kwargs):
119
120
self._init_objman(ident, parent=parent, name='Mode shares',
121
version=0.0,
122
**kwargs)
123
124
self.add_col(am.IdsArrayConf('ids_mode', modes,
125
groupnames=['parameters'],
126
name='Mode ID',
127
info='Transport Mode ID.',
128
))
129
130
self.add_col(am.ArrayConf('shares', '',
131
dtype=np.float32,
132
is_index=True,
133
groupnames=['parameters'],
134
perm='rw',
135
name='Share',
136
info='Mode share.',
137
))
138
139
# self.add_col(am.ArrayConf( 'speeds_max', 50.0/3.6,
140
# dtype = np.float32,
141
# groupnames = ['parameters'],
142
# perm='rw',
143
# name = 'Max. Speed',
144
# unit = 'm/s',
145
# info = 'Maximum possible speed for this mode. Speed is used to estimate free flow link travel times, mainly for routig purposes. Note that speeds are usully limited by the lane speed attribute',
146
# ))
147
self._init_attributes()
148
self.add_default()
149
150
def _init_attributes(self, landuse=None):
151
# self.add_col(SumoIdsConf('Activitytypes'))
152
pass
153
154
def add_share(self, mode, share):
155
modes = self.ids_mode.get_linktab()
156
return self.add_row(ids_mode=modes.get_id_from_formatted(mode),
157
shares=share)
158
159
def add_default(self):
160
"""
161
Sets the default maximum possible speed for certain modes.
162
"""
163
self.add_share("pedestrian", 0.1)
164
self.add_share("bicycle", 0.1)
165
self.add_share("motorcycle", 0.1)
166
self.add_share("passenger", 0.5)
167
self.add_share("bus", 0.2)
168
169
def get_modes_random(self, n):
170
"""
171
Return a vector with mode IDs of length n.
172
"""
173
ids = self.get_ids()
174
ids_modes_all = self.ids_mode[ids]
175
return ids_modes_all[random_choice(n, self.shares[ids])]
176
177
178
class ActivityTypes(am.ArrayObjman):
179
# https://sumo.dlr.de/docs/Networks/PlainXML.html#edge_descriptions
180
def __init__(self, ident, demand, **kwargs):
181
182
self._init_objman(ident, parent=demand, name='Activity Types',
183
version=0.0,
184
xmltag=('actTypes', 'actType', 'names'),
185
**kwargs)
186
187
self._init_attributes()
188
self.add_default()
189
190
def _init_attributes(self, landuse=None):
191
# self.add_col(SumoIdsConf('Activitytypes'))
192
193
self.add_col(am.ArrayConf('names', '',
194
dtype=np.object,
195
is_index=True,
196
groupnames=['parameters'],
197
perm='rw',
198
name='Type name',
199
info='Human readable name of activity type.',
200
))
201
202
self.add_col(am.ArrayConf('symbols', '',
203
dtype=np.object,
204
perm='rw',
205
is_index=True,
206
name='Type symbol',
207
info='Symbol of activity type name. Used to represent activity sequences.',
208
))
209
210
self.add_col(am.ArrayConf('descriptions', '',
211
dtype=np.object,
212
perm='rw',
213
name='Description',
214
info='Description of activity.',
215
))
216
217
# this works only for first init
218
# if landuse is not None:
219
self.add_col(am.IdlistsArrayConf('ids_landusetypes', self.parent.get_scenario().landuse.landusetypes,
220
name='Landuse types',
221
info="Landuse type IDs, eher this activity type can take place.",
222
))
223
224
self.add_col(am.ArrayConf('hours_begin_earliest', 0.0,
225
dtype=np.float32,
226
groupnames=['parameters'],
227
perm='rw',
228
name='Earliest hour begin',
229
unit='h',
230
info='Default value for earliest hour when this activity can begin.',
231
))
232
233
self.add_col(am.ArrayConf('hours_begin_latest', 1.0,
234
dtype=np.float32,
235
groupnames=['parameters'],
236
perm='rw',
237
name='Latest begin hour',
238
unit='h',
239
info='Default value for latest hour when this activity can begin.',
240
))
241
242
self.add_col(am.ArrayConf('durations_min', 6.0,
243
dtype=np.float32,
244
groupnames=['parameters'],
245
perm='rw',
246
name='Min. Duration',
247
unit='h',
248
info='Default value for minimum activity duration for a person within a day.',
249
))
250
251
self.add_col(am.ArrayConf('durations_max', 8.0,
252
dtype=np.float32,
253
groupnames=['parameters'],
254
perm='rw',
255
name='Max. Duration',
256
unit='h',
257
info='Default value for maximum activity duration for a person within a day.',
258
))
259
260
def format_ids(self, ids):
261
return ', '.join(self.names[ids])
262
263
def get_id_from_formatted(self, idstr):
264
return self.names.get_id_from_index(idstr)
265
266
def get_ids_from_formatted(self, idstrs):
267
return self.names.get_ids_from_indices_save(idstrs.split(','))
268
269
def get_id_from_name(self, activitytypename):
270
return self.names.get_id_from_index(activitytypename)
271
272
def get_id_from_symbol(self, activitytypesymbol):
273
return self.symbols.get_id_from_index(activitytypesymbol)
274
275
def add_default(self):
276
"""
277
Sets the default maximum possible speed for certain modes.
278
"""
279
landusetypekeys = self.parent.get_scenario().landuse.landusetypes.typekeys
280
self.add_row(names='none',
281
descriptions='None activity type. Will be skipped when planning.',
282
ids_landusetypes=landusetypekeys.get_ids_from_indices([]),
283
symbols='n',
284
hours_begin_earliest=0.0,
285
hours_begin_latest=0.0,
286
durations_min=0.0,
287
durations_max=0.0,
288
)
289
290
self.add_row(names='home',
291
descriptions='General home activity, like sleeping, eating, watching TV, etc.',
292
ids_landusetypes=landusetypekeys.get_ids_from_indices(
293
['residential', 'mixed']),
294
symbols='h',
295
hours_begin_earliest=-1.0,
296
hours_begin_latest=-1.0,
297
durations_min=7.0,
298
durations_max=8.0,
299
)
300
301
self.add_row(names='work',
302
descriptions="""Work activity, for example work in
303
industry, offices or as employee at
304
educational facilities.""",
305
ids_landusetypes=landusetypekeys.get_ids_from_indices(
306
['industrial', 'commercial', 'education', 'mixed']),
307
symbols='w',
308
hours_begin_earliest=8.5,
309
hours_begin_latest=9.0,
310
durations_min=6.0,
311
durations_max=9.0,
312
)
313
314
self.add_row(names='education',
315
descriptions='Education activity, for example visiting courses at schools or at universities.',
316
ids_landusetypes=landusetypekeys.get_ids_from_indices(
317
['education', ]),
318
symbols='e',
319
hours_begin_earliest=8.0,
320
hours_begin_latest=10.0,
321
durations_min=4.0,
322
durations_max=6.0,
323
)
324
325
self.add_row(names='shopping',
326
descriptions='Shopping activity',
327
ids_landusetypes=landusetypekeys.get_ids_from_indices(
328
['commercial', 'mixed']),
329
symbols='s',
330
hours_begin_earliest=16.0,
331
hours_begin_latest=19.0,
332
durations_min=0.2,
333
durations_max=2.0,
334
)
335
336
self.add_row(names='leisure',
337
descriptions='Leisure activity',
338
ids_landusetypes=landusetypekeys.get_ids_from_indices(
339
['leisure', 'mixed']),
340
symbols='l',
341
hours_begin_earliest=12.0,
342
hours_begin_latest=15.0,
343
durations_min=1.0,
344
durations_max=3.0,
345
)
346
347
348
class DemandobjMixin:
349
def export_trips_xml(self, filepath=None, encoding='UTF-8',
350
ids_vtype_exclude=[], **kwargs):
351
"""
352
Export trips to SUMO xml file.
353
Method takes care of sorting trips by departure time.
354
"""
355
return False
356
357
def get_writexmlinfo(self, is_route=False, **kwargs):
358
"""
359
Returns three array where the first array is the
360
begin time of the first vehicle and the second array is the
361
write function to be called for the respectice vehicle and
362
the third array contains the vehicle ids
363
364
Method used to sort trips when exporting to route or trip xml file
365
"""
366
return [], [], []
367
368
def config_results(self, results):
369
# tripresults = res.Tripresults( 'tripresults', results,
370
# self,
371
# self.get_net().edges
372
# )
373
#
374
#
375
#results.add_resultobj(tripresults, groupnames = ['Trip results'])
376
pass
377
378
def process_results(self, results, process=None):
379
pass
380
381
def get_time_depart_first(self):
382
return np.inf
383
384
def get_time_depart_last(self):
385
return 0.0
386
387
def import_routes_xml(self, routefilepath, **kwargs):
388
"""
389
Import routes from filepath an store them somwhere.
390
Demand object specific.
391
"""
392
393
pass
394
395
396
class TripCounter(handler.ContentHandler):
397
"""Parses a SUMO route XML file and counts trips."""
398
399
def __init__(self):
400
self.n_trip = 0
401
402
def startElement(self, name, attrs):
403
# print 'startElement',name,self.n_trip
404
if name == 'trip':
405
self.n_trip += 1
406
407
408
class TripReader(handler.ContentHandler):
409
"""Reads trips from trip or route file into trip table"""
410
411
def __init__(self, trips, n_trip, vtype_default=None):
412
# print 'RouteReader.__init__',demand.ident
413
self._trips = trips
414
demand = trips.parent
415
416
net = demand.get_scenario().net
417
418
self._ids_vtype_sumo = demand.vtypes.ids_sumo
419
self._modemap = net.modes.names.get_indexmap()
420
self._get_vtype_for_mode = demand.vtypes.get_vtype_for_mode
421
422
if id_vtype_default is None:
423
self._id_vtype_default = self.get_ids()[0]
424
else:
425
self._id_vtype_default = id_vtype_default
426
427
self._ids_edge_sumo = net.edges.ids_sumo
428
429
self.ids_sumo = np.zeros(n_trip, np.object)
430
self.ids_vtype = np.zeros(n_trip, np.int32)
431
self.times_depart = np.zeros(n_trip, np.int32)
432
self.ids_edge_depart = np.zeros(n_trip, np.int32)
433
self.ids_edge_arrival = np.zeros(n_trip, np.int32)
434
self.inds_lane_depart = np.zeros(n_trip, np.int32)
435
self.positions_depart = np.zeros(n_trip, np.float32)
436
self.speeds_depart = np.zeros(n_trip, np.float32)
437
self.inds_lane_arrival = np.zeros(n_trip, np.int32)
438
self.positions_arrival = np.zeros(n_trip, np.float32)
439
self.speeds_arrival = np.zeros(n_trip, np.float32)
440
self.routes = np.zeros(n_trip, np.object)
441
442
self._ind_trip = -1
443
444
self._has_routes = False
445
self._ids_sumoedge_current = []
446
self._id_sumoveh_current = None
447
#self._time_depart = 0
448
#self._attrs = {}
449
#self._is_generate_ids = is_generate_ids
450
self._intervals_current = ''
451
452
# def _init_reader(self):
453
454
def _get_id_vtype(self, attrs):
455
vtype = str(attrs['type'])
456
if self._ids_vtype_sumo.has_index(vtype):
457
# vtype is known
458
return self._ids_vtype_sumo.get_id_from_index(vtype)
459
460
# vtype is not known, so check out whether vtype
461
# is actually a mode
462
elif vtype in self._modemap:
463
# pick id_vtype according to its probability with
464
# all vtypes of this mode
465
id_vtype = self._get_vtype_for_mode(self._modemap[vtype])
466
467
if id_vtype >= 0:
468
return id_vtype
469
else:
470
return self._id_vtype_default
471
472
else:
473
# no valid vtype, get a default
474
return self._id_vtype_default
475
476
def startElement(self, name, attrs):
477
# <vehicle id="3_21" type="bus" depart="2520.00">
478
# <route edges="bottom1to1/0 1/0to0/0 0/0tobottom0"/>
479
# </vehicle>
480
# print 'startElement',name
481
if name == 'trip':
482
# print ' startElement',attrs['id'],attrs['depart']
483
self._ind_trip += 1
484
485
self._id_sumoveh_current = attrs['id']
486
self.ids_sumo[self._ind_trip] = self._id_sumoveh_current
487
# print 'startElement ids_vtype',attrs['type'], self._ids_vtype_sumo.get_id_from_index(str(attrs['type']))
488
489
self.ids_vtype[self._ind_trip] = self._get_id_vtype(attrs)
490
self.times_depart[self._ind_trip] = int(float(attrs['depart']))
491
492
if attrs.has_key('from'):
493
self.ids_edge_depart[self._ind_trip] = self._ids_edge_sumo.get_id_from_index(str(attrs['from']))
494
if attrs.has_key('to'):
495
self.ids_edge_arrival[self._ind_trip] = self._ids_edge_sumo.get_id_from_index(str(attrs['to']))
496
497
ind_lane_depart_raw = attrs.get('departLane', 'free')
498
if OPTIONMAP_LANE_DEPART.has_key(ind_lane_depart_raw):
499
self.inds_lane_depart[self._ind_trip] = OPTIONMAP_LANE_DEPART[ind_lane_depart_raw]
500
else:
501
self.inds_lane_depart[self._ind_trip] = int(ind_lane_depart_raw)
502
503
positions_depart_raw = attrs.get('departPos', 'base')
504
if OPTIONMAP_POS_DEPARTURE.has_key(positions_depart_raw):
505
self.positions_depart[self._ind_trip] = OPTIONMAP_POS_DEPARTURE[positions_depart_raw]
506
else:
507
self.positions_depart[self._ind_trip] = float(positions_depart_raw)
508
509
self.speeds_depart[self._ind_trip] = attrs.get('departSpeed', 0.0)
510
511
ind_lane_arrival_raw = attrs.get('arrivalLane', 'current')
512
if OPTIONMAP_LANE_ARRIVAL.has_key(ind_lane_arrival_raw):
513
self.inds_lane_arrival[self._ind_trip] = OPTIONMAP_LANE_ARRIVAL[ind_lane_arrival_raw]
514
else:
515
self.inds_lane_arrival[self._ind_trip] = int(ind_lane_arrival_raw)
516
517
positions_arrival_raw = attrs.get('arrivalPos', 'max')
518
if OPTIONMAP_POS_ARRIVAL.has_key(positions_arrival_raw):
519
self.positions_arrival[self._ind_trip] = OPTIONMAP_POS_ARRIVAL[positions_arrival_raw]
520
else:
521
self.positions_arrival[self._ind_trip] = float(positions_arrival_raw)
522
523
self.speeds_arrival[self._ind_trip] = attrs.get('arrivalSpeed', 0.0)
524
525
def _get_kwargs(self):
526
return {'ids_sumo': self.ids_sumo,
527
'times_depart': self.times_depart,
528
'ids_edge_depart': self.ids_edge_depart,
529
'ids_edge_arrival': self.ids_edge_arrival,
530
'inds_lane_depart': self.inds_lane_depart,
531
'positions_depart': self.positions_depart,
532
'speeds_depart': self.speeds_depart,
533
'inds_lane_arrival': self.inds_lane_arrival,
534
'positions_arrival': self.positions_arrival,
535
'speeds_arrival': self.speeds_arrival,
536
}
537
538
def insert_trips(self, is_generate_ids=True):
539
540
# print 'TripReader.insert_trips self.ids_vtype',self.ids_vtype
541
kwargs = self._get_kwargs()
542
ids_trips = self._trips.make_trips(self.ids_vtype,
543
is_generate_ids=is_generate_ids,
544
**kwargs)
545
546
return ids_trips
547
548
549
class RouteCounter(handler.ContentHandler):
550
"""Parses a SUMO route XML file and counts trips."""
551
552
def __init__(self):
553
self.n_veh = 0
554
self.n_pers = 0
555
#self.n_rou = 0
556
557
def startElement(self, name, attrs):
558
# print 'startElement',name,self.n_trip
559
if name == 'vehicle':
560
self.n_veh += 1
561
elif name == 'person':
562
self.n_pers += 1
563
# elif name == 'route':
564
# if attrs.has_key('id'):
565
# self.n_rou += 1
566
567
568
class RouteReader(TripReader):
569
"""Reads trips from trip or route file into trip table"""
570
571
def __init__(self, trips, counter):
572
# print 'RouteReader.__init__',demand.ident
573
self._trips = trips
574
n_veh = counter.n_veh
575
n_per = counter.n_pers
576
#n_rou = counter.n_rou
577
n_trip = n_veh+n_per
578
demand = trips.parent
579
580
net = demand.get_scenario().net
581
self._modemap = net.modes.names.get_indexmap()
582
self._get_vtype_for_mode = demand.vtypes.get_vtype_for_mode
583
584
self._ids_vtype_sumo = demand.vtypes.ids_sumo
585
self._ids_edge_sumo = net.edges.ids_sumo
586
587
self.ids_sumo = np.zeros(n_trip, np.object)
588
self.ids_sumo[:] = ''
589
self.ids_vtype = np.zeros(n_trip, np.int32)
590
self.times_depart = np.zeros(n_trip, np.int32)
591
self.times_arrival = np.zeros(n_trip, np.int32)
592
self.type = np.zeros(n_trip, np.object)
593
self.ids_edge_depart = np.zeros(n_trip, np.int32)
594
self.ids_edge_arrival = np.zeros(n_trip, np.int32)
595
self.inds_lane_depart = np.zeros(n_trip, np.int32)
596
self.positions_depart = np.zeros(n_trip, np.float32)
597
self.speeds_depart = np.zeros(n_trip, np.float32)
598
self.inds_lane_arrival = np.zeros(n_trip, np.int32)
599
self.positions_arrival = np.zeros(n_trip, np.float32)
600
self.speeds_arrival = np.zeros(n_trip, np.float32)
601
self.routes = np.zeros(n_trip, np.object)
602
603
self._ind_trip = -1
604
605
self._has_routes = False
606
self._ids_sumoedge_current = []
607
self._id_sumoveh_current = None
608
#self._time_depart = 0
609
#self._attrs = {}
610
#self._is_generate_ids = is_generate_ids
611
self._intervals_current = ''
612
613
def startElement(self, name, attrs):
614
# <vehicle id="3_21" type="bus" depart="2520.00">
615
# <route edges="bottom1to1/0 1/0to0/0 0/0tobottom0"/>
616
# </vehicle>
617
# print 'startElement',name
618
if name == 'vehicle':
619
# print ' startElement',attrs['id'],attrs['depart']
620
self._ind_trip += 1
621
622
self._id_sumoveh_current = attrs['id']
623
self.ids_sumo[self._ind_trip] = self._id_sumoveh_current
624
# print 'startElement ids_vtype',attrs['type'], self._ids_vtype_sumo.get_id_from_index(str(attrs['type']))
625
626
self.ids_vtype[self._ind_trip] = self.ids_vtype[self._ind_trip] = self._get_id_vtype(attrs)
627
628
self.times_depart[self._ind_trip] = int(float(attrs['depart']))
629
if attrs.has_key('arrival'):
630
self.times_arrival[self._ind_trip] = int(float(attrs['arrival']))
631
else:
632
# duarouter is not calculating arrival time in results!
633
self.times_arrival[self._ind_trip] = 0.0
634
635
self.type[self._ind_trip] = attrs['type']
636
if attrs.has_key('from'):
637
self.ids_edge_depart[self._ind_trip] = self._ids_edge_sumo.get_id_from_index(str(attrs['from']))
638
if attrs.has_key('to'):
639
self.ids_edge_arrival[self._ind_trip] = self._ids_edge_sumo.get_id_from_index(str(attrs['to']))
640
641
ind_lane_depart_raw = attrs.get('departLane', 'free')
642
if OPTIONMAP_LANE_DEPART.has_key(ind_lane_depart_raw):
643
self.inds_lane_depart[self._ind_trip] = OPTIONMAP_LANE_DEPART[ind_lane_depart_raw]
644
else:
645
self.inds_lane_depart[self._ind_trip] = int(ind_lane_depart_raw)
646
647
positions_depart_raw = attrs.get('departPos', 'base')
648
if OPTIONMAP_POS_DEPARTURE.has_key(positions_depart_raw):
649
self.positions_depart[self._ind_trip] = OPTIONMAP_POS_DEPARTURE[positions_depart_raw]
650
else:
651
self.positions_depart[self._ind_trip] = float(positions_depart_raw)
652
653
speed_depart_raw = attrs.get('departSpeed', 'max')
654
if OPTIONMAP_SPEED_DEPARTURE.has_key(speed_depart_raw):
655
self.speeds_depart[self._ind_trip] = OPTIONMAP_SPEED_DEPARTURE[speed_depart_raw]
656
else:
657
self.speeds_depart[self._ind_trip] = float(speed_depart_raw)
658
659
ind_lane_arrival_raw = attrs.get('arrivalLane', 'current')
660
if OPTIONMAP_LANE_ARRIVAL.has_key(ind_lane_arrival_raw):
661
self.inds_lane_arrival[self._ind_trip] = OPTIONMAP_LANE_ARRIVAL[ind_lane_arrival_raw]
662
else:
663
self.inds_lane_arrival[self._ind_trip] = int(ind_lane_arrival_raw)
664
665
positions_arrival_raw = attrs.get('arrivalPos', 'max')
666
if OPTIONMAP_POS_ARRIVAL.has_key(positions_arrival_raw):
667
self.positions_arrival[self._ind_trip] = OPTIONMAP_POS_ARRIVAL[positions_arrival_raw]
668
else:
669
self.positions_arrival[self._ind_trip] = float(positions_arrival_raw)
670
671
speed_arrival_raw = attrs.get('arrivalSpeed', 'current')
672
if OPTIONMAP_SPEED_ARRIVAL.has_key(speed_arrival_raw):
673
self.speeds_arrival[self._ind_trip] = OPTIONMAP_SPEED_ARRIVAL[speed_arrival_raw]
674
else:
675
self.speeds_arrival[self._ind_trip] = float(speed_arrival_raw)
676
677
if name == 'route':
678
self._has_routes = True
679
# print ' ',attrs.get('edges', '')
680
self._ids_sumoedge_current = attrs.get('edges', '')
681
self._intervals_current = attrs.get('intervals', '')
682
683
# def characters(self, content):
684
# if (len(self._route_current)>0)&(self._intervals_current!=''):
685
# self._intervals_current = self._intervals_current + content
686
687
def endElement(self, name):
688
689
if name == 'vehicle':
690
# print 'endElement',name,self._id_current,len(self._intervals_current)
691
if (self._id_sumoveh_current is not None):
692
ids_edge = []
693
for id_sumoedge in self._ids_sumoedge_current.split(' '):
694
if not id_sumoedge in ('', ' ', ','):
695
if self._ids_edge_sumo.has_index(id_sumoedge):
696
ids_edge.append(self._ids_edge_sumo.get_id_from_index(id_sumoedge.strip()))
697
self.routes[self._ind_trip] = ids_edge
698
699
if len(ids_edge) >= 1:
700
self.ids_edge_depart[self._ind_trip] = ids_edge[0]
701
self.ids_edge_arrival[self._ind_trip] = ids_edge[-1]
702
703
self._id_sumoveh_current = None
704
#self._attrs = {}
705
self._ids_sumoedge_current = []
706
707
# elif name in ['routes','trips']:
708
# self.make_trips()
709
710
def process_intervals(self):
711
interval = []
712
es = self._intervals_current.rstrip().split(" ")
713
for e in es:
714
p = e.split(",")
715
interval.append((float(p[0]), float(p[1])))
716
self._intervals_current = ''
717
return interval
718
719
def _get_kwargs(self, inds=None):
720
if inds is None:
721
inds = np.arange(len(self.ids_sumo))
722
return {'ids_sumo': self.ids_sumo[inds],
723
'times_depart': self.times_depart[inds],
724
'times_arrival': self.times_arrival[inds],
725
'type': self.type[inds],
726
'ids_edge_depart': self.ids_edge_depart[inds],
727
'ids_edge_arrival': self.ids_edge_arrival[inds],
728
'inds_lane_depart': self.inds_lane_depart[inds],
729
'positions_depart': self.positions_depart[inds],
730
'speeds_depart': self.speeds_depart[inds],
731
'inds_lane_arrival': self.inds_lane_arrival[inds],
732
'positions_arrival': self.positions_arrival[inds],
733
'speeds_arrival': self.speeds_arrival[inds],
734
'ids_edges': self.routes[inds]
735
}
736
737
def insert_routes(self, is_generate_ids=True, is_add=False, is_overwrite_only=False):
738
print 'TripReader.make_routes is_generate_ids', is_generate_ids, 'is_add', is_add, 'is_overwrite_only', is_overwrite_only
739
740
# self._trips is scenario trip database
741
# self.ids_sumo is a list of SUMO IDs read from xml file
742
743
if is_overwrite_only & (not is_add):
744
is_generate_ids = False
745
is_add = False
746
# get trip ids from xml file
747
# ony import routes ids from existing sumo ids
748
749
# this is index of self.ids_sumo to be overwritten
750
inds = np.flatnonzero(np.array(self._trips.ids_sumo.has_indices(self.ids_sumo)))
751
# print ' overwrite trip ids_sumo',self.ids_sumo[inds]
752
753
ids_trip = np.array(self._trips.ids_sumo.get_ids_from_indices(self.ids_sumo[inds]), dtype=np.int32)
754
# print ' ids_trip',ids_trip
755
# print 'n_trips',len(ids_trip)
756
757
ids_routes, ids_trip = self._trips.make_routes(self.ids_vtype[inds],
758
# is_generate_ids = is_generate_ids,# depricated
759
routes=self.routes[inds],
760
ids_trip=ids_trip,
761
is_add=is_add,
762
**self._get_kwargs(inds=inds)
763
)
764
# print ' ids_routes',ids_routes
765
766
else:
767
if is_add:
768
#is_generate_ids = False
769
# get trip ids from xml file
770
771
inds = np.flatnonzero(self.ids_sumo != '') # ony import routes from specified sumo ids
772
# print ' self.ids_sumo',self.ids_sumo[inds]
773
# print ' inds',inds
774
ids_trip = np.array(self._trips.ids_sumo.get_ids_from_indices_save(self.ids_sumo[inds]), dtype=np.int32)
775
inds_valid = np.array(ids_trip, dtype=np.int32) > -1
776
777
ids_routes, ids_trip = self._trips.make_routes(self.ids_vtype[inds[inds_valid]],
778
# is_generate_ids = is_generate_ids,# depricated
779
routes=self.routes[inds[inds_valid]],
780
ids_trip=ids_trip[inds_valid],
781
is_add=is_add,
782
**self._get_kwargs(inds=inds[inds_valid])
783
)
784
785
if (not is_add) & is_generate_ids:
786
inds = np.arange(len(self.routes))
787
ids_trip = None
788
789
# print ' ids_trip',ids_trip
790
ids_routes, ids_trip = self._trips.make_routes(self.ids_vtype[inds],
791
is_generate_ids=is_generate_ids,
792
routes=self.routes[inds],
793
ids_trip=ids_trip,
794
is_add=is_add,
795
**self._get_kwargs(inds=inds)
796
)
797
798
return ids_routes, ids_trip
799
800
# def get_data(self):
801
# values = {'ids_sumo': {}, 'times_depart': {},'ids_edge_depart': {},'ids_edge_arrival': {},\
802
# 'inds_lane_depart': {},'positions_depart': {},'speeds_depart': {},'inds_lane_arrival': {},\
803
# 'positions_arrival': {},'speeds_arrival' : {}, 'ids_edges' : {}}
804
# attrnames = ['ids_sumo', 'times_depart','ids_edge_depart','ids_edge_arrival',\
805
# 'inds_lane_depart','positions_depart','speeds_depart','inds_lane_arrival',\
806
# 'positions_arrival','speeds_arrival', 'ids_edges' ]
807
# valuess = [self.ids_sumo,
808
# self.times_depart,
809
# self.ids_edge_depart,
810
# self.ids_edge_arrival,
811
# self.inds_lane_depart,
812
# self.positions_depart,
813
# self.speeds_depart,
814
# self.inds_lane_arrival,
815
# self.positions_arrival,
816
# self.speeds_arrival,
817
# self.routes
818
# ]
819
# for attrname, value in zip(attrnames, valuess):
820
# print attrname
821
# print values
822
# for id_elem , val in zip(self.get_ids(), value):
823
## values[attrname][id_elem] = (val,1)
824
# return values
825
##
826
827
# def get_ids(self):
828
# return range(len(self.ids_sumo[(self.ids_sumo!='')])+1)[1:]
829
830