Path: blob/main/tools/contributed/sumopy/coremodules/demand/demand.py
169689 views
# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo1# Copyright (C) 2016-2025 German Aerospace Center (DLR) and others.2# SUMOPy module3# Copyright (C) 2012-2021 University of Bologna - DICAM4# This program and the accompanying materials are made available under the5# terms of the Eclipse Public License 2.0 which is available at6# https://www.eclipse.org/legal/epl-2.0/7# This Source Code may also be made available under the following Secondary8# Licenses when the conditions for such availability set forth in the Eclipse9# Public License 2.0 are satisfied: GNU General Public License, version 210# or later which is available at11# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html12# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later1314# @file demand.py15# @author Joerg Schweizer16# @date 20121718import detectorflows19import turnflows20import virtualpop21import origin_to_destination22import vehicles23from coremodules.network.network import SumoIdsConf, MODES24from demandbase import *25import publictransportservices as pt26from coremodules.simulation import results as res27from coremodules.network import routing28from agilepy.lib_base.processes import Process29from agilepy.lib_base.misc import get_inversemap30import agilepy.lib_base.xmlman as xm31import agilepy.lib_base.arrayman as am32import agilepy.lib_base.classman as cm33import numpy as np34from coremodules.modules_common import *35import os36import sys37import time383940if __name__ == '__main__':41try:42APPDIR = os.path.dirname(os.path.abspath(__file__))43except:44APPDIR = os.path.dirname(os.path.abspath(sys.argv[0]))45SUMOPYDIR = os.path.join(APPDIR, '..', '..')46sys.path.append(SUMOPYDIR)474849# Trip depart and arrival options, see50# https://sumo.dlr.de/docs/Definition_of_Vehicles%2C_Vehicle_Types%2C_and_Routes.html#a_vehicles_depart_and_arrival_parameter515253#from agilepy.lib_base.geometry import find_area54#from agilepy.lib_base.processes import Process,CmlMixin,ff,call555657try:58try:59import pyproj60is_pyproj = True61except:62from mpl_toolkits.basemap import pyproj63is_pyproj = True6465except:66is_pyproj = False676869class Demand(cm.BaseObjman):70def __init__(self, scenario=None, net=None, zones=None, name='Demand', info='Transport demand', **kwargs):71print 'Demand.__init__', name, kwargs7273# we need a network from somewhere74if net is None:75net = scenario.net76zones = scenario.landuse.zones7778self._init_objman(ident='demand', parent=scenario, name=name, info=info, **kwargs)79attrsman = self.set_attrsman(cm.Attrsman(self))8081self.vtypes = attrsman.add(cm.ObjConf(vehicles.VehicleTypes(self, net)))8283self.activitytypes = attrsman.add(cm.ObjConf(ActivityTypes('activitytypes', self)))8485self.trips = attrsman.add(cm.ObjConf(Trips(self, net), groupnames=['demand objects']))8687self.odintervals = attrsman.add(cm.ObjConf(88origin_to_destination.OdIntervals('odintervals', self, net, zones),89))9091self.turnflows = attrsman.add(cm.ObjConf(turnflows.Turnflows('turnflows', self, net),92))93self._init_attributes()94self._init_constants()9596def _init_attributes(self):97attrsman = self.get_attrsman()9899scenario = self.parent100print 'Demand._init_attributes', scenario101102if scenario is not None:103self.detectorflows = attrsman.add(cm.ObjConf(detectorflows.Detectorflows('detectorflows', self),104))105106self.ptlines = attrsman.add(cm.ObjConf(pt.PtLines('ptlines', self),107groupnames=['demand objects'])108)109self.virtualpop = attrsman.add(cm.ObjConf(virtualpop.Virtualpopulation('virtualpop', self),110groupnames=['demand objects'])111)112# if hasattr(self,'virtualpolulation'):113# #Virtualpolulation114# self.delete('virtualpolulation')115116# update117118# if hasattr(self,'trips'):119#attrsman.trips.add_groupnames(['demand objects'])120121# if hasattr(self,'ptlines'):122#attrsman.ptlines.add_groupnames(['demand objects'])123124# if hasattr(self,'virtualpop'):125#attrsman.virtualpop.add_groupnames(['demand objects'])126# print attrsman.get_127128def _init_constants(self):129self._xmltag_routes = "routes"130self._xmltag_trips = "trips"131#self._demandobjects = set([self.trips, self.ptlines, self.virtualpop])132133def get_vtypes(self):134return self.vtypes135136def get_scenario(self):137return self.parent138139def get_net(self):140return self.parent.net141142def get_tripfilepath(self):143return self.get_scenario().get_rootfilepath()+'.trip.xml'144145def get_routefilepath(self):146return self.get_scenario().get_rootfilepath()+'.rou.xml'147148def update_netoffset(self, deltaoffset):149"""150Called when network offset has changed.151Children may need to adjust their coordinates.152"""153# self.odintervals.update_netoffset(deltaoffset)154pass155156def add_demandobject(self, obj=None, ident=None, DemandClass=None, **kwargs):157if obj is not None:158ident = obj.get_ident()159160if not hasattr(self, ident):161if obj is None:162# make demandobject a child of demand163164# if ident is None:165# ident = obj.get_ident()166obj = DemandClass(ident, self, **kwargs)167is_child = True168#is_save = True169else:170# link to simobject, which must be a child of another object171is_child = False # will not be saved but linked172#is_save = False173174attrsman = self.get_attrsman()175176attrsman.add(cm.ObjConf(obj,177groupnames=['demand objects'],178is_child=is_child,179#is_save = is_save,180))181182setattr(self, ident, obj)183184return getattr(self, ident)185186def get_demandobjects(self):187#demandobjects = set([])188# for ident, conf in self.get_group_attrs('').iteritems():189# demandobjects.add(conf.get_value())190demandobjects_clean = []191for attrname, demandobject in self.get_attrsman().get_group_attrs('demand objects').iteritems():192if demandobject is not None:193demandobjects_clean.append(demandobject)194else:195print 'WARNING in get_demandobjects: found None as object', attrname196self.get_attrsman().delete(attrname)197return demandobjects_clean198199def get_time_depart_first(self):200# print 'get_time_depart_first'201time = 10**10202for obj in self.get_demandobjects():203# print ' obj',obj.ident,obj.get_time_depart_first()204time = min(time, obj.get_time_depart_first())205return time206207def get_time_depart_last(self):208time = 0209for obj in self.get_demandobjects():210time = max(time, obj.get_time_depart_last())211return time212213def remove_demandobject(self, demandobject):214# self._demandobjects.discard(demandobject)215self.get_attrsman().delete(demandobject.ident)216217def import_routes_xml(self, filepath=None, demandobjects=None,218is_clear_trips=False, is_generate_ids=False,219is_overwrite_only=True):220221if demandobjects is None:222demandobjects = self.get_demandobjects()223224# is_route = True # add edge ids, if available225226if filepath is None:227filepath = self.get_routefilepath()228print 'import_routes_xml', filepath, demandobjects229try:230fd = open(filepath, 'r')231except:232print 'WARNING in import_routes_xml: could not open', filepath233return False234235for demandobj in demandobjects:236print ' try to import routes from demandobj', demandobj237demandobj.import_routes_xml(filepath,238is_clear_trips=is_clear_trips,239is_generate_ids=is_generate_ids,240is_overwrite_only=is_overwrite_only)241242return True243244def export_routes_xml(self, filepath=None, encoding='UTF-8',245demandobjects=None, is_route=True,246vtypeattrs_excluded=[],247is_plain=False,248is_exclude_pedestrians=False,):249"""250Export routes available from the demand to SUMO xml file.251Method takes care of sorting trips by departure time.252"""253254if demandobjects is None:255demandobjects = self.get_demandobjects()256257# is_route = True # add edge ids, if available258259if filepath is None:260filepath = self.get_routefilepath()261print 'export_routes_xml', filepath, demandobjects262try:263fd = open(filepath, 'w')264except:265print 'WARNING in export_routes_xml: could not open', filepath266return False267268fd.write('<?xml version="1.0" encoding="%s"?>\n' % encoding)269fd.write(xm.begin(self._xmltag_routes))270indent = 2271272times_begin = np.zeros((0), dtype=np.int32)273writefuncs = np.zeros((0), dtype=np.object)274ids_trip = [] # use list here to accomodate different id stuctures275#ids_trip =np.zeros((0),dtype = np.int32)276277ids_vtype = set()278for exportobj in demandobjects:279print ' exportobj', exportobj280times, funcs, ids = exportobj.get_writexmlinfo(is_route=is_route,281is_plain=is_plain,282is_exclude_pedestrians=is_exclude_pedestrians)283print ' n_trips', len(times), 'has vtypes', hasattr(exportobj, 'get_vtypes')284if len(times) > 0:285times_begin = np.concatenate((times_begin, times), 0)286writefuncs = np.concatenate((writefuncs, funcs), 0)287#ids_trip = np.concatenate((ids_trip, ids),0)288ids_trip = ids_trip + list(ids)289if hasattr(exportobj, 'get_vtypes'):290# TODO:all export objects have get_vtypes except mapmatching291ids_vtype.update(exportobj.get_vtypes())292293# convert back to array to allow proper indexing294ids_trip = np.array(ids_trip, dtype=np.object)295296attrconfigs_excluded = []297for attrname in vtypeattrs_excluded:298attrconfigs_excluded.append(self.vtypes.get_config(attrname))299300self.vtypes.write_xml(fd, indent=indent,301ids=ids_vtype,302is_print_begin_end=False,303attrconfigs_excluded=attrconfigs_excluded,304)305306# sort trips307inds_trip = np.argsort(times_begin)308309#time0 = times_begin[inds_trip[0]]310# write trips311for writefunc, id_trip, time_begin in zip(312writefuncs[inds_trip],313ids_trip[inds_trip],314times_begin[inds_trip]):315316writefunc(fd, id_trip, time_begin, indent)317318fd.write(xm.end(self._xmltag_routes))319fd.close()320return filepath321322def import_xml(self, rootname, dirname=''):323"""324Import trips and/or routes, if available.325"""326327filepath = os.path.join(dirname, rootname+'.trip.xml')328if os.path.isfile(filepath):329# import trips330self.trips.import_trips_xml(filepath, is_generate_ids=False)331332# now try to add routes to existing trips333filepath = os.path.join(dirname, rootname+'.rou.xml')334if os.path.isfile(filepath):335self.trips.import_routes_xml(filepath, is_generate_ids=False, is_add=True)336337else:338self.get_logger().w('import_xml: files not found:'+filepath, key='message')339340else:341self.get_logger().w('import_xml: files not found:'+filepath, key='message')342343# no trip file exists, but maybe just a route file with trips344filepath = os.path.join(dirname, rootname+'.rou.xml')345if os.path.isfile(filepath):346self.trips.import_routes_xml(filepath, is_generate_ids=False, is_add=False)347348else:349self.get_logger().w('import_xml: files not found:'+filepath, key='message')350351352class Routes(am.ArrayObjman):353def __init__(self, ident, trips, net, **kwargs):354355self._init_objman(ident=ident,356parent=trips,357name='Routes',358info='Table with route info.',359xmltag=('routes', 'route', None),360**kwargs)361362#self.add_col(SumoIdsConf('Route', xmltag = 'id'))363364self.add_col(am.IdsArrayConf('ids_trip', trips,365groupnames=['state'],366name='Trip ID',367info='Route for this trip ID.',368))369370self.add_col(am.IdlistsArrayConf('ids_edges', net.edges,371name='Edge IDs',372info='List of edge IDs constituting the route.',373xmltag='edges',374))375376self.add_col(am.ArrayConf('costs', 0.0,377dtype=np.float32,378perm='r',379name='Costs',380info="Route costs.",381xmltag='cost',382))383384self.add_col(am.ArrayConf('probabilities', 1.0,385dtype=np.float32,386perm='r',387name='Probab.',388info="Route route choice probability.",389xmltag='probability',390))391392self.add_col(am.ArrayConf('colors', np.ones(4, np.float32),393dtype=np.float32,394metatype='color',395perm='rw',396name='Color',397info="Route color. Color as RGBA tuple with values from 0.0 to 1.0",398xmltag='color',399))400401def clear_routes(self):402self.clear()403404def get_shapes(self, ids=None):405if ids is None:406ids = self.get_ids()407n = len(ids)408edges = self.ids_edges.get_linktab()409shapes = np.zeros(n, dtype=np.object)410i = 0411# TODO: if edge shapes were a list, the following would be possible:412# np.sum(shapes)413for ids_edge in self.ids_edges[ids]:414routeshape = []415# print ' ids_edge',ids_edge416for shape in edges.shapes[ids_edge]:417# print ' routeshape',routeshape418# print ' shape',shape,type(shape)419routeshape += list(shape)420shapes[i] = routeshape421i += 1422423return shapes424425426class Trips(DemandobjMixin, am.ArrayObjman):427def __init__(self, demand, net=None, **kwargs):428# print 'Trips.__init__'429self._init_objman(ident='trips',430parent=demand,431name='Trips',432info='Table with trip and route info.',433xmltag=('trips', 'trip', 'ids_sumo'),434version=0.2,435**kwargs)436437self._init_attributes()438self._init_constants()439440def _init_attributes(self):441scenario = self.get_scenario()442net = self.get_net()443self.add_col(SumoIdsConf('Trip', xmltag='id'))444445self.add_col(am.IdsArrayConf('ids_vtype', self.get_obj_vtypes(),446groupnames=['state'],447name='Type',448info='Vehicle type.',449xmltag='type',450))451452self.add_col(am.ArrayConf('times_depart', 0,453dtype=np.int32,454perm='rw',455name='Depart time',456info="Departure time of vehicle in seconds. Must be an integer!",457xmltag='depart',458))459460self.add_col(am.IdsArrayConf('ids_edge_depart', net.edges,461groupnames=['state'],462name='ID from-edge',463info='ID of network edge where trip starts.',464xmltag='from',465))466467self.add_col(am.IdsArrayConf('ids_edge_arrival', net.edges,468groupnames=['state'],469name='ID to-edge',470info='ID of network edge where trip ends.',471xmltag='to',472))473474self.add_col(am.ArrayConf('inds_lane_depart', OPTIONMAP_LANE_DEPART["free"],475dtype=np.int32,476#choices = OPTIONMAP_LANE_DEPART,477perm='r',478name='Depart lane',479info="Departure lane index. 0 is rightmost lane or sidewalk, if existant.",480xmltag='departLane',481xmlmap=get_inversemap(OPTIONMAP_LANE_DEPART),482))483484self.add_col(am.ArrayConf('positions_depart', OPTIONMAP_POS_DEPARTURE["random_free"],485dtype=np.float32,486#choices = OPTIONMAP_POS_DEPARTURE,487perm='r',488name='Depart pos',489unit='m',490info="Position on edge at the moment of departure.",491xmltag='departPos',492xmlmap=get_inversemap(OPTIONMAP_POS_DEPARTURE),493))494495self.add_col(am.ArrayConf('speeds_depart', 0.0,496dtype=np.float32,497#choices = OPTIONMAP_SPEED_DEPARTURE,498perm='r',499name='Depart speed',500unit='m/s',501info="Speed at the moment of departure.",502xmltag='departSpeed',503xmlmap=get_inversemap(OPTIONMAP_SPEED_DEPARTURE),504))505self.add_col(am.ArrayConf('inds_lane_arrival', OPTIONMAP_LANE_ARRIVAL["current"],506dtype=np.int32,507#choices = OPTIONMAP_LANE_ARRIVAL,508perm='r',509name='Arrival lane',510info="Arrival lane index. 0 is rightmost lane or sidewalk, if existant.",511xmltag='arrivalLane',512xmlmap=get_inversemap(OPTIONMAP_LANE_ARRIVAL),513))514515self.add_col(am.ArrayConf('positions_arrival', OPTIONMAP_POS_ARRIVAL["random"],516dtype=np.float32,517#choices = OPTIONMAP_POS_ARRIVAL,518perm='r',519name='Arrival pos',520unit='m',521info="Position on edge at the moment of arrival.",522xmltag='arrivalPos',523xmlmap=get_inversemap(OPTIONMAP_POS_ARRIVAL),524))525526self.add_col(am.ArrayConf('speeds_arrival', 0.0,527dtype=np.float32,528#choices = OPTIONMAP_SPEED_ARRIVAL,529perm='r',530name='Arrival speed',531unit='m/s',532info="Arrival at the moment of departure.",533xmltag='arrivalSpeed',534xmlmap=get_inversemap(OPTIONMAP_SPEED_ARRIVAL),535))536537self.add(cm.ObjConf(Routes('routes', self, net)))538539# this could be extended to a list with more plans540self.add_col(am.IdsArrayConf('ids_route_current', self.routes.get_value(),541name='Route ID ',542info='Currently chosen route ID.',543))544545# print ' self.routes.get_value()',self.routes.get_value()546self.add_col(am.IdlistsArrayConf('ids_routes', self.routes.get_value(),547name='IDs route alt.',548info='IDs of route alternatives for this trip.',549))550551if 1: # self.get_version()<0.2:552# self.inds_lane_depart.set_xmltag(None)553# self.inds_lane_arrival.set_xmltag(None)554self.inds_lane_depart.set_xmltag('departLane', xmlmap=get_inversemap(OPTIONMAP_LANE_DEPART))555self.inds_lane_arrival.set_xmltag('arrivalLane', xmlmap=get_inversemap(OPTIONMAP_LANE_ARRIVAL))556557self.set_version(0.2)558559def _init_constants(self):560#self._method_routechoice = self.get_route_first561562self._xmltag_routes = "routes"563self._xmltag_veh = "vehicle"564self._xmltag_id = "id"565self._xmltag_trip = "trip"566self._xmltag_rou = "route"567self._xmltag_person = 'person'568569def clear_trips(self):570self.routes.get_value().clear_routes()571self.clear()572573def clear_routes(self):574self.routes.get_value().clear_routes()575self.ids_route_current.reset()576self.ids_routes.reset()577578def clear_route_alternatves(self):579ids_route_del = []580ids_trip = self.get_ids()581#ids_routes = self.ids_routes[self.get_ids()]582for id_trip, id_route_current in zip(ids_trip, self.ids_route_current[ids_trip]):583if self.ids_routes[id_trip] is not None:584ids_route = set(self.ids_routes[id_trip])585ids_route_del += list(ids_route.difference([id_route_current]))586self.ids_routes[id_trip] = [id_route_current]587588self.routes.get_value().del_rows(ids_route_del)589590def get_id_from_id_sumo(self, id_veh_sumo):591# print 'get_id_from_id_sumo',id_veh_sumo,len(id_veh_sumo.split('.')) == 1592if len(id_veh_sumo.split('.')) == 1:593return int(id_veh_sumo)594return -1595596def get_routes(self):597return self.routes.get_value()598599def get_obj_vtypes(self):600return self.parent.vtypes601602def get_net(self):603return self.get_scenario().net604605def get_scenario(self):606return self.parent.get_scenario()607608def get_time_depart_first(self):609if len(self) > 0:610return float(np.min(self.times_depart.get_value()))611else:612return np.inf613614def get_time_depart_last(self):615if len(self) > 0:616return float(np.max(self.times_depart.get_value()))+600.0617else:618return 0.0619620def get_tripfilepath(self):621return self.parent.get_tripfilepath()622623def get_routefilepath(self):624return self.parent.get_routefilepath()625626def duaroute(self, is_export_net=False, is_export_trips=True,627routefilepath=None, weights=None, weightfilepath=None,628**kwargs):629"""630Simple fastest path routing using duarouter.631"""632print 'duaroute'633exectime_start = time.clock()634635#routesattrname = self.get_routesattrname(routesindex)636vtypes = self.parent.vtypes637if (not os.path.isfile(self.get_tripfilepath())) | is_export_trips:638ids_vtype_pedestrian = vtypes.select_by_mode(mode='pedestrian', is_sumoid=False)639self.export_trips_xml(ids_vtype_exclude=ids_vtype_pedestrian)640641if (not os.path.isfile(self.get_net().get_filepath())) | is_export_net:642self.get_net().export_netxml()643644if routefilepath is None:645routefilepath = self.get_routefilepath()646647if weights is not None:648weightfilepath = self.get_net().edges.export_edgeweights_xml(649filepath=weightfilepath,650weights=weights,651time_begin=self.get_time_depart_first(),652time_end=self.get_time_depart_last())653654if routing.duaroute(self.get_tripfilepath(), self.get_net().get_filepath(),655routefilepath, weightfilepath=weightfilepath, **kwargs):656657self.import_routes_xml(routefilepath,658is_clear_trips=False,659is_generate_ids=False,660is_overwrite_only=True,661is_add=False)662663print ' exectime', time.clock()-exectime_start664return routefilepath665666else:667return None668669def get_trips_for_vtype(self, id_vtype):670return self.select_ids(self.ids_vtype.get_value() == id_vtype)671672def get_vtypes(self):673return set(self.ids_vtype.get_value())674675def route(self, is_check_lanes=True, is_del_disconnected=False, is_set_current=False):676"""677Fastest path python router.678"""679print 'route is_check_lanes', is_check_lanes680# TODO: if too mant vtypes, better go through id_modes681exectime_start = time.clock()682683net = self.get_scenario().net684edges = net.edges685vtypes = self.parent.vtypes686687ids_edges = []688ids_trip = []689costs = []690691ids_trip_disconnected = []692693for id_vtype in self.get_vtypes():694id_mode = vtypes.ids_mode[id_vtype]695696# no routing for pedestrians697if id_mode != net.modes.get_id_mode('pedestrian'):698ids_trip_vtype = self.get_trips_for_vtype(id_vtype)699print ' id_vtype, id_mode', id_vtype, id_mode # ,ids_trip_vtype700701weights = edges.get_times(id_mode=id_mode,702speed_max=vtypes.speeds_max[id_vtype],703is_check_lanes=is_check_lanes,704modeconst_excl=-10.0, modeconst_mix=-5.0,705)706707fstar = edges.get_fstar(id_mode=id_mode)708709ids_alledges = edges.get_ids()710# for id_edge,id_edge_sumo, weight in zip(ids_alledges,edges.ids_sumo[ids_alledges],weights[ids_alledges]):711# print ' id_edge',id_edge,id_edge_sumo,'weight',weights[id_edge_sumo]712ids_edge_depart = self.ids_edge_depart[ids_trip_vtype]713ids_edge_arrival = self.ids_edge_arrival[ids_trip_vtype]714715for id_trip, id_edge_depart, id_edge_arrival in zip(ids_trip_vtype, ids_edge_depart, ids_edge_arrival):716717cost, route = routing.get_mincostroute_edge2edge(id_edge_depart,718id_edge_arrival,719weights=weights,720fstar=fstar)721722# if id_trip == 1:723# print ' id_trip',id_trip,'id_edge_depart',id_edge_depart,'id_edge_arrival',id_edge_arrival724# print ' route',route725# print ' ids_sumo',edges.ids_sumo[route]726if len(route) > 0:727ids_edges.append(route)728ids_trip.append(id_trip)729costs.append(cost)730731else:732ids_trip_disconnected.append(id_trip)733734ids_route = self.routes.get_value().add_rows(ids_trip=ids_trip,735ids_edges=ids_edges,736costs=costs,737)738if is_set_current:739self.ids_route_current[ids_trip] = ids_route740else:741self.add_routes(ids_trip, ids_route)742743print ' exectime', time.clock()-exectime_start744745if is_del_disconnected:746self.del_rows(ids_trip_disconnected)747748return ids_trip, ids_route749750def estimate_entered(self, method_routechoice=None):751"""752Estimates the entered number of vehicles for each edge.753returns ids_edge and entered_vec754"""755# TODO: we could specify a mode756if method_routechoice is None:757method_routechoice = self.get_route_first758759ids_edges = self.routes.get_value().ids_edges760counts = np.zeros(np.max(self.get_net().edges.get_ids())+1, int)761762for id_trip in self.get_ids():763id_route = method_routechoice(id_trip)764if id_route >= 0:765# here the [1:] eliminates first edge as it is not entered766counts[ids_edges[id_route][1:]] += 1767768ids_edge = np.flatnonzero(counts)769entered_vec = counts[ids_edge].copy()770return ids_edge, entered_vec771772def import_trips_from_scenario(self, scenario2):773"""774Import trips from another scenario.775"""776print 'import_trips_from_scenario', scenario2.ident777if not is_pyproj:778print("WARNING in import_trips_from_scenario: pyproj module not installed")779return None780781scenario = self.get_scenario()782demand = scenario.demand783net = scenario.net784edges = net.edges785ids_edge_depart = demand.trips.ids_edge_depart786ids_edge_arrival = demand.trips.ids_edge_arrival787788demand2 = scenario2.demand789net2 = scenario2.net790791# copy all vtypes from scenario2792793# get vtypes of demand2 that are not in demand794ids_veh2 = demand2.vtypes.get_ids()795ids_vtype_sumo2 = demand2.vtypes.ids_sumo[ids_veh2]796# print ' ids_vtype_sumo2',ids_vtype_sumo2797# print ' ids_vtype_sumo',demand.vtypes.ids_sumo.get_value()798ids_vtype_sumo_diff = list(set(ids_vtype_sumo2).difference(demand.vtypes.ids_sumo.get_value()))799# print ' ids_vtype_sumo_diff',ids_vtype_sumo_diff800# for id_sumo2 in demand2.vtypes.ids_sumo.get_value():801# if demand.vtypes.has_index(id_sumo2):802# for attrconf in demand2.vtypes.get_group('parameters'):803804# copy all attributes from ids_vtype_sumo_diff805ids_vtype_diff = demand.vtypes.copy_cols(806demand2.vtypes, ids=demand2.vtypes.ids_sumo.get_ids_from_indices(ids_vtype_sumo_diff))807#ids_vtype_sumo = demand.vtypes.ids_sumo.get_value()808#ids_vtype = demand.vtypes.get_ids_from_indices(ids_vtype_sumo)809#ids_vtype2 = demand2.vtypes.ids_sumoget_ids_from_indices(ids_vtype_sumo)810811# map id_vtypes from scenario2 to present scenario812vtypemap = np.zeros(np.max(ids_veh2)+1)813vtypemap[ids_veh2] = demand.vtypes.ids_sumo.get_ids_from_indices(ids_vtype_sumo2)814815# print ' vtypemap',vtypemap816# copy trip parameters, by mapping trip types817ids_trip2 = demand2.trips.get_ids()818819ids_trips = self.copy_cols(demand2.trips) # ids_trip in present scenrio820821# delete routes, that cannot be transferred (at the moment)822self.ids_route_current[ids_trips] = -1823self.ids_routes[ids_trips] = len(ids_trips) * [None]824825self.ids_vtype[ids_trips] = vtypemap[demand2.trips.ids_vtype[ids_trip2]]826827# print ' ids_trip2,ids_trips',ids_trip2,ids_trips828829ids_mode = demand.vtypes.ids_mode[self.ids_vtype[ids_trips]]830# for each used mode, we need to select the network edges that are accessible by this mode831ids_modeset = set(ids_mode)832833#maps_edge_laneind = {}834# for id_mode in ids_modeset:835# ids_edge, inds_lane = edges.select_accessible(id_mode)836# maps_edge_laneind[id_mode] = dict(zip(ids_edge,inds_lane))837838# project depart points and arrival points839proj_params = str(net.get_projparams())840proj_params2 = str(net2.get_projparams())841842if (proj_params == '!') | (proj_params2 == '!'):843print 'WARNING in import_trips_from_scenario: unknown projections, use only offsets.', proj_params, proj_params2844is_proj = False845846elif proj_params == proj_params2:847# with identical projections, projecting is useless848is_proj = False849850else:851is_proj = True852proj = pyproj.Proj(proj_params)853proj2 = pyproj.Proj(proj_params2)854855offset = net.get_offset()856offset2 = net2.get_offset()857858# if self._proj is None:859# self._proj, self._offset = self.parent.get_proj_and_offset()860#x,y = self._proj(lons, lats)861# return np.transpose(np.concatenate(([x+self._offset[0]],[y+self._offset[1]]),axis=0))862863# adjust edge ids check lane access864n_failed = 0865ids_trip_failed = set()866867for id_mode in ids_modeset:868# make_segment_edge_map for all edges of this mode869print ' make segment_edge_map for mode', id_mode870ids_edge_access, inds_lane_access = edges.select_accessible_mode(id_mode)871print ' found accessible edges', len(ids_edge_access), len(edges.get_ids())872# dict(zip(ids_edge,inds_lane))873edges.make_segment_edge_map(ids_edge_access)874875# select trips with id_mode876ind_trips = np.flatnonzero(ids_mode == id_mode)877878print ' number of trips for this mode:', len(ind_trips)879for id_trip, id_edge_depart2, id_edge_arrival2 in zip(ids_trips[ind_trips],880demand2.trips.ids_edge_depart[ids_trip2[ind_trips]],881demand2.trips.ids_edge_arrival[ids_trip2[ind_trips]]882):883884# match departure edge885886# treat special numbers of position887pos2 = 0.0888889# get coordinate in scenario2890x2, y2, z2 = net2.edges.get_coord_from_pos(id_edge_depart2, pos2)891892# project coord from scenario2 in present scenario893if is_proj:894xp, yp = pyproj.transform(proj2, proj, x2-offset2[0], y2-offset2[1])895else:896xp, yp = x2-offset2[0], y2-offset2[1]897898coord = (xp+offset[0], yp+offset[1], z2)899# print ' coord2 = ',(x2,y2,z2)900# print ' coord = ',coord901# get edge id in present scenario902id_edge_depart = edges.get_closest_edge(coord)903904# check eucledian distance905#d = edges.get_dist_point_to_edge(coord, id_edge_depart)906# print ' id_edge_depart,d,id_mode',id_edge_depart,d,id_mode907print ' id_edge_depart', id_edge_depart, id_edge_depart in ids_edge_access908909ids_edge_depart[id_trip] = id_edge_depart910911# match arrival edge912913# treat special numbers of position914pos2 = 0.0915916# get coordinate in scenario2917x2, y2, z2 = net2.edges.get_coord_from_pos(id_edge_arrival2, pos2)918919# project coord from scenario2 in present scenario920if is_proj:921xp, yp = pyproj.transform(proj2, proj, x2-offset2[0], y2-offset2[1])922else:923xp, yp = x2-offset2[0], y2-offset2[1]924925coord = (xp+offset[0], yp+offset[1], z2)926# print ' coord2 = ',(x2,y2,z2)927# print ' coord = ',coord928# get edge id in present scenario929id_edge_arrival = edges.get_closest_edge(coord)930931# check eucledian distance932#d = edges.get_dist_point_to_edge(coord, id_edge_arrival)933print ' id_edge_arrival', id_edge_arrival, id_edge_arrival in ids_edge_access934935ids_edge_arrival[id_trip] = id_edge_arrival936937# redo segment map938edges.make_segment_edge_map()939940def make_trip(self, is_generate_ids=True, **kwargs):941id_trip = self.add_row(ids_vtype=kwargs.get('id_vtype', None),942times_depart=kwargs.get('time_depart', None),943ids_edge_depart=kwargs.get('id_edge_depart', None),944ids_edge_arrival=kwargs.get('id_edge_arrival', None),945inds_lane_depart=kwargs.get('ind_lane_depart', None),946positions_depart=kwargs.get('position_depart', None),947speeds_depart=kwargs.get('speed_depart', None),948inds_lane_arrival=kwargs.get('ind_lane_arrival', None),949positions_arrival=kwargs.get('position_arrival', None),950speeds_arrival=kwargs.get('speed_arrival', None),951ids_routes=[],952)953954if is_generate_ids:955self.ids_sumo[id_trip] = str(id_trip)956else:957self.ids_sumo[id_trip] = kwargs.get('id_sumo', str(id_trip)) # id958959if kwargs.has_key('route'):960route = kwargs['route']961if len(route) > 0:962id_route = self.routes.get_value().add_row(ids_trip=id_trip,963ids_edges=kwargs['route']964)965self.ids_route_current[id_trip] = id_route966self.ids_routes[id_trip] = [id_route]967968return id_trip969970def make_trips(self, ids_vtype, is_generate_ids=True, **kwargs):971print 'make_trips len(ids_vtype) =', len(ids_vtype)972# print ' kwargs=',kwargs973ids_trip = self.add_rows(n=len(ids_vtype),974ids_vtype=ids_vtype,975times_depart=kwargs.get('times_depart', None),976ids_edge_depart=kwargs.get('ids_edge_depart', None),977ids_edge_arrival=kwargs.get('ids_edge_arrival', None),978inds_lane_depart=kwargs.get('inds_lane_depart', None),979positions_depart=kwargs.get('positions_depart', None),980speeds_depart=kwargs.get('speeds_depart', None),981inds_lane_arrival=kwargs.get('inds_lane_arrival', None),982positions_arrival=kwargs.get('positions_arrival', None),983speeds_arrival=kwargs.get('speeds_arrival', None),984#ids_routes = len(ids_vtype)*[[]],985)986987if is_generate_ids:988self.ids_sumo[ids_trip] = np.array(ids_trip, np.str)989else:990self.ids_sumo[ids_trip] = kwargs.get('ids_sumo', np.array(ids_trip, np.str))991return ids_trip992993def make_routes(self, ids_vtype, is_generate_ids=True, routes=None, ids_trip=None, is_add=True, **kwargs):994"""Generates or sets routes of trips, generates also trips if necessary995ids_trip: trip IDs,996if None then trip ID and route ID will be generated for each given route997if a list then routes will be associated with these trip IDs and routes will be replaced998but generated if route ID does not exist for given trip ID999is_add: if True then routes are added to the alternative route list1000if False then current routes will be set10011002is_generate_ids: depricated, fully controlled by ids_trip1003"""1004print 'make_routes is_generate_ids', ids_trip is None, 'is_add', is_add1005# print ' ids_trip',ids_trip10061007if ids_trip is None: # is_generate_ids = is_generate_ids,1008print ' generate new trip IDs'1009ids_trip = self.make_trips(ids_vtype, is_generate_ids=is_generate_ids, **kwargs)1010is_generate_ids = True1011else:1012if not is_add:1013print ' replace current route and create if not existent'1014ids_routes = self.ids_route_current[ids_trip]1015inds_new = np.flatnonzero(ids_routes == -1)1016# print ' inds_new',inds_new1017if len(inds_new) > 0:1018print ' complete %d non pre-existant route ids of %d trips' % (len(inds_new), len(ids_trip))1019# create new routes1020ids_routes[inds_new] = self.routes.get_value().add_rows(n=len(inds_new),1021ids_trip=ids_trip[inds_new],1022#ids_edges = routes[inds_new],1023)1024else:1025print ' all new routes have pre-existing routes'1026else:1027# make new route IDs1028ids_routes = self.routes.get_value().add_rows(n=len(ids_trip),1029ids_trip=ids_trip,1030# ids_edges = routes[inds_new],# later!!1031)10321033is_generate_ids = False1034print ' set new routes to routes database', len(ids_routes), 'routes set'1035self.routes.get_value().ids_edges[ids_routes] = routes10361037if not is_add:1038print ' replace current route IDs', len(inds_new), 'routes replaced'1039self.ids_route_current[ids_trip[inds_new]] = ids_routes[inds_new]1040else:1041print ' add new route IDs to alternatives', len(ids_trip), 'routes added'1042self.add_routes(ids_trip, ids_routes)10431044# if np.any(ids_routes == -1):1045# is_generate_ids = True10461047# print ' ids_trip =',ids_trip1048if is_generate_ids:1049print ' generate new route IDs'1050ids_routes = self.routes.get_value().add_rows(n=len(ids_trip),1051ids_trip=ids_trip,1052#ids_edges = routes,1053)1054self.routes.get_value().ids_edges[ids_routes] = routes10551056# print ' ids_routes',ids_routes1057if not is_add:1058print ' set new current routes'1059self.ids_route_current[ids_trip] = ids_routes1060else:1061print ' add new route IDs to alternatives'1062self.add_routes(ids_trip, ids_routes)10631064# no!:self.ids_routes[ids_trip] = ids_routes.reshape((-1,1)).tolist()# this makes an array of lists1065# print ' self.ids_routes.get_value()',self.ids_routes[ids_trip]1066# print ' ids_routes.reshape((-1,1)).tolist()',ids_routes.reshape((-1,1)).tolist()1067# print ' make_routes DONE'1068return ids_routes, ids_trip10691070def add_routes(self, ids_trip, ids_routes):1071for id_trip, id_route in zip(ids_trip, ids_routes):1072# no!: self.ids_routes[id_trip].append(id_route)1073# print ' self.ids_routes[id_trip]',self.ids_routes[id_trip],id_route1074if self.ids_routes[id_trip] is None:1075self.ids_routes[id_trip] = [id_route] # this works!10761077else:1078self.ids_routes[id_trip].append(id_route)10791080# if self.ids_route_current[id_trip] == -1:1081# self.ids_route_current[id_trip] = id_route10821083def prepare_sim(self, process):1084return [] # [(steptime1,func1),(steptime2,func2),...]10851086def export_trips_xml(self, filepath=None, encoding='UTF-8',1087ids_vtype_exclude=[], ids_vtype_include=[],1088vtypeattrs_excluded=[]):1089"""1090Export trips to SUMO xml file.1091Method takes care of sorting trips by departure time.1092"""1093if filepath is None:1094filepath = self.get_tripfilepath()1095print 'export_trips_xml', filepath1096try:1097fd = open(filepath, 'w')1098except:1099print 'WARNING in write_obj_to_xml: could not open', filepath1100return False11011102xmltag, xmltag_item, attrname_id = self.xmltag1103fd.write('<?xml version="1.0" encoding="%s"?>\n' % encoding)1104fd.write(xm.begin(xmltag))1105indent = 211061107ids_trip = self.times_depart.get_ids_sorted()1108ids_vtype = self.ids_vtype[ids_trip]1109#ids_vtypes_exclude = self.ids_vtype.get_ids_from_indices(vtypes_exclude)11101111inds_selected = np.ones(len(ids_vtype), np.bool)1112for id_vtype in ids_vtype_exclude:1113inds_selected[ids_vtype == id_vtype] = False1114ids_trip_selected = ids_trip[inds_selected]1115ids_vtype_selected = set(ids_vtype[inds_selected])1116ids_vtype_selected.union(ids_vtype_include)1117#ids_vtypes_selected = set(ids_vtypes).difference(ids_vtypes_exclude)11181119attrconfigs_excluded = []1120for attrname in vtypeattrs_excluded:1121attrconfigs_excluded.append(self.parent.vtypes.get_config(attrname))11221123self.parent.vtypes.write_xml(fd, indent=indent,1124ids=ids_vtype_selected,1125is_print_begin_end=False,1126attrconfigs_excluded=attrconfigs_excluded)11271128self.write_xml(fd, indent=indent,1129ids=ids_trip_selected,1130attrconfigs_excluded=[self.routes,1131self.ids_routes,1132self.ids_route_current,1133# self.inds_lane_depart,1134# self.inds_lane_arrival1135],1136is_print_begin_end=False)11371138fd.write(xm.end(xmltag))1139fd.close()1140return filepath11411142def get_vtypes(self):1143return set(self.ids_vtype.get_value())11441145def get_trips(self):1146# returns trip object, method common to all demand objects1147return self11481149def get_writexmlinfo(self, is_route=False, is_exclude_pedestrians=False, **kwargs):1150"""1151Returns three array where the first array is the1152begin time of the first vehicle and the second array is the1153write function to be called for the respectice vehicle and1154the third array contains the vehicle ids11551156Method used to sort trips when exporting to route or trip xml file1157"""11581159ids = self.get_ids()11601161if not is_exclude_pedestrians:1162# define different route write functions for pedestriand and vehicles1163n = len(ids)1164writefuncs = np.zeros(n, dtype=np.object)1165inds_ped = self.parent.vtypes.ids_mode[self.ids_vtype[ids]] == MODES['pedestrian']1166writefuncs[inds_ped] = self.write_persontrip_xml1167if is_route:1168writefuncs[np.logical_not(inds_ped) & (self.ids_route_current[ids] > -1)] = self.write_vehroute_xml11691170# vehicles must have a route, this makes sure that OD are connected1171writefuncs[np.logical_not(inds_ped) & (self.ids_route_current[ids] == -1)] = self.write_missingroute_xml1172else:1173# here we write vehicle trip, without explicit route export1174# routing will be performed during simulation1175writefuncs[np.logical_not(inds_ped) & (self.ids_route_current[ids] > -1)] = self.write_vehtrip_xml11761177# vehicles must have a route, this makes sure that OD are connected1178writefuncs[np.logical_not(inds_ped) & (self.ids_route_current[ids] == -1)] = self.write_missingroute_xml1179else:1180# only vehicle types without peds1181inds_noped = self.parent.vtypes.ids_mode[self.ids_vtype[ids]] != MODES['pedestrian']1182ids = ids[inds_noped]1183n = len(ids)1184writefuncs = np.zeros(n, dtype=np.object)1185if is_route:1186writefuncs[self.ids_route_current[ids] > -1] = self.write_vehroute_xml11871188# vehicles must have a route, this makes sure that OD are connected1189writefuncs[self.ids_route_current[ids] == -1] = self.write_missingroute_xml1190else:1191# here we write vehicle trip, without explicit route export1192# routing will be performed during simulation1193writefuncs[self.ids_route_current[ids] > -1] = self.write_vehtrip_xml11941195# vehicles must have a route, this makes sure that OD are connected1196writefuncs[self.ids_route_current[ids] == -1] = self.write_missingroute_xml11971198return self.times_depart[ids], writefuncs, ids11991200def write_missingroute_xml(self, fd, id_trip, time_begin, indent=2):1201"""1202Function called when respective vehicle has an invalid route1203"""1204pass12051206def write_vehroute_xml(self, fd, id_trip, time_begin, indent=2):1207# print 'write_vehroute_xml',id_trip,time_begin1208id_route = self.ids_route_current[id_trip] # self.get_route_first(id_trip)#self._method_routechoice(id_trip)#12091210if id_route >= 0: # a valid route has been found1211# init vehicle route only if valid route exists1212fd.write(xm.start(self._xmltag_veh, indent))1213else:1214# init trip instead of route1215fd.write(xm.start(self._xmltag_trip, indent))12161217# print ' make tag and id',_id1218fd.write(xm.num(self._xmltag_id, self.ids_sumo[id_trip]))12191220# print ' write columns',len(scalarcolconfigs)>0,len(idcolconfig_include_tab)>0,len(objcolconfigs)>01221for attrconfig in [self.ids_vtype,1222self.times_depart,1223self.ids_edge_depart,1224self.ids_edge_arrival,1225self.inds_lane_depart,1226self.positions_depart,1227self.speeds_depart,1228self.inds_lane_arrival,1229self.positions_arrival,1230self.speeds_arrival, ]:1231# print ' attrconfig',attrconfig.attrname1232attrconfig.write_xml(fd, id_trip)12331234if (id_route >= 0): # a valid route has been found1235# write route id1236#fd.write(xm.num('route', id_route ))12371238# instead of route id we write entire route here1239fd.write(xm.stop())1240fd.write(xm.start(self._xmltag_rou, indent+2))12411242routes = self.routes.get_value()1243for attrconfig in [routes.ids_edges, routes.colors]:1244# print ' attrconfig',attrconfig.attrname1245attrconfig.write_xml(fd, id_route)12461247# end route and vehicle1248fd.write(xm.stopit())1249fd.write(xm.end(self._xmltag_veh, indent+2))12501251else:1252# end trip without route1253fd.write(xm.stopit())12541255def write_vehtrip_xml(self, fd, id_trip, time_begin, indent=2):1256# vehicle trip write function1257# no route is written, even if it exisis12581259# init trip instead of route1260fd.write(xm.start(self._xmltag_trip, indent))12611262# print ' make tag and id',_id1263fd.write(xm.num(self._xmltag_id, self.ids_sumo[id_trip]))12641265# print ' write columns',len(scalarcolconfigs)>0,len(idcolconfig_include_tab)>0,len(objcolconfigs)>01266for attrconfig in [self.ids_vtype,1267self.times_depart,1268self.ids_edge_depart,1269self.ids_edge_arrival,1270self.inds_lane_depart,1271self.positions_depart,1272self.speeds_depart,1273self.inds_lane_arrival,1274self.positions_arrival,1275self.speeds_arrival, ]:1276# print ' attrconfig',attrconfig.attrname1277attrconfig.write_xml(fd, id_trip)12781279# end trip without route1280fd.write(xm.stopit())12811282def write_persontrip_xml(self, fd, id_trip, time_begin, indent=2):1283# currently no routes are exported, only origin and destination edges12841285fd.write(xm.start(self._xmltag_person, indent))12861287self.ids_sumo.write_xml(fd, id_trip)1288self.times_depart.write_xml(fd, id_trip)1289self.ids_vtype.write_xml(fd, id_trip)1290fd.write(xm.stop())12911292fd.write(xm.start('walk', indent=indent+2))1293# print 'write walk',id_trip,self.positions_depart[id_trip],self.positions_arrival[id_trip]1294self.ids_edge_depart.write_xml(fd, id_trip)1295if self.positions_depart[id_trip] > 0:1296self.positions_depart.write_xml(fd, id_trip)12971298self.ids_edge_arrival.write_xml(fd, id_trip)1299if self.positions_arrival[id_trip] > 0:1300self.positions_arrival.write_xml(fd, id_trip)13011302fd.write(xm.stopit()) # ends walk1303fd.write(xm.end(self._xmltag_person, indent=indent))13041305def get_route_first(self, id_trip):1306ids_route = self.ids_routes[id_trip]1307if ids_route is None:1308return -11309elif len(ids_route) > 0:1310return ids_route[0]1311else:1312return -1 # no route found13131314def import_routes_xml(self, filepath, is_clear_trips=False,1315is_generate_ids=True, is_add=False,1316is_overwrite_only=False):1317print 'import_routes_xml from %s generate new routes %s, clear trips %s add trips %s' % (filepath, is_generate_ids, is_clear_trips, is_add)1318if is_clear_trips:1319self.clear_trips()13201321counter = RouteCounter()1322parse(filepath, counter)1323reader = RouteReader(self, counter)1324try:1325parse(filepath, reader)1326print ' call insert_routes', is_generate_ids, 'is_add', is_add, 'is_overwrite_only', is_overwrite_only1327reader.insert_routes(is_generate_ids=is_generate_ids,1328is_add=is_add, is_overwrite_only=is_overwrite_only)1329except KeyError:1330print >> sys.stderr, "Error: Problems with reading routes!"1331raise13321333def import_trips_xml(self, filepath, is_clear_trips=False, is_generate_ids=True):1334print 'import_trips_xml from %s generate own trip ' % (filepath)1335if is_clear_trips:1336self.clear_trips()13371338counter = TripCounter()1339parse(filepath, counter)1340reader = TripReader(self, counter.n_trip)1341print ' n_trip=', counter.n_trip13421343try:1344parse(filepath, reader)1345reader.insert_trips(is_generate_ids=is_generate_ids)1346except KeyError:1347print >> sys.stderr, "Error: Problems with reading trips!"1348raise13491350def config_results(self, results):1351# print 'DEMAND.config_results'1352tripresults = res.Tripresults('tripresults', results,1353self,1354self.get_net().edges1355)13561357results.add_resultobj(tripresults, groupnames=['Trip results'])13581359def process_results(self, results, process=None):1360pass136113621363class TaxiGenerator(Process):1364def __init__(self, demand, logger=None, **kwargs):13651366self._init_common('taxigenerator', name='Taxi generator',1367parent=demand,1368logger=logger,1369info='Generates taxi trips on specific zones.',1370)13711372attrsman = self.get_attrsman()1373scenario = self.parent.get_scenario()1374zones = scenario.landuse.zones13751376self.n_taxi = attrsman.add(cm.AttrConf('n_taxi', 100,1377groupnames=['options'],1378name='Number of taxi',1379info="Number of taxis to be generated.",1380))13811382self.priority_max = attrsman.add(cm.AttrConf('priority_max', 8,1383groupnames=['options'],1384name='Max. edge priority',1385perm='rw',1386info="Maximum edge priority for which edges in a zone are considered departure or arrival edges.",1387))13881389self.speed_max = attrsman.add(cm.AttrConf('speed_max', 14.0,1390groupnames=['options'],1391name='Max. edge speed',1392perm='rw',1393unit='m/s',1394info="Maximum edge speed for which edges in a zone are considered departure or arrival edges.",1395))13961397time_start = self.parent.get_time_depart_first()13981399self.time_start = attrsman.add(cm.AttrConf('time_start', kwargs.get('time_start', time_start),1400groupnames=['options', 'timing'],1401name='Start time',1402perm='rw',1403info='Start time when first taxi appears, in seconds after midnight.',1404unit='s',1405))14061407# default is to insert all taxis within the first 60s1408self.time_end = attrsman.add(cm.AttrConf('time_end', kwargs.get('time_end', time_start+60.0),1409groupnames=['options', 'timing'],1410name='End time',1411perm='rw',1412info='Time when last taxi appears in seconds after midnight.',1413unit='s',1414))14151416self.n_edges_min_length = attrsman.add(cm.AttrConf('n_edges_min_length', 1,1417groupnames=['options'],1418name='Min. edge number length prob.',1419perm='rw',1420info="Minimum number of edges for with the departure/arrival probability is proportional to the edge length.",1421))14221423self.n_edges_max_length = attrsman.add(cm.AttrConf('n_edges_max_length', 500,1424groupnames=['options'],1425name='Max. edge number length prob.',1426perm='rw',1427info="Maximum number of edges for with the departure/arrival probability is proportional to the edge length.",1428))14291430self.is_selected_zones = attrsman.add(cm.AttrConf('is_selected_zones', False,1431groupnames=['options'],1432name='Selected zones',1433info="Place taxis only on edges of specified zone list.",1434))14351436ids_zone = zones.get_ids()1437zonechoices = {}1438for id_zone, name_zone in zip(ids_zone, zones.ids_sumo[ids_zone]):1439zonechoices[name_zone] = id_zone1440# print ' zonechoices',zonechoices1441# make for each possible pattern a field for prob1442# if len(zonechoices) > 0:1443self.ids_zone = attrsman.add(cm.ListConf('ids_zone', [],1444groupnames=['options'],1445choices=zonechoices,1446name='Zones',1447info="""Zones where to place taxis. Taxis are distributed proportional to road lengths in zones.""",1448))14491450# self.is_refresh_zoneedges = attrsman.add(am.AttrConf( 'is_refresh_zoneedges', True,1451# groupnames = ['options'],1452# perm='rw',1453# name = 'Refresh zone edges',1454# info = """Identify all edges in all zones before generating the trips.1455# Dependent on the will take some time.""",1456# ))14571458def generate_taxi(self):1459"""1460Generate taxis as trips in the trip database.1461"""1462tripnumber = self.n_taxi1463time_start = self.time_start1464time_end = self.time_end1465id_mode_ped = MODES['pedestrian']1466id_mode_taxi = MODES['taxi']1467scenario = self.parent.get_scenario()1468zones = scenario.landuse.zones1469trips = scenario.demand.trips1470edges = scenario.net.edges1471edgelengths = edges.lengths14721473# define taxi and secondary mode, if appropriate1474ids_vtype_mode_taxi, prob_vtype_mode_taxi = scenario.demand.vtypes.select_by_mode(1475id_mode_taxi, is_share=True)14761477# print ' ids_vtype_mode', ids_vtype_mode1478n_vtypes_taxi = len(ids_vtype_mode_taxi)14791480# update edge probabilities with suitable parameters1481# edge departure probabilities of all edges in all zones1482edgeprops_all = {}14831484if self.is_selected_zones:1485ids_zone = self.ids_zone1486else:1487ids_zone = zones.get_ids()1488for id_zone in ids_zone:1489edgeprops_all.update(zones.get_egdeprobs(id_zone, self.n_edges_min_length, self.n_edges_max_length,1490self.priority_max, self.speed_max, is_normalize=False, is_dict=True))14911492fstar = edges.get_fstar(is_ignor_connections=False)1493times_taxi = edges.get_times(id_mode=id_mode_taxi, is_check_lanes=True)14941495n_trips_generated = 01496n_trips_failed = 014971498if self.is_selected_zones:1499# tale selected zones1500ids_zone = self.ids_zone1501else:1502# take all zones1503ids_zone = zones.get_ids()15041505ids_edges_orig = [] # all accessible edges in all zones1506n_edges_orig = 01507for id_zone in ids_zone:1508#id_orig = self.ids_orig[id_od]1509#id_dest = self.ids_dest[id_od]15101511print ' check id_zone', id_zone1512ids_edges_orig_raw = zones.ids_edges_orig[id_zone]15131514#prob_edges_orig_raw = zones.probs_edges_orig[id_orig]15151516# check accessibility of origin edges15171518#prob_edges_orig = []1519#inds_lane_orig = []15201521for i in xrange(len(ids_edges_orig_raw)):1522id_edge = ids_edges_orig_raw[i]1523# if check accessibility...1524ind_lane_depart_taxi = edges.get_laneindex_allowed(id_edge, id_mode_taxi)1525ind_lane_depart_ped = edges.get_laneindex_allowed(id_edge, id_mode_ped)15261527# print ' O get_laneindex_allowed id_mode_taxi',id_mode_taxi,id_edge,edges.ids_sumo[id_edge],'ind_lane',ind_lane_depart1528if (ind_lane_depart_taxi >= 0) & (ind_lane_depart_ped >= 0):1529ids_edges_orig.append(id_edge)1530# prob_edges_orig.append(prob_edges_orig_raw[i])1531# are_fallback_orig.append(False)1532# inds_lane_orig.append(ind_lane_depart)15331534n_edges_orig = len(ids_edges_orig)15351536print '\n found', n_edges_orig, 'valid zone edges'15371538# now create taxi trips1539if (n_edges_orig > 0) & (tripnumber > 0):1540# normalize weights1541edgeprops = np.zeros(n_edges_orig, dtype=np.float32)15421543for i, id_edge in zip(xrange(n_edges_orig), ids_edges_orig):1544edgeprops[i] = edgeprops_all[id_edge]15451546edgeprops = edgeprops/np.sum(edgeprops)15471548# debug1549if 0:1550for id_edge, prob in zip(ids_edges_orig, edgeprops):1551print ' orig id_edge', id_edge, 'has prob', prob15521553for d in xrange(int(tripnumber+0.5)):1554# print ' ------------'1555# print ' generte trip',d1556time_depart = np.random.uniform(time_start, time_end)15571558i_orig = np.argmax(np.random.rand(n_edges_orig)*edgeprops)1559id_edge_orig = ids_edges_orig[i_orig]15601561# destination edge is origin edge1562# this is no problem as taxis will never leave the sim1563id_edge_dest = id_edge_orig1564route = [id_edge_orig]15651566# Destination is next edge1567#1568#is_accessible = False1569# for id_edge_dest in fstar[id_edge_orig]:1570# # if check accessibility...1571# ind_lane_depart_taxi = edges.get_laneindex_allowed(id_edge_dest, id_mode_taxi)1572# ind_lane_depart_ped = edges.get_laneindex_allowed(id_edge_dest, id_mode_ped)1573# if (ind_lane_depart_taxi >= 0)&(ind_lane_depart_ped >= 0):1574# is_accessible = True1575# break1576# if not is_accessible:1577# id_edge_dest = id_edge_orig1578# route = [id_edge_orig]1579# else:1580# route = [id_edge_orig,id_edge_dest]15811582id_vtype = ids_vtype_mode_taxi[np.argmax(1583np.random.rand(n_vtypes_taxi)*prob_vtype_mode_taxi)]15841585# trip is from beginning to end of edge1586# however, taxi will not be eliminated at the1587# end of edge but continue to next client1588id_trip = trips.make_trip(id_vtype=id_vtype,1589time_depart=time_depart,1590id_edge_depart=id_edge_orig,1591id_edge_arrival=id_edge_dest,1592ind_lane_depart=-5, # "first":1593ind_lane_arrival=-1, # "current",1594position_depart=-4, # "base",1595position_arrival=-2, # "max",1596speed_depart=0.0,1597speed_arrival=0.0,1598route=route,1599)16001601n_trips_generated += 116021603print ' n_trips_generated', n_trips_generated, 'of', self.n_taxi1604return True16051606else:1607print ' no taxi created n_edges_orig', n_edges_orig, 'tripnumber', tripnumber1608return False16091610def do(self):16111612return self.generate_taxi()161316141615if __name__ == '__main__':1616###############################################################################1617# print 'sys.path',sys.path1618from agilepy.lib_wx.objpanel import objbrowser1619from agilepy.lib_base.logger import Logger1620#from coremodules.scenario import scenario1621from coremodules.network import network1622logger = Logger()1623NETPATH = os.path.join(SUMOPYDIR, 'coremodules', 'network', 'testnet')1624net = network.Network(logger=logger)1625rootname = 'facsp2'1626net.import_xml(rootname, NETPATH)1627# net.read_sumonodes(os.path.join(NETPATH,'facsp2.nod.xml'))1628# net.read_sumoedges(os.path.join(NETPATH,'facsp2.edg.xml'))1629demand = Demand(net=net, logger=logger)1630# demand.set_net(net)1631# landuse.facilities.import_poly(os.path.join(NETPATH,'facsp2.poly.xml'))1632#landuse.import_xml(rootname, NETPATH)1633objbrowser(demand)163416351636