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 NIVissimNodeCluster.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 <algorithm> 27 : #include <cassert> 28 : #include <utils/common/VectorHelper.h> 29 : #include <utils/common/ToString.h> 30 : #include <utils/geom/PositionVector.h> 31 : #include <netbuild/NBNode.h> 32 : #include <netbuild/NBNodeCont.h> 33 : #include "NIVissimTL.h" 34 : #include "NIVissimDisturbance.h" 35 : #include "NIVissimConnection.h" 36 : #include "NIVissimNodeCluster.h" 37 : 38 : 39 : // =========================================================================== 40 : // static member variables 41 : // =========================================================================== 42 : NIVissimNodeCluster::DictType NIVissimNodeCluster::myDict; 43 : int NIVissimNodeCluster::myCurrentID = 1; 44 : 45 : 46 : // =========================================================================== 47 : // method definitions 48 : // =========================================================================== 49 348 : NIVissimNodeCluster::NIVissimNodeCluster(int id, int nodeid, int tlid, 50 : const std::vector<int>& connectors, 51 : const std::vector<int>& disturbances, 52 348 : bool amEdgeSplitOnly) 53 348 : : myID(id), myNodeID(nodeid), myTLID(tlid), 54 348 : myConnectors(connectors), myDisturbances(disturbances), 55 348 : myNBNode(nullptr), myAmEdgeSplit(amEdgeSplitOnly) {} 56 : 57 : 58 348 : NIVissimNodeCluster::~NIVissimNodeCluster() {} 59 : 60 : 61 : 62 : 63 : bool 64 348 : NIVissimNodeCluster::dictionary(int id, NIVissimNodeCluster* o) { 65 : DictType::iterator i = myDict.find(id); 66 348 : if (i == myDict.end()) { 67 348 : myDict[id] = o; 68 348 : return true; 69 : } 70 : assert(false); 71 : return false; 72 : } 73 : 74 : 75 : int 76 348 : NIVissimNodeCluster::dictionary(int nodeid, int tlid, 77 : const std::vector<int>& connectors, 78 : const std::vector<int>& disturbances, 79 : bool amEdgeSplitOnly) { 80 : int id = nodeid; 81 348 : if (nodeid < 0) { 82 348 : id = myCurrentID++; 83 : } 84 : NIVissimNodeCluster* o = new NIVissimNodeCluster(id, 85 348 : nodeid, tlid, connectors, disturbances, amEdgeSplitOnly); 86 348 : dictionary(id, o); 87 348 : return id; 88 : } 89 : 90 : 91 : NIVissimNodeCluster* 92 1061 : NIVissimNodeCluster::dictionary(int id) { 93 : DictType::iterator i = myDict.find(id); 94 1061 : if (i == myDict.end()) { 95 : return nullptr; 96 : } 97 1061 : return (*i).second; 98 : } 99 : 100 : 101 : 102 : int 103 0 : NIVissimNodeCluster::contSize() { 104 0 : return (int)myDict.size(); 105 : } 106 : 107 : 108 : 109 : std::string 110 696 : NIVissimNodeCluster::getNodeName() const { 111 696 : if (myTLID == -1) { 112 696 : return toString<int>(myID); 113 : } else { 114 0 : return toString<int>(myID) + "LSA " + toString<int>(myTLID); 115 : } 116 : } 117 : 118 : 119 : void 120 348 : NIVissimNodeCluster::buildNBNode(NBNodeCont& nc) { 121 348 : if (myConnectors.size() == 0) { 122 0 : return; // !!! Check, whether this can happen 123 : } 124 : 125 : // compute the position 126 348 : PositionVector crossings; 127 : std::vector<int>::iterator i, j; 128 : // check whether this is a split of an edge only 129 348 : if (myAmEdgeSplit) { 130 : // !!! should be assert(myTLID==-1); 131 499 : for (i = myConnectors.begin(); i != myConnectors.end(); i++) { 132 286 : NIVissimConnection* c1 = NIVissimConnection::dictionary(*i); 133 286 : crossings.push_back_noDoublePos(c1->getFromGeomPosition()); 134 : } 135 : } else { 136 : // compute the places the connections cross 137 776 : for (i = myConnectors.begin(); i != myConnectors.end(); i++) { 138 641 : NIVissimAbstractEdge* c1 = NIVissimAbstractEdge::dictionary(*i); 139 641 : c1->buildGeom(); 140 2446 : for (j = i + 1; j != myConnectors.end(); j++) { 141 1805 : NIVissimAbstractEdge* c2 = NIVissimAbstractEdge::dictionary(*j); 142 1805 : c2->buildGeom(); 143 1805 : if (c1->crossesEdge(c2)) { 144 674 : crossings.push_back_noDoublePos(c1->crossesEdgeAtPoint(c2)); 145 : } 146 : } 147 : } 148 : // alternative way: compute via positions of crossings 149 135 : if (crossings.size() == 0) { 150 93 : for (i = myConnectors.begin(); i != myConnectors.end(); i++) { 151 65 : NIVissimConnection* c1 = NIVissimConnection::dictionary(*i); 152 65 : crossings.push_back_noDoublePos(c1->getFromGeomPosition()); 153 65 : crossings.push_back_noDoublePos(c1->getToGeomPosition()); 154 : } 155 : } 156 : } 157 : // get the position (center) 158 348 : Position pos = crossings.getPolygonCenter(); 159 : // build the node 160 : /* if(myTLID!=-1) { 161 : !!! NIVissimTL *tl = NIVissimTL::dictionary(myTLID); 162 : if(tl->getType()=="festzeit") { 163 : node = new NBNode(getNodeName(), pos.x(), pos.y(), 164 : "traffic_light"); 165 : } else { 166 : node = new NBNode(getNodeName(), pos.x(), pos.y(), 167 : "actuated_traffic_light"); 168 : } 169 : }*/ 170 348 : NBNode* node = new NBNode(getNodeName(), pos, SumoXMLNodeType::PRIORITY); 171 348 : if (!nc.insert(node)) { 172 0 : delete node; 173 0 : throw 1; 174 : } 175 348 : myNBNode = node; 176 348 : } 177 : 178 : 179 : void 180 9 : NIVissimNodeCluster::buildNBNodes(NBNodeCont& nc) { 181 357 : for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) { 182 348 : (*i).second->buildNBNode(nc); 183 : } 184 9 : } 185 : 186 : 187 : 188 : void 189 0 : NIVissimNodeCluster::dict_recheckEdgeChanges() { 190 0 : return; 191 : } 192 : 193 : 194 : int 195 0 : NIVissimNodeCluster::getFromNode(int edgeid) { 196 : int ret = -1; 197 0 : for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) { 198 0 : NIVissimNodeCluster* c = (*i).second; 199 0 : for (std::vector<int>::iterator j = c->myConnectors.begin(); j != c->myConnectors.end(); j++) { 200 0 : NIVissimConnection* conn = NIVissimConnection::dictionary(*j); 201 0 : if (conn != nullptr && conn->getToEdgeID() == edgeid) { 202 : // return (*i).first; 203 0 : if (ret != -1 && (*i).first != ret) { 204 : // "NIVissimNodeCluster:DoubleNode:" << ret << endl; 205 0 : throw 1; // an edge should not outgo from two different nodes 206 : // but actually, a joined cluster may posess a connections more than once 207 : } 208 0 : ret = (*i).first; 209 : } 210 : } 211 : } 212 0 : return ret; 213 : } 214 : 215 : 216 : int 217 0 : NIVissimNodeCluster::getToNode(int edgeid) { 218 : int ret = -1; 219 0 : for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) { 220 0 : NIVissimNodeCluster* c = (*i).second; 221 0 : for (std::vector<int>::iterator j = c->myConnectors.begin(); j != c->myConnectors.end(); j++) { 222 0 : NIVissimConnection* conn = NIVissimConnection::dictionary(*j); 223 0 : if (conn != nullptr && conn->getFromEdgeID() == edgeid) { 224 : // return (*i).first; 225 0 : if (ret != -1 && ret != (*i).first) { 226 : // << "NIVissimNodeCluster: multiple to-nodes" << endl; 227 0 : throw 1; // an edge should not outgo from two different nodes 228 : // but actually, a joined cluster may posess a connections more than once 229 : 230 : } 231 0 : ret = (*i).first; 232 : } 233 : } 234 : } 235 0 : return ret; 236 : } 237 : 238 : 239 : void 240 0 : NIVissimNodeCluster::_debugOut(std::ostream& into) { 241 0 : for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) { 242 0 : NIVissimNodeCluster* c = (*i).second; 243 0 : into << std::endl << c->myID << ":"; 244 0 : for (std::vector<int>::iterator j = c->myConnectors.begin(); j != c->myConnectors.end(); j++) { 245 0 : if (j != c->myConnectors.begin()) { 246 0 : into << ", "; 247 : } 248 0 : into << (*j); 249 : } 250 : } 251 : into << "=======================" << std::endl; 252 0 : } 253 : 254 : 255 : 256 : NBNode* 257 1061 : NIVissimNodeCluster::getNBNode() const { 258 1061 : return myNBNode; 259 : } 260 : 261 : 262 : Position 263 0 : NIVissimNodeCluster::getPos() const { 264 0 : return myPosition; 265 : } 266 : 267 : 268 : void 269 9 : NIVissimNodeCluster::dict_addDisturbances(NBDistrictCont& dc, 270 : NBNodeCont& nc, NBEdgeCont& ec) { 271 357 : for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) { 272 348 : const std::vector<int>& disturbances = (*i).second->myDisturbances; 273 696 : NBNode* node = nc.retrieve((*i).second->getNodeName()); 274 769 : for (std::vector<int>::const_iterator j = disturbances.begin(); j != disturbances.end(); j++) { 275 421 : NIVissimDisturbance* disturbance = NIVissimDisturbance::dictionary(*j); 276 421 : disturbance->addToNode(node, dc, nc, ec); 277 : } 278 : } 279 9 : NIVissimDisturbance::reportRefused(); 280 9 : } 281 : 282 : 283 : void 284 9 : NIVissimNodeCluster::clearDict() { 285 357 : for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) { 286 348 : delete (*i).second; 287 : } 288 : myDict.clear(); 289 9 : } 290 : 291 : 292 : void 293 9 : NIVissimNodeCluster::setCurrentVirtID(int id) { 294 9 : myCurrentID = id; 295 9 : } 296 : 297 : 298 : /****************************************************************************/