SUMO - Simulation of Urban MObility
NIVissimConnectionCluster.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2017 German Aerospace Center (DLR) and others.
4 /****************************************************************************/
5 //
6 // This program and the accompanying materials
7 // are made available under the terms of the Eclipse Public License v2.0
8 // which accompanies this distribution, and is available at
9 // http://www.eclipse.org/legal/epl-v20.html
10 //
11 /****************************************************************************/
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 #include <algorithm>
33 #include <iostream>
34 #include <cassert>
35 #include <iterator>
36 #include <utils/geom/Boundary.h>
37 #include <utils/geom/GeomHelper.h>
40 #include <utils/common/ToString.h>
41 #include "NIVissimConnection.h"
42 #include "NIVissimDisturbance.h"
43 #include "NIVissimNodeCluster.h"
44 #include "NIVissimNodeDef.h"
45 #include "NIVissimEdge.h"
46 #include "NIVissimTL.h"
48 
49 
50 // ===========================================================================
51 // static members
52 // ===========================================================================
56 
57 
58 
59 // ===========================================================================
60 // method definitions
61 // ===========================================================================
62 // ---------------------------------------------------------------------------
63 // NIVissimConnectionCluster::NodeSubCluster - methods
64 // ---------------------------------------------------------------------------
66  add(c);
67 }
68 
69 
71 
72 
73 void
76  myConnections.push_back(c);
77 }
78 
79 
80 void
82  for (ConnectionCont::const_iterator i = c.myConnections.begin(); i != c.myConnections.end(); i++) {
83  add(*i);
84  }
85 }
86 
87 
88 int
90  return (int)myConnections.size();
91 }
92 
93 
94 std::vector<int>
96  std::vector<int> ret;
98  for (ConnectionCont::const_iterator i = myConnections.begin(); i != myConnections.end(); i++) {
99  ret.push_back((*i)->getID());
100  (*i)->setNodeCluster(id);
101  }
102  return ret;
103 }
104 
105 
106 bool
109  double offset) {
110  assert(myBoundary.xmax() >= myBoundary.xmin());
111  assert(c.myBoundary.xmax() >= c.myBoundary.xmin());
112  return myBoundary.overlapsWith(c.myBoundary, offset);
113 }
114 
115 
116 
117 // ---------------------------------------------------------------------------
118 // NIVissimConnectionCluster - methods
119 // ---------------------------------------------------------------------------
121  const std::vector<int>& connections, int nodeCluster, int edgeid)
122  : myConnections(connections), myNodeCluster(nodeCluster),
125  myClusters.push_back(this);
126  assert(edgeid > 0);
127  if (edgeid >= 0) {
128  myEdges.push_back(edgeid);
129  }
130  // add information about incoming and outgoing edges
131  for (std::vector<int>::const_iterator i = connections.begin(); i != connections.end(); i++) {
133  assert(c != 0);
134  myOutgoingEdges.push_back(c->getToEdgeID());
135  myIncomingEdges.push_back(c->getFromEdgeID());
136  assert(c->getFromEdgeID() == edgeid || c->getToEdgeID() == edgeid);
137  }
140 }
141 
142 
144  const std::vector<int>& connections, const Boundary& boundary,
145  int nodeCluster, const std::vector<int>& edges)
146  : myConnections(connections), myBoundary(boundary),
147  myNodeCluster(nodeCluster), myEdges(edges) {
148  myClusters.push_back(this);
150  assert(myBoundary.xmax() >= myBoundary.xmin());
151  // add information about incoming and outgoing edges
152  for (std::vector<int>::const_iterator i = connections.begin(); i != connections.end(); i++) {
154  assert(c != 0);
155  myOutgoingEdges.push_back(c->getToEdgeID());
156  myIncomingEdges.push_back(c->getFromEdgeID());
157  assert(find(edges.begin(), edges.end(), c->getFromEdgeID()) != edges.end()
158  ||
159  find(edges.begin(), edges.end(), c->getToEdgeID()) != edges.end());
160  }
163 }
164 
165 
167 
168 
169 
170 int
172  return myFirstFreeID++;
173 }
174 
175 
176 bool
178  double offset) const {
179  assert(myBoundary.xmax() >= myBoundary.xmin());
180  assert(c->myBoundary.xmax() >= c->myBoundary.xmin());
181  return c->myBoundary.overlapsWith(myBoundary, offset);
182 }
183 
184 
185 void
187  assert(myBoundary.xmax() >= myBoundary.xmin());
188  assert(c->myBoundary.xmax() >= c->myBoundary.xmin());
190  for (std::vector<int>::iterator i = c->myConnections.begin(); i != c->myConnections.end(); i++) {
191  myConnections.push_back(*i);
192  }
194  assert(myNodeCluster == -1 || c->myNodeCluster == -1);
195  if (myNodeCluster == -1) {
197  }
198  // inform edges about merging
199  // !!! merge should be done within one method
200  for (std::vector<int>::iterator j = c->myEdges.begin(); j != c->myEdges.end(); j++) {
201  NIVissimEdge::dictionary(*j)->mergedInto(c, this);
202  }
203  copy(c->myEdges.begin(), c->myEdges.end(), back_inserter(myEdges));
204  copy(c->myIncomingEdges.begin(), c->myIncomingEdges.end(),
205  back_inserter(myIncomingEdges));
206  copy(c->myOutgoingEdges.begin(), c->myOutgoingEdges.end(),
207  back_inserter(myOutgoingEdges));
211 }
212 
213 
214 
215 void
217  // !!! ...
218  // Further, we try to omit joining of overlaping nodes. This is done by holding
219  // the lists of incoming and outgoing edges and incrementally building the nodes
220  // regarding this information
221  std::vector<NIVissimConnectionCluster*> joinAble;
222  int pos = 0;
223  ContType::iterator i = myClusters.begin();
224  // step1 - faster but no complete
225  while (i != myClusters.end()) {
226  joinAble.clear();
227  ContType::iterator j = i + 1;
228 
229  // check whether every combination has been processed
230  while (j != myClusters.end()) {
231  // check whether the current clusters overlap
232  if ((*i)->joinable(*j, offset)) {
233  joinAble.push_back(*j);
234  }
235  j++;
236  }
237  for (std::vector<NIVissimConnectionCluster*>::iterator k = joinAble.begin();
238  k != joinAble.end(); k++) {
239  // add the overlaping cluster
240  (*i)->add(*k);
241  // erase the overlaping cluster
242  delete *k;
243  myClusters.erase(find(myClusters.begin(), myClusters.end(), *k));
244  }
245  //
246  if (joinAble.size() > 0) {
247  i = myClusters.begin() + pos;
248  // clear temporary storages
249  joinAble.clear();
250  } else {
251  i++;
252  pos++;
253  }
254  }
255  //
256  pos = 0;
257  i = myClusters.begin();
258  while (i != myClusters.end()) {
259  ContType::iterator j = i + 1;
260  // check whether every combination has been processed
261  while (j != myClusters.end()) {
262  // check whether the current clusters overlap
263  if ((*i)->joinable(*j, offset)) {
264  joinAble.push_back(*j);
265  }
266  j++;
267  }
268  for (std::vector<NIVissimConnectionCluster*>::iterator k = joinAble.begin();
269  k != joinAble.end(); k++) {
270  // add the overlaping cluster
271  (*i)->add(*k);
272  // erase the overlaping cluster
273  delete *k;
274  myClusters.erase(find(myClusters.begin(), myClusters.end(), *k));
275  }
276  //
277  if (joinAble.size() > 0) {
278  i = myClusters.begin();
279  // clear temporary storages
280  joinAble.clear();
281  pos = 0;
282  } else {
283  i++;
284  pos++;
285  }
286  }
287  // check for weak district connections
288  // (junctions made up by district connections, where prohibitions are not
289  // modelled properly)
290  pos = 0;
291  i = myClusters.begin();
292  while (i != myClusters.end()) {
293  ContType::iterator j = i + 1;
294  // check whether every combination has been processed
295  while (j != myClusters.end()) {
296  // check whether the current clusters overlap
297  if ((*i)->isWeakDistrictConnRealisation(*j)) {
298  joinAble.push_back(*j);
299  }
300  j++;
301  }
302  for (std::vector<NIVissimConnectionCluster*>::iterator k = joinAble.begin();
303  k != joinAble.end(); k++) {
304  // add the overlaping cluster
305  (*i)->add(*k);
306  // erase the overlaping cluster
307  delete *k;
308  myClusters.erase(find(myClusters.begin(), myClusters.end(), *k));
309  }
310  //
311  if (joinAble.size() > 0) {
312  i = myClusters.begin();
313  // clear temporary storages
314  joinAble.clear();
315  pos = 0;
316  } else {
317  i++;
318  pos++;
319  }
320  }
321 }
322 
323 
324 bool
326  // join clusters which have at least one connection in common
328  return true;
329  }
330 
331  // connections shall overlap otherwise
332  if (!overlapsWith(c2, offset)) {
333  return false;
334  }
335 
336  // at least one of the clusters shall not be assigned to a node in previous (!!!??)
337  if (hasNodeCluster() && c2->hasNodeCluster()) {
338  return false;
339  }
340 
341  // join clusters which where connections do disturb each other
343  ||
345 
346  return true;
347  }
348 
349 
350  // join clusters which do share the same incoming or outgoing edges (not mutually)
351  std::vector<int> extendedOutgoing1;
352  std::vector<int> extendedIncoming1;
353  std::vector<int> extendedOutgoing2;
354  std::vector<int> extendedIncoming2;
355  if (myIncomingEdges.size() > 1 || c2->myIncomingEdges.size() > 1) {
356  extendedOutgoing1 =
358  extendedIncoming1 =
360  extendedOutgoing2 =
362  extendedIncoming2 =
364  } else {
365  extendedOutgoing1 = myIncomingEdges;
366  extendedIncoming1 = myOutgoingEdges;
367  extendedOutgoing2 = c2->myIncomingEdges;
368  extendedIncoming2 = c2->myOutgoingEdges;
369  }
370 
371  if (VectorHelper<int>::subSetExists(extendedOutgoing1, extendedOutgoing2)
372  ||
373  VectorHelper<int>::subSetExists(extendedIncoming1, extendedIncoming2)
374  ) {
375  return true;
376  }
377  return false;
378 }
379 
380 
381 bool
383  if ((myIncomingEdges.size() == 1 && myOutgoingEdges.size() == 1)) {
384  return false;
385  }
386  if ((c2->myIncomingEdges.size() == 1 && c2->myOutgoingEdges.size() == 1)) {
387  return false;
388  }
389 
390  // ok, may be the other way round
391  if (myIncomingEdges.size() == 1 && c2->myOutgoingEdges.size() == 1) {
392  return c2->isWeakDistrictConnRealisation(this);
393  }
394  // connections must cross
395  bool crosses = false;
396  for (std::vector<int>::const_iterator j1 = myConnections.begin(); j1 != myConnections.end() && !crosses; j1++) {
398  const PositionVector& g1 = c1->getGeometry();
399  for (std::vector<int>::const_iterator j2 = c2->myConnections.begin(); j2 != c2->myConnections.end() && !crosses; j2++) {
401  const PositionVector& g2 = c2->getGeometry();
402  if (g1.intersects(g2)) {
403  crosses = true;
404  }
405  }
406  }
407  if (!crosses) {
408  return false;
409  }
410  // ok, check for connection
411  if (myOutgoingEdges.size() != 1 || c2->myIncomingEdges.size() != 1) {
412  return false;
413  }
414  // check whether the connection is bidirectional
417  if (oe == 0 || ie == 0) {
418  return false;
419  }
421 }
422 
423 
424 bool
426  //
427  for (std::vector<int>::iterator i = myConnections.begin(); i != myConnections.end(); i++) {
429  for (std::vector<int>::iterator j = cc2->myConnections.begin(); j != cc2->myConnections.end(); j++) {
431  if (c1->getFromEdgeID() == c2->getFromEdgeID()) {
433  const PositionVector& g = e->getGeometry();
435  g.front(), g.back(), c1->getBoundary().getCenter());
437  g.front(), g.back(), c2->getBoundary().getCenter());
438  if (pos1 <= 5.0 && pos2 <= 5.0) {
439  return true;
440  }
441  }
442  if (c1->getToEdgeID() == c2->getToEdgeID()) {
444  const PositionVector& g = e->getGeometry();
446  g.front(), g.back(), c1->getBoundary().getCenter());
448  g.front(), g.back(), c2->getBoundary().getCenter());
449  if (pos1 >= g.length() - 5.0 && pos2 >= g.length() - 5.0) {
450  return true;
451  }
452  }
453  }
454  }
455  return false;
456 }
457 
458 
459 std::vector<int>
461  const std::vector<int>& iv2) const {
462  std::vector<int> ret(iv1);
463  for (std::vector<int>::const_iterator i = iv1.begin(); i != iv1.end(); i++) {
465  const std::vector<NIVissimEdge*> treatAsSame = e->getToTreatAsSame();
466  for (std::vector<NIVissimEdge*>::const_iterator j = treatAsSame.begin(); j != treatAsSame.end(); j++) {
467  if (find(iv2.begin(), iv2.end(), (*j)->getID()) == iv2.end()) {
468  ret.push_back((*j)->getID());
469  }
470  }
471  }
472  return ret;
473 }
474 
475 std::vector<int>
477  std::vector<int> ret;
478  for (std::vector<int>::iterator i = myConnections.begin(); i != myConnections.end(); i++) {
480  const std::vector<int>& disturbances = c->getDisturbances();
481  for (std::vector<int>::const_iterator j = disturbances.begin(); j != disturbances.end(); j++) {
483  ret.push_back(d->getEdgeID());
484  ret.push_back(d->getDisturbanceID());
485  }
486  }
487  return ret;
488 }
489 
490 
491 void
493  for (ContType::iterator i = myClusters.begin(); i != myClusters.end(); i++) {
494  std::vector<int> disturbances;
495  std::vector<int> tls;
496  std::vector<int> nodes;
497  int tlsid = -1;
498  int nodeid = -1;
499  if ((*i)->myConnections.size() > 0) {
500  (*i)->recomputeBoundary();
501  disturbances = NIVissimDisturbance::getWithin((*i)->myBoundary);
502  }
503  nodes = (*i)->myNodes;//NIVissimTL::getWithin((*i)->myBoundary, 5.0);
504  if (nodes.size() > 1) {
505  WRITE_WARNING("NIVissimConnectionCluster:More than a single node");
506  // throw 1; // !!! eigentlich sollte hier nur eine Ampelanlage sein
507  }
508  if (nodes.size() > 0) {
509  nodeid = nodes[0];
510  }
511  //
512  //
514  nodeid, tlsid, (*i)->myConnections,
515  disturbances, (*i)->myIncomingEdges.size() < 2);
516  assert((*i)->myNodeCluster == id || (*i)->myNodeCluster < 0);
517  (*i)->myNodeCluster = id;
518  }
519 }
520 
521 
522 void
524  for (ContType::iterator i = myClusters.begin(); i != myClusters.end(); i++) {
525  std::vector<int> connections = (*i)->myConnections;
526  for (std::vector<int>::iterator j = connections.begin(); j != connections.end(); j++) {
527  if (j != connections.begin()) {
528  into << ", ";
529  }
530  into << *j;
531  }
532  into << "(" << (*i)->myBoundary << ")" << std::endl;
533  }
534  into << "---------------------------" << std::endl;
535 }
536 
537 
538 
539 bool
541  return myNodeCluster != -1;
542 }
543 
544 
545 int
547  return (int)myClusters.size();
548 }
549 
550 
551 void
553  for (NodeSubCluster::ConnectionCont::const_iterator i = c.myConnections.begin(); i != c.myConnections.end(); i++) {
554  NIVissimConnection* conn = *i;
555  int connid = conn->getID();
556  std::vector<int>::iterator j = find(myConnections.begin(), myConnections.end(), connid);
557  if (j != myConnections.end()) {
558  myConnections.erase(j);
559  }
560  }
562 }
563 
564 
565 void
567  myBoundary = Boundary();
568  for (std::vector<int>::iterator i = myConnections.begin(); i != myConnections.end(); i++) {
570  if (c != 0) {
573  if (c->getGeometry().size() != 0) {
575  }
576  }
577  }
578  assert(myBoundary.xmax() >= myBoundary.xmin());
579 }
580 
581 
582 NBNode*
584  return NIVissimNodeCluster::dictionary(myNodeCluster)->getNBNode();
585 }
586 
587 
588 bool
589 NIVissimConnectionCluster::around(const Position& p, double offset) const {
590  assert(myBoundary.xmax() >= myBoundary.xmin());
591  return myBoundary.around(p, offset);
592 }
593 
594 
595 
596 void
598  assert(myConnections.size() != 0);
599  // remove the cluster from all edges at first
600  std::vector<int>::iterator i;
601  for (i = myEdges.begin(); i != myEdges.end(); i++) {
603  edge->removeFromConnectionCluster(this);
604  }
605  // clear edge information
606  myEdges.clear();
607  // recheck which edges do still participate and add edges
608  for (i = myConnections.begin(); i != myConnections.end(); i++) {
610  assert(myBoundary.xmax() >= myBoundary.xmin());
611  if (myBoundary.around(c->getFromGeomPosition(), 5)) {
612  myEdges.push_back(c->getFromEdgeID());
613  }
614  assert(myBoundary.xmax() >= myBoundary.xmin());
615  if (myBoundary.around(c->getToGeomPosition(), 5)) {
616  myEdges.push_back(c->getToEdgeID());
617  }
618  }
619  // connect edges
620  for (i = myEdges.begin(); i != myEdges.end(); i++) {
622  edge->addToConnectionCluster(this);
623  }
624 }
625 
626 
627 double
629  // return the middle of the connections when there are any
630  if (myConnections.size() != 0) {
631  double sum = 0;
632  int part = 0;
633  std::vector<int>::const_iterator i;
634  for (i = myConnections.begin(); i != myConnections.end(); i++) {
636  if (c->getFromEdgeID() == edgeid) {
637  part++;
638  sum += c->getFromPosition();
639  }
640  if (c->getToEdgeID() == edgeid) {
641  part++;
642  sum += c->getToPosition();
643  }
644  }
645  if (part > 0) {
646  return sum / (double) part;
647  }
648  }
649  // use the position of the node if possible
650  if (myNodeCluster >= 0) {
651  // try to find the nearest point on the edge
652  // !!! only the main geometry is regarded
653  NIVissimNodeDef* node =
655  if (node != 0) {
656  double pos = node->getEdgePosition(edgeid);
657  if (pos >= 0) {
658  return pos;
659  }
660  }
661  /*
662  double try1 = GeomHelper::nearest_offset_on_line_to_point(
663  edge->getBegin2D(), edge->getEnd2D(), node->getPos());
664  if(try1>=0) {
665  return try1;
666  }
667  // try to use simple distance
668  double dist1 =
669  GeomHelper::distance(node->getPos(), edge->getBegin2D());
670  double dist2 =
671  GeomHelper::distance(node->getPos(), edge->getEnd2D());
672  return dist1<dist2
673  ? 0 : edge->getLength();
674  */
675  }
676  // what else?
677  WRITE_WARNING("NIVissimConnectionCluster: how to get an edge's position?");
678  // !!!
679  assert(myBoundary.xmin() <= myBoundary.xmax());
680  NIVissimEdge* edge = NIVissimEdge::dictionary(edgeid);
681  std::vector<int>::const_iterator i = find(myEdges.begin(), myEdges.end(), edgeid);
682  if (i == myEdges.end()) {
683  // edge does not exist!?
684  throw 1;
685  }
686  const PositionVector& edgeGeom = edge->getGeometry();
689  edgeGeom.front(), edgeGeom.back(), p);
690 }
691 
692 
693 
694 void
696  for (ContType::iterator i = myClusters.begin(); i != myClusters.end(); i++) {
697  delete(*i);
698  }
699  myClusters.clear();
700  myFirstFreeID = 100000;
701 }
702 
703 
706  // collect connection where this edge is the incoming one
707  std::vector<NIVissimConnection*> edgeIsIncoming;
708  for (std::vector<int>::const_iterator i = myConnections.begin(); i != myConnections.end(); i++) {
710  if (c->getFromEdgeID() == e->getID()) {
711  edgeIsIncoming.push_back(c);
712  }
713  }
714  //
715  if (edgeIsIncoming.size() == 0) {
716  return PositionVector();
717  }
718  // sort connected edges in same direction
719  sort(edgeIsIncoming.begin(), edgeIsIncoming.end(),
721  NIVissimConnection* c = *(edgeIsIncoming.begin());
722  return c->getGeometry();
723 }
724 
725 
726 
729  // collect connection where this edge is the incoming one
730  std::vector<NIVissimConnection*> edgeIsIncoming;
731  for (std::vector<int>::const_iterator i = myConnections.begin(); i != myConnections.end(); i++) {
733  if (c->getFromEdgeID() == e->getID()) {
734  edgeIsIncoming.push_back(c);
735  }
736  }
737  //
738  if (edgeIsIncoming.size() == 0) {
739  return 0;
740  }
741  // sort connected edges in same direction
742  sort(edgeIsIncoming.begin(), edgeIsIncoming.end(),
744  return *(edgeIsIncoming.begin());
745 }
746 
747 
748 
751  // collect connection where this edge is the outgoing one
752  std::vector<NIVissimConnection*> edgeIsOutgoing;
753  for (std::vector<int>::const_iterator i = myConnections.begin(); i != myConnections.end(); i++) {
755  if (c->getToEdgeID() == e->getID()) {
756  edgeIsOutgoing.push_back(c);
757  }
758  }
759  //
760  if (edgeIsOutgoing.size() == 0) {
761  return PositionVector();
762  }
763  // sort connected edges in same direction
764  sort(edgeIsOutgoing.begin(), edgeIsOutgoing.end(),
766  NIVissimConnection* c = *(edgeIsOutgoing.begin());
767  return c->getGeometry();
768 }
769 
770 
773  // collect connection where this edge is the outgoing one
774  std::vector<NIVissimConnection*> edgeIsOutgoing;
775  for (std::vector<int>::const_iterator i = myConnections.begin(); i != myConnections.end(); i++) {
777  if (c->getToEdgeID() == e->getID()) {
778  edgeIsOutgoing.push_back(c);
779  }
780  }
781  //
782  if (edgeIsOutgoing.size() == 0) {
783  return 0;
784  }
785  // sort connected edges in same direction
786  sort(edgeIsOutgoing.begin(), edgeIsOutgoing.end(),
788  return *(edgeIsOutgoing.begin());
789 }
790 
791 
792 
793 /****************************************************************************/
794 
static void joinBySameEdges(double offset)
Tries to joind clusters participating within a node This is done by joining clusters which overlap...
double xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:131
const std::vector< int > & getDisturbances() const
std::vector< NIVissimConnectionCluster * > ContType
int myNodeCluster
The node the cluster is assigned to.
std::vector< int > myConnections
List of connection-ids which participate within this cluster.
NIVissimConnection * getIncomingContinuation(NIVissimEdge *e) const
static std::vector< int > getWithin(const AbstractPoly &poly)
static bool dictionary(const std::string &name, const NIVissimExtendedEdgePoint &edge, const NIVissimExtendedEdgePoint &by)
const PositionVector & getGeometry() const
void addToConnectionCluster(NIVissimConnectionCluster *c)
static bool dictionary(int id, NIVissimNodeCluster *o)
NIVissimConnection * getOutgoingContinuation(NIVissimEdge *e) const
static bool dictionary(int id, NIVissimConnection *o)
bool overlapsWith(const AbstractPoly &poly, double offset=0) const
Returns whether the boundary overlaps with the given polygon.
Definition: Boundary.cpp:188
static Position crossPoint(const Boundary &b, const PositionVector &v)
Definition: GeomHelper.cpp:122
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:47
std::vector< int > getDisturbanceParticipators()
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:199
double getPositionForEdge(int edgeid) const
A temporary storage for edges imported from Vissim.
Definition: NIVissimEdge.h:59
bool joinable(NIVissimConnectionCluster *c2, double offset)
void add(NIVissimConnectionCluster *c)
Adds the second cluster.
static double nearest_offset_on_line_to_point2D(const Position &lineStart, const Position &lineEnd, const Position &p, bool perpendicular=true)
Definition: GeomHelper.cpp:95
PositionVector getIncomingContinuationGeometry(NIVissimEdge *e) const
double beginEndAngle() const
returns the angle in radians of the line connecting the first and the last position ...
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:45
static void _debugOut(std::ostream &into)
A list of positions.
const Boundary & getBoundingBox() const
static void removeDouble(std::vector< T > &v)
Definition: VectorHelper.h:76
bool around(const Position &p, double offset=0) const
double xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:125
static bool dictionary(int id, NIVissimNodeDef *o)
#define DEG2RAD(x)
Definition: GeomHelper.h:44
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.
double getToPosition() const
PositionVector getOutgoingContinuationGeometry(NIVissimEdge *e) const
Position getToGeomPosition() const
void removeConnections(const NodeSubCluster &c)
std::vector< int > extendByToTreatAsSame(const std::vector< int > &iv1, const std::vector< int > &iv2) const
virtual double getEdgePosition(int edgeid) const =0
bool around(const Position &p, double offset=0) const
Returns whether the boundary contains the given coordinate.
Definition: Boundary.cpp:179
Boundary myBoundary
The boundary of the cluster.
Represents a single node (junction) during network building.
Definition: NBNode.h:74
Position getCenter() const
Returns the center of the boundary.
Definition: Boundary.cpp:119
Position getFromGeomPosition() const
bool overlapsWith(const NodeSubCluster &c, double offset=0)
bool overlapsWith(NIVissimConnectionCluster *c, double offset=0) const
Returns the information whether the given cluster overlaps the current.
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
const std::vector< NIVissimEdge * > & getToTreatAsSame() const
bool liesOnSameEdgesEnd(NIVissimConnectionCluster *cc2)
bool isWeakDistrictConnRealisation(NIVissimConnectionCluster *c2)
NIVissimConnectionCluster(const std::vector< int > &connections, int nodeCluster, int edgeid)
Constructor Build the boundary; The boundary includes both incoming and outgoing nodes.
static double angleDiff(const double angle1, const double angle2)
Returns the difference of the second angle to the first angle in radiants.
Definition: GeomHelper.cpp:173
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:85
bool intersects(const Position &p1, const Position &p2) const
Returns the information whether this list of points interesects the given line.
void removeFromConnectionCluster(NIVissimConnectionCluster *c)
double getFromPosition() const