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(),
64  myRoutesOutput(0), myRouteAlternativesOutput(0), myTypesOutput(0),
65  myReadRouteNo(0), myDiscardedRouteNo(0), myWrittenRouteNo(0),
66  myHaveRestrictions(false), myDefaultVTypeMayBeDeleted(true) {
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  myRoutesOutput->writeXMLHeader("routes", "", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.sf.net/xsd/routes_file.xsd\"");
113  if (useAlternatives) {
114  size_t len = filename.length();
115  if (len > 4 && filename.substr(len - 4) == ".xml") {
116  myRouteAlternativesOutput = &OutputDevice::getDevice(filename.substr(0, len - 4) + ".alt.xml");
117  } else {
119  }
120  myRouteAlternativesOutput->writeXMLHeader("route-alternatives", "", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.sf.net/xsd/routes_file.xsd\"");
121  }
122  if (typefilename != "") {
123  myTypesOutput = &OutputDevice::getDevice(typefilename);
124  myTypesOutput->writeXMLHeader("routes", "", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.sf.net/xsd/routes_file.xsd\"");
125  }
126 }
127 
128 
129 void
131  // end writing
132  if (myRoutesOutput != 0) {
134  }
135  // only if opened
136  if (myRouteAlternativesOutput != 0) {
138  }
139  // only if opened
140  if (myTypesOutput != 0) {
141  myTypesOutput->close();
142  }
143 }
144 
145 
146 
148 RONet::getVehicleTypeSecure(const std::string& id) {
149  // check whether the type was already known
151  if (id == DEFAULT_VTYPE_ID) {
153  }
154  if (type != 0) {
155  return type;
156  }
157  if (id == "") {
158  // ok, no vehicle type was given within the user input
159  // return the default type
162  }
163  // Assume, the user will define the type somewhere else
164  // return a type which contains the id only
165  type = new SUMOVTypeParameter();
166  type->id = id;
167  type->onlyReferenced = true;
168  addVehicleType(type);
169  return type;
170 }
171 
172 
173 bool
178  }
179  if (!myVehicleTypes.add(type->id, type)) {
180  WRITE_ERROR("The vehicle type '" + type->id + "' occurs at least twice.");
181  delete type;
182  return false;
183  }
184  return true;
185 }
186 
187 
188 bool
189 RONet::addVehicle(const std::string& id, ROVehicle* veh) {
190  if (myVehIDs.find(id) == myVehIDs.end() && myVehicles.add(id, veh)) {
191  myVehIDs.insert(id);
192  myReadRouteNo++;
193  return true;
194  }
195  WRITE_ERROR("The vehicle '" + id + "' occurs at least twice.");
196  return false;
197 }
198 
199 
200 bool
202  const ROVehicle* const veh) {
204  std::string noRouteMsg = "The vehicle '" + veh->getID() + "' has no valid route.";
205  if (options.getBool("ignore-errors")) {
207  }
208  RORouteDef* const routeDef = veh->getRouteDefinition();
209  // check if the route definition is valid
210  if (routeDef == 0) {
211  mh->inform(noRouteMsg);
212  return false;
213  }
214  // check whether the route was already saved
215  if (routeDef->isSaved()) {
216  return true;
217  }
218  //
219  RORoute* current = routeDef->buildCurrentRoute(router, veh->getDepartureTime(), *veh);
220  if (current == 0 || current->size() == 0) {
221  delete current;
222  mh->inform(noRouteMsg);
223  return false;
224  }
225  // check whether we have to evaluate the route for not containing loops
226  if (options.getBool("remove-loops")) {
227  current->recheckForLoops();
228  // check whether the route is still valid
229  if (current->size() == 0) {
230  delete current;
231  mh->inform(noRouteMsg + " (after removing loops)");
232  return false;
233  }
234  }
235  // add built route
236  routeDef->addAlternative(router, veh, current, veh->getDepartureTime());
237  return true;
238 }
239 
240 
241 SUMOTime
243  SUMOTime time) {
244  SUMOTime lastTime = -1;
245  // write all vehicles (and additional structures)
246  while (myVehicles.size() != 0) {
247  // get the next vehicle
248  const ROVehicle* const veh = myVehicles.getTopVehicle();
249  SUMOTime currentTime = veh->getDepartureTime();
250  // check whether it shall not yet be computed
251  if (currentTime > time) {
252  lastTime = currentTime;
253  break;
254  }
255  // check whether to print the output
256  if (lastTime != currentTime && lastTime != -1) {
257  // report writing progress
258  if (options.getInt("stats-period") >= 0 && ((int) currentTime % options.getInt("stats-period")) == 0) {
259  WRITE_MESSAGE("Read: " + toString(myReadRouteNo) + ", Discarded: " + toString(myDiscardedRouteNo) + ", Written: " + toString(myWrittenRouteNo));
260  }
261  }
262  lastTime = currentTime;
263 
264  // ok, compute the route (try it)
265  if (computeRoute(options, router, veh)) {
266  // write the route
267  veh->saveAllAsXML(router, *myRoutesOutput, myRouteAlternativesOutput, myTypesOutput, options.getBool("exit-times"));
269  // remove the route if it is not longer used
270  /*
271  if (!myRoutes.erase(route->getID())) {
272  WRITE_WARNING("Could not remove " + route->getID());
273  }
274  */
275  } else {
277  }
278  // and the vehicle
279  myVehicles.erase(veh->getID());
280  }
281  return lastTime;
282 }
283 
284 
285 bool
287  return myVehicles.size() > 0;
288 }
289 
290 
291 ROEdge*
293  // check whether an edge may be returned
295  if (mySourceEdges.size() == 0) {
296  return 0;
297  }
298  // choose a random edge
300 }
301 
302 
303 const ROEdge*
305  // check whether an edge may be returned
307  if (mySourceEdges.size() == 0) {
308  return 0;
309  }
310  // choose a random edge
312 }
313 
314 
315 
316 ROEdge*
318  // check whether an edge may be returned
320  if (myDestinationEdges.size() == 0) {
321  return 0;
322  }
323  // choose a random edge
325 }
326 
327 
328 const ROEdge*
330  // check whether an edge may be returned
332  if (myDestinationEdges.size() == 0) {
333  return 0;
334  }
335  // choose a random edge
337 }
338 
339 
340 void
342  if (myDestinationEdges.size() != 0 || mySourceEdges.size() != 0) {
343  return;
344  }
345  const std::map<std::string, ROEdge*> &edges = myEdges.getMyMap();
346  for (std::map<std::string, ROEdge*>::const_iterator i = edges.begin(); i != edges.end(); ++i) {
347  ROEdge* e = (*i).second;
348  ROEdge::EdgeType type = e->getType();
349  // !!! add something like "classified edges only" for using only sources or sinks
350  if (type != ROEdge::ET_SOURCE) {
351  myDestinationEdges.push_back(e);
352  }
353  if (type != ROEdge::ET_SINK) {
354  mySourceEdges.push_back(e);
355  }
356  }
357 }
358 
359 
360 unsigned int
362  return (unsigned int) myEdges.size();
363 }
364 
365 
366 const std::map<std::string, ROEdge*> &
368  return myEdges.getMyMap();
369 }
370 
371 
372 bool
374  return myHaveRestrictions;
375 }
376 
377 
378 void
380  myHaveRestrictions = true;
381 }
382 
383 
384 
385 /****************************************************************************/
386