Path: blob/main/src/netimport/vissim/tempstructs/NIVissimConnection.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 NIVissimConnection.cpp14/// @author Daniel Krajzewicz15/// @author Jakob Erdmann16/// @author Sascha Krieg17/// @author Michael Behrisch18/// @author Laura Bieker19/// @date Sept 200220///21// -------------------22/****************************************************************************/23#include <config.h>2425#include <string>26#include <map>27#include <iostream>28#include <cassert>29#include <utils/common/VectorHelper.h>30#include <utils/common/MsgHandler.h>31#include <utils/common/ToString.h>32#include "NIVissimExtendedEdgePoint.h"33#include <utils/geom/PositionVector.h>34#include <utils/geom/Boundary.h>35#include <utils/geom/GeomHelper.h>36#include <netbuild/NBEdge.h>37#include <netbuild/NBNode.h>38#include <netbuild/NBEdgeCont.h>39#include "NIVissimEdge.h"40#include "NIVissimClosedLanesVector.h"41#include "NIVissimNodeDef.h"42#include "NIVissimConnection.h"43#include <utils/common/UtilExceptions.h>444546// ===========================================================================47// static members48// ===========================================================================49NIVissimConnection::DictType NIVissimConnection::myDict;50int NIVissimConnection::myMaxID;515253// ===========================================================================54// method definitions55// ===========================================================================56NIVissimConnection::NIVissimConnection(int id,57const std::string& name, const NIVissimExtendedEdgePoint& from_def,58const NIVissimExtendedEdgePoint& to_def,59const PositionVector& geom,60const std::vector<int>& assignedVehicles, const NIVissimClosedLanesVector& clv)61: NIVissimAbstractEdge(id, geom),62myName(name), myFromDef(from_def), myToDef(to_def),63myAssignedVehicles(assignedVehicles), myClosedLanes(clv) {}646566NIVissimConnection::~NIVissimConnection() {67for (NIVissimClosedLanesVector::iterator i = myClosedLanes.begin(); i != myClosedLanes.end(); i++) {68delete (*i);69}70myClosedLanes.clear();71}727374bool75NIVissimConnection::dictionary(int id, NIVissimConnection* o) {76DictType::iterator i = myDict.find(id);77if (i == myDict.end()) {78myDict[id] = o;79return true;80}81return false;82}83848586NIVissimConnection*87NIVissimConnection::dictionary(int id) {88DictType::iterator i = myDict.find(id);89if (i == myDict.end()) {90return nullptr;91}92return (*i).second;93}949596void97NIVissimConnection::buildNodeClusters() {98for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {99NIVissimConnection* e = (*i).second;100if (!e->clustered()) {101assert(e->myBoundary != 0 && e->myBoundary->xmax() > e->myBoundary->xmin());102std::vector<int> connections =103NIVissimConnection::getWithin(*(e->myBoundary));104NIVissimNodeCluster::dictionary(-1, -1, connections,105std::vector<int>(), true); // 19.5.!!! should be on a single edge106}107}108}109110111112113114std::vector<int>115NIVissimConnection::getWithin(const AbstractPoly& poly) {116std::vector<int> ret;117for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {118if ((*i).second->crosses(poly)) {119ret.push_back((*i).second->myID);120}121}122return ret;123}124125126void127NIVissimConnection::computeBounding() {128Boundary* bound = new Boundary();129bound->add(myFromDef.getGeomPosition());130bound->add(myToDef.getGeomPosition());131assert(myBoundary == 0);132myBoundary = bound;133}134135136std::vector<int>137NIVissimConnection::getForEdge(int edgeid, bool /*omitNodeAssigned*/) {138std::vector<int> ret;139for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {140int connID = (*i).first;141if ((*i).second->myFromDef.getEdgeID() == edgeid142||143(*i).second->myToDef.getEdgeID() == edgeid) {144if (!(*i).second->hasNodeCluster()) {145ret.push_back(connID);146}147}148}149return ret;150}151152153int154NIVissimConnection::getFromEdgeID() const {155return myFromDef.getEdgeID();156}157158159int160NIVissimConnection::getToEdgeID() const {161return myToDef.getEdgeID();162}163164165double166NIVissimConnection::getFromPosition() const {167return myFromDef.getPosition();168}169170171double172NIVissimConnection::getToPosition() const {173return myToDef.getPosition();174}175176177Position178NIVissimConnection::getFromGeomPosition() const {179return myFromDef.getGeomPosition();180}181182183184Position185NIVissimConnection::getToGeomPosition() const {186return myToDef.getGeomPosition();187}188189190void191NIVissimConnection::setNodeCluster(int nodeid) {192assert(myNode == -1);193myNode = nodeid;194}195196197void198NIVissimConnection::buildGeom() {199if (myGeom.size() > 0) {200return;201}202myGeom.push_back(myFromDef.getGeomPosition());203myGeom.push_back(myToDef.getGeomPosition());204}205206207int208NIVissimConnection::buildEdgeConnections(NBEdgeCont& ec) {209int unsetConnections = 0;210// try to determine the connected edges211NBEdge* fromEdge = nullptr;212NBEdge* toEdge = nullptr;213NIVissimEdge* vissimFrom = NIVissimEdge::dictionary(getFromEdgeID());214if (vissimFrom->wasWithinAJunction()) {215// this edge was not built, try to get one that approaches it216vissimFrom = vissimFrom->getBestIncoming();217if (vissimFrom != nullptr) {218fromEdge = ec.retrievePossiblySplit(toString(vissimFrom->getID()), toString(getFromEdgeID()), true);219}220} else {221// this edge was built, try to get the proper part222fromEdge = ec.retrievePossiblySplit(toString(getFromEdgeID()), toString(getToEdgeID()), true);223}224NIVissimEdge* vissimTo = NIVissimEdge::dictionary(getToEdgeID());225if (vissimTo->wasWithinAJunction()) {226vissimTo = vissimTo->getBestOutgoing();227if (vissimTo != nullptr) {228toEdge = ec.retrievePossiblySplit(toString(vissimTo->getID()), toString(getToEdgeID()), true);229}230} else {231toEdge = ec.retrievePossiblySplit(toString(getToEdgeID()), toString(getFromEdgeID()), false);232}233234// try to get the edges the current connection connects235/*236NBEdge *fromEdge = ec.retrievePossiblySplit(toString(getFromEdgeID()), toString(getToEdgeID()), true);237NBEdge *toEdge = ec.retrievePossiblySplit(toString(getToEdgeID()), toString(getFromEdgeID()), false);238*/239if (fromEdge == nullptr || toEdge == nullptr) {240WRITE_WARNINGF(TL("Could not build connection between '%' and '%'."), toString(getFromEdgeID()), toString(getToEdgeID()));241return 1; // !!! actually not 1242}243recheckLanes(fromEdge, toEdge);244const std::vector<int>& fromLanes = getFromLanes();245const std::vector<int>& toLanes = getToLanes();246if (fromLanes.size() != toLanes.size()) {247WRITE_WARNINGF(TL("Lane sizes differ for connection '%'."), toString(getID()));248} else {249for (int index = 0; index < (int)fromLanes.size(); ++index) {250if (fromEdge->getNumLanes() <= fromLanes[index]) {251WRITE_WARNING("Could not set connection between '" + fromEdge->getID() + "_" + toString(fromLanes[index]) + "' and '" + toEdge->getID() + "_" + toString(toLanes[index]) + "'.");252++unsetConnections;253} else if (!fromEdge->addLane2LaneConnection(fromLanes[index], toEdge, toLanes[index], NBEdge::Lane2LaneInfoType::VALIDATED, true)) {254WRITE_WARNING("Could not set connection between '" + fromEdge->getID() + "_" + toString(fromLanes[index]) + "' and '" + toEdge->getID() + "_" + toString(toLanes[index]) + "'.");255++unsetConnections;256}257}258}259return unsetConnections;260}261262263void264NIVissimConnection::dict_buildNBEdgeConnections(NBEdgeCont& ec) {265int unsetConnections = 0;266// go through connections267for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {268unsetConnections += (*i).second->buildEdgeConnections(ec);269}270if (unsetConnections != 0) {271WRITE_WARNING(toString<int>(unsetConnections) + " of " + toString<int>((int)myDict.size()) + " connections could not be assigned.");272}273}274275276const std::vector<int>&277NIVissimConnection::getFromLanes() const {278return myFromDef.getLanes();279}280281282const std::vector<int>&283NIVissimConnection::getToLanes() const {284return myToDef.getLanes();285}286287288void289NIVissimConnection::recheckLanes(const NBEdge* const fromEdge, const NBEdge* const toEdge) {290myFromDef.recheckLanes(fromEdge);291myToDef.recheckLanes(toEdge);292}293294295const Boundary&296NIVissimConnection::getBoundingBox() const {297assert(myBoundary != 0 && myBoundary->xmax() >= myBoundary->xmin());298return *myBoundary;299}300301302void303NIVissimConnection::dict_assignToEdges() {304for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {305NIVissimConnection* c = (*i).second;306NIVissimEdge::dictionary(c->getFromEdgeID())->addOutgoingConnection((*i).first);307NIVissimEdge::dictionary(c->getToEdgeID())->addIncomingConnection((*i).first);308}309}310311312int313NIVissimConnection::getMaxID() {314return myMaxID;315}316317318/****************************************************************************/319320321