Eclipse SUMO - Simulation of Urban MObility
NIVissimDisturbance.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 /****************************************************************************/
19 // -------------------
20 /****************************************************************************/
21 #include <config.h>
22 
23 
24 #include <map>
25 #include <string>
26 #include <iostream>
27 #include <cassert>
28 #include <utils/common/ToString.h>
30 #include <utils/geom/GeomHelper.h>
31 #include <utils/geom/Boundary.h>
32 #include <netbuild/NBEdge.h>
33 #include <netbuild/NBNode.h>
34 #include <netbuild/NBEdgeCont.h>
35 #include <netbuild/NBNodeCont.h>
36 #include "NIVissimEdge.h"
37 #include "NIVissimConnection.h"
38 #include "NIVissimNodeDef.h"
39 #include "NIVissimDisturbance.h"
41 
42 
43 // ===========================================================================
44 // static member variables
45 // ===========================================================================
47 int NIVissimDisturbance::myRunningID = 100000000;
48 
50 
51 
52 // ===========================================================================
53 // method definitions
54 // ===========================================================================
56  const std::string& name,
57  const NIVissimExtendedEdgePoint& edge,
58  const NIVissimExtendedEdgePoint& by)
59  : myID(id), myNode(-1), myName(name), myEdge(edge), myDisturbance(by) {}
60 
61 
63 
64 
65 
66 bool
67 NIVissimDisturbance::dictionary(const std::string& name,
68  const NIVissimExtendedEdgePoint& edge,
69  const NIVissimExtendedEdgePoint& by) {
70  int nid = myRunningID++;
72  new NIVissimDisturbance(nid, name, edge, by);
73  if (!dictionary(nid, o)) {
74  delete o;
75  }
76  return true;
77 }
78 
79 
80 bool
82  DictType::iterator i = myDict.find(id);
83  if (i == myDict.end()) {
84  myDict[id] = o;
85  return true;
86  }
87  return false;
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 std::vector<int>
102  std::vector<int> ret;
103  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
104  if ((*i).second->crosses(poly)) {
105  ret.push_back((*i).second->myID);
106  }
107  }
108  return ret;
109 }
110 
111 
112 void
114  assert(myBoundary == 0);
115  Boundary* bound = new Boundary();
117  bound->add(myEdge.getGeomPosition());
118  }
121  }
122  myBoundary = bound;
123  assert(myBoundary != 0 && myBoundary->xmax() >= myBoundary->xmin());
124 }
125 
126 
127 
128 bool
130  NBNodeCont& nc, NBEdgeCont& ec) {
131  myNode = 0;
132  NIVissimConnection* pc =
134  NIVissimConnection* bc =
136  if (pc == nullptr && bc == nullptr) {
137  // This has not been tested completely, yet
138  // Both competing abstract edges are normal edges
139  // We have to find a crossing point, build a node here,
140  // split both edges and add the connections
143  WRITE_WARNINGF(TL("Ugly split to prohibit '%' by '%'."), toString<int>(e1->getID()), toString<int>(e2->getID()));
144  Position pos = e1->crossesEdgeAtPoint(e2);
145  std::string id1 = toString<int>(e1->getID()) + "x" + toString<int>(e2->getID());
146  std::string id2 = toString<int>(e2->getID()) + "x" + toString<int>(e1->getID());
147  NBNode* node1 = nc.retrieve(id1);
148  NBNode* node2 = nc.retrieve(id2);
149  NBNode* splitNode = node1 == nullptr ? node2 : node1;
150  assert(node1 == nullptr || node2 == nullptr);
151  if (splitNode == nullptr) {
153  return false;
154  /* node = new NBNode(id1, pos.x(), pos.y(), "priority");
155  if(!myNodeCont.insert(node)) {
156  "nope, NIVissimDisturbance" << endl;
157  throw 1;
158  }*/
159  }
160  ec.splitAt(dc, ec.retrievePossiblySplit(toString<int>(e1->getID()), myEdge.getPosition()), splitNode);
161  ec.splitAt(dc, ec.retrievePossiblySplit(toString<int>(e2->getID()), myDisturbance.getPosition()), splitNode);
162  // !!! in some cases, one of the edges is not being build because it's too short
163  // !!! what to do in these cases?
164  NBEdge* mayDriveFrom = ec.retrieve(toString<int>(e1->getID()) + "[0]");
165  NBEdge* mayDriveTo = ec.retrieve(toString<int>(e1->getID()) + "[1]");
166  NBEdge* mustStopFrom = ec.retrieve(toString<int>(e2->getID()) + "[0]");
167  NBEdge* mustStopTo = ec.retrieve(toString<int>(e2->getID()) + "[1]");
168  if (mayDriveFrom != nullptr && mayDriveTo != nullptr && mustStopFrom != nullptr && mustStopTo != nullptr) {
169  node->addSortedLinkFoes(
170  NBConnection(mayDriveFrom, mayDriveTo),
171  NBConnection(mayDriveFrom, mayDriveTo));
172  } else {
174  return false;
175  // !!! warning
176  }
177 // }
178  } else if (pc != nullptr && bc == nullptr) {
179  // The prohibited abstract edge is a connection, the other
180  // is not;
181  // The connection will be prohibitesd by all connections
182  // outgoing from the "real" edge
183 
185  if (e == nullptr) {
186  WRITE_WARNINGF(TL("Could not prohibit '%' by '%'. Have not found disturbance."), toString<int>(myEdge.getEdgeID()), toString<int>(myDisturbance.getEdgeID()));
188  return false;
189  }
190  if (e->getFromNode() == e->getToNode()) {
191  WRITE_WARNINGF(TL("Could not prohibit '%' by '%'. Disturbance connects same node."), toString<int>(myEdge.getEdgeID()), toString<int>(myDisturbance.getEdgeID()));
193  // What to do with self-looping edges?
194  return false;
195  }
196  // get the begin of the prohibited connection
197  std::string id_pcoe = toString<int>(pc->getFromEdgeID());
198  std::string id_pcie = toString<int>(pc->getToEdgeID());
199  NBEdge* const pcoe = ec.retrievePossiblySplit(id_pcoe, id_pcie, true);
200  NBEdge* const pcie = ec.retrievePossiblySplit(id_pcie, id_pcoe, false);
201  // check whether its ending node is the node the prohibited
202  // edge end at
203  if (pcoe != nullptr && pcie != nullptr && pcoe->getToNode() == e->getToNode()) {
204  // if so, simply prohibit the connections
205  NBNode* const toNode = e->getToNode();
206  for (NBEdge* const edge : e->getConnectedEdges()) {
207  toNode->addSortedLinkFoes(NBConnection(e, edge), NBConnection(pcoe, pcie));
208  }
209  } else {
210  WRITE_WARNINGF(TL("Would have to split edge '%' to build a prohibition"), e->getID());
212  // quite ugly - why was it not build?
213  return false;
214  /*
215  std::string nid1 = e->getID() + "[0]";
216  std::string nid2 = e->getID() + "[1]";
217 
218  if(ec.splitAt(e, node)) {
219  node->addSortedLinkFoes(
220  NBConnection(
221  ec.retrieve(nid1),
222  ec.retrieve(nid2)
223  ),
224  getConnection(node, myEdge.getEdgeID())
225  );
226  }
227  */
228  }
229  } else if (bc != nullptr && pc == nullptr) {
230  // The prohibiting abstract edge is a connection, the other
231  // is not;
232  // We have to split the other one and add the prohibition
233  // description
234 
235  NBEdge* e = ec.retrievePossiblySplit(toString<int>(myEdge.getEdgeID()), myEdge.getPosition());
236  if (e == nullptr) {
237  WRITE_WARNINGF(TL("Could not prohibit '%' - it was not built."), toString<int>(myEdge.getEdgeID()));
238  return false;
239  }
240  std::string nid1 = e->getID() + "[0]";
241  std::string nid2 = e->getID() + "[1]";
242  if (e->getFromNode() == e->getToNode()) {
243  WRITE_WARNINGF(TL("Could not prohibit '%' by '%'."), toString<int>(myEdge.getEdgeID()), toString<int>(myDisturbance.getEdgeID()));
245  // What to do with self-looping edges?
246  return false;
247  }
248  // get the begin of the prohibiting connection
249  std::string id_bcoe = toString<int>(bc->getFromEdgeID());
250  std::string id_bcie = toString<int>(bc->getToEdgeID());
251  NBEdge* const bcoe = ec.retrievePossiblySplit(id_bcoe, id_bcie, true);
252  NBEdge* const bcie = ec.retrievePossiblySplit(id_bcie, id_bcoe, false);
253  // check whether its ending node is the node the prohibited
254  // edge end at
255  if (bcoe != nullptr && bcie != nullptr && bcoe->getToNode() == e->getToNode()) {
256  // if so, simply prohibit the connections
257  NBNode* const toNode = e->getToNode();
258  for (NBEdge* const edge : e->getConnectedEdges()) {
259  toNode->addSortedLinkFoes(NBConnection(bcoe, bcie), NBConnection(e, edge));
260  }
261  } else {
262  WRITE_WARNINGF(TL("Would have to split edge '%' to build a prohibition"), e->getID());
264  return false;
265  /*
266  // quite ugly - why was it not build?
267  if(ec.splitAt(e, node)) {
268  node->addSortedLinkFoes(
269  getConnection(node, myDisturbance.getEdgeID()),
270  NBConnection(
271  ec.retrieve(nid1),
272  ec.retrieve(nid2)
273  )
274  );
275  }
276  */
277  }
278  } else {
279  // both the prohibiting and the prohibited abstract edges
280  // are connections
281  // We can retrieve the conected edges and add the desription
283  NBConnection conn2 = getConnection(node, myEdge.getEdgeID());
284  if (!conn1.check(ec) || !conn2.check(ec)) {
286  return false;
287  }
288  node->addSortedLinkFoes(conn1, conn2);
289  }
290  return true;
291 }
292 
293 
296  if (NIVissimEdge::dictionary(myEdge.getEdgeID()) == nullptr) {
298  NBEdge* from =
299  node->getPossiblySplittedIncoming(toString<int>(c->getFromEdgeID()));
300  NBEdge* to =
301  node->getPossiblySplittedOutgoing(toString<int>(c->getToEdgeID()));
302 
303  // source is a connection
304  return NBConnection(toString<int>(c->getFromEdgeID()), from,
305  toString<int>(c->getToEdgeID()), to);
306  } else {
307  WRITE_WARNING(TL("NIVissimDisturbance: no connection"));
309 // throw 1; // !!! what to do?
310  }
311 
312 }
313 
314 void
316  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
317  delete (*i).second;
318  }
319  myDict.clear();
320 }
321 
322 
323 void
325  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
326  NIVissimDisturbance* d = (*i).second;
327  NIVissimAbstractEdge::dictionary(d->myEdge.getEdgeID())->addDisturbance((*i).first);
328  NIVissimAbstractEdge::dictionary(d->myDisturbance.getEdgeID())->addDisturbance((*i).first);
329  }
330  /* for(DictType::iterator i=myDict.begin(); i!=myDict.end(); i++) {
331  delete (*i).second;
332  }
333  */
334 }
335 
336 
337 void
339  if (refusedProhibits > 0) {
340  WRITE_WARNINGF(TL("Could not build % of % disturbances."), toString<int>(refusedProhibits), toString<int>((int)myDict.size()));
341  }
342 }
343 
344 
345 /****************************************************************************/
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:296
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:295
#define TL(string)
Definition: MsgHandler.h:315
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:39
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:78
double xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:118
double xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:124
bool check(const NBEdgeCont &ec)
checks whether the edges are still valid
static const NBConnection InvalidConnection
Definition: NBConnection.h:124
A container for districts.
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:59
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:281
NBEdge * retrievePossiblySplit(const std::string &id, bool downstream) const
Tries to retrieve an edge, even if it is splitted.
Definition: NBEdgeCont.cpp:317
bool splitAt(NBDistrictCont &dc, NBEdge *edge, NBNode *node)
Splits the edge at the position nearest to the given node.
Definition: NBEdgeCont.cpp:604
The representation of a single edge during network building.
Definition: NBEdge.h:92
const std::string & getID() const
Definition: NBEdge.h:1522
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:542
EdgeVector getConnectedEdges() const
Returns the list of outgoing edges unsorted.
Definition: NBEdge.cpp:1346
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:535
Container for nodes during the netbuilding process.
Definition: NBNodeCont.h:57
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
void addSortedLinkFoes(const NBConnection &mayDrive, const NBConnection &mustStop)
add shorted link FOES
Definition: NBNode.cpp:1877
NBEdge * getPossiblySplittedOutgoing(const std::string &edgeid)
get possibly splitted outgoing edge
Definition: NBNode.cpp:1907
NBEdge * getPossiblySplittedIncoming(const std::string &edgeid)
get possibly splitted incoming edge
Definition: NBNode.cpp:1894
static bool dictionary(int id, NIVissimAbstractEdge *e)
Position crossesEdgeAtPoint(NIVissimAbstractEdge *c) const
static bool dictionary(int id, NIVissimConnection *o)
NIVissimExtendedEdgePoint myDisturbance
NIVissimDisturbance(int id, const std::string &name, const NIVissimExtendedEdgePoint &edge, const NIVissimExtendedEdgePoint &by)
std::map< int, NIVissimDisturbance * > DictType
static void dict_SetDisturbances()
static DictType myDict
static bool dictionary(const std::string &name, const NIVissimExtendedEdgePoint &edge, const NIVissimExtendedEdgePoint &by)
static std::vector< int > getWithin(const AbstractPoly &poly)
NIVissimExtendedEdgePoint myEdge
NBConnection getConnection(NBNode *node, int aedgeid)
bool addToNode(NBNode *node, NBDistrictCont &dc, NBNodeCont &nc, NBEdgeCont &ec)
A temporary storage for edges imported from Vissim.
Definition: NIVissimEdge.h:51
static bool dictionary(int id, const std::string &name, const std::string &type, int noLanes, double zuschlag1, double zuschlag2, double length, const PositionVector &geom, const NIVissimClosedLanesVector &clv)
Adds the described item to the dictionary Builds the edge first.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37