Eclipse 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-2022 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
20 // -------------------
21 /****************************************************************************/
22 #include <config.h>
23 
24 #include <algorithm>
25 #include <iostream>
26 #include <cassert>
27 #include <iterator>
28 #include <utils/geom/Boundary.h>
29 #include <utils/geom/GeomHelper.h>
32 #include <utils/common/ToString.h>
33 #include "NIVissimConnection.h"
34 #include "NIVissimDisturbance.h"
35 #include "NIVissimNodeCluster.h"
36 #include "NIVissimNodeDef.h"
37 #include "NIVissimEdge.h"
38 #include "NIVissimTL.h"
40 
41 
42 // ===========================================================================
43 // static members
44 // ===========================================================================
48 
49 
50 
51 // ===========================================================================
52 // method definitions
53 // ===========================================================================
54 // ---------------------------------------------------------------------------
55 // NIVissimConnectionCluster::NodeSubCluster - methods
56 // ---------------------------------------------------------------------------
58  add(c);
59 }
60 
61 
63 
64 
65 void
68  myConnections.push_back(c);
69 }
70 
71 
72 void
74  for (ConnectionCont::const_iterator i = c.myConnections.begin(); i != c.myConnections.end(); i++) {
75  add(*i);
76  }
77 }
78 
79 
80 int
82  return (int)myConnections.size();
83 }
84 
85 
86 std::vector<int>
88  std::vector<int> ret;
90  for (ConnectionCont::const_iterator i = myConnections.begin(); i != myConnections.end(); i++) {
91  ret.push_back((*i)->getID());
92  (*i)->setNodeCluster(id);
93  }
94  return ret;
95 }
96 
97 
98 bool
101  double offset) {
102  assert(myBoundary.xmax() >= myBoundary.xmin());
103  assert(c.myBoundary.xmax() >= c.myBoundary.xmin());
104  return myBoundary.overlapsWith(c.myBoundary, offset);
105 }
106 
107 
108 
109 // ---------------------------------------------------------------------------
110 // NIVissimConnectionCluster - methods
111 // ---------------------------------------------------------------------------
113  const std::vector<int>& connections, int nodeCluster, int edgeid)
114  : myConnections(connections), myNodeCluster(nodeCluster),
117  myClusters.push_back(this);
118  assert(edgeid > 0);
119  if (edgeid >= 0) {
120  myEdges.push_back(edgeid);
121  }
122  // add information about incoming and outgoing edges
123  for (std::vector<int>::const_iterator i = connections.begin(); i != connections.end(); i++) {
125  assert(c != 0);
126  myOutgoingEdges.push_back(c->getToEdgeID());
127  myIncomingEdges.push_back(c->getFromEdgeID());
128  assert(c->getFromEdgeID() == edgeid || c->getToEdgeID() == edgeid);
129  }
132 }
133 
134 
136  const std::vector<int>& connections, const Boundary& boundary,
137  int nodeCluster, const std::vector<int>& edges)
138  : myConnections(connections), myBoundary(boundary),
139  myNodeCluster(nodeCluster), myEdges(edges) {
140  myClusters.push_back(this);
142  assert(myBoundary.xmax() >= myBoundary.xmin());
143  // add information about incoming and outgoing edges
144  for (std::vector<int>::const_iterator i = connections.begin(); i != connections.end(); i++) {
146  assert(c != 0);
147  myOutgoingEdges.push_back(c->getToEdgeID());
148  myIncomingEdges.push_back(c->getFromEdgeID());
149  assert(find(edges.begin(), edges.end(), c->getFromEdgeID()) != edges.end()
150  ||
151  std::find(edges.begin(), edges.end(), c->getToEdgeID()) != edges.end());
152  }
155 }
156 
157 
159 
160 
161 
162 int
164  return myFirstFreeID++;
165 }
166 
167 
168 bool
170  double offset) const {
171  assert(myBoundary.xmax() >= myBoundary.xmin());
172  assert(c->myBoundary.xmax() >= c->myBoundary.xmin());
173  return c->myBoundary.overlapsWith(myBoundary, offset);
174 }
175 
176 
177 void
179  assert(myBoundary.xmax() >= myBoundary.xmin());
180  assert(c->myBoundary.xmax() >= c->myBoundary.xmin());
182  for (std::vector<int>::iterator i = c->myConnections.begin(); i != c->myConnections.end(); i++) {
183  myConnections.push_back(*i);
184  }
186  assert(myNodeCluster == -1 || c->myNodeCluster == -1);
187  if (myNodeCluster == -1) {
189  }
190  // inform edges about merging
191  // !!! merge should be done within one method
192  for (std::vector<int>::iterator j = c->myEdges.begin(); j != c->myEdges.end(); j++) {
193  NIVissimEdge::dictionary(*j)->mergedInto(c, this);
194  }
195  copy(c->myEdges.begin(), c->myEdges.end(), back_inserter(myEdges));
196  copy(c->myIncomingEdges.begin(), c->myIncomingEdges.end(),
197  back_inserter(myIncomingEdges));
198  copy(c->myOutgoingEdges.begin(), c->myOutgoingEdges.end(),
199  back_inserter(myOutgoingEdges));
203 }
204 
205 
206 
207 void
209  // !!! ...
210  // Further, we try to omit joining of overlaping nodes. This is done by holding
211  // the lists of incoming and outgoing edges and incrementally building the nodes
212  // regarding this information
213  std::vector<NIVissimConnectionCluster*> joinAble;
214  int pos = 0;
215  ContType::iterator i = myClusters.begin();
216  // step1 - faster but no complete
217  while (i != myClusters.end()) {
218  joinAble.clear();
219  ContType::iterator j = i + 1;
220 
221  // check whether every combination has been processed
222  while (j != myClusters.end()) {
223  // check whether the current clusters overlap
224  if ((*i)->joinable(*j, offset)) {
225  joinAble.push_back(*j);
226  }
227  j++;
228  }
229  for (std::vector<NIVissimConnectionCluster*>::iterator k = joinAble.begin();
230  k != joinAble.end(); k++) {
231  // add the overlaping cluster
232  (*i)->add(*k);
233  // erase the overlaping cluster
234  delete *k;
235  myClusters.erase(find(myClusters.begin(), myClusters.end(), *k));
236  }
237  //
238  if (joinAble.size() > 0) {
239  i = myClusters.begin() + pos;
240  // clear temporary storages
241  joinAble.clear();
242  } else {
243  i++;
244  pos++;
245  }
246  }
247  //
248  pos = 0;
249  i = myClusters.begin();
250  while (i != myClusters.end()) {
251  ContType::iterator j = i + 1;
252  // check whether every combination has been processed
253  while (j != myClusters.end()) {
254  // check whether the current clusters overlap
255  if ((*i)->joinable(*j, offset)) {
256  joinAble.push_back(*j);
257  }
258  j++;
259  }
260  for (std::vector<NIVissimConnectionCluster*>::iterator k = joinAble.begin();
261  k != joinAble.end(); k++) {
262  // add the overlaping cluster
263  (*i)->add(*k);
264  // erase the overlaping cluster
265  delete *k;
266  myClusters.erase(find(myClusters.begin(), myClusters.end(), *k));
267  }
268  //
269  if (joinAble.size() > 0) {
270  i = myClusters.begin();
271  // clear temporary storages
272  joinAble.clear();
273  pos = 0;
274  } else {
275  i++;
276  pos++;
277  }
278  }
279  // check for weak district connections
280  // (junctions made up by district connections, where prohibitions are not
281  // modelled properly)
282  pos = 0;
283  i = myClusters.begin();
284  while (i != myClusters.end()) {
285  ContType::iterator j = i + 1;
286  // check whether every combination has been processed
287  while (j != myClusters.end()) {
288  // check whether the current clusters overlap
289  if ((*i)->isWeakDistrictConnRealisation(*j)) {
290  joinAble.push_back(*j);
291  }
292  j++;
293  }
294  for (std::vector<NIVissimConnectionCluster*>::iterator k = joinAble.begin();
295  k != joinAble.end(); k++) {
296  // add the overlaping cluster
297  (*i)->add(*k);
298  // erase the overlaping cluster
299  delete *k;
300  myClusters.erase(find(myClusters.begin(), myClusters.end(), *k));
301  }
302  //
303  if (joinAble.size() > 0) {
304  i = myClusters.begin();
305  // clear temporary storages
306  joinAble.clear();
307  pos = 0;
308  } else {
309  i++;
310  pos++;
311  }
312  }
313 }
314 
315 
316 bool
318  // join clusters which have at least one connection in common
320  return true;
321  }
322 
323  // connections shall overlap otherwise
324  if (!overlapsWith(c2, offset)) {
325  return false;
326  }
327 
328  // at least one of the clusters shall not be assigned to a node in previous (!!!??)
329  if (hasNodeCluster() && c2->hasNodeCluster()) {
330  return false;
331  }
332 
333  // join clusters which where connections do disturb each other
335  ||
337 
338  return true;
339  }
340 
341 
342  // join clusters which do share the same incoming or outgoing edges (not mutually)
343  std::vector<int> extendedOutgoing1;
344  std::vector<int> extendedIncoming1;
345  std::vector<int> extendedOutgoing2;
346  std::vector<int> extendedIncoming2;
347  if (myIncomingEdges.size() > 1 || c2->myIncomingEdges.size() > 1) {
348  extendedOutgoing1 =
350  extendedIncoming1 =
352  extendedOutgoing2 =
354  extendedIncoming2 =
356  } else {
357  extendedOutgoing1 = myIncomingEdges;
358  extendedIncoming1 = myOutgoingEdges;
359  extendedOutgoing2 = c2->myIncomingEdges;
360  extendedIncoming2 = c2->myOutgoingEdges;
361  }
362 
363  if (VectorHelper<int>::subSetExists(extendedOutgoing1, extendedOutgoing2)
364  ||
365  VectorHelper<int>::subSetExists(extendedIncoming1, extendedIncoming2)
366  ) {
367  return true;
368  }
369  return false;
370 }
371 
372 
373 bool
375  if ((myIncomingEdges.size() == 1 && myOutgoingEdges.size() == 1)) {
376  return false;
377  }
378  if ((c2->myIncomingEdges.size() == 1 && c2->myOutgoingEdges.size() == 1)) {
379  return false;
380  }
381 
382  // ok, may be the other way round
383  if (myIncomingEdges.size() == 1 && c2->myOutgoingEdges.size() == 1) {
384  return c2->isWeakDistrictConnRealisation(this);
385  }
386  // connections must cross
387  bool crosses = false;
388  for (std::vector<int>::const_iterator j1 = myConnections.begin(); j1 != myConnections.end() && !crosses; j1++) {
389  const PositionVector& g1 = NIVissimConnection::dictionary(*j1)->getGeometry();
390  for (const int j2 : c2->myConnections) {
391  const PositionVector& g2 = NIVissimConnection::dictionary(j2)->getGeometry();
392  if (g1.intersects(g2)) {
393  crosses = true;
394  break;
395  }
396  }
397  }
398  if (!crosses) {
399  return false;
400  }
401  // ok, check for connection
402  if (myOutgoingEdges.size() != 1 || c2->myIncomingEdges.size() != 1) {
403  return false;
404  }
405  // check whether the connection is bidirectional
408  if (oe == nullptr || ie == nullptr) {
409  return false;
410  }
412 }
413 
414 
415 bool
417  //
418  for (std::vector<int>::iterator i = myConnections.begin(); i != myConnections.end(); i++) {
420  for (std::vector<int>::iterator j = cc2->myConnections.begin(); j != cc2->myConnections.end(); j++) {
422  if (c1->getFromEdgeID() == c2->getFromEdgeID()) {
424  const PositionVector& g = e->getGeometry();
426  g.front(), g.back(), c1->getBoundary().getCenter());
428  g.front(), g.back(), c2->getBoundary().getCenter());
429  if (pos1 <= 5.0 && pos2 <= 5.0) {
430  return true;
431  }
432  }
433  if (c1->getToEdgeID() == c2->getToEdgeID()) {
435  const PositionVector& g = e->getGeometry();
437  g.front(), g.back(), c1->getBoundary().getCenter());
439  g.front(), g.back(), c2->getBoundary().getCenter());
440  if (pos1 >= g.length() - 5.0 && pos2 >= g.length() - 5.0) {
441  return true;
442  }
443  }
444  }
445  }
446  return false;
447 }
448 
449 
450 std::vector<int>
452  const std::vector<int>& iv2) const {
453  std::vector<int> ret(iv1);
454  for (std::vector<int>::const_iterator i = iv1.begin(); i != iv1.end(); i++) {
456  const std::vector<NIVissimEdge*> treatAsSame = e->getToTreatAsSame();
457  for (std::vector<NIVissimEdge*>::const_iterator j = treatAsSame.begin(); j != treatAsSame.end(); j++) {
458  if (find(iv2.begin(), iv2.end(), (*j)->getID()) == iv2.end()) {
459  ret.push_back((*j)->getID());
460  }
461  }
462  }
463  return ret;
464 }
465 
466 std::vector<int>
468  std::vector<int> ret;
469  for (std::vector<int>::iterator i = myConnections.begin(); i != myConnections.end(); i++) {
471  const std::vector<int>& disturbances = c->getDisturbances();
472  for (std::vector<int>::const_iterator j = disturbances.begin(); j != disturbances.end(); j++) {
474  ret.push_back(d->getEdgeID());
475  ret.push_back(d->getDisturbanceID());
476  }
477  }
478  return ret;
479 }
480 
481 
482 void
484  for (ContType::iterator i = myClusters.begin(); i != myClusters.end(); i++) {
485  std::vector<int> disturbances;
486  std::vector<int> tls;
487  std::vector<int> nodes;
488  int tlsid = -1;
489  int nodeid = -1;
490  if ((*i)->myConnections.size() > 0) {
491  (*i)->recomputeBoundary();
492  disturbances = NIVissimDisturbance::getWithin((*i)->myBoundary);
493  }
494  nodes = (*i)->myNodes;//NIVissimTL::getWithin((*i)->myBoundary, 5.0);
495  if (nodes.size() > 1) {
496  WRITE_WARNING("NIVissimConnectionCluster:More than a single node");
497  // throw 1; // !!! eigentlich sollte hier nur eine Ampelanlage sein
498  }
499  if (nodes.size() > 0) {
500  nodeid = nodes[0];
501  }
502  //
503  //
505  nodeid, tlsid, (*i)->myConnections,
506  disturbances, (*i)->myIncomingEdges.size() < 2);
507  assert((*i)->myNodeCluster == id || (*i)->myNodeCluster < 0);
508  (*i)->myNodeCluster = id;
509  }
510 }
511 
512 
513 void
515  for (ContType::iterator i = myClusters.begin(); i != myClusters.end(); i++) {
516  std::vector<int> connections = (*i)->myConnections;
517  for (std::vector<int>::iterator j = connections.begin(); j != connections.end(); j++) {
518  if (j != connections.begin()) {
519  into << ", ";
520  }
521  into << *j;
522  }
523  into << "(" << (*i)->myBoundary << ")" << std::endl;
524  }
525  into << "---------------------------" << std::endl;
526 }
527 
528 
529 
530 bool
532  return myNodeCluster != -1;
533 }
534 
535 
536 int
538  return (int)myClusters.size();
539 }
540 
541 
542 void
544  for (NodeSubCluster::ConnectionCont::const_iterator i = c.myConnections.begin(); i != c.myConnections.end(); i++) {
545  NIVissimConnection* conn = *i;
546  int connid = conn->getID();
547  std::vector<int>::iterator j = std::find(myConnections.begin(), myConnections.end(), connid);
548  if (j != myConnections.end()) {
549  myConnections.erase(j);
550  }
551  }
553 }
554 
555 
556 void
558  myBoundary = Boundary();
559  for (std::vector<int>::iterator i = myConnections.begin(); i != myConnections.end(); i++) {
561  if (c != nullptr) {
564  if (c->getGeometry().size() != 0) {
566  }
567  }
568  }
569  assert(myBoundary.xmax() >= myBoundary.xmin());
570 }
571 
572 
573 NBNode*
575  return NIVissimNodeCluster::dictionary(myNodeCluster)->getNBNode();
576 }
577 
578 
579 bool
580 NIVissimConnectionCluster::around(const Position& p, double offset) const {
581  assert(myBoundary.xmax() >= myBoundary.xmin());
582  return myBoundary.around(p, offset);
583 }
584 
585 
586 
587 void
589  assert(myConnections.size() != 0);
590  // remove the cluster from all edges at first
591  std::vector<int>::iterator i;
592  for (i = myEdges.begin(); i != myEdges.end(); i++) {
594  edge->removeFromConnectionCluster(this);
595  }
596  // clear edge information
597  myEdges.clear();
598  // recheck which edges do still participate and add edges
599  for (i = myConnections.begin(); i != myConnections.end(); i++) {
601  assert(myBoundary.xmax() >= myBoundary.xmin());
602  if (myBoundary.around(c->getFromGeomPosition(), 5)) {
603  myEdges.push_back(c->getFromEdgeID());
604  }
605  assert(myBoundary.xmax() >= myBoundary.xmin());
606  if (myBoundary.around(c->getToGeomPosition(), 5)) {
607  myEdges.push_back(c->getToEdgeID());
608  }
609  }
610  // connect edges
611  for (i = myEdges.begin(); i != myEdges.end(); i++) {
613  edge->addToConnectionCluster(this);
614  }
615 }
616 
617 
618 double
620  // return the middle of the connections when there are any
621  if (myConnections.size() != 0) {
622  double sum = 0;
623  int part = 0;
624  std::vector<int>::const_iterator i;
625  for (i = myConnections.begin(); i != myConnections.end(); i++) {
627  if (c->getFromEdgeID() == edgeid) {
628  part++;
629  sum += c->getFromPosition();
630  }
631  if (c->getToEdgeID() == edgeid) {
632  part++;
633  sum += c->getToPosition();
634  }
635  }
636  if (part > 0) {
637  return sum / (double) part;
638  }
639  }
640  // use the position of the node if possible
641  if (myNodeCluster >= 0) {
642  // try to find the nearest point on the edge
643  // !!! only the main geometry is regarded
644  NIVissimNodeDef* node =
646  if (node != nullptr) {
647  double pos = node->getEdgePosition(edgeid);
648  if (pos >= 0) {
649  return pos;
650  }
651  }
652  /*
653  double try1 = GeomHelper::nearest_offset_on_line_to_point(
654  edge->getBegin2D(), edge->getEnd2D(), node->getPos());
655  if(try1>=0) {
656  return try1;
657  }
658  // try to use simple distance
659  double dist1 =
660  GeomHelper::distance(node->getPos(), edge->getBegin2D());
661  double dist2 =
662  GeomHelper::distance(node->getPos(), edge->getEnd2D());
663  return dist1<dist2
664  ? 0 : edge->getLength();
665  */
666  }
667  // what else?
668  WRITE_WARNING("NIVissimConnectionCluster: how to get an edge's position?");
669  // !!!
670  assert(myBoundary.xmin() <= myBoundary.xmax());
671  NIVissimEdge* edge = NIVissimEdge::dictionary(edgeid);
672  std::vector<int>::const_iterator i = std::find(myEdges.begin(), myEdges.end(), edgeid);
673  if (i == myEdges.end()) {
674  // edge does not exist!?
675  throw 1;
676  }
677  const PositionVector& edgeGeom = edge->getGeometry();
680  edgeGeom.front(), edgeGeom.back(), p);
681 }
682 
683 
684 
685 void
687  for (ContType::iterator i = myClusters.begin(); i != myClusters.end(); i++) {
688  delete (*i);
689  }
690  myClusters.clear();
691  myFirstFreeID = 100000;
692 }
693 
694 
697  // collect connection where this edge is the incoming one
698  std::vector<NIVissimConnection*> edgeIsIncoming;
699  for (std::vector<int>::const_iterator i = myConnections.begin(); i != myConnections.end(); i++) {
701  if (c->getFromEdgeID() == e->getID()) {
702  edgeIsIncoming.push_back(c);
703  }
704  }
705  //
706  if (edgeIsIncoming.size() == 0) {
707  return PositionVector();
708  }
709  // sort connected edges in same direction
710  sort(edgeIsIncoming.begin(), edgeIsIncoming.end(),
712  NIVissimConnection* c = *(edgeIsIncoming.begin());
713  return c->getGeometry();
714 }
715 
716 
717 
720  // collect connection where this edge is the incoming one
721  std::vector<NIVissimConnection*> edgeIsIncoming;
722  for (std::vector<int>::const_iterator i = myConnections.begin(); i != myConnections.end(); i++) {
724  if (c->getFromEdgeID() == e->getID()) {
725  edgeIsIncoming.push_back(c);
726  }
727  }
728  //
729  if (edgeIsIncoming.size() == 0) {
730  return nullptr;
731  }
732  // sort connected edges in same direction
733  sort(edgeIsIncoming.begin(), edgeIsIncoming.end(),
735  return *(edgeIsIncoming.begin());
736 }
737 
738 
739 
742  // collect connection where this edge is the outgoing one
743  std::vector<NIVissimConnection*> edgeIsOutgoing;
744  for (std::vector<int>::const_iterator i = myConnections.begin(); i != myConnections.end(); i++) {
746  if (c->getToEdgeID() == e->getID()) {
747  edgeIsOutgoing.push_back(c);
748  }
749  }
750  //
751  if (edgeIsOutgoing.size() == 0) {
752  return PositionVector();
753  }
754  // sort connected edges in same direction
755  sort(edgeIsOutgoing.begin(), edgeIsOutgoing.end(),
757  NIVissimConnection* c = *(edgeIsOutgoing.begin());
758  return c->getGeometry();
759 }
760 
761 
764  // collect connection where this edge is the outgoing one
765  std::vector<NIVissimConnection*> edgeIsOutgoing;
766  for (std::vector<int>::const_iterator i = myConnections.begin(); i != myConnections.end(); i++) {
768  if (c->getToEdgeID() == e->getID()) {
769  edgeIsOutgoing.push_back(c);
770  }
771  }
772  //
773  if (edgeIsOutgoing.size() == 0) {
774  return nullptr;
775  }
776  // sort connected edges in same direction
777  sort(edgeIsOutgoing.begin(), edgeIsOutgoing.end(),
779  return *(edgeIsOutgoing.begin());
780 }
781 
782 
783 /****************************************************************************/
#define DEG2RAD(x)
Definition: GeomHelper.h:35
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:280
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:39
Position getCenter() const
Returns the center of the boundary.
Definition: Boundary.cpp:111
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:77
double xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:117
bool overlapsWith(const AbstractPoly &poly, double offset=0) const
Returns whether the boundary overlaps with the given polygon.
Definition: Boundary.cpp:180
bool around(const Position &p, double offset=0) const
Returns whether the AbstractPoly the given coordinate.
Definition: Boundary.cpp:171
double xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:123
static Position crossPoint(const Boundary &b, const PositionVector &v)
Definition: GeomHelper.cpp:128
static double nearest_offset_on_line_to_point2D(const Position &lineStart, const Position &lineEnd, const Position &p, bool perpendicular=true)
Definition: GeomHelper.cpp:88
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:179
Represents a single node (junction) during network building.
Definition: NBNode.h:66
const PositionVector & getGeometry() const
const std::vector< int > & getDisturbances() const
bool overlapsWith(const NodeSubCluster &c, double offset=0)
bool around(const Position &p, double offset=0) const
NIVissimConnection * getIncomingContinuation(NIVissimEdge *e) const
bool liesOnSameEdgesEnd(NIVissimConnectionCluster *cc2)
Boundary myBoundary
The boundary of the cluster.
PositionVector getOutgoingContinuationGeometry(NIVissimEdge *e) const
std::vector< int > myConnections
List of connection-ids which participate within this cluster.
void removeConnections(const NodeSubCluster &c)
std::vector< int > extendByToTreatAsSame(const std::vector< int > &iv1, const std::vector< int > &iv2) const
bool isWeakDistrictConnRealisation(NIVissimConnectionCluster *c2)
static void joinBySameEdges(double offset)
Tries to joind clusters participating within a node This is done by joining clusters which overlap.
std::vector< int > getDisturbanceParticipators()
bool joinable(NIVissimConnectionCluster *c2, double offset)
static void _debugOut(std::ostream &into)
bool overlapsWith(NIVissimConnectionCluster *c, double offset=0) const
Returns the information whether the given cluster overlaps the current.
std::vector< NIVissimConnectionCluster * > ContType
NIVissimConnection * getOutgoingContinuation(NIVissimEdge *e) const
PositionVector getIncomingContinuationGeometry(NIVissimEdge *e) const
int myNodeCluster
The node the cluster is assigned to.
NIVissimConnectionCluster(const std::vector< int > &connections, int nodeCluster, int edgeid)
Constructor Build the boundary; The boundary includes both incoming and outgoing nodes.
double getPositionForEdge(int edgeid) const
void add(NIVissimConnectionCluster *c)
Adds the second cluster.
double getFromPosition() const
const Boundary & getBoundingBox() const
static bool dictionary(int id, NIVissimConnection *o)
Position getToGeomPosition() const
double getToPosition() const
Position getFromGeomPosition() const
static bool dictionary(const std::string &name, const NIVissimExtendedEdgePoint &edge, const NIVissimExtendedEdgePoint &by)
static std::vector< int > getWithin(const AbstractPoly &poly)
A temporary storage for edges imported from Vissim.
Definition: NIVissimEdge.h:51
const std::vector< NIVissimEdge * > & getToTreatAsSame() const
void addToConnectionCluster(NIVissimConnectionCluster *c)
void removeFromConnectionCluster(NIVissimConnectionCluster *c)
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.
static bool dictionary(int id, NIVissimNodeCluster *o)
static bool dictionary(int id, NIVissimNodeDef *o)
virtual double getEdgePosition(int edgeid) const =0
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
A list of positions.
double beginEndAngle() const
returns the angle in radians of the line connecting the first and the last position
double length() const
Returns the length.
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
bool intersects(const Position &p1, const Position &p2) const
Returns the information whether this list of points interesects the given line.
static void removeDouble(std::vector< T > &v)
Definition: VectorHelper.h:66