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.sourceforge.net/
12 // Copyright (C) 2001-2012 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 <string>
34 #include <iostream>
35 #include <fstream>
36 #include <deque>
37 #include <queue>
38 #include "ROEdge.h"
39 #include "RONode.h"
40 #include "RONet.h"
41 #include "RORoute.h"
42 #include "RORouteDef.h"
43 #include "ROVehicle.h"
49 #include <utils/common/ToString.h>
53 
54 #ifdef CHECK_MEMORY_LEAKS
55 #include <foreign/nvwa/debug_new.h>
56 #endif // CHECK_MEMORY_LEAKS
57 
58 
59 // ===========================================================================
60 // method definitions
61 // ===========================================================================
63  : myVehicleTypes(), myDefaultVTypeMayBeDeleted(true),
64  myRoutesOutput(0), myRouteAlternativesOutput(0), myTypesOutput(0),
65  myReadRouteNo(0), myDiscardedRouteNo(0), myWrittenRouteNo(0),
66  myHaveRestrictions(false) {
68  type->id = DEFAULT_VTYPE_ID;
69  type->onlyReferenced = true;
70  myVehicleTypes.add(type->id, type);
71 }
72 
73 
75  myNodes.clear();
76  myEdges.clear();
78  myRoutes.clear();
79  myVehicles.clear();
80 }
81 
82 
83 bool
85  if (!myEdges.add(edge->getID(), edge)) {
86  WRITE_ERROR("The edge '" + edge->getID() + "' occurs at least twice.");
87  delete edge;
88  return false;
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 bool
105  return myRoutes.add(def->getID(), def);
106 }
107 
108 
109 void
110 RONet::openOutput(const std::string& filename, bool useAlternatives, const std::string& typefilename) {
112  if (useAlternatives) {
113  const size_t len = filename.length();
114  if (len > 4 && filename.substr(len - 4) == ".xml") {
115  myRouteAlternativesOutput = &OutputDevice::getDevice(filename.substr(0, len - 4) + ".alt.xml");
116  } else {
117  if (len > 4 && filename.substr(len - 4) == ".sbx") {
118  myRouteAlternativesOutput = &OutputDevice::getDevice(filename.substr(0, len - 4) + ".alt.sbx");
119  } else {
121  }
122  }
123  }
125  if (useAlternatives) {
127  }
128  if (typefilename != "") {
129  myTypesOutput = &OutputDevice::getDevice(typefilename);
130  myTypesOutput->writeXMLHeader("routes", "", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.sf.net/xsd/routes_file.xsd\"");
131  }
132 }
133 
134 
135 void
137  // end writing
138  if (myRoutesOutput != 0) {
140  }
141  // only if opened
142  if (myRouteAlternativesOutput != 0) {
144  }
145  // only if opened
146  if (myTypesOutput != 0) {
147  myTypesOutput->close();
148  }
149 }
150 
151 
152 
154 RONet::getVehicleTypeSecure(const std::string& id) {
155  // check whether the type was already known
157  if (id == DEFAULT_VTYPE_ID) {
159  }
160  if (type != 0) {
161  return type;
162  }
163  VTypeDistDictType::iterator it2 = myVTypeDistDict.find(id);
164  if (it2 != myVTypeDistDict.end()) {
165  return it2->second->get();
166  }
167  if (id == "") {
168  // ok, no vehicle type was given within the user input
169  // return the default type
172  }
173  // Assume, the user will define the type somewhere else
174  // return a type which contains the id only
175  type = new SUMOVTypeParameter();
176  type->id = id;
177  type->onlyReferenced = true;
178  addVehicleType(type);
179  return type;
180 }
181 
182 
183 bool
184 RONet::checkVType(const std::string& id) {
185  if (id == DEFAULT_VTYPE_ID) {
189  } else {
190  return false;
191  }
192  } else {
193  if (myVehicleTypes.get(id) != 0 || myVTypeDistDict.find(id) != myVTypeDistDict.end()) {
194  return false;
195  }
196  }
197  return true;
198 }
199 
200 
201 bool
203  if (checkVType(type->id)) {
204  myVehicleTypes.add(type->id, type);
205  } else {
206  WRITE_ERROR("The vehicle type '" + type->id + "' occurs at least twice.");
207  delete type;
208  return false;
209  }
210  return true;
211 }
212 
213 
214 bool
215 RONet::addVTypeDistribution(const std::string& id, RandomDistributor<SUMOVTypeParameter*>* vehTypeDistribution) {
216  if (checkVType(id)) {
217  myVTypeDistDict[id] = vehTypeDistribution;
218  return true;
219  }
220  return false;
221 }
222 
223 
224 bool
225 RONet::addVehicle(const std::string& id, ROVehicle* veh) {
226  if (myVehIDs.find(id) == myVehIDs.end() && myVehicles.add(id, veh)) {
227  myVehIDs.insert(id);
228  myReadRouteNo++;
229  return true;
230  }
231  WRITE_ERROR("The vehicle '" + id + "' occurs at least twice.");
232  return false;
233 }
234 
235 
236 bool
238  const ROVehicle* const veh) {
240  std::string noRouteMsg = "The vehicle '" + veh->getID() + "' has no valid route.";
241  if (options.getBool("ignore-errors")) {
243  }
244  RORouteDef* const routeDef = veh->getRouteDefinition();
245  // check if the route definition is valid
246  if (routeDef == 0) {
247  mh->inform(noRouteMsg);
248  return false;
249  }
250  // check whether the route was already saved
251  if (routeDef->isSaved()) {
252  return true;
253  }
254  //
255  RORoute* current = routeDef->buildCurrentRoute(router, veh->getDepartureTime(), *veh);
256  if (current == 0 || current->size() == 0) {
257  delete current;
258  mh->inform(noRouteMsg);
259  return false;
260  }
261  // check whether we have to evaluate the route for not containing loops
262  if (options.getBool("remove-loops")) {
263  current->recheckForLoops();
264  // check whether the route is still valid
265  if (current->size() == 0) {
266  delete current;
267  mh->inform(noRouteMsg + " (after removing loops)");
268  return false;
269  }
270  }
271  // add built route
272  routeDef->addAlternative(router, veh, current, veh->getDepartureTime());
273  return true;
274 }
275 
276 
277 SUMOTime
279  SUMOTime time) {
280  SUMOTime lastTime = -1;
281  // write all vehicles (and additional structures)
282  while (myVehicles.size() != 0) {
283  // get the next vehicle
284  const ROVehicle* const veh = myVehicles.getTopVehicle();
285  SUMOTime currentTime = veh->getDepartureTime();
286  // check whether it shall not yet be computed
287  if (currentTime > time) {
288  lastTime = currentTime;
289  break;
290  }
291  // check whether to print the output
292  if (lastTime != currentTime && lastTime != -1) {
293  // report writing progress
294  if (options.getInt("stats-period") >= 0 && ((int) currentTime % options.getInt("stats-period")) == 0) {
295  WRITE_MESSAGE("Read: " + toString(myReadRouteNo) + ", Discarded: " + toString(myDiscardedRouteNo) + ", Written: " + toString(myWrittenRouteNo));
296  }
297  }
298  lastTime = currentTime;
299 
300  // ok, compute the route (try it)
301  if (computeRoute(options, router, veh)) {
302  // write the route
305  } else {
307  }
308  // delete routes and the vehicle
309  if (veh->getRouteDefinition()->getID()[0] == '!') {
310  if (!myRoutes.erase(veh->getRouteDefinition()->getID())) {
311  delete veh->getRouteDefinition();
312  }
313  }
314  myVehicles.erase(veh->getID());
315  }
316  return lastTime;
317 }
318 
319 
320 bool
322  return myVehicles.size() > 0;
323 }
324 
325 
326 ROEdge*
328  // check whether an edge may be returned
330  if (mySourceEdges.size() == 0) {
331  return 0;
332  }
333  // choose a random edge
335 }
336 
337 
338 const ROEdge*
340  // check whether an edge may be returned
342  if (mySourceEdges.size() == 0) {
343  return 0;
344  }
345  // choose a random edge
347 }
348 
349 
350 
351 ROEdge*
353  // check whether an edge may be returned
355  if (myDestinationEdges.size() == 0) {
356  return 0;
357  }
358  // choose a random edge
360 }
361 
362 
363 const ROEdge*
365  // check whether an edge may be returned
367  if (myDestinationEdges.size() == 0) {
368  return 0;
369  }
370  // choose a random edge
372 }
373 
374 
375 void
377  if (myDestinationEdges.size() != 0 || mySourceEdges.size() != 0) {
378  return;
379  }
380  const std::map<std::string, ROEdge*>& edges = myEdges.getMyMap();
381  for (std::map<std::string, ROEdge*>::const_iterator i = edges.begin(); i != edges.end(); ++i) {
382  ROEdge* e = (*i).second;
383  ROEdge::EdgeType type = e->getType();
384  // !!! add something like "classified edges only" for using only sources or sinks
385  if (type != ROEdge::ET_SOURCE) {
386  myDestinationEdges.push_back(e);
387  }
388  if (type != ROEdge::ET_SINK) {
389  mySourceEdges.push_back(e);
390  }
391  }
392 }
393 
394 
395 unsigned int
397  return (unsigned int) myEdges.size();
398 }
399 
400 
401 const std::map<std::string, ROEdge*>&
403  return myEdges.getMyMap();
404 }
405 
406 
407 bool
409  return myHaveRestrictions;
410 }
411 
412 
413 void
415  myHaveRestrictions = true;
416 }
417 
418 
419 
420 /****************************************************************************/
421