SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MSDevice_Vehroutes.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 // A device which collects info on the vehicle trip
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
13 // Copyright (C) 2009-2014 DLR (http://www.dlr.de/) and contributors
14 /****************************************************************************/
15 //
16 // This file is part of SUMO.
17 // SUMO is free software: you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation, either version 3 of the License, or
20 // (at your option) any later version.
21 //
22 /****************************************************************************/
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #ifdef _MSC_VER
28 #include <windows_config.h>
29 #else
30 #include <config.h>
31 #endif
32 
33 #include <microsim/MSNet.h>
34 #include <microsim/MSLane.h>
35 #include <microsim/MSEdge.h>
36 #include <microsim/MSRoute.h>
37 #include <microsim/MSVehicleType.h>
41 #include "MSDevice_Vehroutes.h"
42 
43 #ifdef CHECK_MEMORY_LEAKS
44 #include <foreign/nvwa/debug_new.h>
45 #endif // CHECK_MEMORY_LEAKS
46 
47 
48 // ===========================================================================
49 // static member variables
50 // ===========================================================================
53 bool MSDevice_Vehroutes::mySorted = false;
56 std::map<const SUMOTime, int> MSDevice_Vehroutes::myDepartureCounts;
57 std::map<const SUMOTime, std::string> MSDevice_Vehroutes::myRouteInfos;
58 
59 
60 // ===========================================================================
61 // method definitions
62 // ===========================================================================
63 // ---------------------------------------------------------------------------
64 // static initialisation methods
65 // ---------------------------------------------------------------------------
66 void
68  if (OptionsCont::getOptions().isSet("vehroute-output")) {
69  OutputDevice::createDeviceByOption("vehroute-output", "routes", "routes_file.xsd");
70  mySaveExits = OptionsCont::getOptions().getBool("vehroute-output.exit-times");
71  myLastRouteOnly = OptionsCont::getOptions().getBool("vehroute-output.last-route");
72  mySorted = OptionsCont::getOptions().getBool("vehroute-output.sorted");
73  myWithTaz = OptionsCont::getOptions().getBool("device.rerouting.with-taz");
75  }
76 }
77 
78 
80 MSDevice_Vehroutes::buildVehicleDevices(SUMOVehicle& v, std::vector<MSDevice*>& into, unsigned int maxRoutes) {
81  if (maxRoutes < INT_MAX) {
82  return new MSDevice_Vehroutes(v, "vehroute_" + v.getID(), maxRoutes);
83  }
84  if (OptionsCont::getOptions().isSet("vehroute-output")) {
85  if (myLastRouteOnly) {
86  maxRoutes = 0;
87  }
88  myStateListener.myDevices[&v] = new MSDevice_Vehroutes(v, "vehroute_" + v.getID(), maxRoutes);
89  into.push_back(myStateListener.myDevices[&v]);
90  return myStateListener.myDevices[&v];
91  }
92  return 0;
93 }
94 
95 
96 // ---------------------------------------------------------------------------
97 // MSDevice_Vehroutes::StateListener-methods
98 // ---------------------------------------------------------------------------
99 void
101  if (to == MSNet::VEHICLE_STATE_NEWROUTE) {
102  myDevices[vehicle]->addRoute();
103  }
104 }
105 
106 
107 // ---------------------------------------------------------------------------
108 // MSDevice_Vehroutes-methods
109 // ---------------------------------------------------------------------------
110 MSDevice_Vehroutes::MSDevice_Vehroutes(SUMOVehicle& holder, const std::string& id, unsigned int maxRoutes)
111  : MSDevice(holder, id), myCurrentRoute(&holder.getRoute()), myMaxRoutes(maxRoutes), myLastSavedAt(0) {
113 }
114 
115 
117  for (std::vector<RouteReplaceInfo>::iterator i = myReplacedRoutes.begin(); i != myReplacedRoutes.end(); ++i) {
118  (*i).route->release();
119  }
122 }
123 
124 
125 bool
127  if (mySorted && reason == NOTIFICATION_DEPARTED && myStateListener.myDevices[&veh] == this) {
129  }
130  return mySaveExits;
131 }
132 
133 
134 bool
136  if (mySaveExits && reason != NOTIFICATION_LANE_CHANGE) {
137  if (reason != NOTIFICATION_TELEPORT && myLastSavedAt == veh.getEdge()) { // need to check this for internal lanes
139  } else {
140  myExits.push_back(MSNet::getInstance()->getCurrentTimeStep());
141  myLastSavedAt = veh.getEdge();
142  }
143  }
144  return mySaveExits;
145 }
146 
147 
148 void
150  // check if a previous route shall be written
152  if (index >= 0) {
153  assert((int) myReplacedRoutes.size() > index);
154  // write edge on which the vehicle was when the route was valid
155  os << " replacedOnEdge=\"";
156  if (myReplacedRoutes[index].edge) {
157  os << myReplacedRoutes[index].edge->getID();
158  }
159  // write the time at which the route was replaced
160  os << "\" replacedAtTime=\"" << time2string(myReplacedRoutes[index].time) << "\" probability=\"0\" edges=\"";
161  // get the route
162  int i = index;
163  while (i > 0 && myReplacedRoutes[i - 1].edge) {
164  i--;
165  }
166  const MSEdge* lastEdge = 0;
167  for (; i < index; ++i) {
168  myReplacedRoutes[i].route->writeEdgeIDs(os, lastEdge, myReplacedRoutes[i].edge);
169  lastEdge = myReplacedRoutes[i].edge;
170  }
171  myReplacedRoutes[index].route->writeEdgeIDs(os, lastEdge);
172  } else {
173  os << " edges=\"";
174  const MSEdge* lastEdge = 0;
175  int numWritten = 0;
176  if (myHolder.getNumberReroutes() > 0) {
177  assert(myReplacedRoutes.size() <= myHolder.getNumberReroutes());
178  unsigned int i = static_cast<unsigned int>(myReplacedRoutes.size());
179  while (i > 0 && myReplacedRoutes[i - 1].edge) {
180  i--;
181  }
182  for (; i < myReplacedRoutes.size(); ++i) {
183  numWritten += myReplacedRoutes[i].route->writeEdgeIDs(os, lastEdge, myReplacedRoutes[i].edge);
184  lastEdge = myReplacedRoutes[i].edge;
185  }
186  }
187  const MSEdge* upTo = 0;
188  if (mySaveExits) {
189  int remainingWithExitTime = (int)myExits.size() - numWritten;
190  assert(remainingWithExitTime >= 0);
191  assert(remainingWithExitTime <= (int)myCurrentRoute->size());
192  if (remainingWithExitTime < (int)myCurrentRoute->size()) {
193  upTo = *(myCurrentRoute->begin() + remainingWithExitTime);
194  }
195  }
196  myCurrentRoute->writeEdgeIDs(os, lastEdge, upTo);
197  if (mySaveExits) {
198  os << "\" exitTimes=\"";
199  for (std::vector<SUMOTime>::const_iterator it = myExits.begin(); it != myExits.end(); ++it) {
200  if (it != myExits.begin()) {
201  os << " ";
202  }
203  os << time2string(*it);
204  }
205  }
206  }
207  (os << "\"").closeTag();
208 }
209 
210 
211 void
213  OutputDevice& routeOut = OutputDevice::getDeviceByOption("vehroute-output");
214  OutputDevice_String od(routeOut.isBinary(), 1);
218  }
220  if (myHolder.hasArrived()) {
221  od.writeAttr("arrival", time2string(MSNet::getInstance()->getCurrentTimeStep()));
222  }
223  if (myWithTaz) {
225  }
226  if (myReplacedRoutes.size() > 0) {
228  for (unsigned int i = 0; i < myReplacedRoutes.size(); ++i) {
229  writeXMLRoute(od, i);
230  }
231  }
232  writeXMLRoute(od);
233  if (myReplacedRoutes.size() > 0) {
234  od.closeTag();
235  }
236  od.closeTag();
237  od.lf();
238  if (mySorted) {
239  myRouteInfos[myHolder.getDeparture()] += od.getString();
241  std::map<const SUMOTime, int>::iterator it = myDepartureCounts.begin();
242  while (it != myDepartureCounts.end() && it->second == 0) {
243  routeOut << myRouteInfos[it->first];
244  myRouteInfos.erase(it->first);
245  myDepartureCounts.erase(it);
246  it = myDepartureCounts.begin();
247  }
248  } else {
249  routeOut << od.getString();
250  }
251 }
252 
253 
254 const MSRoute*
256  return myReplacedRoutes[index].route;
257 }
258 
259 
260 void
262  if (myMaxRoutes > 0) {
263  if (myHolder.hasDeparted()) {
265  } else {
266  myReplacedRoutes.push_back(RouteReplaceInfo(0, MSNet::getInstance()->getCurrentTimeStep(), myCurrentRoute));
267  }
268  if (myReplacedRoutes.size() > myMaxRoutes) {
269  myReplacedRoutes.front().route->release();
270  myReplacedRoutes.erase(myReplacedRoutes.begin());
271  }
272  } else {
274  }
277 }
278 
279 
280 void
282  for (std::map<const SUMOVehicle*, MSDevice_Vehroutes*, Named::NamedLikeComparatorIdLess<SUMOVehicle> >::const_iterator it = myStateListener.myDevices.begin();
283  it != myStateListener.myDevices.end(); ++it) {
284  if (it->first->hasDeparted()) {
285  it->second->generateOutput();
286  }
287  }
288 }
289 
290 
291 /****************************************************************************/
292