SUMO - Simulation of Urban MObility
NIVissimDisturbance.cpp
Go to the documentation of this file.
1 /****************************************************************************/
8 // -------------------
9 /****************************************************************************/
10 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
11 // Copyright (C) 2001-2016 DLR (http://www.dlr.de/) and contributors
12 /****************************************************************************/
13 //
14 // This file is part of SUMO.
15 // SUMO is free software: you can redistribute it and/or modify
16 // it under the terms of the GNU General Public License as published by
17 // the Free Software Foundation, either version 3 of the License, or
18 // (at your option) any later version.
19 //
20 /****************************************************************************/
21 
22 
23 // ===========================================================================
24 // included modules
25 // ===========================================================================
26 #ifdef _MSC_VER
27 #include <windows_config.h>
28 #else
29 #include <config.h>
30 #endif
31 
32 
33 #include <map>
34 #include <string>
35 #include <iostream>
36 #include <cassert>
37 #include <utils/common/ToString.h>
39 #include <utils/geom/GeomHelper.h>
40 #include <utils/geom/Boundary.h>
41 #include <netbuild/NBEdge.h>
42 #include <netbuild/NBNode.h>
43 #include <netbuild/NBEdgeCont.h>
44 #include <netbuild/NBNodeCont.h>
45 #include "NIVissimEdge.h"
46 #include "NIVissimConnection.h"
47 #include "NIVissimNodeDef.h"
48 #include "NIVissimDisturbance.h"
50 
51 #ifdef CHECK_MEMORY_LEAKS
52 #include <foreign/nvwa/debug_new.h>
53 #endif // CHECK_MEMORY_LEAKS
54 
55 
56 // ===========================================================================
57 // static member variables
58 // ===========================================================================
60 int NIVissimDisturbance::myRunningID = 100000000;
61 
63 
64 
65 // ===========================================================================
66 // method definitions
67 // ===========================================================================
69  const std::string& name,
70  const NIVissimExtendedEdgePoint& edge,
71  const NIVissimExtendedEdgePoint& by)
72  : myID(id), myNode(-1), myName(name), myEdge(edge), myDisturbance(by) {}
73 
74 
76 
77 
78 
79 bool
80 NIVissimDisturbance::dictionary(const std::string& name,
81  const NIVissimExtendedEdgePoint& edge,
82  const NIVissimExtendedEdgePoint& by) {
83  int nid = myRunningID++;
85  new NIVissimDisturbance(nid, name, edge, by);
86  if (!dictionary(nid, o)) {
87  delete o;
88  }
89  return true;
90 }
91 
92 
93 bool
95  DictType::iterator i = myDict.find(id);
96  if (i == myDict.end()) {
97  myDict[id] = o;
98  return true;
99  }
100  return false;
101 }
102 
103 
106  DictType::iterator i = myDict.find(id);
107  if (i == myDict.end()) {
108  return 0;
109  }
110  return (*i).second;
111 }
112 
113 std::vector<int>
115  std::vector<int> ret;
116  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
117  if ((*i).second->crosses(poly)) {
118  ret.push_back((*i).second->myID);
119  }
120  }
121  return ret;
122 }
123 
124 
125 void
127  assert(myBoundary == 0);
128  Boundary* bound = new Boundary();
130  bound->add(myEdge.getGeomPosition());
131  }
134  }
135  myBoundary = bound;
136  assert(myBoundary != 0 && myBoundary->xmax() >= myBoundary->xmin());
137 }
138 
139 
140 
141 bool
143  NBNodeCont& nc, NBEdgeCont& ec) {
144  myNode = 0;
145  NIVissimConnection* pc =
147  NIVissimConnection* bc =
149  if (pc == 0 && bc == 0) {
150  // This has not been tested completely, yet
151  // Both competing abstract edges are normal edges
152  // We have to find a crossing point, build a node here,
153  // split both edges and add the connections
156  WRITE_WARNING("Ugly split to prohibit '" + toString<int>(e1->getID()) + "' by '" + toString<int>(e2->getID()) + "'.");
157  Position pos = e1->crossesEdgeAtPoint(e2);
158  std::string id1 = toString<int>(e1->getID()) + "x" + toString<int>(e2->getID());
159  std::string id2 = toString<int>(e2->getID()) + "x" + toString<int>(e1->getID());
160  NBNode* node1 = nc.retrieve(id1);
161  NBNode* node2 = nc.retrieve(id2);
162  NBNode* node = 0;
163  assert(node1 == 0 || node2 == 0);
164  if (node1 == 0 && node2 == 0) {
166  return false;
167  /* node = new NBNode(id1, pos.x(), pos.y(), "priority");
168  if(!myNodeCont.insert(node)) {
169  "nope, NIVissimDisturbance" << endl;
170  throw 1;
171  }*/
172  } else {
173  node = node1 == 0 ? node2 : node1;
174  }
175  ec.splitAt(dc, ec.retrievePossiblySplit(toString<int>(e1->getID()), myEdge.getPosition()), node);
176  ec.splitAt(dc, ec.retrievePossiblySplit(toString<int>(e2->getID()), myDisturbance.getPosition()), node);
177  // !!! in some cases, one of the edges is not being build because it's too short
178  // !!! what to do in these cases?
179  NBEdge* mayDriveFrom = ec.retrieve(toString<int>(e1->getID()) + "[0]");
180  NBEdge* mayDriveTo = ec.retrieve(toString<int>(e1->getID()) + "[1]");
181  NBEdge* mustStopFrom = ec.retrieve(toString<int>(e2->getID()) + "[0]");
182  NBEdge* mustStopTo = ec.retrieve(toString<int>(e2->getID()) + "[1]");
183  if (mayDriveFrom != 0 && mayDriveTo != 0 && mustStopFrom != 0 && mustStopTo != 0) {
184  node->addSortedLinkFoes(
185  NBConnection(mayDriveFrom, mayDriveTo),
186  NBConnection(mayDriveFrom, mayDriveTo));
187  } else {
189  return false;
190  // !!! warning
191  }
192 // }
193  } else if (pc != 0 && bc == 0) {
194  // The prohibited abstract edge is a connection, the other
195  // is not;
196  // The connection will be prohibitesd by all connections
197  // outgoing from the "real" edge
198 
200  if (e == 0) {
201  WRITE_WARNING("Could not prohibit '" + toString<int>(myEdge.getEdgeID()) + "' by '" + toString<int>(myDisturbance.getEdgeID()) + "'. Have not found disturbance.");
203  return false;
204  }
205  if (e->getFromNode() == e->getToNode()) {
206  WRITE_WARNING("Could not prohibit '" + toString<int>(myEdge.getEdgeID()) + "' by '" + toString<int>(myDisturbance.getEdgeID()) + "'. Disturbance connects same node.");
208  // What to do with self-looping edges?
209  return false;
210  }
211  // get the begin of the prohibited connection
212  std::string id_pcoe = toString<int>(pc->getFromEdgeID());
213  std::string id_pcie = toString<int>(pc->getToEdgeID());
214  NBEdge* pcoe = ec.retrievePossiblySplit(id_pcoe, id_pcie, true);
215  NBEdge* pcie = ec.retrievePossiblySplit(id_pcie, id_pcoe, false);
216  // check whether it's ending node is the node the prohibited
217  // edge end at
218  if (pcoe != 0 && pcie != 0 && pcoe->getToNode() == e->getToNode()) {
219  // if so, simply prohibit the connections
220  NBNode* node = e->getToNode();
221  const EdgeVector& connected = e->getConnectedEdges();
222  for (EdgeVector::const_iterator i = connected.begin(); i != connected.end(); i++) {
223  node->addSortedLinkFoes(
224  NBConnection(e, *i),
225  NBConnection(pcoe, pcie));
226  }
227  } else {
228  WRITE_WARNING("Would have to split edge '" + e->getID() + "' to build a prohibition");
230  // quite ugly - why was it not build?
231  return false;
232  /*
233  std::string nid1 = e->getID() + "[0]";
234  std::string nid2 = e->getID() + "[1]";
235 
236  if(ec.splitAt(e, node)) {
237  node->addSortedLinkFoes(
238  NBConnection(
239  ec.retrieve(nid1),
240  ec.retrieve(nid2)
241  ),
242  getConnection(node, myEdge.getEdgeID())
243  );
244  }
245  */
246  }
247  } else if (bc != 0 && pc == 0) {
248  // The prohibiting abstract edge is a connection, the other
249  // is not;
250  // We have to split the other one and add the prohibition
251  // description
252 
253  NBEdge* e = ec.retrievePossiblySplit(toString<int>(myEdge.getEdgeID()), myEdge.getPosition());
254  if (e == 0) {
255  WRITE_WARNING("Could not prohibit '" + toString<int>(myEdge.getEdgeID()) + "' - it was not built.");
256  return false;
257  }
258  std::string nid1 = e->getID() + "[0]";
259  std::string nid2 = e->getID() + "[1]";
260  if (e->getFromNode() == e->getToNode()) {
261  WRITE_WARNING("Could not prohibit '" + toString<int>(myEdge.getEdgeID()) + "' by '" + toString<int>(myDisturbance.getEdgeID()) + "'.");
263  // What to do with self-looping edges?
264  return false;
265  }
266  // get the begin of the prohibiting connection
267  std::string id_bcoe = toString<int>(bc->getFromEdgeID());
268  std::string id_bcie = toString<int>(bc->getToEdgeID());
269  NBEdge* bcoe = ec.retrievePossiblySplit(id_bcoe, id_bcie, true);
270  NBEdge* bcie = ec.retrievePossiblySplit(id_bcie, id_bcoe, false);
271  // check whether it's ending node is the node the prohibited
272  // edge end at
273  if (bcoe != 0 && bcie != 0 && bcoe->getToNode() == e->getToNode()) {
274  // if so, simply prohibit the connections
275  NBNode* node = e->getToNode();
276  const EdgeVector& connected = e->getConnectedEdges();
277  for (EdgeVector::const_iterator i = connected.begin(); i != connected.end(); i++) {
278  node->addSortedLinkFoes(
279  NBConnection(bcoe, bcie),
280  NBConnection(e, *i));
281  }
282  } else {
283  WRITE_WARNING("Would have to split edge '" + e->getID() + "' to build a prohibition");
285  return false;
286  /*
287  // quite ugly - why was it not build?
288  if(ec.splitAt(e, node)) {
289  node->addSortedLinkFoes(
290  getConnection(node, myDisturbance.getEdgeID()),
291  NBConnection(
292  ec.retrieve(nid1),
293  ec.retrieve(nid2)
294  )
295  );
296  }
297  */
298  }
299  } else {
300  // both the prohibiting and the prohibited abstract edges
301  // are connections
302  // We can retrieve the conected edges and add the desription
304  NBConnection conn2 = getConnection(node, myEdge.getEdgeID());
305  if (!conn1.check(ec) || !conn2.check(ec)) {
307  return false;
308  }
309  node->addSortedLinkFoes(conn1, conn2);
310  }
311  return true;
312 }
313 
314 
319  NBEdge* from =
320  node->getPossiblySplittedIncoming(toString<int>(c->getFromEdgeID()));
321  NBEdge* to =
322  node->getPossiblySplittedOutgoing(toString<int>(c->getToEdgeID()));
323 
324  // source is a connection
325  return NBConnection(toString<int>(c->getFromEdgeID()), from,
326  toString<int>(c->getToEdgeID()), to);
327  } else {
328  WRITE_WARNING("NIVissimDisturbance: no connection");
330 // throw 1; // !!! what to do?
331  }
332 
333 }
334 
335 void
337  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
338  delete(*i).second;
339  }
340  myDict.clear();
341 }
342 
343 
344 void
346  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
347  NIVissimDisturbance* d = (*i).second;
348  NIVissimAbstractEdge::dictionary(d->myEdge.getEdgeID())->addDisturbance((*i).first);
349  NIVissimAbstractEdge::dictionary(d->myDisturbance.getEdgeID())->addDisturbance((*i).first);
350  }
351  /* for(DictType::iterator i=myDict.begin(); i!=myDict.end(); i++) {
352  delete (*i).second;
353  }
354  */
355 }
356 
357 
358 void
360  if (refusedProhibits > 0) {
361  WRITE_WARNING("Could not build " + toString<size_t>(refusedProhibits) + " of " + toString<size_t>(myDict.size()) + " disturbances.");
362  }
363 }
364 
365 
366 
367 /****************************************************************************/
368 
bool check(const NBEdgeCont &ec)
checks whether the edges are still valid
NBEdge * retrievePossiblySplit(const std::string &id, bool downstream) const
Tries to retrieve an edge, even if it is splitted.
Definition: NBEdgeCont.cpp:282
static DictType myDict
static bool dictionary(int id, NIVissimAbstractEdge *e)
static std::vector< int > getWithin(const AbstractPoly &poly)
static const NBConnection InvalidConnection
Definition: NBConnection.h:128
The representation of a single edge during network building.
Definition: NBEdge.h:70
SUMOReal xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:112
A container for districts.
static bool dictionary(const std::string &name, const NIVissimExtendedEdgePoint &edge, const NIVissimExtendedEdgePoint &by)
bool addToNode(NBNode *node, NBDistrictCont &dc, NBNodeCont &nc, NBEdgeCont &ec)
bool splitAt(NBDistrictCont &dc, NBEdge *edge, NBNode *node)
Splits the edge at the position nearest to the given node.
Definition: NBEdgeCont.cpp:411
static bool dictionary(int id, NIVissimConnection *o)
SUMOReal xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:118
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:48
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
A temporary storage for edges imported from Vissim.
Definition: NIVissimEdge.h:61
EdgeVector getConnectedEdges() const
Returns the list of outgoing edges unsorted.
Definition: NBEdge.cpp:868
NIVissimExtendedEdgePoint myEdge
const std::string & getID() const
Returns the id.
Definition: Named.h:65
NBEdge * getPossiblySplittedIncoming(const std::string &edgeid)
Definition: NBNode.cpp:1187
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:66
std::map< int, NIVissimDisturbance * > DictType
NBEdge * getPossiblySplittedOutgoing(const std::string &edgeid)
Definition: NBNode.cpp:1200
void add(SUMOReal x, SUMOReal y)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:76
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:369
NBConnection getConnection(NBNode *node, int aedgeid)
NIVissimExtendedEdgePoint myDisturbance
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:246
std::vector< NBEdge * > EdgeVector
Definition: NBCont.h:41
static bool dictionary(int id, const std::string &name, const std::string &type, int noLanes, SUMOReal zuschlag1, SUMOReal zuschlag2, SUMOReal length, const PositionVector &geom, const NIVissimClosedLanesVector &clv)
Adds the described item to the dictionary Builds the edge first.
Represents a single node (junction) during network building.
Definition: NBNode.h:74
NIVissimDisturbance(int id, const std::string &name, const NIVissimExtendedEdgePoint &edge, const NIVissimExtendedEdgePoint &by)
void addSortedLinkFoes(const NBConnection &mayDrive, const NBConnection &mustStop)
Definition: NBNode.cpp:1170
static void dict_SetDisturbances()
Position crossesEdgeAtPoint(NIVissimAbstractEdge *c) const
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
Definition: NBNodeCont.cpp:109
Container for nodes during the netbuilding process.
Definition: NBNodeCont.h:64
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:361