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.dev/sumo
3 // Copyright (C) 2001-2024 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(TL("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 void
538  for (NodeSubCluster::ConnectionCont::const_iterator i = c.myConnections.begin(); i != c.myConnections.end(); i++) {
539  NIVissimConnection* conn = *i;
540  int connid = conn->getID();
541  std::vector<int>::iterator j = std::find(myConnections.begin(), myConnections.end(), connid);
542  if (j != myConnections.end()) {
543  myConnections.erase(j);
544  }
545  }
547 }
548 
549 
550 void
552  myBoundary = Boundary();
553  for (std::vector<int>::iterator i = myConnections.begin(); i != myConnections.end(); i++) {
555  if (c != nullptr) {
558  if (c->getGeometry().size() != 0) {
560  }
561  }
562  }
563  assert(myBoundary.xmax() >= myBoundary.xmin());
564 }
565 
566 
567 NBNode*
569  return NIVissimNodeCluster::dictionary(myNodeCluster)->getNBNode();
570 }
571 
572 
573 bool
574 NIVissimConnectionCluster::around(const Position& p, double offset) const {
575  assert(myBoundary.xmax() >= myBoundary.xmin());
576  return myBoundary.around(p, offset);
577 }
578 
579 
580 
581 void
583  assert(myConnections.size() != 0);
584  // remove the cluster from all edges at first
585  std::vector<int>::iterator i;
586  for (i = myEdges.begin(); i != myEdges.end(); i++) {
588  edge->removeFromConnectionCluster(this);
589  }
590  // clear edge information
591  myEdges.clear();
592  // recheck which edges do still participate and add edges
593  for (i = myConnections.begin(); i != myConnections.end(); i++) {
595  assert(myBoundary.xmax() >= myBoundary.xmin());
596  if (myBoundary.around(c->getFromGeomPosition(), 5)) {
597  myEdges.push_back(c->getFromEdgeID());
598  }
599  assert(myBoundary.xmax() >= myBoundary.xmin());
600  if (myBoundary.around(c->getToGeomPosition(), 5)) {
601  myEdges.push_back(c->getToEdgeID());
602  }
603  }
604  // connect edges
605  for (i = myEdges.begin(); i != myEdges.end(); i++) {
607  edge->addToConnectionCluster(this);
608  }
609 }
610 
611 
612 double
614  // return the middle of the connections when there are any
615  if (myConnections.size() != 0) {
616  double sum = 0;
617  int part = 0;
618  std::vector<int>::const_iterator i;
619  for (i = myConnections.begin(); i != myConnections.end(); i++) {
621  if (c->getFromEdgeID() == edgeid) {
622  part++;
623  sum += c->getFromPosition();
624  }
625  if (c->getToEdgeID() == edgeid) {
626  part++;
627  sum += c->getToPosition();
628  }
629  }
630  if (part > 0) {
631  return sum / (double) part;
632  }
633  }
634  // use the position of the node if possible
635  if (myNodeCluster >= 0) {
636  // try to find the nearest point on the edge
637  // !!! only the main geometry is regarded
638  NIVissimNodeDef* node =
640  if (node != nullptr) {
641  double pos = node->getEdgePosition(edgeid);
642  if (pos >= 0) {
643  return pos;
644  }
645  }
646  /*
647  double try1 = GeomHelper::nearest_offset_on_line_to_point(
648  edge->getBegin2D(), edge->getEnd2D(), node->getPos());
649  if(try1>=0) {
650  return try1;
651  }
652  // try to use simple distance
653  double dist1 =
654  GeomHelper::distance(node->getPos(), edge->getBegin2D());
655  double dist2 =
656  GeomHelper::distance(node->getPos(), edge->getEnd2D());
657  return dist1<dist2
658  ? 0 : edge->getLength();
659  */
660  }
661  // what else?
662  WRITE_WARNING(TL("NIVissimConnectionCluster: how to get an edge's position?"));
663  // !!!
664  assert(myBoundary.xmin() <= myBoundary.xmax());
665  NIVissimEdge* edge = NIVissimEdge::dictionary(edgeid);
666  std::vector<int>::const_iterator i = std::find(myEdges.begin(), myEdges.end(), edgeid);
667  if (i == myEdges.end()) {
668  // edge does not exist!?
669  throw 1;
670  }
671  const PositionVector& edgeGeom = edge->getGeometry();
674  edgeGeom.front(), edgeGeom.back(), p);
675 }
676 
677 
678 
679 void
681  for (ContType::iterator i = myClusters.begin(); i != myClusters.end(); i++) {
682  delete (*i);
683  }
684  myClusters.clear();
685  myFirstFreeID = 100000;
686 }
687 
688 
691  // collect connection where this edge is the incoming one
692  std::vector<NIVissimConnection*> edgeIsIncoming;
693  for (std::vector<int>::const_iterator i = myConnections.begin(); i != myConnections.end(); i++) {
695  if (c->getFromEdgeID() == e->getID()) {
696  edgeIsIncoming.push_back(c);
697  }
698  }
699  //
700  if (edgeIsIncoming.size() == 0) {
701  return PositionVector();
702  }
703  // sort connected edges in same direction
704  sort(edgeIsIncoming.begin(), edgeIsIncoming.end(),
706  NIVissimConnection* c = *(edgeIsIncoming.begin());
707  return c->getGeometry();
708 }
709 
710 
711 
714  // collect connection where this edge is the incoming one
715  std::vector<NIVissimConnection*> edgeIsIncoming;
716  for (std::vector<int>::const_iterator i = myConnections.begin(); i != myConnections.end(); i++) {
718  if (c->getFromEdgeID() == e->getID()) {
719  edgeIsIncoming.push_back(c);
720  }
721  }
722  //
723  if (edgeIsIncoming.size() == 0) {
724  return nullptr;
725  }
726  // sort connected edges in same direction
727  sort(edgeIsIncoming.begin(), edgeIsIncoming.end(),
729  return *(edgeIsIncoming.begin());
730 }
731 
732 
733 
736  // collect connection where this edge is the outgoing one
737  std::vector<NIVissimConnection*> edgeIsOutgoing;
738  for (std::vector<int>::const_iterator i = myConnections.begin(); i != myConnections.end(); i++) {
740  if (c->getToEdgeID() == e->getID()) {
741  edgeIsOutgoing.push_back(c);
742  }
743  }
744  //
745  if (edgeIsOutgoing.size() == 0) {
746  return PositionVector();
747  }
748  // sort connected edges in same direction
749  sort(edgeIsOutgoing.begin(), edgeIsOutgoing.end(),
751  NIVissimConnection* c = *(edgeIsOutgoing.begin());
752  return c->getGeometry();
753 }
754 
755 
758  // collect connection where this edge is the outgoing one
759  std::vector<NIVissimConnection*> edgeIsOutgoing;
760  for (std::vector<int>::const_iterator i = myConnections.begin(); i != myConnections.end(); i++) {
762  if (c->getToEdgeID() == e->getID()) {
763  edgeIsOutgoing.push_back(c);
764  }
765  }
766  //
767  if (edgeIsOutgoing.size() == 0) {
768  return nullptr;
769  }
770  // sort connected edges in same direction
771  sort(edgeIsOutgoing.begin(), edgeIsOutgoing.end(),
773  return *(edgeIsOutgoing.begin());
774 }
775 
776 
777 /****************************************************************************/
#define DEG2RAD(x)
Definition: GeomHelper.h:35
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:295
#define TL(string)
Definition: MsgHandler.h:315
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:39
Position getCenter() const
Returns the center of the boundary.
Definition: Boundary.cpp:112
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:78
double xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:118
bool overlapsWith(const AbstractPoly &poly, double offset=0) const
Returns whether the boundary overlaps with the given polygon.
Definition: Boundary.cpp:189
bool around(const Position &p, double offset=0) const
Returns whether the boundary contains the given coordinate.
Definition: Boundary.cpp:172
double xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:124
static Position crossPoint(const Boundary &b, const PositionVector &v)
Definition: GeomHelper.cpp:127
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:178
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