SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MSRoute.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // A vehicle route
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 <cassert>
34 #include <algorithm>
35 #include <limits>
36 #include "MSRoute.h"
37 #include "MSEdge.h"
38 #include "MSLane.h"
40 #include <utils/common/RGBColor.h>
43 
44 #ifdef CHECK_MEMORY_LEAKS
45 #include <foreign/nvwa/debug_new.h>
46 #endif // CHECK_MEMORY_LEAKS
47 
48 
49 // ===========================================================================
50 // static member variables
51 // ===========================================================================
54 
55 
56 // ===========================================================================
57 // member method definitions
58 // ===========================================================================
59 MSRoute::MSRoute(const std::string& id,
60  const MSEdgeVector& edges,
61  unsigned int references, const RGBColor& c,
62  const std::vector<SUMOVehicleParameter::Stop> &stops)
63  : Named(id), myEdges(edges),
64  myReferenceCounter(references),
65  myColor(c), myStops(stops) {}
66 
67 
69 
71 MSRoute::begin() const {
72  return myEdges.begin();
73 }
74 
76 MSRoute::end() const {
77  return myEdges.end();
78 }
79 
80 unsigned
81 MSRoute::size() const {
82  return (unsigned) myEdges.size();
83 }
84 
85 
86 const MSEdge*
88  assert(myEdges.size() > 0);
89  return myEdges[myEdges.size() - 1];
90 }
91 
92 
93 void
96 }
97 
98 
99 void
102  if (myReferenceCounter == 0) {
103  myDict.erase(myID);
104  delete this;
105  }
106 }
107 
108 
109 bool
110 MSRoute::dictionary(const std::string& id, const MSRoute* route) {
111  if (myDict.find(id) == myDict.end() && myDistDict.find(id) == myDistDict.end()) {
112  myDict[id] = route;
113  return true;
114  }
115  return false;
116 }
117 
118 
119 bool
120 MSRoute::dictionary(const std::string& id, RandomDistributor<const MSRoute*>* routeDist) {
121  if (myDict.find(id) == myDict.end() && myDistDict.find(id) == myDistDict.end()) {
122  myDistDict[id] = routeDist;
123  return true;
124  }
125  return false;
126 }
127 
128 
129 const MSRoute*
130 MSRoute::dictionary(const std::string& id) {
131  RouteDict::iterator it = myDict.find(id);
132  if (it == myDict.end()) {
133  RouteDistDict::iterator it2 = myDistDict.find(id);
134  if (it2 == myDistDict.end() || it2->second->getOverallProb() == 0) {
135  return 0;
136  }
137  return it2->second->get();
138  }
139  return it->second;
140 }
141 
142 
144 MSRoute::distDictionary(const std::string& id) {
145  RouteDistDict::iterator it2 = myDistDict.find(id);
146  if (it2 == myDistDict.end()) {
147  return 0;
148  }
149  return it2->second;
150 }
151 
152 
153 void
155  for (RouteDistDict::iterator i = myDistDict.begin(); i != myDistDict.end(); ++i) {
156  delete i->second;
157  }
158  myDistDict.clear();
159  for (RouteDict::iterator i = myDict.begin(); i != myDict.end(); ++i) {
160  delete i->second;
161  }
162  myDict.clear();
163 }
164 
165 
166 void
167 MSRoute::insertIDs(std::vector<std::string> &into) {
168  into.reserve(myDict.size() + myDistDict.size() + into.size());
169  for (RouteDict::const_iterator i = myDict.begin(); i != myDict.end(); ++i) {
170  into.push_back((*i).first);
171  }
172  for (RouteDistDict::const_iterator i = myDistDict.begin(); i != myDistDict.end(); ++i) {
173  into.push_back((*i).first);
174  }
175 }
176 
177 
178 void
179 MSRoute::writeEdgeIDs(OutputDevice& os, const MSEdge* const from, const MSEdge* const upTo) const {
180  MSEdgeVector::const_iterator i = myEdges.begin();
181  if (from != 0) {
182  i = std::find(myEdges.begin(), myEdges.end(), from);
183  }
184  for (; i != myEdges.end(); ++i) {
185  if ((*i) == upTo) {
186  return;
187  }
188  os << (*i)->getID();
189  if (upTo || i != myEdges.end() - 1) {
190  os << ' ';
191  }
192  }
193 }
194 
195 
196 bool
197 MSRoute::containsAnyOf(const std::vector<MSEdge*> &edgelist) const {
198  std::vector<MSEdge*>::const_iterator i = edgelist.begin();
199  for (; i != edgelist.end(); ++i) {
200  if (contains(*i)) {
201  return true;
202  }
203  }
204  return false;
205 }
206 
207 
208 const MSEdge*
209 MSRoute::operator[](unsigned index) const {
210  return myEdges[index];
211 }
212 
213 
214 #ifdef HAVE_MESOSIM
215 void
216 MSRoute::dict_saveState(std::ostream& os) {
217  FileHelpers::writeUInt(os, (unsigned int) myDict.size());
218  for (RouteDict::iterator it = myDict.begin(); it != myDict.end(); ++it) {
219  FileHelpers::writeString(os, (*it).second->getID());
220  const MSEdgeVector& edges = (*it).second->myEdges;
221  FileHelpers::writeUInt(os, (unsigned int)edges.size());
222  FileHelpers::writeUInt(os, (*it).second->myReferenceCounter);
223  std::vector<unsigned int> follow;
224  unsigned int maxFollow = 0;
225  const MSEdge* prev = edges.front();
226  for (MSEdgeVector::const_iterator i = edges.begin() + 1; i != edges.end(); ++i) {
227  unsigned int idx = 0;
228  for (; idx < prev->getNoFollowing(); ++idx) {
229  if (idx > 15) {
230  break;
231  }
232  if (prev->getFollower(idx) == (*i)) {
233  follow.push_back(idx);
234  if (idx > maxFollow) {
235  maxFollow = idx;
236  }
237  break;
238  }
239  }
240  if (idx > 15 || idx == prev->getNoFollowing()) {
241  follow.clear();
242  break;
243  }
244  prev = *i;
245  }
246  if (follow.empty()) {
247  for (MSEdgeVector::const_iterator i = edges.begin(); i != edges.end(); ++i) {
248  FileHelpers::writeInt(os, (*i)->getNumericalID());
249  }
250  } else {
251  const unsigned int bits = maxFollow > 3 ? 4 : 2;
252  const unsigned int numFields = 8 * sizeof(unsigned int) / bits;
253  FileHelpers::writeInt(os, -bits);
254  FileHelpers::writeUInt(os, edges.front()->getNumericalID());
255  unsigned int data = 0;
256  unsigned int field = 0;
257  for (std::vector<unsigned int>::const_iterator i = follow.begin(); i != follow.end(); ++i) {
258  data |= *i;
259  field++;
260  if (field == numFields) {
261  FileHelpers::writeUInt(os, data);
262  data = 0;
263  field = 0;
264  } else {
265  data <<= bits;
266  }
267  }
268  if (field > 0) {
269  FileHelpers::writeUInt(os, data << ((numFields - field - 1) * bits));
270  }
271  }
272  }
273  FileHelpers::writeUInt(os, (unsigned int) myDistDict.size());
274  for (RouteDistDict::iterator it = myDistDict.begin(); it != myDistDict.end(); ++it) {
275  FileHelpers::writeString(os, (*it).first);
276  const unsigned int size = (unsigned int)(*it).second->getVals().size();
277  FileHelpers::writeUInt(os, size);
278  for (unsigned int i = 0; i < size; ++i) {
279  FileHelpers::writeString(os, (*it).second->getVals()[i]->getID());
280  FileHelpers::writeFloat(os, (*it).second->getProbs()[i]);
281  }
282  }
283 }
284 
285 
286 void
287 MSRoute::dict_loadState(BinaryInputDevice& bis) {
288  unsigned int numRoutes;
289  bis >> numRoutes;
290  for (; numRoutes > 0; numRoutes--) {
291  std::string id;
292  bis >> id;
293  unsigned int numEdges;
294  bis >> numEdges;
295  unsigned int references;
296  bis >> references;
297  int first;
298  bis >> first;
299  if (first < 0) {
300  const unsigned int bits = -first;
301  const unsigned int numFields = 8 * sizeof(unsigned int) / bits;
302  if (dictionary(id) == 0) {
303  const unsigned int mask = (1 << bits) - 1;
304  MSEdgeVector edges;
305  edges.reserve(numEdges);
306  unsigned int edgeID;
307  bis >> edgeID;
308  const MSEdge* prev = MSEdge::dictionary(edgeID);
309  assert(prev != 0);
310  edges.push_back(prev);
311  numEdges--;
312  unsigned int data;
313  unsigned int field = numFields;
314  for (; numEdges > 0; numEdges--) {
315  if (field == numFields) {
316  bis >> data;
317  field = 0;
318  }
319  unsigned int followIndex = (data >> ((numFields - field - 1) * bits)) & mask;
320  prev = prev->getFollower(followIndex);
321  edges.push_back(prev);
322  field++;
323  }
324  MSRoute* r = new MSRoute(id, edges, references,
325  RGBColor::DEFAULT_COLOR, std::vector<SUMOVehicleParameter::Stop>());
326  dictionary(id, r);
327  } else {
328  unsigned int data;
329  bis >> data; // first edge id
330  for (int numFollows = numEdges - 1; numFollows > 0; numFollows -= numFields) {
331  bis >> data;
332  }
333  }
334  } else {
335  if (dictionary(id) == 0) {
336  MSEdgeVector edges;
337  edges.reserve(numEdges);
338  edges.push_back(MSEdge::dictionary(first));
339  numEdges--;
340  for (; numEdges > 0; numEdges--) {
341  unsigned int edgeID;
342  bis >> edgeID;
343  assert(MSEdge::dictionary(edgeID) != 0);
344  edges.push_back(MSEdge::dictionary(edgeID));
345  }
346  MSRoute* r = new MSRoute(id, edges, references,
347  RGBColor::DEFAULT_COLOR, std::vector<SUMOVehicleParameter::Stop>());
348  dictionary(id, r);
349  } else {
350  numEdges--;
351  for (; numEdges > 0; numEdges--) {
352  unsigned int edgeID;
353  bis >> edgeID;
354  }
355  }
356  }
357  }
358  unsigned int numRouteDists;
359  bis >> numRouteDists;
360  for (; numRouteDists > 0; numRouteDists--) {
361  std::string id;
362  bis >> id;
363  unsigned int no;
364  bis >> no;
365  if (dictionary(id) == 0) {
367  for (; no > 0; no--) {
368  std::string routeID;
369  bis >> routeID;
370  const MSRoute* r = dictionary(routeID);
371  assert(r != 0);
372  SUMOReal prob;
373  bis >> prob;
374  dist->add(prob, r, false);
375  }
376  dictionary(id, dist);
377  } else {
378  for (; no > 0; no--) {
379  std::string routeID;
380  bis >> routeID;
381  SUMOReal prob;
382  bis >> prob;
383  }
384  }
385  }
386 }
387 #endif
388 
389 
390 SUMOReal
392  SUMOReal ret = 0;
393  for (MSEdgeVector::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
394  ret += (*i)->getLength();
395  }
396  return ret;
397 }
398 
399 
400 SUMOReal
401 MSRoute::getDistanceBetween(SUMOReal fromPos, SUMOReal toPos, const MSEdge* fromEdge, const MSEdge* toEdge) const {
402  bool isFirstIteration = true;
403  SUMOReal distance = -fromPos;
404  MSEdgeVector::const_iterator it = std::find(myEdges.begin(), myEdges.end(), fromEdge);
405 
406  if (it == myEdges.end() || std::find(it, myEdges.end(), toEdge) == myEdges.end()) {
407  // start or destination not contained in route
409  }
410  if (fromEdge == toEdge && fromPos <= toPos) {
411  // destination position is on start edge
412  return (toPos - fromPos);
413  }
414  for (; it != end(); ++it) {
415  if ((*it) == toEdge && !isFirstIteration) {
416  distance += toPos;
417  break;
418  } else {
419  const std::vector<MSLane*>& lanes = (*it)->getLanes();
420  distance += lanes[0]->getLength();
421 #ifdef HAVE_INTERNAL_LANES
422  // add length of internal lanes to the result
423  for (std::vector<MSLane*>::const_iterator laneIt = lanes.begin(); laneIt != lanes.end(); laneIt++) {
424  const MSLinkCont& links = (*laneIt)->getLinkCont();
425  for (MSLinkCont::const_iterator linkIt = links.begin(); linkIt != links.end(); linkIt++) {
426  if ((*linkIt) == 0 || (*linkIt)->getLane() == 0) {
427  continue;
428  }
429  std::string succLaneId = (*(it + 1))->getLanes()[0]->getID();
430  if ((*linkIt)->getLane()->getID().compare(succLaneId) == 0) {
431  distance += (*linkIt)->getLength();
432  }
433  }
434  }
435 #endif
436  }
437  isFirstIteration = false;
438  }
439  return distance;
440 }
441 
442 
443 const RGBColor&
445  return myColor;
446 }
447 
448 
449 const std::vector<SUMOVehicleParameter::Stop> &
451  return myStops;
452 }
453 
454 
455 /****************************************************************************/
456