LCOV - code coverage report
Current view: top level - src/netbuild - NBTrafficLightLogicCont.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 67.2 % 265 178
Test Date: 2026-07-26 16:30:20 Functions: 83.3 % 24 20

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-2026 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    NBTrafficLightLogicCont.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Michael Behrisch
      18              : /// @date    Sept 2002
      19              : ///
      20              : // A container for traffic light definitions and built programs
      21              : /****************************************************************************/
      22              : #include <config.h>
      23              : #include <map>
      24              : #include <string>
      25              : #include <algorithm>
      26              : #include <utils/common/MsgHandler.h>
      27              : #include <utils/common/ToString.h>
      28              : #include <utils/common/IDSupplier.h>
      29              : #include <utils/iodevices/OutputDevice.h>
      30              : #include <utils/options/OptionsCont.h>
      31              : #include "NBTrafficLightLogic.h"
      32              : #include "NBTrafficLightLogicCont.h"
      33              : #include "NBOwnTLDef.h"
      34              : #include "NBLoadedSUMOTLDef.h"
      35              : #include "NBEdgeCont.h"
      36              : #include "NBNodeCont.h"
      37              : 
      38              : 
      39              : // ===========================================================================
      40              : // static members
      41              : // ===========================================================================
      42              : const NBTrafficLightLogicCont::Program2Def NBTrafficLightLogicCont::EmptyDefinitions = NBTrafficLightLogicCont::Program2Def();
      43              : 
      44              : // ===========================================================================
      45              : // method definitions
      46              : // ===========================================================================
      47         2541 : NBTrafficLightLogicCont::NBTrafficLightLogicCont() {}
      48              : 
      49              : 
      50         2541 : NBTrafficLightLogicCont::~NBTrafficLightLogicCont() {
      51         2541 :     clear();
      52         2541 : }
      53              : 
      54              : 
      55              : void
      56         2531 : NBTrafficLightLogicCont::applyOptions(OptionsCont& oc) {
      57              :     // check whether any offsets shall be manipulated by setting
      58              :     //  them to half of the duration
      59         5062 :     if (oc.isSet("tls.half-offset")) {
      60            2 :         std::vector<std::string> ids = oc.getStringVector("tls.half-offset");
      61              :         myHalfOffsetTLS.insert(ids.begin(), ids.end());
      62            1 :     }
      63              :     // check whether any offsets shall be manipulated by setting
      64              :     //  them to a quarter of the duration
      65         5062 :     if (oc.isSet("tls.quarter-offset")) {
      66            2 :         std::vector<std::string> ids = oc.getStringVector("tls.quarter-offset");
      67              :         myQuarterOffsetTLS.insert(ids.begin(), ids.end());
      68            1 :     }
      69         2531 : }
      70              : 
      71              : 
      72              : std::string
      73            0 : NBTrafficLightLogicCont::getNextProgramID(const std::string& id) const {
      74            0 :     IDSupplier idS("", 0);
      75              :     if (myDefinitions.count(id)) {
      76              :         const Program2Def& programs = myDefinitions.find(id)->second;
      77            0 :         for (auto item : programs) {
      78            0 :             idS.avoid(item.first);
      79              :         }
      80              :     }
      81            0 :     return idS.getNext();
      82            0 : }
      83              : 
      84              : 
      85              : bool
      86         4768 : NBTrafficLightLogicCont::insert(NBTrafficLightDefinition* logic, bool forceInsert) {
      87              :     myExtracted.erase(logic);
      88         4768 :     if (myDefinitions.count(logic->getID())) {
      89           53 :         if (myDefinitions[logic->getID()].count(logic->getProgramID())) {
      90            2 :             if (forceInsert) {
      91            0 :                 logic->setProgramID(getNextProgramID(logic->getID()));
      92              :             } else {
      93              :                 return false;
      94              :             }
      95              :         }
      96              :     } else {
      97         9430 :         myDefinitions[logic->getID()] = Program2Def();
      98              :     }
      99         4766 :     myDefinitions[logic->getID()][logic->getProgramID()] = logic;
     100         4766 :     return true;
     101              : }
     102              : 
     103              : 
     104              : bool
     105          148 : NBTrafficLightLogicCont::removeFully(const std::string id) {
     106              :     if (myDefinitions.count(id)) {
     107              :         // delete all programs
     108          286 :         for (Program2Def::iterator i = myDefinitions[id].begin(); i != myDefinitions[id].end(); i++) {
     109          143 :             delete i->second;
     110              :         }
     111              :         myDefinitions.erase(id);
     112              :         // also delete any logics that were already computed
     113              :         if (myComputed.count(id)) {
     114           10 :             for (Program2Logic::iterator i = myComputed[id].begin(); i != myComputed[id].end(); i++) {
     115            5 :                 delete i->second;
     116              :             }
     117              :             myComputed.erase(id);
     118              :         }
     119          143 :         return true;
     120              :     } else {
     121            5 :         return false;
     122              :     }
     123              : }
     124              : 
     125              : 
     126              : bool
     127          991 : NBTrafficLightLogicCont::removeProgram(const std::string id, const std::string programID, bool del) {
     128          991 :     if (myDefinitions.count(id) && myDefinitions[id].count(programID)) {
     129          986 :         if (del) {
     130           38 :             delete myDefinitions[id][programID];
     131              :         }
     132          986 :         myDefinitions[id].erase(programID);
     133            0 :         if (myComputed.count(id) && myComputed[id].count(programID)) {
     134            0 :             if (del) {
     135            0 :                 delete myComputed[id][programID];
     136              :             }
     137            0 :             myComputed[id].erase(programID);
     138              :         }
     139          986 :         return true;
     140              :     } else {
     141            5 :         return false;
     142              :     }
     143              : }
     144              : 
     145              : 
     146              : void
     147          953 : NBTrafficLightLogicCont::extract(NBTrafficLightDefinition* definition) {
     148              :     myExtracted.insert(definition);
     149         2859 :     removeProgram(definition->getID(), definition->getProgramID(), false);
     150          953 : }
     151              : 
     152              : 
     153              : bool
     154            2 : NBTrafficLightLogicCont::exist(const std::string& newID, bool requireComputed) const {
     155              :     const auto itD = myDefinitions.find(newID);
     156              :     const auto itC = myComputed.find(newID);
     157            2 :     if ((itD != myDefinitions.end()) && (itC != myComputed.end() || !requireComputed)) {
     158            1 :         return true;
     159              :     } else {
     160              :         return false;
     161              :     }
     162              : }
     163              : 
     164              : 
     165              : std::pair<int, int>
     166         2240 : NBTrafficLightLogicCont::computeLogics(OptionsCont& oc) {
     167              :     // clean previous logics
     168         2240 :     Logics logics = getComputed();
     169         2240 :     for (Logics::iterator it = logics.begin(); it != logics.end(); it++) {
     170            0 :         delete *it;
     171              :     }
     172              :     myComputed.clear();
     173         4480 :     if (oc.getBool("tls.rebuild")) {
     174           21 :         for (NBTrafficLightDefinition* def : getDefinitions()) {
     175           13 :             NBLoadedSUMOTLDef* lDef = dynamic_cast<NBLoadedSUMOTLDef*>(def);
     176           13 :             if (lDef != nullptr) {
     177              :                 TrafficLightType type = def->getType();
     178           26 :                 if (!oc.isDefault("tls.default-type")) {
     179           14 :                     type = SUMOXMLDefinitions::TrafficLightTypes.get(oc.getString("tls.default-type"));
     180              :                 }
     181           13 :                 NBOwnTLDef* oDef = new NBOwnTLDef(def->getID(), def->getNodes(), def->getOffset(), type);
     182           13 :                 oDef->setProgramID(def->getProgramID());
     183           13 :                 oDef->setParticipantsInformation();
     184           61 :                 for (NBEdge* e : oDef->getIncomingEdges()) {
     185           48 :                     e->clearControllingTLInformation();
     186              :                 }
     187           13 :                 oDef->setTLControllingInformation();
     188           27 :                 for (NBNode* node : oDef->getNodes()) {
     189           14 :                     node->removeTrafficLight(def);
     190           17 :                     for (auto c : node->getCrossings()) {
     191            3 :                         c->customTLIndex = -1;
     192            3 :                         c->customTLIndex2 = -1;
     193            3 :                         c->tlLinkIndex2 = -1;
     194           14 :                     }
     195              :                 }
     196           26 :                 removeProgram(def->getID(), def->getProgramID());
     197           13 :                 insert(oDef);
     198              :             }
     199            8 :         }
     200              :     }
     201         4480 :     if (oc.getBool("tls.group-signals")) {
     202              :         // replace NBOwnTLDef tld with NBLoadedSUMOTLDef
     203            8 :         for (NBTrafficLightDefinition* def : getDefinitions()) {
     204            4 :             NBLoadedSUMOTLDef* lDef = dynamic_cast<NBLoadedSUMOTLDef*>(def);
     205            4 :             if (lDef == nullptr) {
     206            2 :                 NBTrafficLightLogic* logic = def->compute(oc);
     207            2 :                 if (logic != nullptr) {
     208            2 :                     lDef = new NBLoadedSUMOTLDef(*def, *logic);
     209            2 :                     lDef->setParticipantsInformation();
     210            4 :                     for (NBNode* node : lDef->getNodes()) {
     211            2 :                         node->removeTrafficLight(def);
     212            2 :                         node->addTrafficLight(lDef);
     213              :                     }
     214            4 :                     removeProgram(def->getID(), def->getProgramID());
     215            2 :                     insert(lDef);
     216            2 :                     delete logic;
     217              :                 }
     218              :             }
     219            2 :             if (lDef != nullptr) {
     220            4 :                 lDef->groupSignals();
     221              :             }
     222            4 :         }
     223         4472 :     } else if (oc.getBool("tls.ungroup-signals")) {
     224            4 :         for (NBTrafficLightDefinition* def : getDefinitions()) {
     225            2 :             NBLoadedSUMOTLDef* lDef = dynamic_cast<NBLoadedSUMOTLDef*>(def);
     226              :             // NBOwnTLDef are always ungrouped
     227            2 :             if (lDef != nullptr) {
     228            2 :                 if (lDef->usingSignalGroups()) {
     229            2 :                     lDef->ungroupSignals();
     230              :                 }
     231              :             }
     232            2 :         }
     233              :     }
     234              :     int numPrograms = 0;
     235         5871 :     for (NBTrafficLightDefinition* def : getDefinitions()) {
     236         3631 :         if (computeSingleLogic(oc, def)) {
     237         2717 :             numPrograms++;
     238              :         }
     239         2240 :     }
     240         2240 :     return std::pair<int, int>((int)myComputed.size(), numPrograms);
     241         2240 : }
     242              : 
     243              : 
     244              : bool
     245         4432 : NBTrafficLightLogicCont::computeSingleLogic(OptionsCont& oc, NBTrafficLightDefinition* def) {
     246         4432 :     if (def->getNodes().size() == 0) {
     247              :         return false;
     248              :     }
     249              :     const std::string& id = def->getID();
     250              :     const std::string& programID = def->getProgramID();
     251              :     // build program
     252         3583 :     NBTrafficLightLogic* built = def->compute(oc);
     253         3583 :     if (built == nullptr) {
     254          195 :         WRITE_WARNINGF(TL("Could not build program '%' for traffic light '%'"), programID, id);
     255           65 :         return false;
     256              :     }
     257              :     // compute offset
     258         3518 :     SUMOTime T = built->getDuration();
     259              :     if (myHalfOffsetTLS.count(id)) {
     260            2 :         built->setOffset(TIME2STEPS(floor(STEPS2TIME(T / 2))));
     261              :     }
     262              :     if (myQuarterOffsetTLS.count(id)) {
     263            2 :         built->setOffset(TIME2STEPS(floor(STEPS2TIME(T / 4))));
     264              :     }
     265              :     // and insert the result after computation
     266              :     // make sure we don't leak memory if computeSingleLogic is called externally
     267         3518 :     if (myComputed[id][programID] != nullptr) {
     268          801 :         delete myComputed[id][programID];
     269              :     }
     270         3518 :     myComputed[id][programID] = built;
     271         3518 :     return true;
     272              : }
     273              : 
     274              : 
     275              : void
     276         2541 : NBTrafficLightLogicCont::clear() {
     277         2541 :     Definitions definitions = getDefinitions();
     278         6178 :     for (Definitions::iterator it = definitions.begin(); it != definitions.end(); it++) {
     279         3637 :         delete *it;
     280              :     }
     281              :     myDefinitions.clear();
     282         2541 :     Logics logics = getComputed();
     283         5253 :     for (Logics::iterator it = logics.begin(); it != logics.end(); it++) {
     284         2712 :         delete *it;
     285              :     }
     286              :     myComputed.clear();
     287         3489 :     for (std::set<NBTrafficLightDefinition*>::iterator it = myExtracted.begin(); it != myExtracted.end(); it++) {
     288          948 :         delete *it;
     289              :     }
     290              :     myExtracted.clear();
     291         2541 : }
     292              : 
     293              : 
     294              : void
     295            0 : NBTrafficLightLogicCont::remapRemoved(NBEdge* removed, const EdgeVector& incoming,
     296              :                                       const EdgeVector& outgoing) {
     297            0 :     Definitions definitions = getDefinitions();
     298            0 :     for (Definitions::iterator it = definitions.begin(); it != definitions.end(); it++) {
     299            0 :         (*it)->remapRemoved(removed, incoming, outgoing);
     300              :     }
     301            0 : }
     302              : 
     303              : 
     304              : void
     305           54 : NBTrafficLightLogicCont::replaceRemoved(NBEdge* removed, int removedLane,
     306              :                                         NBEdge* by, int byLane, bool incoming) {
     307           54 :     Definitions definitions = getDefinitions();
     308          340 :     for (Definitions::iterator it = definitions.begin(); it != definitions.end(); it++) {
     309          286 :         (*it)->replaceRemoved(removed, removedLane, by, byLane, incoming);
     310              :     }
     311           54 : }
     312              : 
     313              : 
     314              : NBTrafficLightDefinition*
     315         2845 : NBTrafficLightLogicCont::getDefinition(const std::string& id, const std::string& programID) const {
     316              :     Id2Defs::const_iterator i = myDefinitions.find(id);
     317         2845 :     if (i != myDefinitions.end()) {
     318              :         Program2Def programs = i->second;
     319              :         Program2Def::const_iterator i2 = programs.find(programID);
     320         2845 :         if (i2 != programs.end()) {
     321         2829 :             return i2->second;
     322              :         }
     323              :     }
     324              :     return nullptr;
     325              : }
     326              : 
     327              : const NBTrafficLightLogicCont::Program2Def&
     328        11605 : NBTrafficLightLogicCont::getPrograms(const std::string& id) const {
     329              :     Id2Defs::const_iterator it = myDefinitions.find(id);
     330        11605 :     if (it != myDefinitions.end()) {
     331        11259 :         return it->second;
     332              :     } else {
     333              :         return EmptyDefinitions;
     334              :     }
     335              : }
     336              : 
     337              : 
     338              : NBTrafficLightLogic*
     339            0 : NBTrafficLightLogicCont::getLogic(const std::string& id, const std::string& programID) const {
     340              :     Id2Logics::const_iterator i = myComputed.find(id);
     341            0 :     if (i != myComputed.end()) {
     342              :         Program2Logic programs = i->second;
     343              :         Program2Logic::const_iterator i2 = programs.find(programID);
     344            0 :         if (i2 != programs.end()) {
     345            0 :             return i2->second;
     346              :         }
     347              :     }
     348              :     return nullptr;
     349              : }
     350              : 
     351              : 
     352              : void
     353         2241 : NBTrafficLightLogicCont::setTLControllingInformation(const NBEdgeCont& ec, const NBNodeCont& nc) {
     354         2241 :     Definitions definitions = getDefinitions();
     355              :     // set the information about all participants, first
     356         5874 :     for (Definitions::iterator it = definitions.begin(); it != definitions.end(); it++) {
     357         3633 :         (*it)->setParticipantsInformation();
     358              :     }
     359              :     // clear previous information because tlDefs may have been removed in netedit
     360         2241 :     ec.clearControllingTLInformation();
     361              :     // insert the information about the tl-controlling
     362         5872 :     for (Definitions::iterator it = definitions.begin(); it != definitions.end(); it++) {
     363         3632 :         (*it)->setTLControllingInformation();
     364              :     }
     365              :     // handle rail signals which are not instantiated as normal definitions
     366        73128 :     for (std::map<std::string, NBNode*>::const_iterator it = nc.begin(); it != nc.end(); it ++) {
     367        70888 :         NBNode* n = it->second;
     368        70888 :         if (n->getType() == SumoXMLNodeType::RAIL_SIGNAL || n->getType() == SumoXMLNodeType::RAIL_CROSSING) {
     369         1829 :             NBOwnTLDef dummy(n->getID(), n, 0, TrafficLightType::STATIC);
     370         1829 :             dummy.setParticipantsInformation();
     371         1829 :             dummy.setTLControllingInformation();
     372         1829 :             n->setCrossingTLIndices(dummy.getID(), (int)dummy.getControlledLinks().size());
     373         1829 :             n->removeTrafficLight(&dummy);
     374         1829 :         }
     375              :     }
     376         2241 : }
     377              : 
     378              : 
     379              : void
     380           23 : NBTrafficLightLogicCont::setOpenDriveSignalParameters() {
     381           23 :     Definitions definitions = getDefinitions();
     382           26 :     for (NBTrafficLightDefinition* def : getDefinitions()) {
     383              :         std::map<NBEdge*, std::string> defaultSignalIDs;
     384           28 :         for (const NBConnection& con : def->getControlledLinks()) {
     385           25 :             const NBEdge::Connection& c = con.getFrom()->getConnection(con.getFromLane(), con.getTo(), con.getToLane());
     386           50 :             if (c.hasParameter("signalID")) {
     387           75 :                 defaultSignalIDs[con.getFrom()] = c.getParameter("signalID");
     388          100 :                 def->setParameter("linkSignalID:" + toString(con.getTLIndex()), c.getParameter("signalID"));
     389              :             }
     390              :         }
     391              :         // oftentimes, signals are placed on connecting road but are meant to apply to all connections from the incoming edge
     392           28 :         for (const NBConnection& con : def->getControlledLinks()) {
     393           25 :             const NBEdge::Connection& c = con.getFrom()->getConnection(con.getFromLane(), con.getTo(), con.getToLane());
     394           50 :             if (!c.hasParameter("signalID") && defaultSignalIDs.count(con.getFrom()) != 0) {
     395            0 :                 WRITE_WARNINGF(TL("Guessing signalID for link index % at traffic light '%'."), con.getTLIndex(), def->getID());
     396            0 :                 def->setParameter("linkSignalID:" + toString(con.getTLIndex()), defaultSignalIDs[con.getFrom()]);
     397              :             }
     398              :         }
     399           23 :     }
     400           23 : }
     401              : 
     402              : 
     403              : void
     404            0 : NBTrafficLightLogicCont::applyOpenDriveControllers(OptionsCont& oc) {
     405              :     // collect connections with controllerID which can be controlled together
     406            0 :     Definitions definitions = getDefinitions();
     407              :     std::map<std::string, NBTrafficLightDefinition*> defsToGroup;
     408              :     std::map<std::string, std::map<std::string, std::set<int>>> controllerID2tlIndex;
     409            0 :     for (NBTrafficLightDefinition* def : definitions) {
     410              :         bool makeGroups = false;
     411              :         NBConnectionVector& connections = def->getControlledLinks();
     412              :         std::string defID = def->getID();
     413              : 
     414            0 :         for (NBConnection conn : connections) {
     415            0 :             std::string controllerID = conn.getFrom()->getConnection(conn.getFromLane(), conn.getTo(), conn.getToLane()).getParameter("controllerID");
     416            0 :             if (controllerID != "") {
     417            0 :                 if (controllerID2tlIndex.find(defID) == controllerID2tlIndex.end()) {
     418            0 :                     controllerID2tlIndex[defID][controllerID] = std::set<int>({ conn.getTLIndex() });
     419            0 :                 } else if (controllerID2tlIndex[defID].find(controllerID) != controllerID2tlIndex[defID].end()) {
     420            0 :                     controllerID2tlIndex[defID][controllerID].insert(conn.getTLIndex());
     421              :                 } else {
     422            0 :                     controllerID2tlIndex[defID][controllerID] = std::set<int>({ conn.getTLIndex() });
     423              :                 }
     424            0 :                 makeGroups = controllerID2tlIndex[defID][controllerID].size() > 1 || makeGroups;
     425              :             }
     426            0 :         }
     427            0 :         if (makeGroups) {
     428            0 :             defsToGroup[def->getID()] = def;
     429              :         }
     430              :     }
     431              :     bool same = true;
     432            0 :     for (NBTrafficLightLogic* computed : getComputed()) {
     433              :         const std::string computedID = computed->getID();
     434            0 :         if (defsToGroup.find(computedID) != defsToGroup.end()) {
     435              :             // remember corresponding tl indices and check if they can be joined
     436              :             // execute tl index joins if possible
     437            0 :             const std::vector<NBTrafficLightLogic::PhaseDefinition> phases = computed->getPhases();
     438              :             std::vector<int> major2minor;
     439            0 :             for (const auto& indexSet : controllerID2tlIndex[computedID]) {
     440            0 :                 if (indexSet.second.size() < 2) {
     441            0 :                     continue;
     442              :                 }
     443              :                 bool toMinor = false;
     444            0 :                 for (NBTrafficLightLogic::PhaseDefinition phase : phases) {
     445              :                     std::set<int>::iterator it = indexSet.second.begin();
     446            0 :                     char firstChar = phase.state[*it];
     447            0 :                     if (firstChar == LINKSTATE_TL_GREEN_MAJOR) {
     448              :                         firstChar = LINKSTATE_TL_GREEN_MINOR;
     449              :                     }
     450              :                     it++;
     451            0 :                     for (; it != indexSet.second.end(); it++) {
     452            0 :                         const char compareChar = (phase.state[*it] != LINKSTATE_TL_GREEN_MAJOR) ? phase.state[*it] : (char)LINKSTATE_TL_GREEN_MINOR;
     453            0 :                         if (compareChar != firstChar) {
     454              :                             same = false;
     455              :                             break;
     456            0 :                         } else if (phase.state[*it] == LINKSTATE_TL_GREEN_MINOR) {
     457              :                             toMinor = true;
     458              :                         }
     459              :                     }
     460            0 :                     if (!same) {
     461              :                         break;
     462              :                     }
     463            0 :                 }
     464            0 :                 if (toMinor) {
     465            0 :                     major2minor.push_back(*indexSet.second.begin());
     466              :                 }
     467              :             }
     468            0 :             if (same) {
     469            0 :                 NBLoadedSUMOTLDef* lDef = dynamic_cast<NBLoadedSUMOTLDef*>(defsToGroup[computedID]);
     470            0 :                 if (lDef == nullptr) {
     471            0 :                     lDef = new NBLoadedSUMOTLDef(*defsToGroup[computedID], *computed);
     472            0 :                     lDef->setParticipantsInformation();
     473            0 :                     for (int index : major2minor) { // update the signal states (G -> g where needed)
     474            0 :                         for (int i = 0; i < (int)phases.size(); i++) {
     475            0 :                             if (phases[i].state[index] == LINKSTATE_TL_GREEN_MAJOR) {
     476            0 :                                 lDef->getLogic()->setPhaseState(i, index, LINKSTATE_TL_GREEN_MINOR);
     477              :                             }
     478              :                         }
     479              :                     }
     480              :                     // join signal groups, update the connections
     481              :                     std::vector<int> indexToRemove;
     482            0 :                     for (const auto& indexSet : controllerID2tlIndex[computedID]) {
     483            0 :                         int minIndex = *indexSet.second.begin();
     484            0 :                         for (int index : indexSet.second) {
     485            0 :                             if (index != minIndex) {
     486            0 :                                 lDef->replaceIndex(index, minIndex);
     487            0 :                                 indexToRemove.push_back(index);
     488              :                             }
     489              :                         }
     490              :                     }
     491              :                     // remove unused indices from signal programs
     492            0 :                     lDef->cleanupStates();
     493            0 :                     for (NBNode* node : lDef->getNodes()) {
     494            0 :                         node->removeTrafficLight(defsToGroup[computedID]);
     495            0 :                         node->addTrafficLight(lDef);
     496              :                     }
     497            0 :                     removeProgram(defsToGroup[computedID]->getID(), defsToGroup[computedID]->getProgramID());
     498            0 :                     insert(lDef);
     499            0 :                     computeSingleLogic(oc, lDef);
     500            0 :                 }
     501              :             } else { // TODO: try other strategy to build signal groups
     502            0 :                 WRITE_WARNINGF(TL("Was not able to apply the OpenDRIVE signal group information onto the signal program of traffic light % generated by SUMO."), computed->getID());
     503              :             }
     504              :             break;
     505            0 :         }
     506            0 :     }
     507            0 : }
     508              : 
     509              : 
     510              : NBTrafficLightLogicCont::Logics
     511         7107 : NBTrafficLightLogicCont::getComputed() const {
     512              :     Logics result;
     513        12539 :     for (Id2Logics::const_iterator it_id = myComputed.begin(); it_id != myComputed.end(); it_id++) {
     514              :         const Program2Logic& programs = it_id->second;
     515        10887 :         for (Program2Logic::const_iterator it_prog = programs.begin(); it_prog != programs.end(); it_prog++) {
     516         5455 :             result.push_back(it_prog->second);
     517              :         }
     518              :     }
     519         7107 :     return result;
     520            0 : }
     521              : 
     522              : 
     523              : NBTrafficLightLogicCont::Definitions
     524         7136 : NBTrafficLightLogicCont::getDefinitions() const {
     525              :     Definitions result;
     526        21185 :     for (Id2Defs::const_iterator it_id = myDefinitions.begin(); it_id != myDefinitions.end(); it_id++) {
     527              :         const Program2Def& programs = it_id->second;
     528        25261 :         for (Program2Def::const_iterator it_prog = programs.begin(); it_prog != programs.end(); it_prog++) {
     529        11212 :             result.push_back(it_prog->second);
     530              :         }
     531              :     }
     532         7136 :     return result;
     533            0 : }
     534              : 
     535              : 
     536              : void
     537           21 : NBTrafficLightLogicCont::rename(NBTrafficLightDefinition* tlDef, const std::string& newID) {
     538              :     auto it = myDefinitions.find(tlDef->getID());
     539           21 :     if (it != myDefinitions.end()) {
     540           42 :         for (auto item : it->second) {
     541           21 :             item.second->setID(newID);
     542              :         }
     543           21 :         myDefinitions[newID] = it->second;
     544              :         myDefinitions.erase(it);
     545              :     }
     546              :     auto it2 = myComputed.find(tlDef->getID());
     547           21 :     if (it2 != myComputed.end()) {
     548            0 :         for (auto item : it2->second) {
     549            0 :             item.second->setID(newID);
     550              :         }
     551            0 :         myComputed[newID] = it2->second;
     552              :         myComputed.erase(it2);
     553              :     }
     554           21 : }
     555              : 
     556              : 
     557              : int
     558           56 : NBTrafficLightLogicCont::getNumExtracted() const {
     559           56 :     return (int)myExtracted.size();
     560              : }
     561              : 
     562              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1