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