LCOV - code coverage report
Current view: top level - src/microsim - MSRightOfWayJunction.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 98.7 % 75 74
Test Date: 2025-11-13 15:38:19 Functions: 100.0 % 4 4

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-2025 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    MSRightOfWayJunction.cpp
      15              : /// @author  Christian Roessel
      16              : /// @author  Daniel Krajzewicz
      17              : /// @author  Michael Behrisch
      18              : /// @author  Jakob Erdmann
      19              : /// @date    Wed, 12 Dez 2001
      20              : ///
      21              : // junction.
      22              : /****************************************************************************/
      23              : #include <config.h>
      24              : 
      25              : #include <algorithm>
      26              : #include <cassert>
      27              : #include <cmath>
      28              : #include <utils/common/RandHelper.h>
      29              : #include "MSEdge.h"
      30              : #include "MSJunctionLogic.h"
      31              : #include "MSGlobals.h"
      32              : #include "MSLane.h"
      33              : #include "MSLink.h"
      34              : #include "MSRightOfWayJunction.h"
      35              : #include <utils/common/MsgHandler.h>
      36              : 
      37              : 
      38              : // ===========================================================================
      39              : // method definitions
      40              : // ===========================================================================
      41       279287 : MSRightOfWayJunction::MSRightOfWayJunction(const std::string& id,
      42              :         SumoXMLNodeType type,
      43              :         const Position& position,
      44              :         const PositionVector& shape,
      45              :         const std::string& name,
      46              :         std::vector<MSLane*> incoming,
      47              :         std::vector<MSLane*> internal,
      48       279287 :         MSJunctionLogic* logic) : MSLogicJunction(id, type, position, shape, name, incoming, internal),
      49       279287 :     myLogic(logic) {}
      50              : 
      51              : 
      52       552756 : MSRightOfWayJunction::~MSRightOfWayJunction() {
      53       276378 :     delete myLogic;
      54       552756 : }
      55              : 
      56              : 
      57              : void
      58       278447 : MSRightOfWayJunction::postloadInit() {
      59              :     // inform links where they have to report approaching vehicles to
      60       278447 :     int requestPos = 0;
      61              :     // going through the incoming lanes...
      62              :     int maxNo = 0;
      63              :     std::vector<std::pair<const MSLane*, MSLink*> > sortedLinks;
      64      1105096 :     for (MSLane* const lane : myIncomingLanes) {
      65              :         // ... set information for every link
      66      2444257 :         for (MSLink* const link : lane->getLinkCont()) {
      67      1617608 :             if (link->getLane()->getEdge().isWalkingArea() ||
      68        32208 :                     (lane->getEdge().isWalkingArea() && !link->getLane()->getEdge().isCrossing())) {
      69       115903 :                 continue;
      70              :             }
      71      1501705 :             sortedLinks.emplace_back(lane, link);
      72      1501705 :             ++maxNo;
      73              :         }
      74              :     }
      75              : 
      76       278447 :     const bool hasFoes = myLogic->hasFoes();
      77      1105092 :     for (const MSLane* const lane : myIncomingLanes) {
      78              :         // ... set information for every link
      79              :         const MSLane* walkingAreaFoe = nullptr;
      80      2444253 :         for (MSLink* const link : lane->getLinkCont()) {
      81      1617608 :             if (link->getLane()->getEdge().isWalkingArea()) {
      82       100055 :                 if (lane->getPermissions() != SVC_PEDESTRIAN) {
      83              :                     // vehicular lane connects to a walkingarea
      84              :                     walkingAreaFoe = link->getLane();
      85              :                 }
      86       115903 :                 continue;
      87      1517553 :             } else if ((lane->getEdge().isWalkingArea() && !link->getLane()->getEdge().isCrossing())) {
      88        15848 :                 continue;
      89              :             }
      90      1501705 :             if (myLogic->getLogicSize() <= requestPos) {
      91           12 :                 throw ProcessError(TLF("Found invalid logic position of a link for junction '%' (%, max %) -> (network error)", getID(), toString(requestPos), toString(myLogic->getLogicSize())));
      92              :             }
      93      1501701 :             const MSLogicJunction::LinkBits& linkResponse = myLogic->getResponseFor(requestPos); // SUMO_ATTR_RESPONSE
      94      1501701 :             const MSLogicJunction::LinkBits& linkFoes = myLogic->getFoesFor(requestPos); // SUMO_ATTR_FOES
      95      1501701 :             bool cont = myLogic->getIsCont(requestPos);
      96     17357592 :             for (int c = 0; c < maxNo; ++c) {
      97     15855891 :                 if (linkResponse.test(c)) {
      98      2516339 :                     MSLink* foe = sortedLinks[c].second;
      99      2516339 :                     myLinkFoeLinks[link].push_back(foe);
     100      2516339 :                     if (MSGlobals::gUsingInternalLanes && foe->getViaLane() != nullptr) {
     101              :                         assert(foe->getViaLane()->getLinkCont().size() == 1);
     102      1038223 :                         MSLink* foeExitLink = foe->getViaLane()->getLinkCont()[0];
     103              :                         // add foe links after an internal junction
     104      1038223 :                         if (foeExitLink->getViaLane() != nullptr) {
     105       282517 :                             myLinkFoeLinks[link].push_back(foeExitLink);
     106              :                         }
     107              :                     }
     108              :                 }
     109              :             }
     110              :             std::vector<MSLink*> foes;
     111     17357592 :             for (int c = 0; c < maxNo; ++c) {
     112     15855891 :                 if (linkFoes.test(c)) {
     113      4881802 :                     MSLink* foe = sortedLinks[c].second;
     114      4881802 :                     foes.push_back(foe);
     115              :                     MSLane* l = foe->getViaLane();
     116      4881802 :                     if (l == nullptr) {
     117      2860883 :                         continue;
     118              :                     }
     119              :                     // add foe links after an internal junction
     120      4041838 :                     for (MSLink* const vLink : l->getLinkCont()) {
     121      2020919 :                         if (vLink->getViaLane() != nullptr) {
     122       639192 :                             foes.push_back(vLink);
     123              :                         }
     124              :                     }
     125              :                 }
     126              :             }
     127              : 
     128      1501701 :             if (MSGlobals::gUsingInternalLanes && myInternalLanes.size() > 0) {
     129              :                 int li = 0;
     130      7334410 :                 for (int c = 0; c < (int)sortedLinks.size(); ++c) {
     131      6700303 :                     if (sortedLinks[c].second->getLane() == nullptr) { // dead end
     132            0 :                         continue;
     133              :                     }
     134      6700303 :                     if (linkFoes.test(c)) {
     135              :                         // vehicles waiting at an internal junction can mostly be ignored. The main exceptions are:
     136              :                         // - they are on the main road and the current link is from a side road
     137              :                         // - its a tls and the current link is on a side road relative to the internal junction
     138              :                         // both cases are encoded in a positive linkResponse
     139              :                         // (case 2 only if netconvert option --tls.ignore-internal-junction-jam was not set)
     140      2117126 :                         myLinkFoeInternalLanes[link].push_back(myInternalLanes[li]);
     141      3113413 :                         if (linkResponse.test(c) || sortedLinks[c].second->isIndirect() ||
     142       996287 :                                 link->getLane()->getBidiLane() == sortedLinks[c].second->getLaneBefore()) {
     143      1123924 :                             const std::vector<MSLane::IncomingLaneInfo>& l = myInternalLanes[li]->getIncomingLanes();
     144      1123924 :                             if (l.size() == 1 && l[0].lane->getEdge().isInternal()) {
     145       282792 :                                 myLinkFoeInternalLanes[link].push_back(l[0].lane);
     146              :                             }
     147              :                         }
     148              :                     }
     149      6700303 :                     ++li;
     150              :                 }
     151              :             }
     152      1501701 :             link->setRequestInformation((int)requestPos, hasFoes, cont, myLinkFoeLinks[link], myLinkFoeInternalLanes[link]);
     153              :             // the exit link for a link before an internal junction is handled in MSInternalJunction
     154              :             // so we need to skip if cont=true
     155      1501701 :             if (MSGlobals::gUsingInternalLanes && link->getViaLane() != nullptr && !cont) {
     156              :                 assert(link->getViaLane()->getLinkCont().size() == 1);
     157       476978 :                 MSLink* exitLink = link->getViaLane()->getLinkCont()[0];
     158       476978 :                 exitLink->setRequestInformation((int)requestPos, false, false, std::vector<MSLink*>(),
     159       476978 :                                                 myLinkFoeInternalLanes[link], link->getViaLane());
     160      1601563 :                 for (const auto& ili : exitLink->getLane()->getIncomingLanes()) {
     161      1130712 :                     if (ili.lane->getEdge().isWalkingArea()) {
     162              :                         exitLink->addWalkingAreaFoeExit(ili.lane);
     163              :                         break;
     164              :                     }
     165              :                 }
     166              :             }
     167              :             // the exit link for a crossing is needed for the pedestrian model
     168      1501701 :             if (MSGlobals::gUsingInternalLanes && link->getLane()->getEdge().isCrossing()) {
     169        16360 :                 MSLink* exitLink = link->getLane()->getLinkCont()[0];
     170        16360 :                 exitLink->setRequestInformation((int)requestPos, false, false, std::vector<MSLink*>(),
     171        16360 :                                                 myLinkFoeInternalLanes[link], link->getLane());
     172              :             }
     173      1501701 :             requestPos++;
     174      1501701 :         }
     175       826645 :         if (walkingAreaFoe != nullptr && lane->getLinkCont().size() > 1) {
     176        12057 :             for (const MSLink* const link : lane->getLinkCont()) {
     177         9413 :                 if (!link->getLane()->getEdge().isWalkingArea()) {
     178         6769 :                     MSLink* exitLink = link->getViaLane()->getLinkCont()[0];
     179              :                     exitLink->addWalkingAreaFoe(walkingAreaFoe);
     180              :                 }
     181              :             }
     182              :         }
     183              :     }
     184       278447 : }
     185              : 
     186              : 
     187              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1