SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RONet.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // The router's network representation
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 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #ifdef _MSC_VER
28 #include <windows_config.h>
29 #else
30 #include <config.h>
31 #endif
32 
33 #include <algorithm>
34 #include "ROEdge.h"
35 #include "RONode.h"
36 #include "RONet.h"
37 #include "RORoute.h"
38 #include "RORouteDef.h"
39 #include "ROVehicle.h"
45 #include <utils/common/ToString.h>
49 
50 #ifdef CHECK_MEMORY_LEAKS
51 #include <foreign/nvwa/debug_new.h>
52 #endif // CHECK_MEMORY_LEAKS
53 
54 
55 // ===========================================================================
56 // method definitions
57 // ===========================================================================
59  : myVehicleTypes(), myDefaultVTypeMayBeDeleted(true),
60  myRoutesOutput(0), myRouteAlternativesOutput(0), myTypesOutput(0),
61  myReadRouteNo(0), myDiscardedRouteNo(0), myWrittenRouteNo(0),
62  myHaveRestrictions(false) {
64  type->id = DEFAULT_VTYPE_ID;
65  type->onlyReferenced = true;
66  myVehicleTypes.add(type->id, type);
67 }
68 
69 
71  myNodes.clear();
72  myEdges.clear();
74  myRoutes.clear();
75  myVehicles.clear();
76 }
77 
78 
79 bool
81  if (!myEdges.add(edge->getID(), edge)) {
82  WRITE_ERROR("The edge '" + edge->getID() + "' occurs at least twice.");
83  delete edge;
84  return false;
85  }
86  return true;
87 }
88 
89 
90 void
92  if (!myNodes.add(node->getID(), node)) {
93  WRITE_ERROR("The node '" + node->getID() + "' occurs at least twice.");
94  delete node;
95  }
96 }
97 
98 
99 bool
101  return myRoutes.add(def->getID(), def);
102 }
103 
104 
105 void
106 RONet::openOutput(const std::string& filename, const std::string altFilename, const std::string typeFilename) {
107  if (filename != "") {
110  myRoutesOutput->writeAttr("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance").writeAttr("xsi:noNamespaceSchemaLocation", "http://sumo.sf.net/xsd/routes_file.xsd");
111  }
112  if (altFilename != "") {
115  myRouteAlternativesOutput->writeAttr("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance").writeAttr("xsi:noNamespaceSchemaLocation", "http://sumo.sf.net/xsd/routes_file.xsd");
116  }
117  if (typeFilename != "") {
118  myTypesOutput = &OutputDevice::getDevice(typeFilename);
119  myTypesOutput->writeXMLHeader("routes", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.sf.net/xsd/routes_file.xsd\"");
120  }
121 }
122 
123 
124 void
126  // end writing
127  if (myRoutesOutput != 0) {
129  }
130  // only if opened
131  if (myRouteAlternativesOutput != 0) {
133  }
134  // only if opened
135  if (myTypesOutput != 0) {
136  myTypesOutput->close();
137  }
138 }
139 
140 
141 
143 RONet::getVehicleTypeSecure(const std::string& id) {
144  // check whether the type was already known
146  if (id == DEFAULT_VTYPE_ID) {
148  }
149  if (type != 0) {
150  return type;
151  }
152  VTypeDistDictType::iterator it2 = myVTypeDistDict.find(id);
153  if (it2 != myVTypeDistDict.end()) {
154  return it2->second->get();
155  }
156  if (id == "") {
157  // ok, no vehicle type was given within the user input
158  // return the default type
161  }
162  // Assume, the user will define the type somewhere else
163  // return a type which contains the id only
164  type = new SUMOVTypeParameter();
165  type->id = id;
166  type->onlyReferenced = true;
167  addVehicleType(type);
168  return type;
169 }
170 
171 
172 bool
173 RONet::checkVType(const std::string& id) {
174  if (id == DEFAULT_VTYPE_ID) {
178  } else {
179  return false;
180  }
181  } else {
182  if (myVehicleTypes.get(id) != 0 || myVTypeDistDict.find(id) != myVTypeDistDict.end()) {
183  return false;
184  }
185  }
186  return true;
187 }
188 
189 
190 bool
192  if (checkVType(type->id)) {
193  myVehicleTypes.add(type->id, type);
194  } else {
195  WRITE_ERROR("The vehicle type '" + type->id + "' occurs at least twice.");
196  delete type;
197  return false;
198  }
199  return true;
200 }
201 
202 
203 bool
204 RONet::addVTypeDistribution(const std::string& id, RandomDistributor<SUMOVTypeParameter*>* vehTypeDistribution) {
205  if (checkVType(id)) {
206  myVTypeDistDict[id] = vehTypeDistribution;
207  return true;
208  }
209  return false;
210 }
211 
212 
213 bool
214 RONet::addVehicle(const std::string& id, ROVehicle* veh) {
215  if (myVehIDs.find(id) == myVehIDs.end() && myVehicles.add(id, veh)) {
216  myVehIDs.insert(id);
217  myReadRouteNo++;
218  return true;
219  }
220  WRITE_ERROR("The vehicle '" + id + "' occurs at least twice.");
221  return false;
222 }
223 
224 
225 bool
226 RONet::addFlow(SUMOVehicleParameter* flow, const bool randomize) {
227  if (randomize) {
228  myDepartures[flow->id].reserve(flow->repetitionNumber);
229  for (int i = 0; i < flow->repetitionNumber; ++i) {
230  myDepartures[flow->id].push_back(flow->depart + RandHelper::rand(flow->repetitionNumber * flow->repetitionOffset));
231  }
232  std::sort(myDepartures[flow->id].begin(), myDepartures[flow->id].end());
233  std::reverse(myDepartures[flow->id].begin(), myDepartures[flow->id].end());
234  }
235  return myFlows.add(flow->id, flow);
236 }
237 
238 
239 void
240 RONet::addPerson(const SUMOTime depart, const std::string desc) {
241  myPersons.insert(std::pair<const SUMOTime, const std::string>(depart, desc));
242 }
243 
244 
245 bool
247  const ROVehicle* const veh) {
248  MsgHandler* mh = (OptionsCont::getOptions().getBool("ignore-errors") ?
250  std::string noRouteMsg = "The vehicle '" + veh->getID() + "' has no valid route.";
251  RORouteDef* const routeDef = veh->getRouteDefinition();
252  // check if the route definition is valid
253  if (routeDef == 0) {
254  mh->inform(noRouteMsg);
255  return false;
256  }
257  // check whether the route was already saved
258  if (routeDef->isSaved()) {
259  return true;
260  }
261  //
262  RORoute* current = routeDef->buildCurrentRoute(router, veh->getDepartureTime(), *veh);
263  if (current == 0 || current->size() == 0) {
264  delete current;
265  mh->inform(noRouteMsg);
266  return false;
267  }
268  // check whether we have to evaluate the route for not containing loops
269  if (options.getBool("remove-loops")) {
270  current->recheckForLoops();
271  // check whether the route is still valid
272  if (current->size() == 0) {
273  delete current;
274  mh->inform(noRouteMsg + " (after removing loops)");
275  return false;
276  }
277  }
278  // add built route
279  routeDef->addAlternative(router, veh, current, veh->getDepartureTime());
280  return true;
281 }
282 
283 
284 void
286  std::vector<std::string> toRemove;
288  SUMOVehicleParameter* pars = i->second;
289  while (pars->repetitionsDone < pars->repetitionNumber) {
290  SUMOTime depart = static_cast<SUMOTime>(pars->depart + pars->repetitionsDone * pars->repetitionOffset);
291  if (myDepartures.find(pars->id) != myDepartures.end()) {
292  depart = myDepartures[pars->id].back();
293  }
294  if (depart >= time + DELTA_T) {
295  break;
296  }
297  if (myDepartures.find(pars->id) != myDepartures.end()) {
298  myDepartures[pars->id].pop_back();
299  }
300  SUMOVehicleParameter* newPars = new SUMOVehicleParameter(*pars);
301  newPars->id = pars->id + "." + toString(pars->repetitionsDone);
302  newPars->depart = depart;
303  pars->repetitionsDone++;
304  // try to build the vehicle
306  RORouteDef* route = getRouteDef(pars->routeid)->copy("!" + newPars->id);
307  ROVehicle* veh = new ROVehicle(*newPars, route, type);
308  addVehicle(newPars->id, veh);
309  delete newPars;
310  }
311  if (pars->repetitionsDone == pars->repetitionNumber) {
312  toRemove.push_back(i->first);
313  }
314  }
315  for (std::vector<std::string>::const_iterator i = toRemove.begin(); i != toRemove.end(); ++i) {
316  myFlows.erase(*i);
317  }
318 }
319 
320 
321 SUMOTime
323  SUMOTime time) {
324  checkFlows(time);
325  SUMOTime lastTime = -1;
326  // write all vehicles (and additional structures)
327  while (myVehicles.size() != 0 || myPersons.size() != 0) {
328  // get the next vehicle and person
329  const ROVehicle* const veh = myVehicles.getTopVehicle();
330  const SUMOTime vehicleTime = veh == 0 ? SUMOTime_MAX : veh->getDepartureTime();
331  PersonMap::iterator person = myPersons.begin();
332  const SUMOTime personTime = person == myPersons.end() ? SUMOTime_MAX : person->first;
333  // check whether it shall not yet be computed
334  if (vehicleTime > time && personTime > time) {
335  lastTime = MIN2(vehicleTime, personTime);
336  break;
337  }
338  if (vehicleTime < personTime) {
339  // check whether to print the output
340  if (lastTime != vehicleTime && lastTime != -1) {
341  // report writing progress
342  if (options.getInt("stats-period") >= 0 && ((int) vehicleTime % options.getInt("stats-period")) == 0) {
343  WRITE_MESSAGE("Read: " + toString(myReadRouteNo) + ", Discarded: " + toString(myDiscardedRouteNo) + ", Written: " + toString(myWrittenRouteNo));
344  }
345  }
346  lastTime = vehicleTime;
347 
348  // ok, compute the route (try it)
349  if (computeRoute(options, router, veh)) {
350  // write the route
353  } else {
355  }
356  // delete routes and the vehicle
357  if (veh->getRouteDefinition()->getID()[0] == '!') {
358  if (!myRoutes.erase(veh->getRouteDefinition()->getID())) {
359  delete veh->getRouteDefinition();
360  }
361  }
362  myVehicles.erase(veh->getID());
363  } else {
364  (*myRoutesOutput) << person->second;
365  if (myRouteAlternativesOutput != 0) {
366  (*myRouteAlternativesOutput) << person->second;
367  }
368  myPersons.erase(person);
369  }
370  }
371  return lastTime;
372 }
373 
374 
375 bool
377  return myVehicles.size() > 0 || myFlows.size() > 0;
378 }
379 
380 
381 unsigned int
383  return (unsigned int) myEdges.size();
384 }
385 
386 
387 const std::map<std::string, ROEdge*>&
389  return myEdges.getMyMap();
390 }
391 
392 
393 bool
395  return myHaveRestrictions;
396 }
397 
398 
399 void
401  myHaveRestrictions = true;
402 }
403 
404 
405 
406 /****************************************************************************/
407