Eclipse SUMO - Simulation of Urban MObility
NIVissimNodeCluster.cpp
Go to the documentation of this file.
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 /****************************************************************************/
20 // -------------------
21 /****************************************************************************/
22 #include <config.h>
23 
24 
25 #include <map>
26 #include <algorithm>
27 #include <cassert>
29 #include <utils/common/ToString.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 // ===========================================================================
44 
45 
46 // ===========================================================================
47 // method definitions
48 // ===========================================================================
49 NIVissimNodeCluster::NIVissimNodeCluster(int id, int nodeid, int tlid,
50  const std::vector<int>& connectors,
51  const std::vector<int>& disturbances,
52  bool amEdgeSplitOnly)
53  : myID(id), myNodeID(nodeid), myTLID(tlid),
54  myConnectors(connectors), myDisturbances(disturbances),
55  myNBNode(nullptr), myAmEdgeSplit(amEdgeSplitOnly) {}
56 
57 
59 
60 
61 
62 
63 bool
65  DictType::iterator i = myDict.find(id);
66  if (i == myDict.end()) {
67  myDict[id] = o;
68  return true;
69  }
70  assert(false);
71  return false;
72 }
73 
74 
75 int
76 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  if (nodeid < 0) {
82  id = myCurrentID++;
83  }
85  nodeid, tlid, connectors, disturbances, amEdgeSplitOnly);
86  dictionary(id, o);
87  return id;
88 }
89 
90 
93  DictType::iterator i = myDict.find(id);
94  if (i == myDict.end()) {
95  return nullptr;
96  }
97  return (*i).second;
98 }
99 
100 
101 
102 int
104  return (int)myDict.size();
105 }
106 
107 
108 
109 std::string
111  if (myTLID == -1) {
112  return toString<int>(myID);
113  } else {
114  return toString<int>(myID) + "LSA " + toString<int>(myTLID);
115  }
116 }
117 
118 
119 void
121  if (myConnectors.size() == 0) {
122  return; // !!! Check, whether this can happen
123  }
124 
125  // compute the position
126  PositionVector crossings;
127  std::vector<int>::iterator i, j;
128  // check whether this is a split of an edge only
129  if (myAmEdgeSplit) {
130 // !!! should be assert(myTLID==-1);
131  for (i = myConnectors.begin(); i != myConnectors.end(); i++) {
134  }
135  } else {
136  // compute the places the connections cross
137  for (i = myConnectors.begin(); i != myConnectors.end(); i++) {
139  c1->buildGeom();
140  for (j = i + 1; j != myConnectors.end(); j++) {
142  c2->buildGeom();
143  if (c1->crossesEdge(c2)) {
144  crossings.push_back_noDoublePos(c1->crossesEdgeAtPoint(c2));
145  }
146  }
147  }
148  // alternative way: compute via positions of crossings
149  if (crossings.size() == 0) {
150  for (i = myConnectors.begin(); i != myConnectors.end(); i++) {
153  crossings.push_back_noDoublePos(c1->getToGeomPosition());
154  }
155  }
156  }
157  // get the position (center)
158  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  NBNode* node = new NBNode(getNodeName(), pos, SumoXMLNodeType::PRIORITY);
171  if (!nc.insert(node)) {
172  delete node;
173  throw 1;
174  }
175  myNBNode = node;
176 }
177 
178 
179 void
181  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
182  (*i).second->buildNBNode(nc);
183  }
184 }
185 
186 
187 
188 void
190  return;
191 }
192 
193 
194 int
196  int ret = -1;
197  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
198  NIVissimNodeCluster* c = (*i).second;
199  for (std::vector<int>::iterator j = c->myConnectors.begin(); j != c->myConnectors.end(); j++) {
201  if (conn != nullptr && conn->getToEdgeID() == edgeid) {
202 // return (*i).first;
203  if (ret != -1 && (*i).first != ret) {
204 // "NIVissimNodeCluster:DoubleNode:" << ret << endl;
205  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  ret = (*i).first;
209  }
210  }
211  }
212  return ret;
213 }
214 
215 
216 int
218  int ret = -1;
219  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
220  NIVissimNodeCluster* c = (*i).second;
221  for (std::vector<int>::iterator j = c->myConnectors.begin(); j != c->myConnectors.end(); j++) {
223  if (conn != nullptr && conn->getFromEdgeID() == edgeid) {
224 // return (*i).first;
225  if (ret != -1 && ret != (*i).first) {
226 // << "NIVissimNodeCluster: multiple to-nodes" << endl;
227  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  ret = (*i).first;
232  }
233  }
234  }
235  return ret;
236 }
237 
238 
239 void
240 NIVissimNodeCluster::_debugOut(std::ostream& into) {
241  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
242  NIVissimNodeCluster* c = (*i).second;
243  into << std::endl << c->myID << ":";
244  for (std::vector<int>::iterator j = c->myConnectors.begin(); j != c->myConnectors.end(); j++) {
245  if (j != c->myConnectors.begin()) {
246  into << ", ";
247  }
248  into << (*j);
249  }
250  }
251  into << "=======================" << std::endl;
252 }
253 
254 
255 
256 NBNode*
258  return myNBNode;
259 }
260 
261 
262 Position
264  return myPosition;
265 }
266 
267 
268 void
270  NBNodeCont& nc, NBEdgeCont& ec) {
271  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
272  const std::vector<int>& disturbances = (*i).second->myDisturbances;
273  NBNode* node = nc.retrieve((*i).second->getNodeName());
274  for (std::vector<int>::const_iterator j = disturbances.begin(); j != disturbances.end(); j++) {
276  disturbance->addToNode(node, dc, nc, ec);
277  }
278  }
280 }
281 
282 
283 void
285  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
286  delete (*i).second;
287  }
288  myDict.clear();
289 }
290 
291 
292 void
294  myCurrentID = id;
295 }
296 
297 
298 /****************************************************************************/
A container for districts.
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:59
Container for nodes during the netbuilding process.
Definition: NBNodeCont.h:57
bool insert(const std::string &id, const Position &position, NBDistrict *district=0)
Inserts a node into the map.
Definition: NBNodeCont.cpp:87
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
Definition: NBNodeCont.cpp:116
Represents a single node (junction) during network building.
Definition: NBNode.h:66
static bool dictionary(int id, NIVissimAbstractEdge *e)
Position crossesEdgeAtPoint(NIVissimAbstractEdge *c) const
virtual void buildGeom()=0
bool crossesEdge(NIVissimAbstractEdge *c) const
static bool dictionary(int id, NIVissimConnection *o)
Position getToGeomPosition() const
Position getFromGeomPosition() const
static bool dictionary(const std::string &name, const NIVissimExtendedEdgePoint &edge, const NIVissimExtendedEdgePoint &by)
bool addToNode(NBNode *node, NBDistrictCont &dc, NBNodeCont &nc, NBEdgeCont &ec)
static void setCurrentVirtID(int id)
std::map< int, NIVissimNodeCluster * > DictType
static int getToNode(int edgeid)
NIVissimNodeCluster(int id, int nodeid, int tlid, const std::vector< int > &connectors, const std::vector< int > &disturbances, bool amEdgeSplitOnly)
static DictType myDict
static int getFromNode(int edgeid)
static bool dictionary(int id, NIVissimNodeCluster *o)
void buildNBNode(NBNodeCont &nc)
std::string getNodeName() const
static void dict_addDisturbances(NBDistrictCont &dc, NBNodeCont &nc, NBEdgeCont &ec)
static void dict_recheckEdgeChanges()
NBNode * getNBNode() const
std::vector< int > myConnectors
static void buildNBNodes(NBNodeCont &nc)
static void _debugOut(std::ostream &into)
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
A list of positions.
Position getPolygonCenter() const
Returns the arithmetic of all corner points.
void push_back_noDoublePos(const Position &p)
insert in back a non double position