|
SUMO - Simulation of Urban MObility
|
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