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 NIVissimConnection.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Sascha Krieg
18 : /// @author Michael Behrisch
19 : /// @author Laura Bieker
20 : /// @date Sept 2002
21 : ///
22 : // -------------------
23 : /****************************************************************************/
24 : #include <config.h>
25 :
26 : #include <string>
27 : #include <map>
28 : #include <iostream>
29 : #include <cassert>
30 : #include <utils/common/VectorHelper.h>
31 : #include <utils/common/MsgHandler.h>
32 : #include <utils/common/ToString.h>
33 : #include "NIVissimExtendedEdgePoint.h"
34 : #include <utils/geom/PositionVector.h>
35 : #include <utils/geom/Boundary.h>
36 : #include <utils/geom/GeomHelper.h>
37 : #include <netbuild/NBEdge.h>
38 : #include <netbuild/NBNode.h>
39 : #include <netbuild/NBEdgeCont.h>
40 : #include "NIVissimEdge.h"
41 : #include "NIVissimClosedLanesVector.h"
42 : #include "NIVissimNodeDef.h"
43 : #include "NIVissimConnection.h"
44 : #include <utils/common/UtilExceptions.h>
45 :
46 :
47 : // ===========================================================================
48 : // static members
49 : // ===========================================================================
50 : NIVissimConnection::DictType NIVissimConnection::myDict;
51 : int NIVissimConnection::myMaxID;
52 :
53 :
54 : // ===========================================================================
55 : // method definitions
56 : // ===========================================================================
57 927 : NIVissimConnection::NIVissimConnection(int id,
58 : const std::string& name, const NIVissimExtendedEdgePoint& from_def,
59 : const NIVissimExtendedEdgePoint& to_def,
60 : const PositionVector& geom,
61 927 : const std::vector<int>& assignedVehicles, const NIVissimClosedLanesVector& clv)
62 : : NIVissimAbstractEdge(id, geom),
63 927 : myName(name), myFromDef(from_def), myToDef(to_def),
64 1854 : myAssignedVehicles(assignedVehicles), myClosedLanes(clv) {}
65 :
66 :
67 1854 : NIVissimConnection::~NIVissimConnection() {
68 950 : for (NIVissimClosedLanesVector::iterator i = myClosedLanes.begin(); i != myClosedLanes.end(); i++) {
69 23 : delete (*i);
70 : }
71 : myClosedLanes.clear();
72 1854 : }
73 :
74 :
75 : bool
76 927 : NIVissimConnection::dictionary(int id, NIVissimConnection* o) {
77 : DictType::iterator i = myDict.find(id);
78 927 : if (i == myDict.end()) {
79 927 : myDict[id] = o;
80 927 : return true;
81 : }
82 : return false;
83 : }
84 :
85 :
86 :
87 : NIVissimConnection*
88 315215 : NIVissimConnection::dictionary(int id) {
89 : DictType::iterator i = myDict.find(id);
90 315215 : if (i == myDict.end()) {
91 : return nullptr;
92 : }
93 314656 : return (*i).second;
94 : }
95 :
96 :
97 : void
98 0 : NIVissimConnection::buildNodeClusters() {
99 0 : for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
100 0 : NIVissimConnection* e = (*i).second;
101 0 : if (!e->clustered()) {
102 : assert(e->myBoundary != 0 && e->myBoundary->xmax() > e->myBoundary->xmin());
103 : std::vector<int> connections =
104 0 : NIVissimConnection::getWithin(*(e->myBoundary));
105 0 : NIVissimNodeCluster::dictionary(-1, -1, connections,
106 0 : std::vector<int>(), true); // 19.5.!!! should be on a single edge
107 0 : }
108 : }
109 0 : }
110 :
111 :
112 :
113 :
114 :
115 : std::vector<int>
116 0 : NIVissimConnection::getWithin(const AbstractPoly& poly) {
117 : std::vector<int> ret;
118 0 : for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
119 0 : if ((*i).second->crosses(poly)) {
120 0 : ret.push_back((*i).second->myID);
121 : }
122 : }
123 0 : return ret;
124 0 : }
125 :
126 :
127 : void
128 927 : NIVissimConnection::computeBounding() {
129 927 : Boundary* bound = new Boundary();
130 927 : bound->add(myFromDef.getGeomPosition());
131 927 : bound->add(myToDef.getGeomPosition());
132 : assert(myBoundary == 0);
133 927 : myBoundary = bound;
134 927 : }
135 :
136 :
137 : std::vector<int>
138 0 : NIVissimConnection::getForEdge(int edgeid, bool /*omitNodeAssigned*/) {
139 : std::vector<int> ret;
140 0 : for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
141 0 : int connID = (*i).first;
142 0 : if ((*i).second->myFromDef.getEdgeID() == edgeid
143 0 : ||
144 0 : (*i).second->myToDef.getEdgeID() == edgeid) {
145 0 : if (!(*i).second->hasNodeCluster()) {
146 0 : ret.push_back(connID);
147 : }
148 : }
149 : }
150 0 : return ret;
151 0 : }
152 :
153 :
154 : int
155 129813 : NIVissimConnection::getFromEdgeID() const {
156 129813 : return myFromDef.getEdgeID();
157 : }
158 :
159 :
160 : int
161 118978 : NIVissimConnection::getToEdgeID() const {
162 118978 : return myToDef.getEdgeID();
163 : }
164 :
165 :
166 : double
167 8301 : NIVissimConnection::getFromPosition() const {
168 8301 : return myFromDef.getPosition();
169 : }
170 :
171 :
172 : double
173 8250 : NIVissimConnection::getToPosition() const {
174 8250 : return myToDef.getPosition();
175 : }
176 :
177 :
178 : Position
179 3132 : NIVissimConnection::getFromGeomPosition() const {
180 3132 : return myFromDef.getGeomPosition();
181 : }
182 :
183 :
184 :
185 : Position
186 2846 : NIVissimConnection::getToGeomPosition() const {
187 2846 : return myToDef.getGeomPosition();
188 : }
189 :
190 :
191 : void
192 0 : NIVissimConnection::setNodeCluster(int nodeid) {
193 : assert(myNode == -1);
194 0 : myNode = nodeid;
195 0 : }
196 :
197 :
198 : void
199 2446 : NIVissimConnection::buildGeom() {
200 2446 : if (myGeom.size() > 0) {
201 : return;
202 : }
203 190 : myGeom.push_back(myFromDef.getGeomPosition());
204 380 : myGeom.push_back(myToDef.getGeomPosition());
205 : }
206 :
207 :
208 : int
209 927 : NIVissimConnection::buildEdgeConnections(NBEdgeCont& ec) {
210 : int unsetConnections = 0;
211 : // try to determine the connected edges
212 : NBEdge* fromEdge = nullptr;
213 : NBEdge* toEdge = nullptr;
214 927 : NIVissimEdge* vissimFrom = NIVissimEdge::dictionary(getFromEdgeID());
215 927 : if (vissimFrom->wasWithinAJunction()) {
216 : // this edge was not built, try to get one that approaches it
217 2 : vissimFrom = vissimFrom->getBestIncoming();
218 2 : if (vissimFrom != nullptr) {
219 4 : fromEdge = ec.retrievePossiblySplit(toString(vissimFrom->getID()), toString(getFromEdgeID()), true);
220 : }
221 : } else {
222 : // this edge was built, try to get the proper part
223 1850 : fromEdge = ec.retrievePossiblySplit(toString(getFromEdgeID()), toString(getToEdgeID()), true);
224 : }
225 927 : NIVissimEdge* vissimTo = NIVissimEdge::dictionary(getToEdgeID());
226 927 : if (vissimTo->wasWithinAJunction()) {
227 6 : vissimTo = vissimTo->getBestOutgoing();
228 6 : if (vissimTo != nullptr) {
229 12 : toEdge = ec.retrievePossiblySplit(toString(vissimTo->getID()), toString(getToEdgeID()), true);
230 : }
231 : } else {
232 1842 : toEdge = ec.retrievePossiblySplit(toString(getToEdgeID()), toString(getFromEdgeID()), false);
233 : }
234 :
235 : // try to get the edges the current connection connects
236 : /*
237 : NBEdge *fromEdge = ec.retrievePossiblySplit(toString(getFromEdgeID()), toString(getToEdgeID()), true);
238 : NBEdge *toEdge = ec.retrievePossiblySplit(toString(getToEdgeID()), toString(getFromEdgeID()), false);
239 : */
240 927 : if (fromEdge == nullptr || toEdge == nullptr) {
241 48 : WRITE_WARNINGF(TL("Could not build connection between '%' and '%'."), toString(getFromEdgeID()), toString(getToEdgeID()));
242 24 : return 1; // !!! actually not 1
243 : }
244 903 : recheckLanes(fromEdge, toEdge);
245 903 : const std::vector<int>& fromLanes = getFromLanes();
246 903 : const std::vector<int>& toLanes = getToLanes();
247 903 : if (fromLanes.size() != toLanes.size()) {
248 0 : WRITE_WARNINGF(TL("Lane sizes differ for connection '%'."), toString(getID()));
249 : } else {
250 2039 : for (int index = 0; index < (int)fromLanes.size(); ++index) {
251 1136 : if (fromEdge->getNumLanes() <= fromLanes[index]) {
252 5 : WRITE_WARNING("Could not set connection between '" + fromEdge->getID() + "_" + toString(fromLanes[index]) + "' and '" + toEdge->getID() + "_" + toString(toLanes[index]) + "'.");
253 1 : ++unsetConnections;
254 2270 : } else if (!fromEdge->addLane2LaneConnection(fromLanes[index], toEdge, toLanes[index], NBEdge::Lane2LaneInfoType::VALIDATED, true)) {
255 60 : WRITE_WARNING("Could not set connection between '" + fromEdge->getID() + "_" + toString(fromLanes[index]) + "' and '" + toEdge->getID() + "_" + toString(toLanes[index]) + "'.");
256 12 : ++unsetConnections;
257 : }
258 : }
259 : }
260 : return unsetConnections;
261 : }
262 :
263 :
264 : void
265 9 : NIVissimConnection::dict_buildNBEdgeConnections(NBEdgeCont& ec) {
266 9 : int unsetConnections = 0;
267 : // go through connections
268 936 : for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
269 927 : unsetConnections += (*i).second->buildEdgeConnections(ec);
270 : }
271 9 : if (unsetConnections != 0) {
272 16 : WRITE_WARNING(toString<int>(unsetConnections) + " of " + toString<int>((int)myDict.size()) + " connections could not be assigned.");
273 : }
274 9 : }
275 :
276 :
277 : const std::vector<int>&
278 903 : NIVissimConnection::getFromLanes() const {
279 903 : return myFromDef.getLanes();
280 : }
281 :
282 :
283 : const std::vector<int>&
284 909 : NIVissimConnection::getToLanes() const {
285 909 : return myToDef.getLanes();
286 : }
287 :
288 :
289 : void
290 903 : NIVissimConnection::recheckLanes(const NBEdge* const fromEdge, const NBEdge* const toEdge) {
291 903 : myFromDef.recheckLanes(fromEdge);
292 903 : myToDef.recheckLanes(toEdge);
293 903 : }
294 :
295 :
296 : const Boundary&
297 0 : NIVissimConnection::getBoundingBox() const {
298 : assert(myBoundary != 0 && myBoundary->xmax() >= myBoundary->xmin());
299 0 : return *myBoundary;
300 : }
301 :
302 :
303 : void
304 9 : NIVissimConnection::dict_assignToEdges() {
305 936 : for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
306 927 : NIVissimConnection* c = (*i).second;
307 927 : NIVissimEdge::dictionary(c->getFromEdgeID())->addOutgoingConnection((*i).first);
308 927 : NIVissimEdge::dictionary(c->getToEdgeID())->addIncomingConnection((*i).first);
309 : }
310 9 : }
311 :
312 :
313 : int
314 0 : NIVissimConnection::getMaxID() {
315 0 : return myMaxID;
316 : }
317 :
318 :
319 : /****************************************************************************/
|