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