Path: blob/main/src/netimport/vissim/tempstructs/NIVissimTL.cpp
169684 views
/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file NIVissimTL.cpp14/// @author Daniel Krajzewicz15/// @author Jakob Erdmann16/// @author Michael Behrisch17/// @date Sept 200218///19// -------------------20/****************************************************************************/21#include <config.h>222324#include <map>25#include <string>26#include <cassert>27#include <utils/geom/GeomHelper.h>28#include <utils/geom/Boundary.h>29#include <utils/common/MsgHandler.h>30#include <utils/common/ToString.h>31#include "NIVissimConnection.h"32#include <netbuild/NBEdge.h>33#include <netbuild/NBEdgeCont.h>34#include <netbuild/NBTrafficLightLogicCont.h>35#include <netbuild/NBLoadedTLDef.h>36#include "NIVissimDisturbance.h"37#include "NIVissimNodeDef.h"38#include "NIVissimEdge.h"39#include "NIVissimTL.h"404142// ===========================================================================43// static member variables44// ===========================================================================45NIVissimTL::SignalDictType NIVissimTL::NIVissimTLSignal::myDict;464748// ===========================================================================49// method definitions50// ===========================================================================51NIVissimTL::NIVissimTLSignal::NIVissimTLSignal(int id,52const std::string& name,53const std::vector<int>& groupids,54int edgeid,55int laneno,56double position,57const std::vector<int>& vehicleTypes)58: myID(id), myName(name), myGroupIDs(groupids),59myEdgeID(edgeid), myLane(laneno), myPosition(position),60myVehicleTypes(vehicleTypes) {}616263NIVissimTL::NIVissimTLSignal::~NIVissimTLSignal() {}6465bool66NIVissimTL::NIVissimTLSignal::isWithin(const PositionVector& poly) const {67return poly.around(getPosition());68}697071Position72NIVissimTL::NIVissimTLSignal::getPosition() const {73return NIVissimAbstractEdge::dictionary(myEdgeID)->getGeomPosition(myPosition);74}757677bool78NIVissimTL::NIVissimTLSignal::dictionary(int lsaid, int id,79NIVissimTL::NIVissimTLSignal* o) {80SignalDictType::iterator i = myDict.find(lsaid);81if (i == myDict.end()) {82myDict[lsaid] = SSignalDictType();83i = myDict.find(lsaid);84}85SSignalDictType::iterator j = (*i).second.find(id);86if (j == (*i).second.end()) {87myDict[lsaid][id] = o;88return true;89}90return false;91}929394NIVissimTL::NIVissimTLSignal*95NIVissimTL::NIVissimTLSignal::dictionary(int lsaid, int id) {96SignalDictType::iterator i = myDict.find(lsaid);97if (i == myDict.end()) {98return nullptr;99}100SSignalDictType::iterator j = (*i).second.find(id);101if (j == (*i).second.end()) {102return nullptr;103}104return (*j).second;105}106107108void109NIVissimTL::NIVissimTLSignal::clearDict() {110for (SignalDictType::iterator i = myDict.begin(); i != myDict.end(); i++) {111for (SSignalDictType::iterator j = (*i).second.begin(); j != (*i).second.end(); j++) {112delete (*j).second;113}114}115myDict.clear();116}117118119NIVissimTL::SSignalDictType120NIVissimTL::NIVissimTLSignal::getSignalsFor(int tlid) {121SignalDictType::iterator i = myDict.find(tlid);122if (i == myDict.end()) {123return SSignalDictType();124}125return (*i).second;126}127128129bool130NIVissimTL::NIVissimTLSignal::addTo(NBEdgeCont& ec, NBLoadedTLDef* tl) const {131NIVissimConnection* c = NIVissimConnection::dictionary(myEdgeID);132NBConnectionVector assignedConnections;133if (c == nullptr) {134// What to do if on an edge? -> close all outgoing connections135NBEdge* edge = ec.retrievePossiblySplit(toString<int>(myEdgeID), myPosition);136if (edge == nullptr) {137WRITE_WARNINGF(TL("Could not set tls signal at edge '%' - the edge was not built."), myEdgeID);138return false;139}140// Check whether it is already known, which edges are approached141// by which lanes142// check whether to use the original lanes only143if (edge->lanesWereAssigned()) {144std::vector<NBEdge::Connection> connections = edge->getConnectionsFromLane(myLane - 1);145for (std::vector<NBEdge::Connection>::iterator i = connections.begin(); i != connections.end(); i++) {146const NBEdge::Connection& conn = *i;147assert(myLane - 1 < (int)edge->getNumLanes());148assignedConnections.push_back(NBConnection(edge, myLane - 1, conn.toEdge, conn.toLane));149}150} else {151WRITE_WARNINGF(TL("Edge '%': Lanes were not assigned."), myEdgeID);152for (int j = 0; j < edge->getNumLanes(); j++) {153std::vector<NBEdge::Connection> connections = edge->getConnectionsFromLane(j);154for (std::vector<NBEdge::Connection>::iterator i = connections.begin(); i != connections.end(); i++) {155const NBEdge::Connection& conn = *i;156assignedConnections.push_back(NBConnection(edge, j, conn.toEdge, conn.toLane));157}158}159}160} else {161// get the edges162NBEdge* tmpFrom = ec.retrievePossiblySplit(toString<int>(c->getFromEdgeID()), toString<int>(c->getToEdgeID()), true);163NBEdge* tmpTo = ec.retrievePossiblySplit(toString<int>(c->getToEdgeID()), toString<int>(c->getFromEdgeID()), false);164// check whether the edges are known165if (tmpFrom != nullptr && tmpTo != nullptr) {166// add connections this signal is responsible for167assignedConnections.push_back(NBConnection(tmpFrom, -1, tmpTo, -1));168} else {169return false;170// !!! one of the edges could not be build171}172}173// add to the group174assert(myGroupIDs.size() != 0);175// @todo just another hack?!176/*177if (myGroupIDs.size() == 1) {178return tl->addToSignalGroup(toString<int>(*(myGroupIDs.begin())),179assignedConnections);180} else {181// !!!182return tl->addToSignalGroup(toString<int>(*(myGroupIDs.begin())),183assignedConnections);184}185*/186return tl->addToSignalGroup(toString<int>(myGroupIDs.front()), assignedConnections);187}188189190191192193194195196NIVissimTL::GroupDictType NIVissimTL::NIVissimTLSignalGroup::myDict;197198NIVissimTL::NIVissimTLSignalGroup::NIVissimTLSignalGroup(199int id,200const std::string& name,201bool isGreenBegin, const std::vector<SUMOTime>& times,202SUMOTime tredyellow, SUMOTime tyellow)203: myID(id), myName(name), myTimes(times),204myFirstIsRed(!isGreenBegin), myTRedYellow(tredyellow),205myTYellow(tyellow) {}206207208NIVissimTL::NIVissimTLSignalGroup::~NIVissimTLSignalGroup() {}209210211bool212NIVissimTL::NIVissimTLSignalGroup::dictionary(int lsaid, int id,213NIVissimTL::NIVissimTLSignalGroup* o) {214GroupDictType::iterator i = myDict.find(lsaid);215if (i == myDict.end()) {216myDict[lsaid] = SGroupDictType();217i = myDict.find(lsaid);218}219SGroupDictType::iterator j = (*i).second.find(id);220if (j == (*i).second.end()) {221myDict[lsaid][id] = o;222return true;223}224return false;225/*226GroupDictType::iterator i=myDict.find(id);227if(i==myDict.end()) {228myDict[id] = o;229return true;230}231return false;232*/233}234235236NIVissimTL::NIVissimTLSignalGroup*237NIVissimTL::NIVissimTLSignalGroup::dictionary(int lsaid, int id) {238GroupDictType::iterator i = myDict.find(lsaid);239if (i == myDict.end()) {240return nullptr;241}242SGroupDictType::iterator j = (*i).second.find(id);243if (j == (*i).second.end()) {244return nullptr;245}246return (*j).second;247}248249void250NIVissimTL::NIVissimTLSignalGroup::clearDict() {251for (GroupDictType::iterator i = myDict.begin(); i != myDict.end(); i++) {252for (SGroupDictType::iterator j = (*i).second.begin(); j != (*i).second.end(); j++) {253delete (*j).second;254}255}256myDict.clear();257}258259260NIVissimTL::SGroupDictType261NIVissimTL::NIVissimTLSignalGroup::getGroupsFor(int tlid) {262GroupDictType::iterator i = myDict.find(tlid);263if (i == myDict.end()) {264return SGroupDictType();265}266return (*i).second;267}268269270bool271NIVissimTL::NIVissimTLSignalGroup::addTo(NBLoadedTLDef* tl) const {272// get the color at the begin273NBTrafficLightDefinition::TLColor color = myFirstIsRed274? NBTrafficLightDefinition::TLCOLOR_RED : NBTrafficLightDefinition::TLCOLOR_GREEN;275std::string id = toString<int>(myID);276tl->addSignalGroup(id);277for (SUMOTime t : myTimes) {278tl->addSignalGroupPhaseBegin(id, t, color);279color = color == NBTrafficLightDefinition::TLCOLOR_RED280? NBTrafficLightDefinition::TLCOLOR_GREEN : NBTrafficLightDefinition::TLCOLOR_RED;281}282if (myTimes.size() == 0) {283if (myFirstIsRed) {284tl->addSignalGroupPhaseBegin(id, 0, NBTrafficLightDefinition::TLCOLOR_RED);285} else {286tl->addSignalGroupPhaseBegin(id, 0, NBTrafficLightDefinition::TLCOLOR_GREEN);287}288}289tl->setSignalYellowTimes(id, myTRedYellow, myTYellow);290return true;291}292293294NIVissimTL::DictType NIVissimTL::myDict;295296NIVissimTL::NIVissimTL(int id, const std::string& type,297const std::string& name, SUMOTime absdur,298SUMOTime offset)299: myID(id), myName(name), myAbsDuration(absdur), myOffset(offset),300myCurrentGroup(nullptr), myType(type)301302{}303304305NIVissimTL::~NIVissimTL() {}306307308bool309NIVissimTL::dictionary(int id, const std::string& type,310const std::string& name, SUMOTime absdur,311SUMOTime offset) {312NIVissimTL* o = new NIVissimTL(id, type, name, absdur, offset);313if (!dictionary(id, o)) {314delete o;315return false;316}317return true;318}319320bool321NIVissimTL::dictionary(int id, NIVissimTL* o) {322DictType::iterator i = myDict.find(id);323if (i == myDict.end()) {324myDict[id] = o;325return true;326}327return false;328}329330331NIVissimTL*332NIVissimTL::dictionary(int id) {333DictType::iterator i = myDict.find(id);334if (i == myDict.end()) {335return nullptr;336}337return (*i).second;338}339340341void342NIVissimTL::clearDict() {343for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {344delete (*i).second;345}346myDict.clear();347}348349350351352353bool354NIVissimTL::dict_SetSignals(NBTrafficLightLogicCont& tlc,355NBEdgeCont& ec) {356int ref = 0;357int ref_groups = 0;358int ref_signals = 0;359int no_signals = 0;360int no_groups = 0;361for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {362NIVissimTL* tl = (*i).second;363/* if(tl->myType!="festzeit") {364cout << " Warning: The traffic light '" << tl->myID365<< "' could not be assigned to a node." << endl;366ref++;367continue;368}*/369std::string id = toString<int>(tl->myID);370TrafficLightType type = ((tl->getType() == "festzeit" || tl->getType() == "festzeit_fake") ?371TrafficLightType::STATIC : TrafficLightType::ACTUATED);372NBLoadedTLDef* def = new NBLoadedTLDef(ec, id, 0, type);373if (!tlc.insert(def)) {374WRITE_ERRORF(TL("Error on adding a traffic light\n Must be a multiple id ('%')"), id);375continue;376}377def->setCycleDuration(tl->myAbsDuration);378// add each group to the node's container379SGroupDictType sgs = NIVissimTLSignalGroup::getGroupsFor(tl->getID());380for (SGroupDictType::const_iterator j = sgs.begin(); j != sgs.end(); j++) {381if (!(*j).second->addTo(def)) {382WRITE_WARNINGF(TL("The signal group '%' could not be assigned to tl '%'."), toString<int>((*j).first), toString<int>(tl->myID));383ref_groups++;384}385no_groups++;386}387// add the signal group signals to the node388SSignalDictType signals = NIVissimTLSignal::getSignalsFor(tl->getID());389for (SSignalDictType::const_iterator k = signals.begin(); k != signals.end(); k++) {390if (!(*k).second->addTo(ec, def)) {391WRITE_WARNINGF(TL("The signal '%' could not be assigned to tl '%'."), toString<int>((*k).first), toString<int>(tl->myID));392ref_signals++;393}394no_signals++;395}396}397if (ref != 0) {398WRITE_WARNINGF(TL("Could not set % of % traffic lights."), toString<int>(ref), toString<int>((int)myDict.size()));399}400if (ref_groups != 0) {401WRITE_WARNINGF(TL("Could not set % of % groups."), toString<int>(ref_groups), toString<int>(no_groups));402}403if (ref_signals != 0) {404WRITE_WARNINGF(TL("Could not set % of % signals."), toString<int>(ref_signals), toString<int>(no_signals));405}406return true;407408}409410411std::string412NIVissimTL::getType() const {413return myType;414}415416417int418NIVissimTL::getID() const {419return myID;420}421422423/****************************************************************************/424425426