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),
63  myNumInternalEdges(0) {
65  type->id = DEFAULT_VTYPE_ID;
66  type->onlyReferenced = true;
67  myVehicleTypes.add(type->id, type);
68 }
69 
70 
72  myNodes.clear();
73  myEdges.clear();
75  myRoutes.clear();
76  myVehicles.clear();
77 }
78 
79 
80 bool
82  if (!myEdges.add(edge->getID(), edge)) {
83  WRITE_ERROR("The edge '" + edge->getID() + "' occurs at least twice.");
84  delete edge;
85  return false;
86  }
87  if (edge->getType() == ROEdge::ET_INTERNAL) {
88  myNumInternalEdges += 1;
89  }
90  return true;
91 }
92 
93 
94 void
96  if (!myNodes.add(node->getID(), node)) {
97  WRITE_ERROR("The node '" + node->getID() + "' occurs at least twice.");
98  delete node;
99  }
100 }
101 
102 
103 void
104 RONet::addBusStop(const std::string& id, SUMOVehicleParameter::Stop* stop) {
105  std::map<std::string, SUMOVehicleParameter::Stop*>::const_iterator it = myBusStops.find(id);
106  if (it != myBusStops.end()) {
107  WRITE_ERROR("The bus stop '" + id + "' occurs at least twice.");
108  delete stop;
109  }
110  myBusStops[id] = stop;
111 }
112 
113 
114 bool
116  return myRoutes.add(def->getID(), def);
117 }
118 
119 
120 void
121 RONet::openOutput(const std::string& filename, const std::string altFilename, const std::string typeFilename) {
122  if (filename != "") {
125  myRoutesOutput->writeAttr("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance").writeAttr("xsi:noNamespaceSchemaLocation", "http://sumo-sim.org/xsd/routes_file.xsd");
126  }
127  if (altFilename != "") {
130  myRouteAlternativesOutput->writeAttr("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance").writeAttr("xsi:noNamespaceSchemaLocation", "http://sumo-sim.org/xsd/routes_file.xsd");
131  }
132  if (typeFilename != "") {
133  myTypesOutput = &OutputDevice::getDevice(typeFilename);
134  myTypesOutput->writeXMLHeader("routes", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo-sim.org/xsd/routes_file.xsd\"");
135  }
136 }
137 
138 
139 void
141  // end writing
142  if (myRoutesOutput != 0) {
144  }
145  // only if opened
146  if (myRouteAlternativesOutput != 0) {
148  }
149  // only if opened
150  if (myTypesOutput != 0) {
151  myTypesOutput->close();
152  }
153 }
154 
155 
156 
158 RONet::getVehicleTypeSecure(const std::string& id) {
159  // check whether the type was already known
161  if (id == DEFAULT_VTYPE_ID) {
163  }
164  if (type != 0) {
165  return type;
166  }
167  VTypeDistDictType::iterator it2 = myVTypeDistDict.find(id);
168  if (it2 != myVTypeDistDict.end()) {
169  return it2->second->get();
170  }
171  if (id == "") {
172  // ok, no vehicle type was given within the user input
173  // return the default type
176  }
177  // Assume, the user will define the type somewhere else
178  // return a type which contains the id only
179  type = new SUMOVTypeParameter();
180  type->id = id;
181  type->onlyReferenced = true;
182  addVehicleType(type);
183  return type;
184 }
185 
186 
187 bool
188 RONet::checkVType(const std::string& id) {
189  if (id == DEFAULT_VTYPE_ID) {
193  } else {
194  return false;
195  }
196  } else {
197  if (myVehicleTypes.get(id) != 0 || myVTypeDistDict.find(id) != myVTypeDistDict.end()) {
198  return false;
199  }
200  }
201  return true;
202 }
203 
204 
205 bool
207  if (checkVType(type->id)) {
208  myVehicleTypes.add(type->id, type);
209  } else {
210  WRITE_ERROR("The vehicle type '" + type->id + "' occurs at least twice.");
211  delete type;
212  return false;
213  }
214  return true;
215 }
216 
217 
218 bool
219 RONet::addVTypeDistribution(const std::string& id, RandomDistributor<SUMOVTypeParameter*>* vehTypeDistribution) {
220  if (checkVType(id)) {
221  myVTypeDistDict[id] = vehTypeDistribution;
222  return true;
223  }
224  return false;
225 }
226 
227 
228 bool
229 RONet::addVehicle(const std::string& id, ROVehicle* veh) {
230  if (myVehIDs.find(id) == myVehIDs.end() && myVehicles.add(id, veh)) {
231  myVehIDs.insert(id);
232  myReadRouteNo++;
233  return true;
234  }
235  WRITE_ERROR("The vehicle '" + id + "' occurs at least twice.");
236  return false;
237 }
238 
239 
240 bool
241 RONet::addFlow(SUMOVehicleParameter* flow, const bool randomize) {
242  if (randomize) {
243  myDepartures[flow->id].reserve(flow->repetitionNumber);
244  for (int i = 0; i < flow->repetitionNumber; ++i) {
245  myDepartures[flow->id].push_back(flow->depart + RandHelper::rand(flow->repetitionNumber * flow->repetitionOffset));
246  }
247  std::sort(myDepartures[flow->id].begin(), myDepartures[flow->id].end());
248  std::reverse(myDepartures[flow->id].begin(), myDepartures[flow->id].end());
249  }
250  return myFlows.add(flow->id, flow);
251 }
252 
253 
254 void
255 RONet::addPerson(const SUMOTime depart, const std::string desc) {
256  myPersons.insert(std::pair<const SUMOTime, const std::string>(depart, desc));
257 }
258 
259 
260 bool
262  const ROVehicle* const veh) {
263  MsgHandler* mh = (OptionsCont::getOptions().getBool("ignore-errors") ?
265  std::string noRouteMsg = "The vehicle '" + veh->getID() + "' has no valid route.";
266  RORouteDef* const routeDef = veh->getRouteDefinition();
267  // check if the route definition is valid
268  if (routeDef == 0) {
269  mh->inform(noRouteMsg);
270  return false;
271  }
272  // check whether the route was already saved
273  if (routeDef->isSaved()) {
274  return true;
275  }
276  //
277  RORoute* current = routeDef->buildCurrentRoute(router, veh->getDepartureTime(), *veh);
278  if (current == 0 || current->size() == 0) {
279  delete current;
280  mh->inform(noRouteMsg);
281  return false;
282  }
283  // check whether we have to evaluate the route for not containing loops
284  if (options.getBool("remove-loops")) {
285  current->recheckForLoops();
286  // check whether the route is still valid
287  if (current->size() == 0) {
288  delete current;
289  mh->inform(noRouteMsg + " (after removing loops)");
290  return false;
291  }
292  }
293  // add built route
294  routeDef->addAlternative(router, veh, current, veh->getDepartureTime());
295  return true;
296 }
297 
298 
299 void
301  std::vector<std::string> toRemove;
303  SUMOVehicleParameter* pars = i->second;
304  while (pars->repetitionsDone < pars->repetitionNumber) {
305  SUMOTime depart = static_cast<SUMOTime>(pars->depart + pars->repetitionsDone * pars->repetitionOffset);
306  if (myDepartures.find(pars->id) != myDepartures.end()) {
307  depart = myDepartures[pars->id].back();
308  }
309  if (depart >= time + DELTA_T) {
310  break;
311  }
312  if (myDepartures.find(pars->id) != myDepartures.end()) {
313  myDepartures[pars->id].pop_back();
314  }
315  SUMOVehicleParameter* newPars = new SUMOVehicleParameter(*pars);
316  newPars->id = pars->id + "." + toString(pars->repetitionsDone);
317  newPars->depart = depart;
318  pars->repetitionsDone++;
319  // try to build the vehicle
321  RORouteDef* route = getRouteDef(pars->routeid)->copy("!" + newPars->id);
322  ROVehicle* veh = new ROVehicle(*newPars, route, type, this);
323  addVehicle(newPars->id, veh);
324  delete newPars;
325  }
326  if (pars->repetitionsDone == pars->repetitionNumber) {
327  toRemove.push_back(i->first);
328  }
329  }
330  for (std::vector<std::string>::const_iterator i = toRemove.begin(); i != toRemove.end(); ++i) {
331  myFlows.erase(*i);
332  }
333 }
334 
335 
336 SUMOTime
338  SUMOTime time) {
339  checkFlows(time);
340  SUMOTime lastTime = -1;
341  // write all vehicles (and additional structures)
342  while (myVehicles.size() != 0 || myPersons.size() != 0) {
343  // get the next vehicle and person
344  const ROVehicle* const veh = myVehicles.getTopVehicle();
345  const SUMOTime vehicleTime = veh == 0 ? SUMOTime_MAX : veh->getDepartureTime();
346  PersonMap::iterator person = myPersons.begin();
347  const SUMOTime personTime = person == myPersons.end() ? SUMOTime_MAX : person->first;
348  // check whether it shall not yet be computed
349  if (vehicleTime > time && personTime > time) {
350  lastTime = MIN2(vehicleTime, personTime);
351  break;
352  }
353  if (vehicleTime < personTime) {
354  // check whether to print the output
355  if (lastTime != vehicleTime && lastTime != -1) {
356  // report writing progress
357  if (options.getInt("stats-period") >= 0 && ((int) vehicleTime % options.getInt("stats-period")) == 0) {
358  WRITE_MESSAGE("Read: " + toString(myReadRouteNo) + ", Discarded: " + toString(myDiscardedRouteNo) + ", Written: " + toString(myWrittenRouteNo));
359  }
360  }
361  lastTime = vehicleTime;
362 
363  // ok, compute the route (try it)
364  if (computeRoute(options, router, veh)) {
365  // write the route
368  } else {
370  }
371  // delete routes and the vehicle
372  if (veh->getRouteDefinition()->getID()[0] == '!') {
373  if (!myRoutes.erase(veh->getRouteDefinition()->getID())) {
374  delete veh->getRouteDefinition();
375  }
376  }
377  myVehicles.erase(veh->getID());
378  } else {
379  (*myRoutesOutput) << person->second;
380  if (myRouteAlternativesOutput != 0) {
381  (*myRouteAlternativesOutput) << person->second;
382  }
383  myPersons.erase(person);
384  }
385  }
386  return lastTime;
387 }
388 
389 
390 bool
392  return myVehicles.size() > 0 || myFlows.size() > 0;
393 }
394 
395 
396 unsigned int
398  return (unsigned int) myEdges.size();
399 }
400 
401 
402 unsigned int
404  return (unsigned int)(myEdges.size() - myNumInternalEdges);
405 }
406 
407 
408 const std::map<std::string, ROEdge*>&
410  return myEdges.getMyMap();
411 }
412 
413 
414 bool
416  return myHaveRestrictions;
417 }
418 
419 
420 void
422  myHaveRestrictions = true;
423 }
424 
425 
426 
427 /****************************************************************************/
428