LCOV - code coverage report
Current view: top level - src/microsim - MSRoute.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 96.5 % 142 137
Test Date: 2024-10-24 15:46:30 Functions: 92.0 % 25 23

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2002-2024 German Aerospace Center (DLR) and others.
       4              : // This program and the accompanying materials are made available under the
       5              : // terms of the Eclipse Public License 2.0 which is available at
       6              : // https://www.eclipse.org/legal/epl-2.0/
       7              : // This Source Code may also be made available under the following Secondary
       8              : // Licenses when the conditions for such availability set forth in the Eclipse
       9              : // Public License 2.0 are satisfied: GNU General Public License, version 2
      10              : // or later which is available at
      11              : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
      12              : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
      13              : /****************************************************************************/
      14              : /// @file    MSRoute.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Friedemann Wesner
      17              : /// @author  Michael Behrisch
      18              : /// @author  Jakob Erdmann
      19              : /// @date    Sept 2002
      20              : ///
      21              : // A vehicle route
      22              : /****************************************************************************/
      23              : #include <config.h>
      24              : 
      25              : #include <cassert>
      26              : #include <algorithm>
      27              : #include <limits>
      28              : #include <utils/common/FileHelpers.h>
      29              : #include <utils/common/RGBColor.h>
      30              : #include <utils/iodevices/OutputDevice.h>
      31              : #include "MSEdge.h"
      32              : #include "MSLane.h"
      33              : #include "MSRoute.h"
      34              : 
      35              : 
      36              : // ===========================================================================
      37              : // static member variables
      38              : // ===========================================================================
      39              : MSRoute::RouteDict MSRoute::myDict;
      40              : MSRoute::RouteDistDict MSRoute::myDistDict;
      41              : #ifdef HAVE_FOX
      42              : FXMutex MSRoute::myDictMutex(true);
      43              : #endif
      44              : 
      45              : 
      46              : // ===========================================================================
      47              : // member method definitions
      48              : // ===========================================================================
      49      1876000 : MSRoute::MSRoute(const std::string& id,
      50              :                  const ConstMSEdgeVector& edges,
      51              :                  const bool isPermanent, const RGBColor* const c,
      52              :                  const std::vector<SUMOVehicleParameter::Stop>& stops,
      53              :                  SUMOTime replacedTime,
      54      1876000 :                  int replacedIndex) :
      55      3752000 :     Named(id), myEdges(edges), myAmPermanent(isPermanent),
      56      1876000 :     myColor(c),
      57      1876000 :     myPeriod(0),
      58      1876000 :     myCosts(-1),
      59      1876000 :     mySavings(0),
      60      1876000 :     myReroute(false),
      61      1876000 :     myStops(stops),
      62      1876000 :     myReplacedTime(replacedTime),
      63      1876000 :     myReplacedIndex(replacedIndex)
      64      1876000 : {}
      65              : 
      66              : 
      67      3520077 : MSRoute::~MSRoute() {
      68      1875954 :     delete myColor;
      69      3520077 : }
      70              : 
      71              : 
      72              : MSRouteIterator
      73   1403133233 : MSRoute::begin() const {
      74   1403133233 :     return myEdges.begin();
      75              : }
      76              : 
      77              : 
      78              : MSRouteIterator
      79   4065930773 : MSRoute::end() const {
      80   4065930773 :     return myEdges.end();
      81              : }
      82              : 
      83              : 
      84              : int
      85     13759474 : MSRoute::size() const {
      86     13759474 :     return (int)myEdges.size();
      87              : }
      88              : 
      89              : 
      90              : const MSEdge*
      91     24725643 : MSRoute::getLastEdge() const {
      92              :     assert(myEdges.size() > 0);
      93     24725643 :     return myEdges.back();
      94              : }
      95              : 
      96              : 
      97              : void
      98      1293152 : MSRoute::checkRemoval() const {
      99              : #ifdef HAVE_FOX
     100              :     FXMutexLock f(myDictMutex);
     101              : #endif
     102      1293152 :     if (!myAmPermanent) {
     103              :         myDict.erase(getID());
     104              :     }
     105      1293152 : }
     106              : 
     107              : 
     108              : bool
     109      1644425 : MSRoute::dictionary(const std::string& id, ConstMSRoutePtr route) {
     110              : #ifdef HAVE_FOX
     111              :     FXMutexLock f(myDictMutex);
     112              : #endif
     113      1644425 :     if (myDict.find(id) == myDict.end() && myDistDict.find(id) == myDistDict.end()) {
     114      1644275 :         myDict[id] = route;
     115      1644275 :         return true;
     116              :     }
     117              :     return false;
     118              : }
     119              : 
     120              : 
     121              : bool
     122         1834 : MSRoute::dictionary(const std::string& id, RandomDistributor<ConstMSRoutePtr>* const routeDist, const bool permanent) {
     123              : #ifdef HAVE_FOX
     124              :     FXMutexLock f(myDictMutex);
     125              : #endif
     126         1834 :     if (myDict.find(id) == myDict.end() && myDistDict.find(id) == myDistDict.end()) {
     127         1834 :         myDistDict[id] = std::make_pair(routeDist, permanent);
     128         1834 :         return true;
     129              :     }
     130              :     return false;
     131              : }
     132              : 
     133              : 
     134              : ConstMSRoutePtr
     135      4735797 : MSRoute::dictionary(const std::string& id, SumoRNG* rng) {
     136              : #ifdef HAVE_FOX
     137              :     FXMutexLock f(myDictMutex);
     138              : #endif
     139              :     RouteDict::iterator it = myDict.find(id);
     140      4735797 :     if (it == myDict.end()) {
     141              :         RouteDistDict::iterator it2 = myDistDict.find(id);
     142       165339 :         if (it2 == myDistDict.end() || it2->second.first->getOverallProb() == 0) {
     143              :             return nullptr;
     144              :         }
     145         6375 :         return it2->second.first->get(rng);
     146              :     }
     147              :     return it->second;
     148              : }
     149              : 
     150              : 
     151              : bool
     152      4886799 : MSRoute::hasRoute(const std::string& id) {
     153              : #ifdef HAVE_FOX
     154              :     FXMutexLock f(myDictMutex);
     155              : #endif
     156      4886799 :     return myDict.find(id) != myDict.end();
     157              : }
     158              : 
     159              : 
     160              : RandomDistributor<ConstMSRoutePtr>*
     161        15606 : MSRoute::distDictionary(const std::string& id) {
     162              : #ifdef HAVE_FOX
     163              :     FXMutexLock f(myDictMutex);
     164              : #endif
     165              :     RouteDistDict::iterator it2 = myDistDict.find(id);
     166        15606 :     if (it2 == myDistDict.end()) {
     167              :         return nullptr;
     168              :     }
     169         2330 :     return it2->second.first;
     170              : }
     171              : 
     172              : 
     173              : void
     174        40044 : MSRoute::clear() {
     175              : #ifdef HAVE_FOX
     176              :     FXMutexLock f(myDictMutex);
     177              : #endif
     178        40462 :     for (RouteDistDict::iterator i = myDistDict.begin(); i != myDistDict.end(); ++i) {
     179          836 :         delete i->second.first;
     180              :     }
     181              :     myDistDict.clear();
     182              :     myDict.clear();
     183        40044 : }
     184              : 
     185              : 
     186              : void
     187       456663 : MSRoute::checkDist(const std::string& id) {
     188              : #ifdef HAVE_FOX
     189              :     FXMutexLock f(myDictMutex);
     190              : #endif
     191              :     RouteDistDict::iterator it = myDistDict.find(id);
     192       456663 :     if (it != myDistDict.end() && !it->second.second) {
     193         4735 :         for (ConstMSRoutePtr rp : it->second.first->getVals()) {
     194              :             const MSRoute& r = *rp;
     195         3319 :             r.checkRemoval();
     196              :         }
     197         2832 :         delete it->second.first;
     198              :         myDistDict.erase(it);
     199              :     }
     200       456663 : }
     201              : 
     202              : 
     203              : void
     204          260 : MSRoute::insertIDs(std::vector<std::string>& into) {
     205              : #ifdef HAVE_FOX
     206              :     FXMutexLock f(myDictMutex);
     207              : #endif
     208          260 :     into.reserve(myDict.size() + myDistDict.size() + into.size());
     209          842 :     for (RouteDict::const_iterator i = myDict.begin(); i != myDict.end(); ++i) {
     210          582 :         into.push_back((*i).first);
     211              :     }
     212         1028 :     for (RouteDistDict::const_iterator i = myDistDict.begin(); i != myDistDict.end(); ++i) {
     213          768 :         into.push_back((*i).first);
     214              :     }
     215          260 : }
     216              : 
     217              : 
     218              : int
     219       286587 : MSRoute::writeEdgeIDs(OutputDevice& os, int firstIndex, int lastIndex, bool withInternal, SUMOVehicleClass svc) const {
     220              :     //std::cout << SIMTIME << " writeEdgeIDs " << getID() << " first=" << firstIndex << " lastIndex=" << lastIndex << " edges=" << toString(myEdges) << "\n";
     221       286587 :     if (lastIndex < 0) {
     222       142850 :         lastIndex = (int)myEdges.size();
     223              :     }
     224              :     int internal = 0;
     225      1504967 :     for (int i = firstIndex; i < lastIndex; i++) {
     226      1218380 :         os << myEdges[i]->getID() << ' ';
     227      1218380 :         if (withInternal && i + 1 < lastIndex) {
     228            6 :             const MSEdge* next = myEdges[i + 1];
     229            6 :             const MSEdge* edge = myEdges[i]->getInternalFollowingEdge(next, svc);
     230              :             // Take into account non-internal lengths until next non-internal edge
     231           14 :             while (edge != nullptr && edge->isInternal()) {
     232            8 :                 os << edge->getID() << ' ';
     233            8 :                 internal++;
     234            8 :                 edge = edge->getInternalFollowingEdge(next, svc);
     235              :             }
     236              :         }
     237              :     }
     238       286587 :     return internal + lastIndex - firstIndex;
     239              : }
     240              : 
     241              : 
     242              : bool
     243            0 : MSRoute::containsAnyOf(const MSEdgeVector& edgelist) const {
     244              :     MSEdgeVector::const_iterator i = edgelist.begin();
     245            0 :     for (; i != edgelist.end(); ++i) {
     246            0 :         if (contains(*i)) {
     247              :             return true;
     248              :         }
     249              :     }
     250              :     return false;
     251              : }
     252              : 
     253              : 
     254              : const MSEdge*
     255            0 : MSRoute::operator[](int index) const {
     256            0 :     return myEdges[index];
     257              : }
     258              : 
     259              : 
     260              : void
     261          424 : MSRoute::dict_saveState(OutputDevice& out) {
     262              : #ifdef HAVE_FOX
     263              :     FXMutexLock f(myDictMutex);
     264              : #endif
     265         3617 :     for (RouteDict::iterator it = myDict.begin(); it != myDict.end(); ++it) {
     266              :         ConstMSRoutePtr r = (*it).second;
     267         3193 :         out.openTag(SUMO_TAG_ROUTE);
     268              :         out.writeAttr(SUMO_ATTR_ID, r->getID());
     269         3193 :         out.writeAttr(SUMO_ATTR_STATE, r->myAmPermanent);
     270         3193 :         out.writeAttr(SUMO_ATTR_EDGES, r->myEdges);
     271         3193 :         if (r->myColor != nullptr) {
     272              :             out.writeAttr(SUMO_ATTR_COLOR, *r->myColor);
     273              :         }
     274         3257 :         for (auto stop : r->getStops()) {
     275           64 :             stop.write(out);
     276           64 :         }
     277         6386 :         out.closeTag();
     278              :     }
     279          440 :     for (const auto& item : myDistDict) {
     280           16 :         if (item.second.first->getVals().size() > 0) {
     281           12 :             out.openTag(SUMO_TAG_ROUTE_DISTRIBUTION).writeAttr(SUMO_ATTR_ID, item.first);
     282           12 :             out.writeAttr(SUMO_ATTR_STATE, item.second.second);
     283           12 :             std::ostringstream oss;
     284              :             bool space = false;
     285           32 :             for (const auto& route : item.second.first->getVals()) {
     286           20 :                 if (space) {
     287            8 :                     oss << " ";
     288              :                 }
     289              :                 oss << route->getID();
     290              :                 space = true;
     291              :             }
     292           12 :             out.writeAttr(SUMO_ATTR_ROUTES, oss.str());
     293           12 :             out.writeAttr(SUMO_ATTR_PROBS, item.second.first->getProbs());
     294           12 :             out.closeTag();
     295           12 :         }
     296              :     }
     297          424 : }
     298              : 
     299              : 
     300              : void
     301          186 : MSRoute::dict_clearState() {
     302              : #ifdef HAVE_FOX
     303              :     FXMutexLock f(myDictMutex);
     304              : #endif
     305              :     myDistDict.clear();
     306              :     myDict.clear();
     307          186 : }
     308              : 
     309              : 
     310              : double
     311        21508 : MSRoute::getDistanceBetween(double fromPos, double toPos,
     312              :                             const MSLane* fromLane, const MSLane* toLane, int routePosition) const {
     313              :     // std::cout << SIMTIME << " getDistanceBetween from=" << fromEdge->getID() << " to=" << toEdge->getID() << " fromPos=" << fromPos << " toPos=" << toPos << "\n";
     314              :     assert(fromPos >= 0. && fromPos <= fromLane->getLength());
     315              :     assert(toPos >= 0. && toPos <= toLane->getLength());
     316              :     assert(routePosition >= 0 && routePosition < (int)myEdges.size());
     317              :     assert(routePosition == 0 || !myEdges.front()->isInternal());
     318        21508 :     const MSEdge* fromEdge = &fromLane->getEdge();
     319        21508 :     const MSEdge* toEdge = &toLane->getEdge();
     320        21508 :     if (fromEdge == toEdge && fromPos <= toPos) {
     321        15959 :         return toPos - fromPos;
     322              :     }
     323              :     // TODO If fromEdge and toEdge are identical or both are internal and directly connected,
     324              :     // the code does not check whether they are in any relation to the route.
     325         5549 :     if (fromEdge->isInternal()) {
     326              :         double minDist = std::numeric_limits<double>::max();
     327         1020 :         for (const auto& via : fromEdge->getViaSuccessors()) {
     328          510 :             const MSEdge* const succ = via.second == nullptr ? via.first : via.second;
     329              :             assert(succ != nullptr);
     330              :             // std::cout << "  recurse fromSucc=" << succ->getID() << "\n";
     331          510 :             const double d = getDistanceBetween(0., toPos, succ->getLanes()[0], toLane, routePosition);
     332          510 :             if (d != std::numeric_limits<double>::max() && fromLane->getLength() - fromPos + d  < minDist) {
     333              :                 minDist = fromLane->getLength() - fromPos + d;
     334              :             }
     335              :         }
     336          510 :         return minDist;
     337              :     }
     338         5039 :     if (toEdge->isInternal()) {
     339         1820 :         const MSEdge* const pred = toEdge->getPredecessors().front();
     340              :         assert(pred != nullptr);
     341              :         // std::cout << "  recurse toPred=" << pred->getID() << "\n";
     342         1820 :         const double d = getDistanceBetween(fromPos, pred->getLength(), fromLane, pred->getLanes()[0], routePosition);
     343         1820 :         return d == std::numeric_limits<double>::max() ? d : toPos + d;
     344              :     }
     345         3219 :     ConstMSEdgeVector::const_iterator fromIt = std::find(myEdges.begin() + routePosition, myEdges.end(), fromEdge);
     346         3219 :     if (fromIt == myEdges.end()) {
     347              :         // start not contained in route
     348              :         return std::numeric_limits<double>::max();
     349              :     }
     350         3214 :     ConstMSEdgeVector::const_iterator toIt = std::find(fromIt + 1, myEdges.end(), toEdge);
     351         3214 :     if (toIt == myEdges.end()) {
     352              :         // destination not contained in route
     353              :         return std::numeric_limits<double>::max();
     354              :     }
     355         1781 :     return getDistanceBetween(fromPos, toPos, fromIt, toIt, true);
     356              : }
     357              : 
     358              : 
     359              : double
     360        54043 : MSRoute::getDistanceBetween(double fromPos, double toPos,
     361              :                             const MSRouteIterator& fromEdge, const MSRouteIterator& toEdge, bool includeInternal) const {
     362              :     bool isFirstIteration = true;
     363        54043 :     double distance = -fromPos;
     364        54043 :     MSRouteIterator it = fromEdge;
     365        54043 :     if (fromEdge == toEdge) {
     366              :         // destination position is on start edge
     367         3071 :         if (fromPos <= toPos) {
     368         3071 :             return toPos - fromPos;
     369              :         } else {
     370              :             // we cannot go backwards. Something is wrong here
     371              :             return std::numeric_limits<double>::max();
     372              :         }
     373        50972 :     } else if (fromEdge > toEdge) {
     374              :         // we don't visit the edge again
     375              :         return std::numeric_limits<double>::max();
     376              :     }
     377       476263 :     for (; it != end(); ++it) {
     378       469931 :         if (it == toEdge && !isFirstIteration) {
     379        44640 :             distance += toPos;
     380        44640 :             break;
     381              :         } else {
     382       425291 :             distance += (*it)->getLength();
     383       425291 :             if (includeInternal && (it + 1) != end()) {
     384              :                 // XXX the length may be wrong if there are parallel internal edges for different vClasses
     385       418582 :                 distance += (*it)->getInternalFollowingLengthTo(*(it + 1), SVC_IGNORING);
     386              :             }
     387              :         }
     388              :         isFirstIteration = false;
     389              :     }
     390              :     return distance;
     391              : }
     392              : 
     393              : 
     394              : const RGBColor&
     395     10040481 : MSRoute::getColor() const {
     396     10040481 :     if (myColor == nullptr) {
     397      9650035 :         return RGBColor::DEFAULT_COLOR;
     398              :     }
     399              :     return *myColor;
     400              : }
     401              : 
     402              : 
     403              : const std::vector<SUMOVehicleParameter::Stop>&
     404      8449734 : MSRoute::getStops() const {
     405      8449734 :     return myStops;
     406              : }
     407              : 
     408              : 
     409              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1