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