Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/netimport/vissim/tempstructs/NIVissimConnection.cpp
169684 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2025 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
NIVissimConnection::NIVissimConnection(int id,
58
const std::string& name, const NIVissimExtendedEdgePoint& from_def,
59
const NIVissimExtendedEdgePoint& to_def,
60
const PositionVector& geom,
61
const std::vector<int>& assignedVehicles, const NIVissimClosedLanesVector& clv)
62
: NIVissimAbstractEdge(id, geom),
63
myName(name), myFromDef(from_def), myToDef(to_def),
64
myAssignedVehicles(assignedVehicles), myClosedLanes(clv) {}
65
66
67
NIVissimConnection::~NIVissimConnection() {
68
for (NIVissimClosedLanesVector::iterator i = myClosedLanes.begin(); i != myClosedLanes.end(); i++) {
69
delete (*i);
70
}
71
myClosedLanes.clear();
72
}
73
74
75
bool
76
NIVissimConnection::dictionary(int id, NIVissimConnection* o) {
77
DictType::iterator i = myDict.find(id);
78
if (i == myDict.end()) {
79
myDict[id] = o;
80
return true;
81
}
82
return false;
83
}
84
85
86
87
NIVissimConnection*
88
NIVissimConnection::dictionary(int id) {
89
DictType::iterator i = myDict.find(id);
90
if (i == myDict.end()) {
91
return nullptr;
92
}
93
return (*i).second;
94
}
95
96
97
void
98
NIVissimConnection::buildNodeClusters() {
99
for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
100
NIVissimConnection* e = (*i).second;
101
if (!e->clustered()) {
102
assert(e->myBoundary != 0 && e->myBoundary->xmax() > e->myBoundary->xmin());
103
std::vector<int> connections =
104
NIVissimConnection::getWithin(*(e->myBoundary));
105
NIVissimNodeCluster::dictionary(-1, -1, connections,
106
std::vector<int>(), true); // 19.5.!!! should be on a single edge
107
}
108
}
109
}
110
111
112
113
114
115
std::vector<int>
116
NIVissimConnection::getWithin(const AbstractPoly& poly) {
117
std::vector<int> ret;
118
for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
119
if ((*i).second->crosses(poly)) {
120
ret.push_back((*i).second->myID);
121
}
122
}
123
return ret;
124
}
125
126
127
void
128
NIVissimConnection::computeBounding() {
129
Boundary* bound = new Boundary();
130
bound->add(myFromDef.getGeomPosition());
131
bound->add(myToDef.getGeomPosition());
132
assert(myBoundary == 0);
133
myBoundary = bound;
134
}
135
136
137
std::vector<int>
138
NIVissimConnection::getForEdge(int edgeid, bool /*omitNodeAssigned*/) {
139
std::vector<int> ret;
140
for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
141
int connID = (*i).first;
142
if ((*i).second->myFromDef.getEdgeID() == edgeid
143
||
144
(*i).second->myToDef.getEdgeID() == edgeid) {
145
if (!(*i).second->hasNodeCluster()) {
146
ret.push_back(connID);
147
}
148
}
149
}
150
return ret;
151
}
152
153
154
int
155
NIVissimConnection::getFromEdgeID() const {
156
return myFromDef.getEdgeID();
157
}
158
159
160
int
161
NIVissimConnection::getToEdgeID() const {
162
return myToDef.getEdgeID();
163
}
164
165
166
double
167
NIVissimConnection::getFromPosition() const {
168
return myFromDef.getPosition();
169
}
170
171
172
double
173
NIVissimConnection::getToPosition() const {
174
return myToDef.getPosition();
175
}
176
177
178
Position
179
NIVissimConnection::getFromGeomPosition() const {
180
return myFromDef.getGeomPosition();
181
}
182
183
184
185
Position
186
NIVissimConnection::getToGeomPosition() const {
187
return myToDef.getGeomPosition();
188
}
189
190
191
void
192
NIVissimConnection::setNodeCluster(int nodeid) {
193
assert(myNode == -1);
194
myNode = nodeid;
195
}
196
197
198
void
199
NIVissimConnection::buildGeom() {
200
if (myGeom.size() > 0) {
201
return;
202
}
203
myGeom.push_back(myFromDef.getGeomPosition());
204
myGeom.push_back(myToDef.getGeomPosition());
205
}
206
207
208
int
209
NIVissimConnection::buildEdgeConnections(NBEdgeCont& ec) {
210
int unsetConnections = 0;
211
// try to determine the connected edges
212
NBEdge* fromEdge = nullptr;
213
NBEdge* toEdge = nullptr;
214
NIVissimEdge* vissimFrom = NIVissimEdge::dictionary(getFromEdgeID());
215
if (vissimFrom->wasWithinAJunction()) {
216
// this edge was not built, try to get one that approaches it
217
vissimFrom = vissimFrom->getBestIncoming();
218
if (vissimFrom != nullptr) {
219
fromEdge = ec.retrievePossiblySplit(toString(vissimFrom->getID()), toString(getFromEdgeID()), true);
220
}
221
} else {
222
// this edge was built, try to get the proper part
223
fromEdge = ec.retrievePossiblySplit(toString(getFromEdgeID()), toString(getToEdgeID()), true);
224
}
225
NIVissimEdge* vissimTo = NIVissimEdge::dictionary(getToEdgeID());
226
if (vissimTo->wasWithinAJunction()) {
227
vissimTo = vissimTo->getBestOutgoing();
228
if (vissimTo != nullptr) {
229
toEdge = ec.retrievePossiblySplit(toString(vissimTo->getID()), toString(getToEdgeID()), true);
230
}
231
} else {
232
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
if (fromEdge == nullptr || toEdge == nullptr) {
241
WRITE_WARNINGF(TL("Could not build connection between '%' and '%'."), toString(getFromEdgeID()), toString(getToEdgeID()));
242
return 1; // !!! actually not 1
243
}
244
recheckLanes(fromEdge, toEdge);
245
const std::vector<int>& fromLanes = getFromLanes();
246
const std::vector<int>& toLanes = getToLanes();
247
if (fromLanes.size() != toLanes.size()) {
248
WRITE_WARNINGF(TL("Lane sizes differ for connection '%'."), toString(getID()));
249
} else {
250
for (int index = 0; index < (int)fromLanes.size(); ++index) {
251
if (fromEdge->getNumLanes() <= fromLanes[index]) {
252
WRITE_WARNING("Could not set connection between '" + fromEdge->getID() + "_" + toString(fromLanes[index]) + "' and '" + toEdge->getID() + "_" + toString(toLanes[index]) + "'.");
253
++unsetConnections;
254
} else if (!fromEdge->addLane2LaneConnection(fromLanes[index], toEdge, toLanes[index], NBEdge::Lane2LaneInfoType::VALIDATED, true)) {
255
WRITE_WARNING("Could not set connection between '" + fromEdge->getID() + "_" + toString(fromLanes[index]) + "' and '" + toEdge->getID() + "_" + toString(toLanes[index]) + "'.");
256
++unsetConnections;
257
}
258
}
259
}
260
return unsetConnections;
261
}
262
263
264
void
265
NIVissimConnection::dict_buildNBEdgeConnections(NBEdgeCont& ec) {
266
int unsetConnections = 0;
267
// go through connections
268
for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
269
unsetConnections += (*i).second->buildEdgeConnections(ec);
270
}
271
if (unsetConnections != 0) {
272
WRITE_WARNING(toString<int>(unsetConnections) + " of " + toString<int>((int)myDict.size()) + " connections could not be assigned.");
273
}
274
}
275
276
277
const std::vector<int>&
278
NIVissimConnection::getFromLanes() const {
279
return myFromDef.getLanes();
280
}
281
282
283
const std::vector<int>&
284
NIVissimConnection::getToLanes() const {
285
return myToDef.getLanes();
286
}
287
288
289
void
290
NIVissimConnection::recheckLanes(const NBEdge* const fromEdge, const NBEdge* const toEdge) {
291
myFromDef.recheckLanes(fromEdge);
292
myToDef.recheckLanes(toEdge);
293
}
294
295
296
const Boundary&
297
NIVissimConnection::getBoundingBox() const {
298
assert(myBoundary != 0 && myBoundary->xmax() >= myBoundary->xmin());
299
return *myBoundary;
300
}
301
302
303
void
304
NIVissimConnection::dict_assignToEdges() {
305
for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
306
NIVissimConnection* c = (*i).second;
307
NIVissimEdge::dictionary(c->getFromEdgeID())->addOutgoingConnection((*i).first);
308
NIVissimEdge::dictionary(c->getToEdgeID())->addIncomingConnection((*i).first);
309
}
310
}
311
312
313
int
314
NIVissimConnection::getMaxID() {
315
return myMaxID;
316
}
317
318
319
/****************************************************************************/
320
321