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-2018 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
17 // -------------------
18 /****************************************************************************/
19 
20 
21 // ===========================================================================
22 // included modules
23 // ===========================================================================
24 #include <config.h>
25 
26 #include <algorithm>
27 #include <iostream>
28 #include <cassert>
29 #include <iterator>
30 #include <utils/geom/Boundary.h>
31 #include <utils/geom/GeomHelper.h>
34 #include <utils/common/ToString.h>
35 #include "NIVissimConnection.h"
36 #include "NIVissimDisturbance.h"
37 #include "NIVissimNodeCluster.h"
38 #include "NIVissimNodeDef.h"
39 #include "NIVissimEdge.h"
40 #include "NIVissimTL.h"
42 
43 
44 // ===========================================================================
45 // static members
46 // ===========================================================================
50 
51 
52 
53 // ===========================================================================
54 // method definitions
55 // ===========================================================================
56 // ---------------------------------------------------------------------------
57 // NIVissimConnectionCluster::NodeSubCluster - methods
58 // ---------------------------------------------------------------------------
60  add(c);
61 }
62 
63 
65 
66 
67 void
70  myConnections.push_back(c);
71 }
72 
73 
74 void
76  for (ConnectionCont::const_iterator i = c.myConnections.begin(); i != c.myConnections.end(); i++) {
77  add(*i);
78  }
79 }
80 
81 
82 int
84  return (int)myConnections.size();
85 }
86 
87 
88 std::vector<int>
90  std::vector<int> ret;
92  for (ConnectionCont::const_iterator i = myConnections.begin(); i != myConnections.end(); i++) {
93  ret.push_back((*i)->getID());
94  (*i)->setNodeCluster(id);
95  }
96  return ret;
97 }
98 
99 
100 bool
103  double offset) {
104  assert(myBoundary.xmax() >= myBoundary.xmin());
105  assert(c.myBoundary.xmax() >= c.myBoundary.xmin());
106  return myBoundary.overlapsWith(c.myBoundary, offset);
107 }
108 
109 
110 
111 // ---------------------------------------------------------------------------
112 // NIVissimConnectionCluster - methods
113 // ---------------------------------------------------------------------------
115  const std::vector<int>& connections, int nodeCluster, int edgeid)
116  : myConnections(connections), myNodeCluster(nodeCluster),
119  myClusters.push_back(this);
120  assert(edgeid > 0);
121  if (edgeid >= 0) {
122  myEdges.push_back(edgeid);
123  }
124  // add information about incoming and outgoing edges
125  for (std::vector<int>::const_iterator i = connections.begin(); i != connections.end(); i++) {
127  assert(c != 0);
128  myOutgoingEdges.push_back(c->getToEdgeID());
129  myIncomingEdges.push_back(c->getFromEdgeID());
130  assert(c->getFromEdgeID() == edgeid || c->getToEdgeID() == edgeid);
131  }
134 }
135 
136 
138  const std::vector<int>& connections, const Boundary& boundary,
139  int nodeCluster, const std::vector<int>& edges)
140  : myConnections(connections), myBoundary(boundary),
141  myNodeCluster(nodeCluster), myEdges(edges) {
142  myClusters.push_back(this);
144  assert(myBoundary.xmax() >= myBoundary.xmin());
145  // add information about incoming and outgoing edges
146  for (std::vector<int>::const_iterator i = connections.begin(); i != connections.end(); i++) {
148  assert(c != 0);
149  myOutgoingEdges.push_back(c->getToEdgeID());
150  myIncomingEdges.push_back(c->getFromEdgeID());
151  assert(find(edges.begin(), edges.end(), c->getFromEdgeID()) != edges.end()
152  ||
153  find(edges.begin(), edges.end(), c->getToEdgeID()) != edges.end());
154  }
157 }
158 
159 
161 
162 
163 
164 int
166  return myFirstFreeID++;
167 }
168 
169 
170 bool
172  double offset) const {
173  assert(myBoundary.xmax() >= myBoundary.xmin());
174  assert(c->myBoundary.xmax() >= c->myBoundary.xmin());
175  return c->myBoundary.overlapsWith(myBoundary, offset);
176 }
177 
178 
179 void
181  assert(myBoundary.xmax() >= myBoundary.xmin());
182  assert(c->myBoundary.xmax() >= c->myBoundary.xmin());
184  for (std::vector<int>::iterator i = c->myConnections.begin(); i != c->myConnections.end(); i++) {
185  myConnections.push_back(*i);
186  }
188  assert(myNodeCluster == -1 || c->myNodeCluster == -1);
189  if (myNodeCluster == -1) {
191  }
192  // inform edges about merging
193  // !!! merge should be done within one method
194  for (std::vector<int>::iterator j = c->myEdges.begin(); j != c->myEdges.end(); j++) {
195  NIVissimEdge::dictionary(*j)->mergedInto(c, this);
196  }
197  copy(c->myEdges.begin(), c->myEdges.end(), back_inserter(myEdges));
198  copy(c->myIncomingEdges.begin(), c->myIncomingEdges.end(),
199  back_inserter(myIncomingEdges));
200  copy(c->myOutgoingEdges.begin(), c->myOutgoingEdges.end(),
201  back_inserter(myOutgoingEdges));
205 }
206 
207 
208 
209 void
211  // !!! ...
212  // Further, we try to omit joining of overlaping nodes. This is done by holding
213  // the lists of incoming and outgoing edges and incrementally building the nodes
214  // regarding this information
215  std::vector<NIVissimConnectionCluster*> joinAble;
216  int pos = 0;
217  ContType::iterator i = myClusters.begin();
218  // step1 - faster but no complete
219  while (i != myClusters.end()) {
220  joinAble.clear();
221  ContType::iterator j = i + 1;
222 
223  // check whether every combination has been processed
224  while (j != myClusters.end()) {
225  // check whether the current clusters overlap
226  if ((*i)->joinable(*j, offset)) {
227  joinAble.push_back(*j);
228  }
229  j++;
230  }
231  for (std::vector<NIVissimConnectionCluster*>::iterator k = joinAble.begin();
232  k != joinAble.end(); k++) {
233  // add the overlaping cluster
234  (*i)->add(*k);
235  // erase the overlaping cluster
236  delete *k;
237  myClusters.erase(find(myClusters.begin(), myClusters.end(), *k));
238  }
239  //
240  if (joinAble.size() > 0) {
241  i = myClusters.begin() + pos;
242  // clear temporary storages
243  joinAble.clear();
244  } else {
245  i++;
246  pos++;
247  }
248  }
249  //
250  pos = 0;
251  i = myClusters.begin();
252  while (i != myClusters.end()) {
253  ContType::iterator j = i + 1;
254  // check whether every combination has been processed
255  while (j != myClusters.end()) {
256  // check whether the current clusters overlap
257  if ((*i)->joinable(*j, offset)) {
258  joinAble.push_back(*j);
259  }
260  j++;
261  }
262  for (std::vector<NIVissimConnectionCluster*>::iterator k = joinAble.begin();
263  k != joinAble.end(); k++) {
264  // add the overlaping cluster
265  (*i)->add(*k);
266  // erase the overlaping cluster
267  delete *k;
268  myClusters.erase(find(myClusters.begin(), myClusters.end(), *k));
269  }
270  //
271  if (joinAble.size() > 0) {
272  i = myClusters.begin();
273  // clear temporary storages
274  joinAble.clear();
275  pos = 0;
276  } else {
277  i++;
278  pos++;
279  }
280  }
281  // check for weak district connections
282  // (junctions made up by district connections, where prohibitions are not
283  // modelled properly)
284  pos = 0;
285  i = myClusters.begin();
286  while (i != myClusters.end()) {
287  ContType::iterator j = i + 1;
288  // check whether every combination has been processed
289  while (j != myClusters.end()) {
290  // check whether the current clusters overlap
291  if ((*i)->isWeakDistrictConnRealisation(*j)) {
292  joinAble.push_back(*j);
293  }
294  j++;
295  }
296  for (std::vector<NIVissimConnectionCluster*>::iterator k = joinAble.begin();
297  k != joinAble.end(); k++) {
298  // add the overlaping cluster
299  (*i)->add(*k);
300  // erase the overlaping cluster
301  delete *k;
302  myClusters.erase(find(myClusters.begin(), myClusters.end(), *k));
303  }
304  //
305  if (joinAble.size() > 0) {
306  i = myClusters.begin();
307  // clear temporary storages
308  joinAble.clear();
309  pos = 0;
310  } else {
311  i++;
312  pos++;
313  }
314  }
315 }
316 
317 
318 bool
320  // join clusters which have at least one connection in common
322  return true;
323  }
324 
325  // connections shall overlap otherwise
326  if (!overlapsWith(c2, offset)) {
327  return false;
328  }
329 
330  // at least one of the clusters shall not be assigned to a node in previous (!!!??)
331  if (hasNodeCluster() && c2->hasNodeCluster()) {
332  return false;
333  }
334 
335  // join clusters which where connections do disturb each other
337  ||
339 
340  return true;
341  }
342 
343 
344  // join clusters which do share the same incoming or outgoing edges (not mutually)
345  std::vector<int> extendedOutgoing1;
346  std::vector<int> extendedIncoming1;
347  std::vector<int> extendedOutgoing2;
348  std::vector<int> extendedIncoming2;
349  if (myIncomingEdges.size() > 1 || c2->myIncomingEdges.size() > 1) {
350  extendedOutgoing1 =
352  extendedIncoming1 =
354  extendedOutgoing2 =
356  extendedIncoming2 =
358  } else {
359  extendedOutgoing1 = myIncomingEdges;
360  extendedIncoming1 = myOutgoingEdges;
361  extendedOutgoing2 = c2->myIncomingEdges;
362  extendedIncoming2 = c2->myOutgoingEdges;
363  }
364 
365  if (VectorHelper<int>::subSetExists(extendedOutgoing1, extendedOutgoing2)
366  ||
367  VectorHelper<int>::subSetExists(extendedIncoming1, extendedIncoming2)
368  ) {
369  return true;
370  }
371  return false;
372 }
373 
374 
375 bool
377  if ((myIncomingEdges.size() == 1 && myOutgoingEdges.size() == 1)) {
378  return false;
379  }
380  if ((c2->myIncomingEdges.size() == 1 && c2->myOutgoingEdges.size() == 1)) {
381  return false;
382  }
383 
384  // ok, may be the other way round
385  if (myIncomingEdges.size() == 1 && c2->myOutgoingEdges.size() == 1) {
386  return c2->isWeakDistrictConnRealisation(this);
387  }
388  // connections must cross
389  bool crosses = false;
390  for (std::vector<int>::const_iterator j1 = myConnections.begin(); j1 != myConnections.end() && !crosses; j1++) {
392  const PositionVector& g1 = c1->getGeometry();
393  for (std::vector<int>::const_iterator j2 = c2->myConnections.begin(); j2 != c2->myConnections.end() && !crosses; j2++) {
395  const PositionVector& g2 = c2->getGeometry();
396  if (g1.intersects(g2)) {
397  crosses = true;
398  }
399  }
400  }
401  if (!crosses) {
402  return false;
403  }
404  // ok, check for connection
405  if (myOutgoingEdges.size() != 1 || c2->myIncomingEdges.size() != 1) {
406  return false;
407  }
408  // check whether the connection is bidirectional
411  if (oe == nullptr || ie == nullptr) {
412  return false;
413  }
415 }
416 
417 
418 bool
420  //
421  for (std::vector<int>::iterator i = myConnections.begin(); i != myConnections.end(); i++) {
423  for (std::vector<int>::iterator j = cc2->myConnections.begin(); j != cc2->myConnections.end(); j++) {
425  if (c1->getFromEdgeID() == c2->getFromEdgeID()) {
427  const PositionVector& g = e->getGeometry();
429  g.front(), g.back(), c1->getBoundary().getCenter());
431  g.front(), g.back(), c2->getBoundary().getCenter());
432  if (pos1 <= 5.0 && pos2 <= 5.0) {
433  return true;
434  }
435  }
436  if (c1->getToEdgeID() == c2->getToEdgeID()) {
438  const PositionVector& g = e->getGeometry();
440  g.front(), g.back(), c1->getBoundary().getCenter());
442  g.front(), g.back(), c2->getBoundary().getCenter());
443  if (pos1 >= g.length() - 5.0 && pos2 >= g.length() - 5.0) {
444  return true;
445  }
446  }
447  }
448  }
449  return false;
450 }
451 
452 
453 std::vector<int>
455  const std::vector<int>& iv2) const {
456  std::vector<int> ret(iv1);
457  for (std::vector<int>::const_iterator i = iv1.begin(); i != iv1.end(); i++) {
459  const std::vector<NIVissimEdge*> treatAsSame = e->getToTreatAsSame();
460  for (std::vector<NIVissimEdge*>::const_iterator j = treatAsSame.begin(); j != treatAsSame.end(); j++) {
461  if (find(iv2.begin(), iv2.end(), (*j)->getID()) == iv2.end()) {
462  ret.push_back((*j)->getID());
463  }
464  }
465  }
466  return ret;
467 }
468 
469 std::vector<int>
471  std::vector<int> ret;
472  for (std::vector<int>::iterator i = myConnections.begin(); i != myConnections.end(); i++) {
474  const std::vector<int>& disturbances = c->getDisturbances();
475  for (std::vector<int>::const_iterator j = disturbances.begin(); j != disturbances.end(); j++) {
477  ret.push_back(d->getEdgeID());
478  ret.push_back(d->getDisturbanceID());
479  }
480  }
481  return ret;
482 }
483 
484 
485 void
487  for (ContType::iterator i = myClusters.begin(); i != myClusters.end(); i++) {
488  std::vector<int> disturbances;
489  std::vector<int> tls;
490  std::vector<int> nodes;
491  int tlsid = -1;
492  int nodeid = -1;
493  if ((*i)->myConnections.size() > 0) {
494  (*i)->recomputeBoundary();
495  disturbances = NIVissimDisturbance::getWithin((*i)->myBoundary);
496  }
497  nodes = (*i)->myNodes;//NIVissimTL::getWithin((*i)->myBoundary, 5.0);
498  if (nodes.size() > 1) {
499  WRITE_WARNING("NIVissimConnectionCluster:More than a single node");
500  // throw 1; // !!! eigentlich sollte hier nur eine Ampelanlage sein
501  }
502  if (nodes.size() > 0) {
503  nodeid = nodes[0];
504  }
505  //
506  //
508  nodeid, tlsid, (*i)->myConnections,
509  disturbances, (*i)->myIncomingEdges.size() < 2);
510  assert((*i)->myNodeCluster == id || (*i)->myNodeCluster < 0);
511  (*i)->myNodeCluster = id;
512  }
513 }
514 
515 
516 void
518  for (ContType::iterator i = myClusters.begin(); i != myClusters.end(); i++) {
519  std::vector<int> connections = (*i)->myConnections;
520  for (std::vector<int>::iterator j = connections.begin(); j != connections.end(); j++) {
521  if (j != connections.begin()) {
522  into << ", ";
523  }
524  into << *j;
525  }
526  into << "(" << (*i)->myBoundary << ")" << std::endl;
527  }
528  into << "---------------------------" << std::endl;
529 }
530 
531 
532 
533 bool
535  return myNodeCluster != -1;
536 }
537 
538 
539 int
541  return (int)myClusters.size();
542 }
543 
544 
545 void
547  for (NodeSubCluster::ConnectionCont::const_iterator i = c.myConnections.begin(); i != c.myConnections.end(); i++) {
548  NIVissimConnection* conn = *i;
549  int connid = conn->getID();
550  std::vector<int>::iterator j = find(myConnections.begin(), myConnections.end(), connid);
551  if (j != myConnections.end()) {
552  myConnections.erase(j);
553  }
554  }
556 }
557 
558 
559 void
561  myBoundary = Boundary();
562  for (std::vector<int>::iterator i = myConnections.begin(); i != myConnections.end(); i++) {
564  if (c != nullptr) {
567  if (c->getGeometry().size() != 0) {
569  }
570  }
571  }
572  assert(myBoundary.xmax() >= myBoundary.xmin());
573 }
574 
575 
576 NBNode*
578  return NIVissimNodeCluster::dictionary(myNodeCluster)->getNBNode();
579 }
580 
581 
582 bool
583 NIVissimConnectionCluster::around(const Position& p, double offset) const {
584  assert(myBoundary.xmax() >= myBoundary.xmin());
585  return myBoundary.around(p, offset);
586 }
587 
588 
589 
590 void
592  assert(myConnections.size() != 0);
593  // remove the cluster from all edges at first
594  std::vector<int>::iterator i;
595  for (i = myEdges.begin(); i != myEdges.end(); i++) {
597  edge->removeFromConnectionCluster(this);
598  }
599  // clear edge information
600  myEdges.clear();
601  // recheck which edges do still participate and add edges
602  for (i = myConnections.begin(); i != myConnections.end(); i++) {
604  assert(myBoundary.xmax() >= myBoundary.xmin());
605  if (myBoundary.around(c->getFromGeomPosition(), 5)) {
606  myEdges.push_back(c->getFromEdgeID());
607  }
608  assert(myBoundary.xmax() >= myBoundary.xmin());
609  if (myBoundary.around(c->getToGeomPosition(), 5)) {
610  myEdges.push_back(c->getToEdgeID());
611  }
612  }
613  // connect edges
614  for (i = myEdges.begin(); i != myEdges.end(); i++) {
616  edge->addToConnectionCluster(this);
617  }
618 }
619 
620 
621 double
623  // return the middle of the connections when there are any
624  if (myConnections.size() != 0) {
625  double sum = 0;
626  int part = 0;
627  std::vector<int>::const_iterator i;
628  for (i = myConnections.begin(); i != myConnections.end(); i++) {
630  if (c->getFromEdgeID() == edgeid) {
631  part++;
632  sum += c->getFromPosition();
633  }
634  if (c->getToEdgeID() == edgeid) {
635  part++;
636  sum += c->getToPosition();
637  }
638  }
639  if (part > 0) {
640  return sum / (double) part;
641  }
642  }
643  // use the position of the node if possible
644  if (myNodeCluster >= 0) {
645  // try to find the nearest point on the edge
646  // !!! only the main geometry is regarded
647  NIVissimNodeDef* node =
649  if (node != nullptr) {
650  double pos = node->getEdgePosition(edgeid);
651  if (pos >= 0) {
652  return pos;
653  }
654  }
655  /*
656  double try1 = GeomHelper::nearest_offset_on_line_to_point(
657  edge->getBegin2D(), edge->getEnd2D(), node->getPos());
658  if(try1>=0) {
659  return try1;
660  }
661  // try to use simple distance
662  double dist1 =
663  GeomHelper::distance(node->getPos(), edge->getBegin2D());
664  double dist2 =
665  GeomHelper::distance(node->getPos(), edge->getEnd2D());
666  return dist1<dist2
667  ? 0 : edge->getLength();
668  */
669  }
670  // what else?
671  WRITE_WARNING("NIVissimConnectionCluster: how to get an edge's position?");
672  // !!!
673  assert(myBoundary.xmin() <= myBoundary.xmax());
674  NIVissimEdge* edge = NIVissimEdge::dictionary(edgeid);
675  std::vector<int>::const_iterator i = find(myEdges.begin(), myEdges.end(), edgeid);
676  if (i == myEdges.end()) {
677  // edge does not exist!?
678  throw 1;
679  }
680  const PositionVector& edgeGeom = edge->getGeometry();
683  edgeGeom.front(), edgeGeom.back(), p);
684 }
685 
686 
687 
688 void
690  for (ContType::iterator i = myClusters.begin(); i != myClusters.end(); i++) {
691  delete(*i);
692  }
693  myClusters.clear();
694  myFirstFreeID = 100000;
695 }
696 
697 
700  // collect connection where this edge is the incoming one
701  std::vector<NIVissimConnection*> edgeIsIncoming;
702  for (std::vector<int>::const_iterator i = myConnections.begin(); i != myConnections.end(); i++) {
704  if (c->getFromEdgeID() == e->getID()) {
705  edgeIsIncoming.push_back(c);
706  }
707  }
708  //
709  if (edgeIsIncoming.size() == 0) {
710  return PositionVector();
711  }
712  // sort connected edges in same direction
713  sort(edgeIsIncoming.begin(), edgeIsIncoming.end(),
715  NIVissimConnection* c = *(edgeIsIncoming.begin());
716  return c->getGeometry();
717 }
718 
719 
720 
723  // collect connection where this edge is the incoming one
724  std::vector<NIVissimConnection*> edgeIsIncoming;
725  for (std::vector<int>::const_iterator i = myConnections.begin(); i != myConnections.end(); i++) {
727  if (c->getFromEdgeID() == e->getID()) {
728  edgeIsIncoming.push_back(c);
729  }
730  }
731  //
732  if (edgeIsIncoming.size() == 0) {
733  return nullptr;
734  }
735  // sort connected edges in same direction
736  sort(edgeIsIncoming.begin(), edgeIsIncoming.end(),
738  return *(edgeIsIncoming.begin());
739 }
740 
741 
742 
745  // collect connection where this edge is the outgoing one
746  std::vector<NIVissimConnection*> edgeIsOutgoing;
747  for (std::vector<int>::const_iterator i = myConnections.begin(); i != myConnections.end(); i++) {
749  if (c->getToEdgeID() == e->getID()) {
750  edgeIsOutgoing.push_back(c);
751  }
752  }
753  //
754  if (edgeIsOutgoing.size() == 0) {
755  return PositionVector();
756  }
757  // sort connected edges in same direction
758  sort(edgeIsOutgoing.begin(), edgeIsOutgoing.end(),
760  NIVissimConnection* c = *(edgeIsOutgoing.begin());
761  return c->getGeometry();
762 }
763 
764 
767  // collect connection where this edge is the outgoing one
768  std::vector<NIVissimConnection*> edgeIsOutgoing;
769  for (std::vector<int>::const_iterator i = myConnections.begin(); i != myConnections.end(); i++) {
771  if (c->getToEdgeID() == e->getID()) {
772  edgeIsOutgoing.push_back(c);
773  }
774  }
775  //
776  if (edgeIsOutgoing.size() == 0) {
777  return nullptr;
778  }
779  // sort connected edges in same direction
780  sort(edgeIsOutgoing.begin(), edgeIsOutgoing.end(),
782  return *(edgeIsOutgoing.begin());
783 }
784 
785 
786 
787 /****************************************************************************/
788 
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:125
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:182
static Position crossPoint(const Boundary &b, const PositionVector &v)
Definition: GeomHelper.cpp:116
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:42
std::vector< int > getDisturbanceParticipators()
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:241
double getPositionForEdge(int edgeid) const
A temporary storage for edges imported from Vissim.
Definition: NIVissimEdge.h:53
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:89
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:39
static void _debugOut(std::ostream &into)
A list of positions.
const Boundary & getBoundingBox() const
static void removeDouble(std::vector< T > &v)
Definition: VectorHelper.h:70
bool around(const Position &p, double offset=0) const
double xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:119
static bool dictionary(int id, NIVissimNodeDef *o)
#define DEG2RAD(x)
Definition: GeomHelper.h:38
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 AbstractPoly the given coordinate.
Definition: Boundary.cpp:173
Boundary myBoundary
The boundary of the cluster.
Represents a single node (junction) during network building.
Definition: NBNode.h:68
Position getCenter() const
Returns the center of the boundary.
Definition: Boundary.cpp:113
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:167
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:79
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