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 : /****************************************************************************/
|