SUMO - Simulation of Urban MObility
NIVissimConnectionCluster.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // -------------------
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
12 // Copyright (C) 2001-2017 DLR (http://www.dlr.de/) and contributors
13 /****************************************************************************/
14 //
15 // This file is part of SUMO.
16 // SUMO is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
21 /****************************************************************************/
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #ifdef _MSC_VER
28 #include <windows_config.h>
29 #else
30 #include <config.h>
31 #endif
32 
33 #include <algorithm>
34 #include <iostream>
35 #include <cassert>
36 #include <iterator>
37 #include <utils/geom/Boundary.h>
38 #include <utils/geom/GeomHelper.h>
41 #include <utils/common/ToString.h>
42 #include "NIVissimConnection.h"
43 #include "NIVissimDisturbance.h"
44 #include "NIVissimNodeCluster.h"
45 #include "NIVissimNodeDef.h"
46 #include "NIVissimEdge.h"
47 #include "NIVissimTL.h"
49 
50 
51 // ===========================================================================
52 // static members
53 // ===========================================================================
57 
58 
59 
60 // ===========================================================================
61 // method definitions
62 // ===========================================================================
63 // ---------------------------------------------------------------------------
64 // NIVissimConnectionCluster::NodeSubCluster - methods
65 // ---------------------------------------------------------------------------
67  add(c);
68 }
69 
70 
72 
73 
74 void
77  myConnections.push_back(c);
78 }
79 
80 
81 void
83  for (ConnectionCont::const_iterator i = c.myConnections.begin(); i != c.myConnections.end(); i++) {
84  add(*i);
85  }
86 }
87 
88 
89 int
91  return (int)myConnections.size();
92 }
93 
94 
95 std::vector<int>
97  std::vector<int> ret;
99  for (ConnectionCont::const_iterator i = myConnections.begin(); i != myConnections.end(); i++) {
100  ret.push_back((*i)->getID());
101  (*i)->setNodeCluster(id);
102  }
103  return ret;
104 }
105 
106 
107 bool
110  double offset) {
111  assert(myBoundary.xmax() >= myBoundary.xmin());
112  assert(c.myBoundary.xmax() >= c.myBoundary.xmin());
113  return myBoundary.overlapsWith(c.myBoundary, offset);
114 }
115 
116 
117 
118 // ---------------------------------------------------------------------------
119 // NIVissimConnectionCluster - methods
120 // ---------------------------------------------------------------------------
122  const std::vector<int>& connections, int nodeCluster, int edgeid)
123  : myConnections(connections), myNodeCluster(nodeCluster),
126  myClusters.push_back(this);
127  assert(edgeid > 0);
128  if (edgeid >= 0) {
129  myEdges.push_back(edgeid);
130  }
131  // add information about incoming and outgoing edges
132  for (std::vector<int>::const_iterator i = connections.begin(); i != connections.end(); i++) {
134  assert(c != 0);
135  myOutgoingEdges.push_back(c->getToEdgeID());
136  myIncomingEdges.push_back(c->getFromEdgeID());
137  assert(c->getFromEdgeID() == edgeid || c->getToEdgeID() == edgeid);
138  }
141 }
142 
143 
145  const std::vector<int>& connections, const Boundary& boundary,
146  int nodeCluster, const std::vector<int>& edges)
147  : myConnections(connections), myBoundary(boundary),
148  myNodeCluster(nodeCluster), myEdges(edges) {
149  myClusters.push_back(this);
151  assert(myBoundary.xmax() >= myBoundary.xmin());
152  // add information about incoming and outgoing edges
153  for (std::vector<int>::const_iterator i = connections.begin(); i != connections.end(); i++) {
155  assert(c != 0);
156  myOutgoingEdges.push_back(c->getToEdgeID());
157  myIncomingEdges.push_back(c->getFromEdgeID());
158  assert(find(edges.begin(), edges.end(), c->getFromEdgeID()) != edges.end()
159  ||
160  find(edges.begin(), edges.end(), c->getToEdgeID()) != edges.end());
161  }
164 }
165 
166 
168 
169 
170 
171 int
173  return myFirstFreeID++;
174 }
175 
176 
177 bool
179  double offset) const {
180  assert(myBoundary.xmax() >= myBoundary.xmin());
181  assert(c->myBoundary.xmax() >= c->myBoundary.xmin());
182  return c->myBoundary.overlapsWith(myBoundary, offset);
183 }
184 
185 
186 void
188  assert(myBoundary.xmax() >= myBoundary.xmin());
189  assert(c->myBoundary.xmax() >= c->myBoundary.xmin());
191  for (std::vector<int>::iterator i = c->myConnections.begin(); i != c->myConnections.end(); i++) {
192  myConnections.push_back(*i);
193  }
195  assert(myNodeCluster == -1 || c->myNodeCluster == -1);
196  if (myNodeCluster == -1) {
198  }
199  // inform edges about merging
200  // !!! merge should be done within one method
201  for (std::vector<int>::iterator j = c->myEdges.begin(); j != c->myEdges.end(); j++) {
202  NIVissimEdge::dictionary(*j)->mergedInto(c, this);
203  }
204  copy(c->myEdges.begin(), c->myEdges.end(), back_inserter(myEdges));
205  copy(c->myIncomingEdges.begin(), c->myIncomingEdges.end(),
206  back_inserter(myIncomingEdges));
207  copy(c->myOutgoingEdges.begin(), c->myOutgoingEdges.end(),
208  back_inserter(myOutgoingEdges));
212 }
213 
214 
215 
216 void
218  // !!! ...
219  // Further, we try to omit joining of overlaping nodes. This is done by holding
220  // the lists of incoming and outgoing edges and incrementally building the nodes
221  // regarding this information
222  std::vector<NIVissimConnectionCluster*> joinAble;
223  int pos = 0;
224  ContType::iterator i = myClusters.begin();
225  // step1 - faster but no complete
226  while (i != myClusters.end()) {
227  joinAble.clear();
228  ContType::iterator j = i + 1;
229 
230  // check whether every combination has been processed
231  while (j != myClusters.end()) {
232  // check whether the current clusters overlap
233  if ((*i)->joinable(*j, offset)) {
234  joinAble.push_back(*j);
235  }
236  j++;
237  }
238  for (std::vector<NIVissimConnectionCluster*>::iterator k = joinAble.begin();
239  k != joinAble.end(); k++) {
240  // add the overlaping cluster
241  (*i)->add(*k);
242  // erase the overlaping cluster
243  delete *k;
244  myClusters.erase(find(myClusters.begin(), myClusters.end(), *k));
245  }
246  //
247  if (joinAble.size() > 0) {
248  i = myClusters.begin() + pos;
249  // clear temporary storages
250  joinAble.clear();
251  } else {
252  i++;
253  pos++;
254  }
255  }
256  //
257  pos = 0;
258  i = myClusters.begin();
259  while (i != myClusters.end()) {
260  ContType::iterator j = i + 1;
261  // check whether every combination has been processed
262  while (j != myClusters.end()) {
263  // check whether the current clusters overlap
264  if ((*i)->joinable(*j, offset)) {
265  joinAble.push_back(*j);
266  }
267  j++;
268  }
269  for (std::vector<NIVissimConnectionCluster*>::iterator k = joinAble.begin();
270  k != joinAble.end(); k++) {
271  // add the overlaping cluster
272  (*i)->add(*k);
273  // erase the overlaping cluster
274  delete *k;
275  myClusters.erase(find(myClusters.begin(), myClusters.end(), *k));
276  }
277  //
278  if (joinAble.size() > 0) {
279  i = myClusters.begin();
280  // clear temporary storages
281  joinAble.clear();
282  pos = 0;
283  } else {
284  i++;
285  pos++;
286  }
287  }
288  // check for weak district connections
289  // (junctions made up by district connections, where prohibitions are not
290  // modelled properly)
291  pos = 0;
292  i = myClusters.begin();
293  while (i != myClusters.end()) {
294  ContType::iterator j = i + 1;
295  // check whether every combination has been processed
296  while (j != myClusters.end()) {
297  // check whether the current clusters overlap
298  if ((*i)->isWeakDistrictConnRealisation(*j)) {
299  joinAble.push_back(*j);
300  }
301  j++;
302  }
303  for (std::vector<NIVissimConnectionCluster*>::iterator k = joinAble.begin();
304  k != joinAble.end(); k++) {
305  // add the overlaping cluster
306  (*i)->add(*k);
307  // erase the overlaping cluster
308  delete *k;
309  myClusters.erase(find(myClusters.begin(), myClusters.end(), *k));
310  }
311  //
312  if (joinAble.size() > 0) {
313  i = myClusters.begin();
314  // clear temporary storages
315  joinAble.clear();
316  pos = 0;
317  } else {
318  i++;
319  pos++;
320  }
321  }
322 }
323 
324 
325 bool
327  // join clusters which have at least one connection in common
329  return true;
330  }
331 
332  // connections shall overlap otherwise
333  if (!overlapsWith(c2, offset)) {
334  return false;
335  }
336 
337  // at least one of the clusters shall not be assigned to a node in previous (!!!??)
338  if (hasNodeCluster() && c2->hasNodeCluster()) {
339  return false;
340  }
341 
342  // join clusters which where connections do disturb each other
344  ||
346 
347  return true;
348  }
349 
350 
351  // join clusters which do share the same incoming or outgoing edges (not mutually)
352  std::vector<int> extendedOutgoing1;
353  std::vector<int> extendedIncoming1;
354  std::vector<int> extendedOutgoing2;
355  std::vector<int> extendedIncoming2;
356  if (myIncomingEdges.size() > 1 || c2->myIncomingEdges.size() > 1) {
357  extendedOutgoing1 =
359  extendedIncoming1 =
361  extendedOutgoing2 =
363  extendedIncoming2 =
365  } else {
366  extendedOutgoing1 = myIncomingEdges;
367  extendedIncoming1 = myOutgoingEdges;
368  extendedOutgoing2 = c2->myIncomingEdges;
369  extendedIncoming2 = c2->myOutgoingEdges;
370  }
371 
372  if (VectorHelper<int>::subSetExists(extendedOutgoing1, extendedOutgoing2)
373  ||
374  VectorHelper<int>::subSetExists(extendedIncoming1, extendedIncoming2)
375  ) {
376  return true;
377  }
378  return false;
379 }
380 
381 
382 bool
384  if ((myIncomingEdges.size() == 1 && myOutgoingEdges.size() == 1)) {
385  return false;
386  }
387  if ((c2->myIncomingEdges.size() == 1 && c2->myOutgoingEdges.size() == 1)) {
388  return false;
389  }
390 
391  // ok, may be the other way round
392  if (myIncomingEdges.size() == 1 && c2->myOutgoingEdges.size() == 1) {
393  return c2->isWeakDistrictConnRealisation(this);
394  }
395  // connections must cross
396  bool crosses = false;
397  for (std::vector<int>::const_iterator j1 = myConnections.begin(); j1 != myConnections.end() && !crosses; j1++) {
399  const PositionVector& g1 = c1->getGeometry();
400  for (std::vector<int>::const_iterator j2 = c2->myConnections.begin(); j2 != c2->myConnections.end() && !crosses; j2++) {
402  const PositionVector& g2 = c2->getGeometry();
403  if (g1.intersects(g2)) {
404  crosses = true;
405  }
406  }
407  }
408  if (!crosses) {
409  return false;
410  }
411  // ok, check for connection
412  if (myOutgoingEdges.size() != 1 || c2->myIncomingEdges.size() != 1) {
413  return false;
414  }
415  // check whether the connection is bidirectional
418  if (oe == 0 || ie == 0) {
419  return false;
420  }
422 }
423 
424 
425 bool
427  //
428  for (std::vector<int>::iterator i = myConnections.begin(); i != myConnections.end(); i++) {
430  for (std::vector<int>::iterator j = cc2->myConnections.begin(); j != cc2->myConnections.end(); j++) {
432  if (c1->getFromEdgeID() == c2->getFromEdgeID()) {
434  const PositionVector& g = e->getGeometry();
436  g.front(), g.back(), c1->getBoundary().getCenter());
438  g.front(), g.back(), c2->getBoundary().getCenter());
439  if (pos1 <= 5.0 && pos2 <= 5.0) {
440  return true;
441  }
442  }
443  if (c1->getToEdgeID() == c2->getToEdgeID()) {
445  const PositionVector& g = e->getGeometry();
447  g.front(), g.back(), c1->getBoundary().getCenter());
449  g.front(), g.back(), c2->getBoundary().getCenter());
450  if (pos1 >= g.length() - 5.0 && pos2 >= g.length() - 5.0) {
451  return true;
452  }
453  }
454  }
455  }
456  return false;
457 }
458 
459 
460 std::vector<int>
462  const std::vector<int>& iv2) const {
463  std::vector<int> ret(iv1);
464  for (std::vector<int>::const_iterator i = iv1.begin(); i != iv1.end(); i++) {
466  const std::vector<NIVissimEdge*> treatAsSame = e->getToTreatAsSame();
467  for (std::vector<NIVissimEdge*>::const_iterator j = treatAsSame.begin(); j != treatAsSame.end(); j++) {
468  if (find(iv2.begin(), iv2.end(), (*j)->getID()) == iv2.end()) {
469  ret.push_back((*j)->getID());
470  }
471  }
472  }
473  return ret;
474 }
475 
476 std::vector<int>
478  std::vector<int> ret;
479  for (std::vector<int>::iterator i = myConnections.begin(); i != myConnections.end(); i++) {
481  const std::vector<int>& disturbances = c->getDisturbances();
482  for (std::vector<int>::const_iterator j = disturbances.begin(); j != disturbances.end(); j++) {
484  ret.push_back(d->getEdgeID());
485  ret.push_back(d->getDisturbanceID());
486  }
487  }
488  return ret;
489 }
490 
491 
492 void
494  for (ContType::iterator i = myClusters.begin(); i != myClusters.end(); i++) {
495  std::vector<int> disturbances;
496  std::vector<int> tls;
497  std::vector<int> nodes;
498  int tlsid = -1;
499  int nodeid = -1;
500  if ((*i)->myConnections.size() > 0) {
501  (*i)->recomputeBoundary();
502  disturbances = NIVissimDisturbance::getWithin((*i)->myBoundary);
503  }
504  nodes = (*i)->myNodes;//NIVissimTL::getWithin((*i)->myBoundary, 5.0);
505  if (nodes.size() > 1) {
506  WRITE_WARNING("NIVissimConnectionCluster:More than a single node");
507  // throw 1; // !!! eigentlich sollte hier nur eine Ampelanlage sein
508  }
509  if (nodes.size() > 0) {
510  nodeid = nodes[0];
511  }
512  //
513  //
515  nodeid, tlsid, (*i)->myConnections,
516  disturbances, (*i)->myIncomingEdges.size() < 2);
517  assert((*i)->myNodeCluster == id || (*i)->myNodeCluster < 0);
518  (*i)->myNodeCluster = id;
519  }
520 }
521 
522 
523 void
525  for (ContType::iterator i = myClusters.begin(); i != myClusters.end(); i++) {
526  std::vector<int> connections = (*i)->myConnections;
527  for (std::vector<int>::iterator j = connections.begin(); j != connections.end(); j++) {
528  if (j != connections.begin()) {
529  into << ", ";
530  }
531  into << *j;
532  }
533  into << "(" << (*i)->myBoundary << ")" << std::endl;
534  }
535  into << "---------------------------" << std::endl;
536 }
537 
538 
539 
540 bool
542  return myNodeCluster != -1;
543 }
544 
545 
546 int
548  return (int)myClusters.size();
549 }
550 
551 
552 void
554  for (NodeSubCluster::ConnectionCont::const_iterator i = c.myConnections.begin(); i != c.myConnections.end(); i++) {
555  NIVissimConnection* conn = *i;
556  int connid = conn->getID();
557  std::vector<int>::iterator j = find(myConnections.begin(), myConnections.end(), connid);
558  if (j != myConnections.end()) {
559  myConnections.erase(j);
560  }
561  }
563 }
564 
565 
566 void
568  myBoundary = Boundary();
569  for (std::vector<int>::iterator i = myConnections.begin(); i != myConnections.end(); i++) {
571  if (c != 0) {
574  if (c->getGeometry().size() != 0) {
576  }
577  }
578  }
579  assert(myBoundary.xmax() >= myBoundary.xmin());
580 }
581 
582 
583 NBNode*
585  return NIVissimNodeCluster::dictionary(myNodeCluster)->getNBNode();
586 }
587 
588 
589 bool
590 NIVissimConnectionCluster::around(const Position& p, double offset) const {
591  assert(myBoundary.xmax() >= myBoundary.xmin());
592  return myBoundary.around(p, offset);
593 }
594 
595 
596 
597 void
599  assert(myConnections.size() != 0);
600  // remove the cluster from all edges at first
601  std::vector<int>::iterator i;
602  for (i = myEdges.begin(); i != myEdges.end(); i++) {
604  edge->removeFromConnectionCluster(this);
605  }
606  // clear edge information
607  myEdges.clear();
608  // recheck which edges do still participate and add edges
609  for (i = myConnections.begin(); i != myConnections.end(); i++) {
611  assert(myBoundary.xmax() >= myBoundary.xmin());
612  if (myBoundary.around(c->getFromGeomPosition(), 5)) {
613  myEdges.push_back(c->getFromEdgeID());
614  }
615  assert(myBoundary.xmax() >= myBoundary.xmin());
616  if (myBoundary.around(c->getToGeomPosition(), 5)) {
617  myEdges.push_back(c->getToEdgeID());
618  }
619  }
620  // connect edges
621  for (i = myEdges.begin(); i != myEdges.end(); i++) {
623  edge->addToConnectionCluster(this);
624  }
625 }
626 
627 
628 double
630  // return the middle of the connections when there are any
631  if (myConnections.size() != 0) {
632  double sum = 0;
633  int part = 0;
634  std::vector<int>::const_iterator i;
635  for (i = myConnections.begin(); i != myConnections.end(); i++) {
637  if (c->getFromEdgeID() == edgeid) {
638  part++;
639  sum += c->getFromPosition();
640  }
641  if (c->getToEdgeID() == edgeid) {
642  part++;
643  sum += c->getToPosition();
644  }
645  }
646  if (part > 0) {
647  return sum / (double) part;
648  }
649  }
650  // use the position of the node if possible
651  if (myNodeCluster >= 0) {
652  // try to find the nearest point on the edge
653  // !!! only the main geometry is regarded
654  NIVissimNodeDef* node =
656  if (node != 0) {
657  double pos = node->getEdgePosition(edgeid);
658  if (pos >= 0) {
659  return pos;
660  }
661  }
662  /*
663  double try1 = GeomHelper::nearest_offset_on_line_to_point(
664  edge->getBegin2D(), edge->getEnd2D(), node->getPos());
665  if(try1>=0) {
666  return try1;
667  }
668  // try to use simple distance
669  double dist1 =
670  GeomHelper::distance(node->getPos(), edge->getBegin2D());
671  double dist2 =
672  GeomHelper::distance(node->getPos(), edge->getEnd2D());
673  return dist1<dist2
674  ? 0 : edge->getLength();
675  */
676  }
677  // what else?
678  WRITE_WARNING("NIVissimConnectionCluster: how to get an edge's position?");
679  // !!!
680  assert(myBoundary.xmin() <= myBoundary.xmax());
681  NIVissimEdge* edge = NIVissimEdge::dictionary(edgeid);
682  std::vector<int>::const_iterator i = find(myEdges.begin(), myEdges.end(), edgeid);
683  if (i == myEdges.end()) {
684  // edge does not exist!?
685  throw 1;
686  }
687  const PositionVector& edgeGeom = edge->getGeometry();
690  edgeGeom.front(), edgeGeom.back(), p);
691 }
692 
693 
694 
695 void
697  for (ContType::iterator i = myClusters.begin(); i != myClusters.end(); i++) {
698  delete(*i);
699  }
700  myClusters.clear();
701  myFirstFreeID = 100000;
702 }
703 
704 
707  // collect connection where this edge is the incoming one
708  std::vector<NIVissimConnection*> edgeIsIncoming;
709  for (std::vector<int>::const_iterator i = myConnections.begin(); i != myConnections.end(); i++) {
711  if (c->getFromEdgeID() == e->getID()) {
712  edgeIsIncoming.push_back(c);
713  }
714  }
715  //
716  if (edgeIsIncoming.size() == 0) {
717  return PositionVector();
718  }
719  // sort connected edges in same direction
720  sort(edgeIsIncoming.begin(), edgeIsIncoming.end(),
722  NIVissimConnection* c = *(edgeIsIncoming.begin());
723  return c->getGeometry();
724 }
725 
726 
727 
730  // collect connection where this edge is the incoming one
731  std::vector<NIVissimConnection*> edgeIsIncoming;
732  for (std::vector<int>::const_iterator i = myConnections.begin(); i != myConnections.end(); i++) {
734  if (c->getFromEdgeID() == e->getID()) {
735  edgeIsIncoming.push_back(c);
736  }
737  }
738  //
739  if (edgeIsIncoming.size() == 0) {
740  return 0;
741  }
742  // sort connected edges in same direction
743  sort(edgeIsIncoming.begin(), edgeIsIncoming.end(),
745  return *(edgeIsIncoming.begin());
746 }
747 
748 
749 
752  // collect connection where this edge is the outgoing one
753  std::vector<NIVissimConnection*> edgeIsOutgoing;
754  for (std::vector<int>::const_iterator i = myConnections.begin(); i != myConnections.end(); i++) {
756  if (c->getToEdgeID() == e->getID()) {
757  edgeIsOutgoing.push_back(c);
758  }
759  }
760  //
761  if (edgeIsOutgoing.size() == 0) {
762  return PositionVector();
763  }
764  // sort connected edges in same direction
765  sort(edgeIsOutgoing.begin(), edgeIsOutgoing.end(),
767  NIVissimConnection* c = *(edgeIsOutgoing.begin());
768  return c->getGeometry();
769 }
770 
771 
774  // collect connection where this edge is the outgoing one
775  std::vector<NIVissimConnection*> edgeIsOutgoing;
776  for (std::vector<int>::const_iterator i = myConnections.begin(); i != myConnections.end(); i++) {
778  if (c->getToEdgeID() == e->getID()) {
779  edgeIsOutgoing.push_back(c);
780  }
781  }
782  //
783  if (edgeIsOutgoing.size() == 0) {
784  return 0;
785  }
786  // sort connected edges in same direction
787  sort(edgeIsOutgoing.begin(), edgeIsOutgoing.end(),
789  return *(edgeIsOutgoing.begin());
790 }
791 
792 
793 
794 /****************************************************************************/
795 
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:132
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:189
static Position crossPoint(const Boundary &b, const PositionVector &v)
Definition: GeomHelper.cpp:123
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:48
std::vector< int > getDisturbanceParticipators()
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
double getPositionForEdge(int edgeid) const
A temporary storage for edges imported from Vissim.
Definition: NIVissimEdge.h:60
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:96
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:46
static void _debugOut(std::ostream &into)
A list of positions.
const Boundary & getBoundingBox() const
static void removeDouble(std::vector< T > &v)
Definition: VectorHelper.h:77
bool around(const Position &p, double offset=0) const
double xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:126
static bool dictionary(int id, NIVissimNodeDef *o)
#define DEG2RAD(x)
Definition: GeomHelper.h:45
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:180
Boundary myBoundary
The boundary of the cluster.
Represents a single node (junction) during network building.
Definition: NBNode.h:75
Position getCenter() const
Returns the center of the boundary.
Definition: Boundary.cpp:120
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:174
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:86
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