SUMO - Simulation of Urban MObility

MSRoute.cpp

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