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-2013 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, ec.retrievePossiblySplit(toString<int>(e1->getID()), myEdge.getPosition()), node);
180  ec.splitAt(dc, ec.retrievePossiblySplit(toString<int>(e2->getID()), myDisturbance.getPosition()), node);
181  // !!! in some cases, one of the edges is not being build because it's too short
182  // !!! what to do in these cases?
183  NBEdge* mayDriveFrom = ec.retrieve(toString<int>(e1->getID()) + "[0]");
184  NBEdge* mayDriveTo = ec.retrieve(toString<int>(e1->getID()) + "[1]");
185  NBEdge* mustStopFrom = ec.retrieve(toString<int>(e2->getID()) + "[0]");
186  NBEdge* mustStopTo = ec.retrieve(toString<int>(e2->getID()) + "[1]");
187  if (mayDriveFrom != 0 && mayDriveTo != 0 && mustStopFrom != 0 && mustStopTo != 0) {
188  node->addSortedLinkFoes(
189  NBConnection(mayDriveFrom, mayDriveTo),
190  NBConnection(mayDriveFrom, mayDriveTo));
191  } else {
193  return false;
194  // !!! warning
195  }
196 // }
197  } else if (pc != 0 && bc == 0) {
198  // The prohibited abstract edge is a connection, the other
199  // is not;
200  // The connection will be prohibitesd by all connections
201  // outgoing from the "real" edge
202 
204  if (e == 0) {
205  WRITE_WARNING("Could not prohibit '" + toString<int>(myEdge.getEdgeID()) + "' by '" + toString<int>(myDisturbance.getEdgeID()) + "'. Have not found disturbance.");
207  return false;
208  }
209  if (e->getFromNode() == e->getToNode()) {
210  WRITE_WARNING("Could not prohibit '" + toString<int>(myEdge.getEdgeID()) + "' by '" + toString<int>(myDisturbance.getEdgeID()) + "'. Disturbance connects same node.");
212  // What to do with self-looping edges?
213  return false;
214  }
215  // get the begin of the prohibited connection
216  std::string id_pcoe = toString<int>(pc->getFromEdgeID());
217  std::string id_pcie = toString<int>(pc->getToEdgeID());
218  NBEdge* pcoe = ec.retrievePossiblySplit(id_pcoe, id_pcie, true);
219  NBEdge* pcie = ec.retrievePossiblySplit(id_pcie, id_pcoe, false);
220  // check whether it's ending node is the node the prohibited
221  // edge end at
222  if (pcoe != 0 && pcie != 0 && pcoe->getToNode() == e->getToNode()) {
223  // if so, simply prohibit the connections
224  NBNode* node = e->getToNode();
225  const EdgeVector& connected = e->getConnectedEdges();
226  for (EdgeVector::const_iterator i = connected.begin(); i != connected.end(); i++) {
227  node->addSortedLinkFoes(
228  NBConnection(e, *i),
229  NBConnection(pcoe, pcie));
230  }
231  } else {
232  WRITE_WARNING("Would have to split edge '" + e->getID() + "' to build a prohibition");
234  // quite ugly - why was it not build?
235  return false;
236  /*
237  std::string nid1 = e->getID() + "[0]";
238  std::string nid2 = e->getID() + "[1]";
239 
240  if(ec.splitAt(e, node)) {
241  node->addSortedLinkFoes(
242  NBConnection(
243  ec.retrieve(nid1),
244  ec.retrieve(nid2)
245  ),
246  getConnection(node, myEdge.getEdgeID())
247  );
248  }
249  */
250  }
251  } else if (bc != 0 && pc == 0) {
252  // The prohibiting abstract edge is a connection, the other
253  // is not;
254  // We have to split the other one and add the prohibition
255  // description
256 
257  NBEdge* e = ec.retrievePossiblySplit(toString<int>(myEdge.getEdgeID()), myEdge.getPosition());
258  if (e == 0) {
259  WRITE_WARNING("Could not prohibit '" + toString<int>(myEdge.getEdgeID()) + "' - it was not built.");
260  return false;
261  }
262  std::string nid1 = e->getID() + "[0]";
263  std::string nid2 = e->getID() + "[1]";
264  if (e->getFromNode() == e->getToNode()) {
265  WRITE_WARNING("Could not prohibit '" + toString<int>(myEdge.getEdgeID()) + "' by '" + toString<int>(myDisturbance.getEdgeID()) + "'.");
267  // What to do with self-looping edges?
268  return false;
269  }
270  // get the begin of the prohibiting connection
271  std::string id_bcoe = toString<int>(bc->getFromEdgeID());
272  std::string id_bcie = toString<int>(bc->getToEdgeID());
273  NBEdge* bcoe = ec.retrievePossiblySplit(id_bcoe, id_bcie, true);
274  NBEdge* bcie = ec.retrievePossiblySplit(id_bcie, id_bcoe, false);
275  // check whether it's ending node is the node the prohibited
276  // edge end at
277  if (bcoe != 0 && bcie != 0 && bcoe->getToNode() == e->getToNode()) {
278  // if so, simply prohibit the connections
279  NBNode* node = e->getToNode();
280  const EdgeVector& connected = e->getConnectedEdges();
281  for (EdgeVector::const_iterator i = connected.begin(); i != connected.end(); i++) {
282  node->addSortedLinkFoes(
283  NBConnection(bcoe, bcie),
284  NBConnection(e, *i));
285  }
286  } else {
287  WRITE_WARNING("Would have to split edge '" + e->getID() + "' to build a prohibition");
289  return false;
290  /*
291  // quite ugly - why was it not build?
292  if(ec.splitAt(e, node)) {
293  node->addSortedLinkFoes(
294  getConnection(node, myDisturbance.getEdgeID()),
295  NBConnection(
296  ec.retrieve(nid1),
297  ec.retrieve(nid2)
298  )
299  );
300  }
301  */
302  }
303  } else {
304  // both the prohibiting and the prohibited abstract edges
305  // are connections
306  // We can retrieve the conected edges and add the desription
308  NBConnection conn2 = getConnection(node, myEdge.getEdgeID());
309  if (!conn1.check(ec) || !conn2.check(ec)) {
311  return false;
312  }
313  node->addSortedLinkFoes(conn1, conn2);
314  }
315  return true;
316 }
317 
318 
323  NBEdge* from =
324  node->getPossiblySplittedIncoming(toString<int>(c->getFromEdgeID()));
325  NBEdge* to =
326  node->getPossiblySplittedOutgoing(toString<int>(c->getToEdgeID()));
327 
328  // source is a connection
329  return NBConnection(toString<int>(c->getFromEdgeID()), from,
330  toString<int>(c->getToEdgeID()), to);
331  } else {
332  WRITE_WARNING("NIVissimDisturbance: no connection");
333  return NBConnection(0, 0);
334 // throw 1; // !!! what to do?
335  }
336 
337 }
338 
339 void
341  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
342  delete(*i).second;
343  }
344  myDict.clear();
345 }
346 
347 
348 void
350  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
351  NIVissimDisturbance* d = (*i).second;
352  NIVissimAbstractEdge::dictionary(d->myEdge.getEdgeID())->addDisturbance((*i).first);
353  NIVissimAbstractEdge::dictionary(d->myDisturbance.getEdgeID())->addDisturbance((*i).first);
354  }
355  /* for(DictType::iterator i=myDict.begin(); i!=myDict.end(); i++) {
356  delete (*i).second;
357  }
358  */
359 }
360 
361 
362 void
364  if (refusedProhibits > 0) {
365  WRITE_WARNING("Could not build " + toString<size_t>(refusedProhibits) + " of " + toString<size_t>(myDict.size()) + " disturbances.");
366  }
367 }
368 
369 
370 
371 /****************************************************************************/
372