LCOV - code coverage report
Current view: top level - src/netimport/vissim/tempstructs - NIVissimTL.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 129 149 86.6 %
Date: 2024-05-01 15:34:42 Functions: 21 25 84.0 %

          Line data    Source code
       1             : /****************************************************************************/
       2             : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3             : // Copyright (C) 2001-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    NIVissimTL.cpp
      15             : /// @author  Daniel Krajzewicz
      16             : /// @author  Jakob Erdmann
      17             : /// @author  Michael Behrisch
      18             : /// @date    Sept 2002
      19             : ///
      20             : // -------------------
      21             : /****************************************************************************/
      22             : #include <config.h>
      23             : 
      24             : 
      25             : #include <map>
      26             : #include <string>
      27             : #include <cassert>
      28             : #include <utils/geom/GeomHelper.h>
      29             : #include <utils/geom/Boundary.h>
      30             : #include <utils/common/MsgHandler.h>
      31             : #include <utils/common/ToString.h>
      32             : #include "NIVissimConnection.h"
      33             : #include <netbuild/NBEdge.h>
      34             : #include <netbuild/NBEdgeCont.h>
      35             : #include <netbuild/NBTrafficLightLogicCont.h>
      36             : #include <netbuild/NBLoadedTLDef.h>
      37             : #include "NIVissimDisturbance.h"
      38             : #include "NIVissimNodeDef.h"
      39             : #include "NIVissimEdge.h"
      40             : #include "NIVissimTL.h"
      41             : 
      42             : 
      43             : // ===========================================================================
      44             : // static member variables
      45             : // ===========================================================================
      46             : NIVissimTL::SignalDictType NIVissimTL::NIVissimTLSignal::myDict;
      47             : 
      48             : 
      49             : // ===========================================================================
      50             : // method definitions
      51             : // ===========================================================================
      52         155 : NIVissimTL::NIVissimTLSignal::NIVissimTLSignal(int id,
      53             :         const std::string& name,
      54             :         const std::vector<int>& groupids,
      55             :         int edgeid,
      56             :         int laneno,
      57             :         double position,
      58         155 :         const std::vector<int>& vehicleTypes)
      59         155 :     : myID(id), myName(name), myGroupIDs(groupids),
      60         155 :       myEdgeID(edgeid), myLane(laneno), myPosition(position),
      61         155 :       myVehicleTypes(vehicleTypes) {}
      62             : 
      63             : 
      64         155 : NIVissimTL::NIVissimTLSignal::~NIVissimTLSignal() {}
      65             : 
      66             : bool
      67           0 : NIVissimTL::NIVissimTLSignal::isWithin(const PositionVector& poly) const {
      68           0 :     return poly.around(getPosition());
      69             : }
      70             : 
      71             : 
      72             : Position
      73           0 : NIVissimTL::NIVissimTLSignal::getPosition() const {
      74           0 :     return NIVissimAbstractEdge::dictionary(myEdgeID)->getGeomPosition(myPosition);
      75             : }
      76             : 
      77             : 
      78             : bool
      79         155 : NIVissimTL::NIVissimTLSignal::dictionary(int lsaid, int id,
      80             :         NIVissimTL::NIVissimTLSignal* o) {
      81             :     SignalDictType::iterator i = myDict.find(lsaid);
      82         155 :     if (i == myDict.end()) {
      83          24 :         myDict[lsaid] = SSignalDictType();
      84             :         i = myDict.find(lsaid);
      85             :     }
      86             :     SSignalDictType::iterator j = (*i).second.find(id);
      87         155 :     if (j == (*i).second.end()) {
      88         155 :         myDict[lsaid][id] = o;
      89         155 :         return true;
      90             :     }
      91             :     return false;
      92             : }
      93             : 
      94             : 
      95             : NIVissimTL::NIVissimTLSignal*
      96           0 : NIVissimTL::NIVissimTLSignal::dictionary(int lsaid, int id) {
      97             :     SignalDictType::iterator i = myDict.find(lsaid);
      98           0 :     if (i == myDict.end()) {
      99             :         return nullptr;
     100             :     }
     101             :     SSignalDictType::iterator j = (*i).second.find(id);
     102           0 :     if (j == (*i).second.end()) {
     103             :         return nullptr;
     104             :     }
     105           0 :     return (*j).second;
     106             : }
     107             : 
     108             : 
     109             : void
     110           9 : NIVissimTL::NIVissimTLSignal::clearDict() {
     111          21 :     for (SignalDictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
     112         167 :         for (SSignalDictType::iterator j = (*i).second.begin(); j != (*i).second.end(); j++) {
     113         155 :             delete (*j).second;
     114             :         }
     115             :     }
     116             :     myDict.clear();
     117           9 : }
     118             : 
     119             : 
     120             : NIVissimTL::SSignalDictType
     121          33 : NIVissimTL::NIVissimTLSignal::getSignalsFor(int tlid) {
     122             :     SignalDictType::iterator i = myDict.find(tlid);
     123          33 :     if (i == myDict.end()) {
     124          21 :         return SSignalDictType();
     125             :     }
     126             :     return (*i).second;
     127             : }
     128             : 
     129             : 
     130             : bool
     131         155 : NIVissimTL::NIVissimTLSignal::addTo(NBEdgeCont& ec, NBLoadedTLDef* tl) const {
     132         155 :     NIVissimConnection* c = NIVissimConnection::dictionary(myEdgeID);
     133             :     NBConnectionVector assignedConnections;
     134         155 :     if (c == nullptr) {
     135             :         // What to do if on an edge? -> close all outgoing connections
     136         105 :         NBEdge* edge = ec.retrievePossiblySplit(toString<int>(myEdgeID), myPosition);
     137         105 :         if (edge == nullptr) {
     138          12 :             WRITE_WARNINGF(TL("Could not set tls signal at edge '%' - the edge was not built."), myEdgeID);
     139          12 :             return false;
     140             :         }
     141             :         // Check whether it is already known, which edges are approached
     142             :         //  by which lanes
     143             :         // check whether to use the original lanes only
     144          93 :         if (edge->lanesWereAssigned()) {
     145          48 :             std::vector<NBEdge::Connection> connections = edge->getConnectionsFromLane(myLane - 1);
     146         105 :             for (std::vector<NBEdge::Connection>::iterator i = connections.begin(); i != connections.end(); i++) {
     147             :                 const NBEdge::Connection& conn = *i;
     148             :                 assert(myLane - 1 < (int)edge->getNumLanes());
     149         114 :                 assignedConnections.push_back(NBConnection(edge, myLane - 1, conn.toEdge, conn.toLane));
     150             :             }
     151          48 :         } else {
     152          45 :             WRITE_WARNINGF(TL("Edge '%': Lanes were not assigned."), myEdgeID);
     153         114 :             for (int j = 0; j < edge->getNumLanes(); j++) {
     154          69 :                 std::vector<NBEdge::Connection> connections = edge->getConnectionsFromLane(j);
     155         123 :                 for (std::vector<NBEdge::Connection>::iterator i = connections.begin(); i != connections.end(); i++) {
     156             :                     const NBEdge::Connection& conn = *i;
     157         108 :                     assignedConnections.push_back(NBConnection(edge, j, conn.toEdge, conn.toLane));
     158             :                 }
     159          69 :             }
     160             :         }
     161             :     } else {
     162             :         // get the edges
     163         100 :         NBEdge* tmpFrom = ec.retrievePossiblySplit(toString<int>(c->getFromEdgeID()), toString<int>(c->getToEdgeID()), true);
     164         100 :         NBEdge* tmpTo = ec.retrievePossiblySplit(toString<int>(c->getToEdgeID()), toString<int>(c->getFromEdgeID()), false);
     165             :         // check whether the edges are known
     166          50 :         if (tmpFrom != nullptr && tmpTo != nullptr) {
     167             :             // add connections this signal is responsible for
     168         100 :             assignedConnections.push_back(NBConnection(tmpFrom, -1, tmpTo, -1));
     169             :         } else {
     170             :             return false;
     171             :             // !!! one of the edges could not be build
     172             :         }
     173             :     }
     174             :     // add to the group
     175             :     assert(myGroupIDs.size() != 0);
     176             :     // @todo just another hack?!
     177             :     /*
     178             :     if (myGroupIDs.size() == 1) {
     179             :         return tl->addToSignalGroup(toString<int>(*(myGroupIDs.begin())),
     180             :                                     assignedConnections);
     181             :     } else {
     182             :         // !!!
     183             :         return tl->addToSignalGroup(toString<int>(*(myGroupIDs.begin())),
     184             :                                     assignedConnections);
     185             :     }
     186             :     */
     187         286 :     return tl->addToSignalGroup(toString<int>(myGroupIDs.front()), assignedConnections);
     188         155 : }
     189             : 
     190             : 
     191             : 
     192             : 
     193             : 
     194             : 
     195             : 
     196             : 
     197             : NIVissimTL::GroupDictType NIVissimTL::NIVissimTLSignalGroup::myDict;
     198             : 
     199          77 : NIVissimTL::NIVissimTLSignalGroup::NIVissimTLSignalGroup(
     200             :     int id,
     201             :     const std::string& name,
     202             :     bool isGreenBegin, const std::vector<SUMOTime>& times,
     203          77 :     SUMOTime tredyellow, SUMOTime tyellow)
     204          77 :     : myID(id), myName(name), myTimes(times),
     205          77 :       myFirstIsRed(!isGreenBegin), myTRedYellow(tredyellow),
     206          77 :       myTYellow(tyellow) {}
     207             : 
     208             : 
     209          77 : NIVissimTL::NIVissimTLSignalGroup::~NIVissimTLSignalGroup() {}
     210             : 
     211             : 
     212             : bool
     213          77 : NIVissimTL::NIVissimTLSignalGroup::dictionary(int lsaid, int id,
     214             :         NIVissimTL::NIVissimTLSignalGroup* o) {
     215             :     GroupDictType::iterator i = myDict.find(lsaid);
     216          77 :     if (i == myDict.end()) {
     217          24 :         myDict[lsaid] = SGroupDictType();
     218             :         i = myDict.find(lsaid);
     219             :     }
     220             :     SGroupDictType::iterator j = (*i).second.find(id);
     221          77 :     if (j == (*i).second.end()) {
     222          77 :         myDict[lsaid][id] = o;
     223          77 :         return true;
     224             :     }
     225             :     return false;
     226             :     /*
     227             :         GroupDictType::iterator i=myDict.find(id);
     228             :         if(i==myDict.end()) {
     229             :             myDict[id] = o;
     230             :             return true;
     231             :         }
     232             :         return false;
     233             :         */
     234             : }
     235             : 
     236             : 
     237             : NIVissimTL::NIVissimTLSignalGroup*
     238           0 : NIVissimTL::NIVissimTLSignalGroup::dictionary(int lsaid, int id) {
     239             :     GroupDictType::iterator i = myDict.find(lsaid);
     240           0 :     if (i == myDict.end()) {
     241             :         return nullptr;
     242             :     }
     243             :     SGroupDictType::iterator j = (*i).second.find(id);
     244           0 :     if (j == (*i).second.end()) {
     245             :         return nullptr;
     246             :     }
     247           0 :     return (*j).second;
     248             : }
     249             : 
     250             : void
     251           9 : NIVissimTL::NIVissimTLSignalGroup::clearDict() {
     252          21 :     for (GroupDictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
     253          89 :         for (SGroupDictType::iterator j = (*i).second.begin(); j != (*i).second.end(); j++) {
     254          77 :             delete (*j).second;
     255             :         }
     256             :     }
     257             :     myDict.clear();
     258           9 : }
     259             : 
     260             : 
     261             : NIVissimTL::SGroupDictType
     262          33 : NIVissimTL::NIVissimTLSignalGroup::getGroupsFor(int tlid) {
     263             :     GroupDictType::iterator i = myDict.find(tlid);
     264          33 :     if (i == myDict.end()) {
     265          21 :         return SGroupDictType();
     266             :     }
     267             :     return (*i).second;
     268             : }
     269             : 
     270             : 
     271             : bool
     272          77 : NIVissimTL::NIVissimTLSignalGroup::addTo(NBLoadedTLDef* tl) const {
     273             :     // get the color at the begin
     274          77 :     NBTrafficLightDefinition::TLColor color = myFirstIsRed
     275          77 :             ? NBTrafficLightDefinition::TLCOLOR_RED : NBTrafficLightDefinition::TLCOLOR_GREEN;
     276          77 :     std::string id = toString<int>(myID);
     277          77 :     tl->addSignalGroup(id);
     278         231 :     for (SUMOTime t : myTimes) {
     279         154 :         tl->addSignalGroupPhaseBegin(id, t, color);
     280             :         color = color == NBTrafficLightDefinition::TLCOLOR_RED
     281         154 :                 ? NBTrafficLightDefinition::TLCOLOR_GREEN : NBTrafficLightDefinition::TLCOLOR_RED;
     282             :     }
     283          77 :     if (myTimes.size() == 0) {
     284           3 :         if (myFirstIsRed) {
     285           3 :             tl->addSignalGroupPhaseBegin(id, 0, NBTrafficLightDefinition::TLCOLOR_RED);
     286             :         } else {
     287           0 :             tl->addSignalGroupPhaseBegin(id, 0, NBTrafficLightDefinition::TLCOLOR_GREEN);
     288             :         }
     289             :     }
     290          77 :     tl->setSignalYellowTimes(id, myTRedYellow, myTYellow);
     291          77 :     return true;
     292             : }
     293             : 
     294             : 
     295             : NIVissimTL::DictType NIVissimTL::myDict;
     296             : 
     297          33 : NIVissimTL::NIVissimTL(int id, const std::string& type,
     298             :                        const std::string& name, SUMOTime absdur,
     299          33 :                        SUMOTime offset)
     300          33 :     : myID(id), myName(name), myAbsDuration(absdur), myOffset(offset),
     301          33 :       myCurrentGroup(nullptr), myType(type)
     302             : 
     303          33 : {}
     304             : 
     305             : 
     306          33 : NIVissimTL::~NIVissimTL() {}
     307             : 
     308             : 
     309             : bool
     310          33 : NIVissimTL::dictionary(int id, const std::string& type,
     311             :                        const std::string& name, SUMOTime absdur,
     312             :                        SUMOTime offset) {
     313          33 :     NIVissimTL* o = new NIVissimTL(id, type, name, absdur, offset);
     314          33 :     if (!dictionary(id, o)) {
     315           0 :         delete o;
     316           0 :         return false;
     317             :     }
     318             :     return true;
     319             : }
     320             : 
     321             : bool
     322          33 : NIVissimTL::dictionary(int id, NIVissimTL* o) {
     323             :     DictType::iterator i = myDict.find(id);
     324          33 :     if (i == myDict.end()) {
     325          33 :         myDict[id] = o;
     326          33 :         return true;
     327             :     }
     328             :     return false;
     329             : }
     330             : 
     331             : 
     332             : NIVissimTL*
     333         553 : NIVissimTL::dictionary(int id) {
     334             :     DictType::iterator i = myDict.find(id);
     335         553 :     if (i == myDict.end()) {
     336             :         return nullptr;
     337             :     }
     338         541 :     return (*i).second;
     339             : }
     340             : 
     341             : 
     342             : void
     343           9 : NIVissimTL::clearDict() {
     344          42 :     for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
     345          33 :         delete (*i).second;
     346             :     }
     347             :     myDict.clear();
     348           9 : }
     349             : 
     350             : 
     351             : 
     352             : 
     353             : 
     354             : bool
     355           9 : NIVissimTL::dict_SetSignals(NBTrafficLightLogicCont& tlc,
     356             :                             NBEdgeCont& ec) {
     357           9 :     int ref = 0;
     358           9 :     int ref_groups = 0;
     359           9 :     int ref_signals = 0;
     360           9 :     int no_signals = 0;
     361           9 :     int no_groups = 0;
     362          42 :     for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
     363          33 :         NIVissimTL* tl = (*i).second;
     364             :         /*  if(tl->myType!="festzeit") {
     365             :            cout << " Warning: The traffic light '" << tl->myID
     366             :             << "' could not be assigned to a node." << endl;
     367             :            ref++;
     368             :            continue;
     369             :           }*/
     370          33 :         std::string id = toString<int>(tl->myID);
     371         114 :         TrafficLightType type = ((tl->getType() == "festzeit" || tl->getType() == "festzeit_fake") ?
     372             :                                  TrafficLightType::STATIC : TrafficLightType::ACTUATED);
     373          33 :         NBLoadedTLDef* def = new NBLoadedTLDef(ec, id, 0, type);
     374          33 :         if (!tlc.insert(def)) {
     375           0 :             WRITE_ERRORF(TL("Error on adding a traffic light\n Must be a multiple id ('%')"), id);
     376             :             continue;
     377             :         }
     378          33 :         def->setCycleDuration(tl->myAbsDuration);
     379             :         // add each group to the node's container
     380          33 :         SGroupDictType sgs = NIVissimTLSignalGroup::getGroupsFor(tl->getID());
     381         110 :         for (SGroupDictType::const_iterator j = sgs.begin(); j != sgs.end(); j++) {
     382          77 :             if (!(*j).second->addTo(def)) {
     383           0 :                 WRITE_WARNINGF(TL("The signal group '%' could not be assigned to tl '%'."), toString<int>((*j).first), toString<int>(tl->myID));
     384           0 :                 ref_groups++;
     385             :             }
     386          77 :             no_groups++;
     387             :         }
     388             :         // add the signal group signals to the node
     389          33 :         SSignalDictType signals = NIVissimTLSignal::getSignalsFor(tl->getID());
     390         188 :         for (SSignalDictType::const_iterator k = signals.begin(); k != signals.end(); k++) {
     391         155 :             if (!(*k).second->addTo(ec, def)) {
     392          24 :                 WRITE_WARNINGF(TL("The signal '%' could not be assigned to tl '%'."), toString<int>((*k).first), toString<int>(tl->myID));
     393          12 :                 ref_signals++;
     394             :             }
     395         155 :             no_signals++;
     396             :         }
     397             :     }
     398           9 :     if (ref != 0) {
     399           0 :         WRITE_WARNINGF(TL("Could not set % of % traffic lights."), toString<int>(ref), toString<int>((int)myDict.size()));
     400             :     }
     401           9 :     if (ref_groups != 0) {
     402           0 :         WRITE_WARNINGF(TL("Could not set % of % groups."), toString<int>(ref_groups), toString<int>(no_groups));
     403             :     }
     404           9 :     if (ref_signals != 0) {
     405           6 :         WRITE_WARNINGF(TL("Could not set % of % signals."), toString<int>(ref_signals), toString<int>(no_signals));
     406             :     }
     407           9 :     return true;
     408             : 
     409             : }
     410             : 
     411             : 
     412             : std::string
     413         455 : NIVissimTL::getType() const {
     414         455 :     return myType;
     415             : }
     416             : 
     417             : 
     418             : int
     419          66 : NIVissimTL::getID() const {
     420          66 :     return myID;
     421             : }
     422             : 
     423             : 
     424             : /****************************************************************************/

Generated by: LCOV version 1.14