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.sourceforge.net/
11 // Copyright (C) 2001-2012 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 // used namespaces
56 // ===========================================================================
57 
58 using namespace std;
59 
61 int NIVissimDisturbance::myRunningID = 100000000;
62 
64 
65 
67  const std::string& name,
68  const NIVissimExtendedEdgePoint& edge,
69  const NIVissimExtendedEdgePoint& by,
70  SUMOReal timegap, SUMOReal waygap,
71  SUMOReal vmax)
72  : myID(id), myNode(-1), myName(name), myEdge(edge), myDisturbance(by),
73  myTimeGap(timegap), myWayGap(waygap), myVMax(vmax) {}
74 
75 
77 
78 
79 
80 bool
82  const std::string& name,
83  const NIVissimExtendedEdgePoint& edge,
84  const NIVissimExtendedEdgePoint& by,
85  SUMOReal timegap, SUMOReal waygap, SUMOReal vmax) {
86  UNUSED_PARAMETER(id);
87  int nid = myRunningID++;
89  new NIVissimDisturbance(nid, name, edge, by, timegap, waygap, vmax);
90  if (!dictionary(nid, o)) {
91  delete o;
92  }
93  return true;
94 }
95 
96 
97 bool
99  DictType::iterator i = myDict.find(id);
100  if (i == myDict.end()) {
101  myDict[id] = o;
102  return true;
103  }
104  return false;
105 }
106 
107 
110  DictType::iterator i = myDict.find(id);
111  if (i == myDict.end()) {
112  return 0;
113  }
114  return (*i).second;
115 }
116 
117 std::vector<int>
119  std::vector<int> ret;
120  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
121  if ((*i).second->crosses(poly)) {
122  ret.push_back((*i).second->myID);
123  }
124  }
125  return ret;
126 }
127 
128 
129 void
131  assert(myBoundary == 0);
132  Boundary* bound = new Boundary();
134  bound->add(myEdge.getGeomPosition());
135  }
138  }
139  myBoundary = bound;
140  assert(myBoundary != 0 && myBoundary->xmax() >= myBoundary->xmin());
141 }
142 
143 
144 
145 bool
147  NBNodeCont& nc, NBEdgeCont& ec) {
148  myNode = 0;
149  NIVissimConnection* pc =
151  NIVissimConnection* bc =
153  if (pc == 0 && bc == 0) {
154  // This has not been tested completely, yet
155  // Both competing abstract edges are normal edges
156  // We have to find a crossing point, build a node here,
157  // split both edges and add the connections
160  WRITE_WARNING("Ugly split to prohibit '" + toString<int>(e1->getID()) + "' by '" + toString<int>(e2->getID()) + "'.");
161  Position pos = e1->crossesEdgeAtPoint(e2);
162  std::string id1 = toString<int>(e1->getID()) + "x" + toString<int>(e2->getID());
163  std::string id2 = toString<int>(e2->getID()) + "x" + toString<int>(e1->getID());
164  NBNode* node1 = nc.retrieve(id1);
165  NBNode* node2 = nc.retrieve(id2);
166  NBNode* node = 0;
167  assert(node1 == 0 || node2 == 0);
168  if (node1 == 0 && node2 == 0) {
170  return false;
171  /* node = new NBNode(id1, pos.x(), pos.y(), "priority");
172  if(!myNodeCont.insert(node)) {
173  "nope, NIVissimDisturbance" << endl;
174  throw 1;
175  }*/
176  } else {
177  node = node1 == 0 ? node2 : node1;
178  }
179  ec.splitAt(dc,
181  toString<int>(e1->getID()), myEdge.getPosition()),
182  node);
183  ec.splitAt(dc,
185  toString<int>(e2->getID()), myDisturbance.getPosition()),
186  node);
187  // !!! in some cases, one of the edges is not being build because it's too short
188  // !!! what to do in these cases?
189  NBEdge* mayDriveFrom = ec.retrieve(toString<int>(e1->getID()) + "[0]");
190  NBEdge* mayDriveTo = ec.retrieve(toString<int>(e1->getID()) + "[1]");
191  NBEdge* mustStopFrom = ec.retrieve(toString<int>(e2->getID()) + "[0]");
192  NBEdge* mustStopTo = ec.retrieve(toString<int>(e2->getID()) + "[1]");
193  if (mayDriveFrom != 0 && mayDriveTo != 0 && mustStopFrom != 0 && mustStopTo != 0) {
194  node->addSortedLinkFoes(
195  NBConnection(mayDriveFrom, mayDriveTo),
196  NBConnection(mayDriveFrom, mayDriveTo));
197  } else {
199  return false;
200  // !!! warning
201  }
202 // }
203  } else if (pc != 0 && bc == 0) {
204  // The prohibited abstract edge is a connection, the other
205  // is not;
206  // The connection will be prohibitesd by all connections
207  // outgoing from the "real" edge
208 
210  if (e == 0) {
211  WRITE_WARNING("Could not prohibit '" + toString<int>(myEdge.getEdgeID()) + "' by '" + toString<int>(myDisturbance.getEdgeID()) + "'. Have not found disturbance.");
213  return false;
214  }
215  if (e->getFromNode() == e->getToNode()) {
216  WRITE_WARNING("Could not prohibit '" + toString<int>(myEdge.getEdgeID()) + "' by '" + toString<int>(myDisturbance.getEdgeID()) + "'. Disturbance connects same node.");
218  // What to do with self-looping edges?
219  return false;
220  }
221  // get the begin of the prohibited connection
222  std::string id_pcoe = toString<int>(pc->getFromEdgeID());
223  std::string id_pcie = toString<int>(pc->getToEdgeID());
224  NBEdge* pcoe = ec.retrievePossiblySplitted(id_pcoe, id_pcie, true);
225  NBEdge* pcie = ec.retrievePossiblySplitted(id_pcie, id_pcoe, false);
226  // check whether it's ending node is the node the prohibited
227  // edge end at
228  if (pcoe != 0 && pcie != 0 && pcoe->getToNode() == e->getToNode()) {
229  // if so, simply prohibit the connections
230  NBNode* node = e->getToNode();
231  const EdgeVector& connected = e->getConnectedEdges();
232  for (EdgeVector::const_iterator i = connected.begin(); i != connected.end(); i++) {
233  node->addSortedLinkFoes(
234  NBConnection(e, *i),
235  NBConnection(pcoe, pcie));
236  }
237  } else {
238  WRITE_WARNING("Would have to split edge '" + e->getID() + "' to build a prohibition");
240  // quite ugly - why was it not build?
241  return false;
242  /*
243  std::string nid1 = e->getID() + "[0]";
244  std::string nid2 = e->getID() + "[1]";
245 
246  if(ec.splitAt(e, node)) {
247  node->addSortedLinkFoes(
248  NBConnection(
249  ec.retrieve(nid1),
250  ec.retrieve(nid2)
251  ),
252  getConnection(node, myEdge.getEdgeID())
253  );
254  }
255  */
256  }
257  } else if (bc != 0 && pc == 0) {
258  // The prohibiting abstract edge is a connection, the other
259  // is not;
260  // We have to split the other one and add the prohibition
261  // description
262 
264  toString<int>(myEdge.getEdgeID()), myEdge.getPosition());
265  if (e == 0) {
266  WRITE_WARNING("Could not prohibit '" + toString<int>(myEdge.getEdgeID()) + "' - it was not built.");
267  return false;
268  }
269  std::string nid1 = e->getID() + "[0]";
270  std::string nid2 = e->getID() + "[1]";
271  if (e->getFromNode() == e->getToNode()) {
272  WRITE_WARNING("Could not prohibit '" + toString<int>(myEdge.getEdgeID()) + "' by '" + toString<int>(myDisturbance.getEdgeID()) + "'.");
274  // What to do with self-looping edges?
275  return false;
276  }
277  // get the begin of the prohibiting connection
278  std::string id_bcoe = toString<int>(bc->getFromEdgeID());
279  std::string id_bcie = toString<int>(bc->getToEdgeID());
280  NBEdge* bcoe = ec.retrievePossiblySplitted(id_bcoe, id_bcie, true);
281  NBEdge* bcie = ec.retrievePossiblySplitted(id_bcie, id_bcoe, false);
282  // check whether it's ending node is the node the prohibited
283  // edge end at
284  if (bcoe != 0 && bcie != 0 && bcoe->getToNode() == e->getToNode()) {
285  // if so, simply prohibit the connections
286  NBNode* node = e->getToNode();
287  const EdgeVector& connected = e->getConnectedEdges();
288  for (EdgeVector::const_iterator i = connected.begin(); i != connected.end(); i++) {
289  node->addSortedLinkFoes(
290  NBConnection(bcoe, bcie),
291  NBConnection(e, *i));
292  }
293  } else {
294  WRITE_WARNING("Would have to split edge '" + e->getID() + "' to build a prohibition");
296  return false;
297  /*
298  // quite ugly - why was it not build?
299  if(ec.splitAt(e, node)) {
300  node->addSortedLinkFoes(
301  getConnection(node, myDisturbance.getEdgeID()),
302  NBConnection(
303  ec.retrieve(nid1),
304  ec.retrieve(nid2)
305  )
306  );
307  }
308  */
309  }
310  } else {
311  // both the prohibiting and the prohibited abstract edges
312  // are connections
313  // We can retrieve the conected edges and add the desription
315  NBConnection conn2 = getConnection(node, myEdge.getEdgeID());
316  if (!conn1.check(ec) || !conn2.check(ec)) {
318  return false;
319  }
320  node->addSortedLinkFoes(conn1, conn2);
321  }
322  return true;
323 }
324 
325 
330  NBEdge* from =
331  node->getPossiblySplittedIncoming(toString<int>(c->getFromEdgeID()));
332  NBEdge* to =
333  node->getPossiblySplittedOutgoing(toString<int>(c->getToEdgeID()));
334 
335  // source is a connection
336  return NBConnection(toString<int>(c->getFromEdgeID()), from,
337  toString<int>(c->getToEdgeID()), to);
338  } else {
339  WRITE_WARNING("NIVissimDisturbance: no connection");
340  return NBConnection(0, 0);
341 // throw 1; // !!! what to do?
342  }
343 
344 }
345 
346 void
348  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
349  delete(*i).second;
350  }
351  myDict.clear();
352 }
353 
354 
355 void
357  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
358  NIVissimDisturbance* d = (*i).second;
359  NIVissimAbstractEdge::dictionary(d->myEdge.getEdgeID())->addDisturbance((*i).first);
360  NIVissimAbstractEdge::dictionary(d->myDisturbance.getEdgeID())->addDisturbance((*i).first);
361  }
362  /* for(DictType::iterator i=myDict.begin(); i!=myDict.end(); i++) {
363  delete (*i).second;
364  }
365  */
366 }
367 
368 
369 void
371  if (refusedProhibits > 0) {
372  WRITE_WARNING("Could not build " + toString<size_t>(refusedProhibits) + " of " + toString<size_t>(myDict.size()) + " disturbances.");
373  }
374 }
375 
376 
377 
378 /****************************************************************************/
379