SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NIVissimDisturbance.cpp
Go to the documentation of this file.
1 /****************************************************************************/
8 // -------------------
9 /****************************************************************************/
10 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
11 // Copyright (C) 2001-2014 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  SUMOReal timegap, SUMOReal waygap,
73  SUMOReal vmax)
74  : myID(id), myNode(-1), myName(name), myEdge(edge), myDisturbance(by),
75  myTimeGap(timegap), myWayGap(waygap), myVMax(vmax) {}
76 
77 
79 
80 
81 
82 bool
84  const std::string& name,
85  const NIVissimExtendedEdgePoint& edge,
86  const NIVissimExtendedEdgePoint& by,
87  SUMOReal timegap, SUMOReal waygap, SUMOReal vmax) {
88  UNUSED_PARAMETER(id);
89  int nid = myRunningID++;
91  new NIVissimDisturbance(nid, name, edge, by, timegap, waygap, vmax);
92  if (!dictionary(nid, o)) {
93  delete o;
94  }
95  return true;
96 }
97 
98 
99 bool
101  DictType::iterator i = myDict.find(id);
102  if (i == myDict.end()) {
103  myDict[id] = o;
104  return true;
105  }
106  return false;
107 }
108 
109 
112  DictType::iterator i = myDict.find(id);
113  if (i == myDict.end()) {
114  return 0;
115  }
116  return (*i).second;
117 }
118 
119 std::vector<int>
121  std::vector<int> ret;
122  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
123  if ((*i).second->crosses(poly)) {
124  ret.push_back((*i).second->myID);
125  }
126  }
127  return ret;
128 }
129 
130 
131 void
133  assert(myBoundary == 0);
134  Boundary* bound = new Boundary();
136  bound->add(myEdge.getGeomPosition());
137  }
140  }
141  myBoundary = bound;
142  assert(myBoundary != 0 && myBoundary->xmax() >= myBoundary->xmin());
143 }
144 
145 
146 
147 bool
149  NBNodeCont& nc, NBEdgeCont& ec) {
150  myNode = 0;
151  NIVissimConnection* pc =
153  NIVissimConnection* bc =
155  if (pc == 0 && bc == 0) {
156  // This has not been tested completely, yet
157  // Both competing abstract edges are normal edges
158  // We have to find a crossing point, build a node here,
159  // split both edges and add the connections
162  WRITE_WARNING("Ugly split to prohibit '" + toString<int>(e1->getID()) + "' by '" + toString<int>(e2->getID()) + "'.");
163  Position pos = e1->crossesEdgeAtPoint(e2);
164  std::string id1 = toString<int>(e1->getID()) + "x" + toString<int>(e2->getID());
165  std::string id2 = toString<int>(e2->getID()) + "x" + toString<int>(e1->getID());
166  NBNode* node1 = nc.retrieve(id1);
167  NBNode* node2 = nc.retrieve(id2);
168  NBNode* node = 0;
169  assert(node1 == 0 || node2 == 0);
170  if (node1 == 0 && node2 == 0) {
172  return false;
173  /* node = new NBNode(id1, pos.x(), pos.y(), "priority");
174  if(!myNodeCont.insert(node)) {
175  "nope, NIVissimDisturbance" << endl;
176  throw 1;
177  }*/
178  } else {
179  node = node1 == 0 ? node2 : node1;
180  }
181  ec.splitAt(dc, ec.retrievePossiblySplit(toString<int>(e1->getID()), myEdge.getPosition()), node);
182  ec.splitAt(dc, ec.retrievePossiblySplit(toString<int>(e2->getID()), myDisturbance.getPosition()), node);
183  // !!! in some cases, one of the edges is not being build because it's too short
184  // !!! what to do in these cases?
185  NBEdge* mayDriveFrom = ec.retrieve(toString<int>(e1->getID()) + "[0]");
186  NBEdge* mayDriveTo = ec.retrieve(toString<int>(e1->getID()) + "[1]");
187  NBEdge* mustStopFrom = ec.retrieve(toString<int>(e2->getID()) + "[0]");
188  NBEdge* mustStopTo = ec.retrieve(toString<int>(e2->getID()) + "[1]");
189  if (mayDriveFrom != 0 && mayDriveTo != 0 && mustStopFrom != 0 && mustStopTo != 0) {
190  node->addSortedLinkFoes(
191  NBConnection(mayDriveFrom, mayDriveTo),
192  NBConnection(mayDriveFrom, mayDriveTo));
193  } else {
195  return false;
196  // !!! warning
197  }
198 // }
199  } else if (pc != 0 && bc == 0) {
200  // The prohibited abstract edge is a connection, the other
201  // is not;
202  // The connection will be prohibitesd by all connections
203  // outgoing from the "real" edge
204 
206  if (e == 0) {
207  WRITE_WARNING("Could not prohibit '" + toString<int>(myEdge.getEdgeID()) + "' by '" + toString<int>(myDisturbance.getEdgeID()) + "'. Have not found disturbance.");
209  return false;
210  }
211  if (e->getFromNode() == e->getToNode()) {
212  WRITE_WARNING("Could not prohibit '" + toString<int>(myEdge.getEdgeID()) + "' by '" + toString<int>(myDisturbance.getEdgeID()) + "'. Disturbance connects same node.");
214  // What to do with self-looping edges?
215  return false;
216  }
217  // get the begin of the prohibited connection
218  std::string id_pcoe = toString<int>(pc->getFromEdgeID());
219  std::string id_pcie = toString<int>(pc->getToEdgeID());
220  NBEdge* pcoe = ec.retrievePossiblySplit(id_pcoe, id_pcie, true);
221  NBEdge* pcie = ec.retrievePossiblySplit(id_pcie, id_pcoe, false);
222  // check whether it's ending node is the node the prohibited
223  // edge end at
224  if (pcoe != 0 && pcie != 0 && pcoe->getToNode() == e->getToNode()) {
225  // if so, simply prohibit the connections
226  NBNode* node = e->getToNode();
227  const EdgeVector& connected = e->getConnectedEdges();
228  for (EdgeVector::const_iterator i = connected.begin(); i != connected.end(); i++) {
229  node->addSortedLinkFoes(
230  NBConnection(e, *i),
231  NBConnection(pcoe, pcie));
232  }
233  } else {
234  WRITE_WARNING("Would have to split edge '" + e->getID() + "' to build a prohibition");
236  // quite ugly - why was it not build?
237  return false;
238  /*
239  std::string nid1 = e->getID() + "[0]";
240  std::string nid2 = e->getID() + "[1]";
241 
242  if(ec.splitAt(e, node)) {
243  node->addSortedLinkFoes(
244  NBConnection(
245  ec.retrieve(nid1),
246  ec.retrieve(nid2)
247  ),
248  getConnection(node, myEdge.getEdgeID())
249  );
250  }
251  */
252  }
253  } else if (bc != 0 && pc == 0) {
254  // The prohibiting abstract edge is a connection, the other
255  // is not;
256  // We have to split the other one and add the prohibition
257  // description
258 
259  NBEdge* e = ec.retrievePossiblySplit(toString<int>(myEdge.getEdgeID()), myEdge.getPosition());
260  if (e == 0) {
261  WRITE_WARNING("Could not prohibit '" + toString<int>(myEdge.getEdgeID()) + "' - it was not built.");
262  return false;
263  }
264  std::string nid1 = e->getID() + "[0]";
265  std::string nid2 = e->getID() + "[1]";
266  if (e->getFromNode() == e->getToNode()) {
267  WRITE_WARNING("Could not prohibit '" + toString<int>(myEdge.getEdgeID()) + "' by '" + toString<int>(myDisturbance.getEdgeID()) + "'.");
269  // What to do with self-looping edges?
270  return false;
271  }
272  // get the begin of the prohibiting connection
273  std::string id_bcoe = toString<int>(bc->getFromEdgeID());
274  std::string id_bcie = toString<int>(bc->getToEdgeID());
275  NBEdge* bcoe = ec.retrievePossiblySplit(id_bcoe, id_bcie, true);
276  NBEdge* bcie = ec.retrievePossiblySplit(id_bcie, id_bcoe, false);
277  // check whether it's ending node is the node the prohibited
278  // edge end at
279  if (bcoe != 0 && bcie != 0 && bcoe->getToNode() == e->getToNode()) {
280  // if so, simply prohibit the connections
281  NBNode* node = e->getToNode();
282  const EdgeVector& connected = e->getConnectedEdges();
283  for (EdgeVector::const_iterator i = connected.begin(); i != connected.end(); i++) {
284  node->addSortedLinkFoes(
285  NBConnection(bcoe, bcie),
286  NBConnection(e, *i));
287  }
288  } else {
289  WRITE_WARNING("Would have to split edge '" + e->getID() + "' to build a prohibition");
291  return false;
292  /*
293  // quite ugly - why was it not build?
294  if(ec.splitAt(e, node)) {
295  node->addSortedLinkFoes(
296  getConnection(node, myDisturbance.getEdgeID()),
297  NBConnection(
298  ec.retrieve(nid1),
299  ec.retrieve(nid2)
300  )
301  );
302  }
303  */
304  }
305  } else {
306  // both the prohibiting and the prohibited abstract edges
307  // are connections
308  // We can retrieve the conected edges and add the desription
310  NBConnection conn2 = getConnection(node, myEdge.getEdgeID());
311  if (!conn1.check(ec) || !conn2.check(ec)) {
313  return false;
314  }
315  node->addSortedLinkFoes(conn1, conn2);
316  }
317  return true;
318 }
319 
320 
325  NBEdge* from =
326  node->getPossiblySplittedIncoming(toString<int>(c->getFromEdgeID()));
327  NBEdge* to =
328  node->getPossiblySplittedOutgoing(toString<int>(c->getToEdgeID()));
329 
330  // source is a connection
331  return NBConnection(toString<int>(c->getFromEdgeID()), from,
332  toString<int>(c->getToEdgeID()), to);
333  } else {
334  WRITE_WARNING("NIVissimDisturbance: no connection");
336 // throw 1; // !!! what to do?
337  }
338 
339 }
340 
341 void
343  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
344  delete(*i).second;
345  }
346  myDict.clear();
347 }
348 
349 
350 void
352  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
353  NIVissimDisturbance* d = (*i).second;
354  NIVissimAbstractEdge::dictionary(d->myEdge.getEdgeID())->addDisturbance((*i).first);
355  NIVissimAbstractEdge::dictionary(d->myDisturbance.getEdgeID())->addDisturbance((*i).first);
356  }
357  /* for(DictType::iterator i=myDict.begin(); i!=myDict.end(); i++) {
358  delete (*i).second;
359  }
360  */
361 }
362 
363 
364 void
366  if (refusedProhibits > 0) {
367  WRITE_WARNING("Could not build " + toString<size_t>(refusedProhibits) + " of " + toString<size_t>(myDict.size()) + " disturbances.");
368  }
369 }
370 
371 
372 
373 /****************************************************************************/
374