SUMO - Simulation of Urban MObility
MSRoute.cpp
Go to the documentation of this file.
00001 /****************************************************************************/
00009 // A vehicle route
00010 /****************************************************************************/
00011 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00012 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
00013 /****************************************************************************/
00014 //
00015 //   This file is part of SUMO.
00016 //   SUMO is free software: you can redistribute it and/or modify
00017 //   it under the terms of the GNU General Public License as published by
00018 //   the Free Software Foundation, either version 3 of the License, or
00019 //   (at your option) any later version.
00020 //
00021 /****************************************************************************/
00022 
00023 
00024 // ===========================================================================
00025 // included modules
00026 // ===========================================================================
00027 #ifdef _MSC_VER
00028 #include <windows_config.h>
00029 #else
00030 #include <config.h>
00031 #endif
00032 
00033 #include <cassert>
00034 #include <algorithm>
00035 #include <limits>
00036 #include "MSRoute.h"
00037 #include "MSEdge.h"
00038 #include "MSLane.h"
00039 #include <utils/common/FileHelpers.h>
00040 #include <utils/common/RGBColor.h>
00041 #include <utils/iodevices/BinaryInputDevice.h>
00042 #include <utils/iodevices/OutputDevice.h>
00043 
00044 #ifdef CHECK_MEMORY_LEAKS
00045 #include <foreign/nvwa/debug_new.h>
00046 #endif // CHECK_MEMORY_LEAKS
00047 
00048 
00049 // ===========================================================================
00050 // static member variables
00051 // ===========================================================================
00052 MSRoute::RouteDict MSRoute::myDict;
00053 MSRoute::RouteDistDict MSRoute::myDistDict;
00054 
00055 
00056 // ===========================================================================
00057 // member method definitions
00058 // ===========================================================================
00059 MSRoute::MSRoute(const std::string& id,
00060                  const MSEdgeVector& edges,
00061                  unsigned int references, const RGBColor& c,
00062                  const std::vector<SUMOVehicleParameter::Stop> &stops)
00063     : Named(id), myEdges(edges),
00064       myReferenceCounter(references),
00065       myColor(c), myStops(stops) {}
00066 
00067 
00068 MSRoute::~MSRoute() {}
00069 
00070 MSRouteIterator
00071 MSRoute::begin() const {
00072     return myEdges.begin();
00073 }
00074 
00075 MSRouteIterator
00076 MSRoute::end() const {
00077     return myEdges.end();
00078 }
00079 
00080 unsigned
00081 MSRoute::size() const {
00082     return (unsigned) myEdges.size();
00083 }
00084 
00085 
00086 const MSEdge*
00087 MSRoute::getLastEdge() const {
00088     assert(myEdges.size() > 0);
00089     return myEdges[myEdges.size() - 1];
00090 }
00091 
00092 
00093 void
00094 MSRoute::addReference() const {
00095     myReferenceCounter++;
00096 }
00097 
00098 
00099 void
00100 MSRoute::release() const {
00101     myReferenceCounter--;
00102     if (myReferenceCounter == 0) {
00103         myDict.erase(myID);
00104         delete this;
00105     }
00106 }
00107 
00108 
00109 bool
00110 MSRoute::dictionary(const std::string& id, const MSRoute* route) {
00111     if (myDict.find(id) == myDict.end() && myDistDict.find(id) == myDistDict.end()) {
00112         myDict[id] = route;
00113         return true;
00114     }
00115     return false;
00116 }
00117 
00118 
00119 bool
00120 MSRoute::dictionary(const std::string& id, RandomDistributor<const MSRoute*>* routeDist) {
00121     if (myDict.find(id) == myDict.end() && myDistDict.find(id) == myDistDict.end()) {
00122         myDistDict[id] = routeDist;
00123         return true;
00124     }
00125     return false;
00126 }
00127 
00128 
00129 const MSRoute*
00130 MSRoute::dictionary(const std::string& id) {
00131     RouteDict::iterator it = myDict.find(id);
00132     if (it == myDict.end()) {
00133         RouteDistDict::iterator it2 = myDistDict.find(id);
00134         if (it2 == myDistDict.end() || it2->second->getOverallProb() == 0) {
00135             return 0;
00136         }
00137         return it2->second->get();
00138     }
00139     return it->second;
00140 }
00141 
00142 
00143 RandomDistributor<const MSRoute*> *
00144 MSRoute::distDictionary(const std::string& id) {
00145     RouteDistDict::iterator it2 = myDistDict.find(id);
00146     if (it2 == myDistDict.end()) {
00147         return 0;
00148     }
00149     return it2->second;
00150 }
00151 
00152 
00153 void
00154 MSRoute::clear() {
00155     for (RouteDistDict::iterator i = myDistDict.begin(); i != myDistDict.end(); ++i) {
00156         delete i->second;
00157     }
00158     myDistDict.clear();
00159     for (RouteDict::iterator i = myDict.begin(); i != myDict.end(); ++i) {
00160         delete i->second;
00161     }
00162     myDict.clear();
00163 }
00164 
00165 
00166 void
00167 MSRoute::insertIDs(std::vector<std::string> &into) {
00168     into.reserve(myDict.size() + myDistDict.size() + into.size());
00169     for (RouteDict::const_iterator i = myDict.begin(); i != myDict.end(); ++i) {
00170         into.push_back((*i).first);
00171     }
00172     for (RouteDistDict::const_iterator i = myDistDict.begin(); i != myDistDict.end(); ++i) {
00173         into.push_back((*i).first);
00174     }
00175 }
00176 
00177 
00178 void
00179 MSRoute::writeEdgeIDs(OutputDevice& os, const MSEdge* const from, const MSEdge* const upTo) const {
00180     MSEdgeVector::const_iterator i = myEdges.begin();
00181     if (from != 0) {
00182         i = std::find(myEdges.begin(), myEdges.end(), from);
00183     }
00184     for (; i != myEdges.end(); ++i) {
00185         if ((*i) == upTo) {
00186             return;
00187         }
00188         os << (*i)->getID();
00189         if (upTo || i != myEdges.end() - 1) {
00190             os << ' ';
00191         }
00192     }
00193 }
00194 
00195 
00196 bool
00197 MSRoute::containsAnyOf(const std::vector<MSEdge*> &edgelist) const {
00198     std::vector<MSEdge*>::const_iterator i = edgelist.begin();
00199     for (; i != edgelist.end(); ++i) {
00200         if (contains(*i)) {
00201             return true;
00202         }
00203     }
00204     return false;
00205 }
00206 
00207 
00208 const MSEdge*
00209 MSRoute::operator[](unsigned index) const {
00210     return myEdges[index];
00211 }
00212 
00213 
00214 #ifdef HAVE_MESOSIM
00215 void
00216 MSRoute::dict_saveState(std::ostream& os) {
00217     FileHelpers::writeUInt(os, (unsigned int) myDict.size());
00218     for (RouteDict::iterator it = myDict.begin(); it != myDict.end(); ++it) {
00219         FileHelpers::writeString(os, (*it).second->getID());
00220         const MSEdgeVector& edges = (*it).second->myEdges;
00221         FileHelpers::writeUInt(os, (unsigned int)edges.size());
00222         FileHelpers::writeUInt(os, (*it).second->myReferenceCounter);
00223         std::vector<unsigned int> follow;
00224         unsigned int maxFollow = 0;
00225         const MSEdge* prev = edges.front();
00226         for (MSEdgeVector::const_iterator i = edges.begin() + 1; i != edges.end(); ++i) {
00227             unsigned int idx = 0;
00228             for (; idx < prev->getNoFollowing(); ++idx) {
00229                 if (idx > 15) {
00230                     break;
00231                 }
00232                 if (prev->getFollower(idx) == (*i)) {
00233                     follow.push_back(idx);
00234                     if (idx > maxFollow) {
00235                         maxFollow = idx;
00236                     }
00237                     break;
00238                 }
00239             }
00240             if (idx > 15 || idx == prev->getNoFollowing()) {
00241                 follow.clear();
00242                 break;
00243             }
00244             prev = *i;
00245         }
00246         if (follow.empty()) {
00247             for (MSEdgeVector::const_iterator i = edges.begin(); i != edges.end(); ++i) {
00248                 FileHelpers::writeInt(os, (*i)->getNumericalID());
00249             }
00250         } else {
00251             const unsigned int bits = maxFollow > 3 ? 4 : 2;
00252             const unsigned int numFields = 8 * sizeof(unsigned int) / bits;
00253             FileHelpers::writeInt(os, -bits);
00254             FileHelpers::writeUInt(os, edges.front()->getNumericalID());
00255             unsigned int data = 0;
00256             unsigned int field = 0;
00257             for (std::vector<unsigned int>::const_iterator i = follow.begin(); i != follow.end(); ++i) {
00258                 data |= *i;
00259                 field++;
00260                 if (field == numFields) {
00261                     FileHelpers::writeUInt(os, data);
00262                     data = 0;
00263                     field = 0;
00264                 } else {
00265                     data <<= bits;
00266                 }
00267             }
00268             if (field > 0) {
00269                 FileHelpers::writeUInt(os, data << ((numFields - field - 1) * bits));
00270             }
00271         }
00272     }
00273     FileHelpers::writeUInt(os, (unsigned int) myDistDict.size());
00274     for (RouteDistDict::iterator it = myDistDict.begin(); it != myDistDict.end(); ++it) {
00275         FileHelpers::writeString(os, (*it).first);
00276         const unsigned int size = (unsigned int)(*it).second->getVals().size();
00277         FileHelpers::writeUInt(os, size);
00278         for (unsigned int i = 0; i < size; ++i) {
00279             FileHelpers::writeString(os, (*it).second->getVals()[i]->getID());
00280             FileHelpers::writeFloat(os, (*it).second->getProbs()[i]);
00281         }
00282     }
00283 }
00284 
00285 
00286 void
00287 MSRoute::dict_loadState(BinaryInputDevice& bis) {
00288     unsigned int numRoutes;
00289     bis >> numRoutes;
00290     for (; numRoutes > 0; numRoutes--) {
00291         std::string id;
00292         bis >> id;
00293         unsigned int numEdges;
00294         bis >> numEdges;
00295         unsigned int references;
00296         bis >> references;
00297         int first;
00298         bis >> first;
00299         if (first < 0) {
00300             const unsigned int bits = -first;
00301             const unsigned int numFields = 8 * sizeof(unsigned int) / bits;
00302             if (dictionary(id) == 0) {
00303                 const unsigned int mask = (1 << bits) - 1;
00304                 MSEdgeVector edges;
00305                 edges.reserve(numEdges);
00306                 unsigned int edgeID;
00307                 bis >> edgeID;
00308                 const MSEdge* prev = MSEdge::dictionary(edgeID);
00309                 assert(prev != 0);
00310                 edges.push_back(prev);
00311                 numEdges--;
00312                 unsigned int data;
00313                 unsigned int field = numFields;
00314                 for (; numEdges > 0; numEdges--) {
00315                     if (field == numFields) {
00316                         bis >> data;
00317                         field = 0;
00318                     }
00319                     unsigned int followIndex = (data >> ((numFields - field - 1) * bits)) & mask;
00320                     prev = prev->getFollower(followIndex);
00321                     edges.push_back(prev);
00322                     field++;
00323                 }
00324                 MSRoute* r = new MSRoute(id, edges, references,
00325                                          RGBColor::DEFAULT_COLOR, std::vector<SUMOVehicleParameter::Stop>());
00326                 dictionary(id, r);
00327             } else {
00328                 unsigned int data;
00329                 bis >> data; // first edge id
00330                 for (int numFollows = numEdges - 1; numFollows > 0; numFollows -= numFields) {
00331                     bis >> data;
00332                 }
00333             }
00334         } else {
00335             if (dictionary(id) == 0) {
00336                 MSEdgeVector edges;
00337                 edges.reserve(numEdges);
00338                 edges.push_back(MSEdge::dictionary(first));
00339                 numEdges--;
00340                 for (; numEdges > 0; numEdges--) {
00341                     unsigned int edgeID;
00342                     bis >> edgeID;
00343                     assert(MSEdge::dictionary(edgeID) != 0);
00344                     edges.push_back(MSEdge::dictionary(edgeID));
00345                 }
00346                 MSRoute* r = new MSRoute(id, edges, references,
00347                                          RGBColor::DEFAULT_COLOR, std::vector<SUMOVehicleParameter::Stop>());
00348                 dictionary(id, r);
00349             } else {
00350                 numEdges--;
00351                 for (; numEdges > 0; numEdges--) {
00352                     unsigned int edgeID;
00353                     bis >> edgeID;
00354                 }
00355             }
00356         }
00357     }
00358     unsigned int numRouteDists;
00359     bis >> numRouteDists;
00360     for (; numRouteDists > 0; numRouteDists--) {
00361         std::string id;
00362         bis >> id;
00363         unsigned int no;
00364         bis >> no;
00365         if (dictionary(id) == 0) {
00366             RandomDistributor<const MSRoute*> *dist = new RandomDistributor<const MSRoute*>();
00367             for (; no > 0; no--) {
00368                 std::string routeID;
00369                 bis >> routeID;
00370                 const MSRoute* r = dictionary(routeID);
00371                 assert(r != 0);
00372                 SUMOReal prob;
00373                 bis >> prob;
00374                 dist->add(prob, r, false);
00375             }
00376             dictionary(id, dist);
00377         } else {
00378             for (; no > 0; no--) {
00379                 std::string routeID;
00380                 bis >> routeID;
00381                 SUMOReal prob;
00382                 bis >> prob;
00383             }
00384         }
00385     }
00386 }
00387 #endif
00388 
00389 
00390 SUMOReal
00391 MSRoute::getLength() const {
00392     SUMOReal ret = 0;
00393     for (MSEdgeVector::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
00394         ret += (*i)->getLength();
00395     }
00396     return ret;
00397 }
00398 
00399 
00400 SUMOReal
00401 MSRoute::getDistanceBetween(SUMOReal fromPos, SUMOReal toPos, const MSEdge* fromEdge, const MSEdge* toEdge) const {
00402     bool isFirstIteration = true;
00403     SUMOReal distance = -fromPos;
00404     MSEdgeVector::const_iterator it = std::find(myEdges.begin(), myEdges.end(), fromEdge);
00405 
00406     if (it == myEdges.end() || std::find(it, myEdges.end(), toEdge) == myEdges.end()) {
00407         // start or destination not contained in route
00408         return std::numeric_limits<SUMOReal>::max();
00409     }
00410     if (fromEdge == toEdge && fromPos <= toPos) {
00411         // destination position is on start edge
00412         return (toPos - fromPos);
00413     }
00414     for (; it != end(); ++it) {
00415         if ((*it) == toEdge && !isFirstIteration) {
00416             distance += toPos;
00417             break;
00418         } else {
00419             const std::vector<MSLane*>& lanes = (*it)->getLanes();
00420             distance += lanes[0]->getLength();
00421 #ifdef HAVE_INTERNAL_LANES
00422             // add length of internal lanes to the result
00423             for (std::vector<MSLane*>::const_iterator laneIt = lanes.begin(); laneIt != lanes.end(); laneIt++) {
00424                 const MSLinkCont& links = (*laneIt)->getLinkCont();
00425                 for (MSLinkCont::const_iterator linkIt = links.begin(); linkIt != links.end(); linkIt++) {
00426                     if ((*linkIt) == 0 || (*linkIt)->getLane() == 0) {
00427                         continue;
00428                     }
00429                     std::string succLaneId = (*(it + 1))->getLanes()[0]->getID();
00430                     if ((*linkIt)->getLane()->getID().compare(succLaneId) == 0) {
00431                         distance += (*linkIt)->getLength();
00432                     }
00433                 }
00434             }
00435 #endif
00436         }
00437         isFirstIteration = false;
00438     }
00439     return distance;
00440 }
00441 
00442 
00443 const RGBColor&
00444 MSRoute::getColor() const {
00445     return myColor;
00446 }
00447 
00448 
00449 const std::vector<SUMOVehicleParameter::Stop> &
00450 MSRoute::getStops() const {
00451     return myStops;
00452 }
00453 
00454 
00455 /****************************************************************************/
00456 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines