42 #define DEBUGCOND (myNode.getID() == "C") 49 myRadius(node.getRadius()) {
61 bool singleDirection =
false;
63 singleDirection =
true;
67 singleDirection =
true;
70 #ifdef DEBUG_NODE_SHAPE 80 if (singleDirection) {
93 for (EdgeVector::const_iterator i = incoming.begin(); i != incoming.end(); ++i) {
94 double ia = (*i)->getAngleAtNode(&
myNode);
95 for (EdgeVector::const_iterator j = outgoing.begin(); j != outgoing.end(); ++j) {
96 double oa = (*j)->getAngleAtNode(&
myNode);
99 maxAngle =
MAX2(ad, maxAngle);
103 if (maxAngle > 22.5) {
111 if (ret.size() < 3) {
120 assert(l1[0].distanceTo2D(l1[1]) >= 100.);
121 assert(l2[0].distanceTo2D(l2[1]) >= 100.);
124 tmp.push_back(l1[1]);
126 tmp[1].set(-tmp[1].y(), tmp[1].x());
134 l2.erase(l2.begin(), l2.begin() + (l2.size() - tl2.size()));
151 const int cornerDetail = oc.
getInt(
"junctions.corner-detail");
152 const double sCurveStretch = oc.
getFloat(
"junctions.scurve-stretch");
153 const bool rectangularCut = oc.
getBool(
"rectangular-lane-cut");
154 const bool openDriveOutput = oc.
isSet(
"opendrive-output");
161 const double advanceStopLine = oc.
exists(
"opendrive-files") && oc.
isSet(
"opendrive-files") ? oc.
getFloat(
"opendrive.advance-stopline") : 0;
164 #ifdef DEBUG_NODE_SHAPE 166 std::cout <<
"\ncomputeNodeShapeDefault node " <<
myNode.
getID() <<
" simple=" << simpleContinuation <<
" radius=" <<
myRadius <<
"\n";
171 EdgeVector::const_iterator i;
173 std::map<NBEdge*, std::set<NBEdge*> > same;
183 if (newAll.size() < 2) {
192 std::map<NBEdge*, double> distances;
193 std::map<NBEdge*, bool> myExtended;
195 for (i = newAll.begin(); i != newAll.end(); ++i) {
196 EdgeVector::const_iterator cwi = i;
197 EdgeVector::const_iterator ccwi = i;
200 initNeighbors(newAll, i, geomsCW, geomsCCW, cwi, ccwi, cad, ccad);
201 assert(geomsCCW.find(*i) != geomsCCW.end());
202 assert(geomsCW.find(*ccwi) != geomsCW.end());
203 assert(geomsCW.find(*cwi) != geomsCW.end());
209 (simpleContinuation && fabs(ccad - cad) < (
double) 0.1)
212 || (!simpleContinuation && fabs(ccad - cad) <
DEG2RAD(22.5)))
216 if (myExtended.find(*ccwi) != myExtended.end()) {
217 p = geomsCCW[*ccwi][0];
218 p.
add(geomsCW[*ccwi][0]);
220 #ifdef DEBUG_NODE_SHAPE 222 std::cout <<
" extended: p=" << p <<
" angle=" << (ccad - cad) <<
"\n";
226 p = geomsCCW[*ccwi][0];
227 p.
add(geomsCW[*ccwi][0]);
228 p.
add(geomsCCW[*i][0]);
229 p.
add(geomsCW[*i][0]);
231 #ifdef DEBUG_NODE_SHAPE 233 std::cout <<
" unextended: p=" << p <<
" angle=" << (ccad - cad) <<
"\n";
239 geomsCCW[*i].nearest_offset_to_point2D(p),
240 geomsCW[*i].nearest_offset_to_point2D(p));
252 (*i)->setGeometry(g);
254 geomsCCW[*i] = (*i)->getCCWBoundaryLine(
myNode);
255 geomsCCW[*i].extrapolate(100);
256 geomsCW[*i] = (*i)->getCWBoundaryLine(
myNode);
257 geomsCW[*i].extrapolate(100);
260 myExtended[*i] =
true;
261 #ifdef DEBUG_NODE_SHAPE 263 std::cout <<
" extending (dist=" << dist <<
")\n";
267 if (!simpleContinuation) {
271 double radius2 = fabs(ccad - cad) * (*i)->getNumLanes();
273 radius2 =
MAX2(0.15, radius2);
276 #ifdef DEBUG_NODE_SHAPE 278 std::cout <<
" using radius=" << fabs(ccad - cad) * (*i)->getNumLanes() <<
" ccad=" << ccad <<
" cad=" << cad <<
"\n";
282 distances[*i] = dist;
288 const bool ccwCloser = ccad < cad;
290 const PositionVector& currGeom = ccwCloser ? geomsCCW[*i] : geomsCW[*i];
292 const PositionVector& currGeom2 = ccwCloser ? geomsCW[*i] : geomsCCW[*i];
294 const PositionVector& neighGeom = ccwCloser ? geomsCW[*ccwi] : geomsCCW[*cwi];
296 const PositionVector& neighGeom2 = ccwCloser ? geomsCCW[*cwi] : geomsCW[*ccwi];
297 #ifdef DEBUG_NODE_SHAPE 299 std::cout <<
" i=" << (*i)->getID() <<
" neigh=" << (*ccwi)->getID() <<
" neigh2=" << (*cwi)->getID() <<
"\n";
302 if (!simpleContinuation) {
305 #ifdef DEBUG_NODE_SHAPE 307 std::cout <<
" neigh intersects dist=" << distances[*i] <<
" currGeom=" << currGeom <<
" neighGeom=" << neighGeom <<
"\n";
310 if (*cwi != *ccwi && currGeom2.
intersects(neighGeom2)) {
313 const double farAngleDist = ccwCloser ? cad : ccad;
314 double a1 = distances[*i];
316 #ifdef DEBUG_NODE_SHAPE 318 std::cout <<
" neigh2 also intersects a1=" << a1 <<
" a2=" << a2 <<
" ccad=" <<
RAD2DEG(ccad) <<
" cad=" <<
RAD2DEG(cad) <<
" dist[cwi]=" << distances[*cwi] <<
" dist[ccwi]=" << distances[*ccwi] <<
" farAngleDist=" <<
RAD2DEG(farAngleDist) <<
" currGeom2=" << currGeom2 <<
" neighGeom2=" << neighGeom2 <<
"\n";
326 }
else if (farAngleDist <
DEG2RAD(135) || (fabs(
RAD2DEG(farAngleDist) - 180) > 1 && fabs(a2 - a1) < 10)) {
327 distances[*i] =
MAX2(a1, a2);
329 #ifdef DEBUG_NODE_SHAPE 331 std::cout <<
" a1=" << a1 <<
" a2=" << a2 <<
" dist=" << distances[*i] <<
"\n";
336 if (*cwi != *ccwi && currGeom2.
intersects(neighGeom2)) {
338 #ifdef DEBUG_NODE_SHAPE 340 std::cout <<
" neigh2 intersects dist=" << distances[*i] <<
" currGeom2=" << currGeom2 <<
" neighGeom2=" << neighGeom2 <<
"\n";
345 #ifdef DEBUG_NODE_SHAPE 347 std::cout <<
" no intersects dist=" << distances[*i] <<
" currGeom=" << currGeom <<
" neighGeom=" << neighGeom <<
" currGeom2=" << currGeom2 <<
" neighGeom2=" << neighGeom2 <<
"\n";
356 distances[*i] = (double) 100.;
360 if (useDefaultRadius && sCurveStretch > 0) {
362 if (sCurveWidth > 0) {
363 const double sCurveRadius =
myRadius + sCurveWidth /
SUMO_const_laneWidth * sCurveStretch * pow((*i)->getSpeed(), 2 + sCurveStretch) / 1000;
364 const double stretch = 100 + sCurveRadius - distances[*i];
366 distances[*i] += stretch;
368 const double shorten = distances[*i] - 100;
369 (*i)->shortenGeometryAtNode(&
myNode, shorten);
370 for (std::set<NBEdge*>::iterator k = same[*i].begin(); k != same[*i].end(); ++k) {
371 (*k)->shortenGeometryAtNode(&
myNode, shorten);
373 #ifdef DEBUG_NODE_SHAPE 375 std::cout <<
" stretching junction: sCurveWidth=" << sCurveWidth <<
" sCurveRadius=" << sCurveRadius <<
" stretch=" << stretch <<
" dist=" << distances[*i] <<
"\n";
383 for (i = newAll.begin(); i != newAll.end(); ++i) {
384 if (distances.find(*i) == distances.end()) {
391 const double minDistSum = 2 * (100 +
myRadius);
392 for (i = newAll.begin(); i != newAll.end(); ++i) {
393 if (distances[*i] < 100 && (*i)->hasDefaultGeometryEndpointAtNode(&
myNode)) {
394 for (EdgeVector::const_iterator j = newAll.begin(); j != newAll.end(); ++j) {
395 if (distances[*j] > 100 && (*j)->hasDefaultGeometryEndpointAtNode(&
myNode) && distances[*i] + distances[*j] < minDistSum) {
397 if (angleDiff > 160 || angleDiff < 20) {
398 #ifdef DEBUG_NODE_SHAPE 400 std::cout <<
" increasing dist for i=" << (*i)->getID() <<
" because of j=" << (*j)->getID() <<
" jDist=" << distances[*j]
401 <<
" oldI=" << distances[*i] <<
" newI=" << minDistSum - distances[*j]
402 <<
" angleDiff=" << angleDiff
403 <<
" geomI=" << (*i)->getGeometry() <<
" geomJ=" << (*j)->getGeometry() <<
"\n";
406 distances[*i] = minDistSum - distances[*j];
416 for (i = newAll.begin(); i != newAll.end(); ++i) {
420 double offset = distances[*i];
421 if (!(*i)->hasDefaultGeometryEndpointAtNode(&
myNode)) {
423 if (advanceStopLine > 0 && offset < 100) {
424 #ifdef DEBUG_NODE_SHAPE 425 std::cout <<
" i=" << (*i)->getID() <<
" offset=" << offset <<
" advanceStopLine=" << advanceStopLine <<
"\n";
428 (*i)->extendGeometryAtNode(&
myNode, advanceStopLine);
429 for (std::set<NBEdge*>::iterator k = same[*i].begin(); k != same[*i].end(); ++k) {
430 (*k)->extendGeometryAtNode(&
myNode, advanceStopLine);
433 offset =
MAX2(100.0 - advanceStopLine, offset);
437 offset = (double) - .1;
441 if (i != newAll.begin()) {
449 #ifdef DEBUG_NODE_SHAPE 451 std::cout <<
" build stopLine for i=" << (*i)->getID() <<
" offset=" << offset <<
" dist=" << distances[*i] <<
" cwLength=" << cwBound.
length2D() <<
" ccwLength=" << ccwBound.
length2D() <<
" p=" << p <<
" p2=" << p2 <<
" ccwBound=" << ccwBound <<
" cwBound=" << cwBound <<
"\n";
454 (*i)->setNodeBorder(&
myNode, p, p2, rectangularCut);
455 for (std::set<NBEdge*>::iterator k = same[*i].begin(); k != same[*i].end(); ++k) {
456 (*k)->setNodeBorder(&
myNode, p, p2, rectangularCut);
460 ret.
append(
getSmoothCorner(geomsCW[*(newAll.end() - 1)], geomsCCW[*newAll.begin()], ret[-1], ret[0], cornerDetail));
468 double result = intersections[0];
469 for (std::vector<double>::iterator it = intersections.begin() + 1; it != intersections.end(); ++it) {
470 if (fabs(*it - offset) < fabs(result - offset)) {
482 if (cornerDetail > 0) {
485 #ifdef DEBUG_SMOOTH_CORNERS 487 std::cout <<
" begLength=" << begShape2.
length2D() <<
" begSplit=" << begSplit <<
"\n";
491 begShape2 = begShape2.
splitAt(begSplit,
true).first;
497 #ifdef DEBUG_SMOOTH_CORNERS 499 std::cout <<
" endLength=" << endShape2.
length2D() <<
" endSplit=" << endSplit <<
"\n";
503 endShape2 = endShape2.
splitAt(endSplit,
true).second;
510 #ifdef DEBUG_SMOOTH_CORNERS 512 std::cout <<
"getSmoothCorner begPoint=" << begPoint <<
" endPoint=" << endPoint
513 <<
" begShape=" << begShape <<
" endShape=" << endShape
514 <<
" begShape2=" << begShape2 <<
" endShape2=" << endShape2
518 if (begShape2.size() < 2 || endShape2.size() < 2) {
522 NBNode* recordError =
nullptr;
523 #ifdef DEBUG_SMOOTH_CORNERS 525 std::cout <<
" angle=" <<
RAD2DEG(angle) <<
"\n";
536 #ifdef DEBUG_SMOOTH_CORNERS 538 std::cout <<
" curveLength=" << curve.
length2D() <<
" dist=" << begPoint.
distanceTo2D(endPoint) <<
" curvature=" << curvature <<
"\n";
541 if (curvature > 2 && angle >
DEG2RAD(85)) {
545 if (curve.size() > 2) {
546 curve.erase(curve.begin());
558 EdgeVector::const_iterator i, j;
563 geomsCCW[*i] = (*i)->getCCWBoundaryLine(
myNode);
565 WRITE_WARNING(
"While computing intersection geometry at junction '" +
myNode.
getID() +
"': " + std::string(e.what()));
566 geomsCCW[*i] = (*i)->getGeometry();
569 geomsCW[*i] = (*i)->getCWBoundaryLine(
myNode);
571 WRITE_WARNING(
"While computing intersection geometry at junction '" +
myNode.
getID() +
"': " + std::string(e.what()));
572 geomsCW[*i] = (*i)->getGeometry();
576 geomsCCW[*i] = (*i)->getGeometry();
579 geomsCW[*i] = (*i)->getGeometry();
582 geomsCCW[*i].extrapolate2D(100,
true);
583 geomsCW[*i].extrapolate2D(100,
true);
588 const double angleChangeLookahead = 35;
591 EdgeVector::const_iterator j;
597 const bool incoming = (*i)->getToNode() == &
myNode;
598 const bool incoming2 = (*j)->getToNode() == &
myNode;
599 const Position positionAtNode = (*i)->getGeometry()[incoming ? -1 : 0];
600 const Position positionAtNode2 = (*j)->getGeometry()[incoming2 ? -1 : 0];
603 const double angle1further = (g1.size() > 2 && g1[0].distanceTo2D(g1[1]) < angleChangeLookahead ?
605 const double angle2further = (g2.size() > 2 && g2[0].distanceTo2D(g2[1]) < angleChangeLookahead ?
609 const bool ambiguousGeometry = ((angleDiff > 0 && angleDiffFurther < 0) || (angleDiff < 0 && angleDiffFurther > 0));
610 const bool differentDirs = (incoming != incoming2);
615 #ifdef DEBUG_NODE_SHAPE 617 std::cout <<
" checkSameDirection " << (*i)->getID() <<
" " << (*j)->getID()
618 <<
" diffDirs=" << differentDirs
619 <<
" isOpposite=" << (differentDirs && foundOpposite.count(*i) == 0)
620 <<
" angleDiff=" << angleDiff
621 <<
" ambiguousGeometry=" << ambiguousGeometry
627 if (fabs(angleDiff) <
DEG2RAD(20)) {
628 const bool isOpposite = differentDirs && foundOpposite.count(*i) == 0;
630 foundOpposite.insert(*i);
631 foundOpposite.insert(*j);
635 for (std::set<NBEdge*>::iterator k = same[*i].begin(); k != same[*i].end(); ++k) {
641 for (std::set<NBEdge*>::iterator k = same[*j].begin(); k != same[*j].end(); ++k) {
649 #ifdef DEBUG_NODE_SHAPE 651 std::cout <<
" joinedSameDirectionEdges " << (*i)->getID() <<
" " << (*j)->getID() <<
" isOpposite=" << isOpposite <<
" ambiguousGeometry=" << ambiguousGeometry <<
"\n";
676 geom1 = geom1.reverse();
684 std::vector<double> distances = geom1.distances(geom2,
true);
687 const bool curvingTowards = geom1[0].distanceTo2D(geom2[0]) > minDistanceThreshold && minDist < minDistanceThreshold;
688 const bool onTop = maxDist -
POSITION_EPS < minDistanceThreshold;
689 geom1.extrapolate2D(100);
691 Position intersect = geom1.intersectionPosition2D(geom2);
693 #ifdef DEBUG_NODE_SHAPE 695 std::cout <<
" badIntersect: onTop=" << onTop <<
" curveTo=" << curvingTowards <<
" intersects=" << intersects
696 <<
" geom1=" << geom1 <<
" geom2=" << geom2
697 <<
" intersectPos=" << intersect
701 return onTop || curvingTowards || !intersects;
707 std::map<
NBEdge*, std::set<NBEdge*> >& same,
715 auto e2NewAll = find(newAll.begin(), newAll.end(), e1);
716 #ifdef DEBUG_NODE_SHAPE 717 if (
DEBUGCOND) std::cout <<
"computeUniqueDirectionList e1=" << e1->getID()
718 <<
" deleted=" << (e2NewAll == newAll.end())
721 if (e2NewAll == newAll.end()) {
724 auto e1It = find(all.begin(), all.end(), e1);
730 for (
NBEdge* e2 : same[e1]) {
731 #ifdef DEBUG_NODE_SHAPE 733 std::cout <<
" e2=" << e2->getID() <<
"\n";
736 auto e2It = find(all.begin(), all.end(), e2);
737 if (e2It + 1 == bestCCW || (e2It == (all.end() - 1) && bestCCW == all.begin())) {
740 #ifdef DEBUG_NODE_SHAPE 742 std::cout <<
" bestCCW=" << e2->getID() <<
"\n";
745 }
else if (bestCW + 1 == e2It || (bestCW == (all.end() - 1) && e2It == all.begin())) {
748 #ifdef DEBUG_NODE_SHAPE 750 std::cout <<
" bestCW=" << e2->getID() <<
"\n";
756 if (bestCW != e1It) {
757 geomsCW[e1] = geomsCW[*bestCW];
760 if (bestCCW != e1It) {
761 geomsCCW[e1] = geomsCCW[*bestCCW];
765 for (
NBEdge* e2 : same[e1]) {
766 auto e2NewAll = find(newAll.begin(), newAll.end(), e2);
767 if (e2NewAll != newAll.end()) {
768 newAll.erase(e2NewAll);
772 #ifdef DEBUG_NODE_SHAPE 774 std::cout <<
" newAll:\n";
775 for (
NBEdge* e : newAll) {
776 std::cout <<
" " << e->getID() <<
" geomCCW=" << geomsCCW[e] <<
" geomsCW=" << geomsCW[e] <<
"\n";
788 EdgeVector::const_iterator& cwi,
789 EdgeVector::const_iterator& ccwi,
792 const double twoPI = (double)(2 *
M_PI);
795 if (cwi == edges.end()) {
796 std::advance(cwi, -((
int)edges.size()));
799 if (ccwi == edges.begin()) {
800 std::advance(ccwi, edges.size() - 1);
805 const double angleCurCCW = geomsCCW[*current].angleAt2D(0);
806 const double angleCurCW = geomsCW[*current].angleAt2D(0);
807 const double angleCCW = geomsCW[*ccwi].angleAt2D(0);
808 const double angleCW = geomsCCW[*cwi].angleAt2D(0);
809 ccad = angleCCW - angleCurCCW;
813 cad = angleCurCW - angleCW;
823 #ifdef DEBUG_NODE_SHAPE 825 std::cout <<
"computeNodeShapeSmall node=" <<
myNode.
getID() <<
"\n";
829 EdgeVector::const_iterator i;
834 Position delta = edgebound1[1] - edgebound1[0];
835 delta.
set(-delta.
y(), delta.
x());
838 edgebound1.extrapolate2D(500);
840 if (cross.intersects(edgebound1)) {
841 Position np = cross.intersectionPosition2D(edgebound1);
845 if (cross.intersects(edgebound2)) {
846 Position np = cross.intersectionPosition2D(edgebound2);
850 (*i)->resetNodeBorder(&
myNode);
861 const double radius = oc.
getFloat(
"default.junctions.radius");
862 const double smallRadius = oc.
getFloat(
"junctions.small-radius");
867 double maxRightAngle = 0;
868 double extraWidthRight = 0;
869 double maxLeftAngle = 0;
870 double extraWidthLeft = 0;
874 for (
int i = 0; i < in->getNumLanes(); i++) {
875 if ((in->getPermissions(i) & large) != 0) {
880 if ((in->getPermissions() & out->getPermissions() & large) != 0) {
885 in->getGeometry().angleAt2D(-2),
886 out->getGeometry().angleAt2D(0));
888 if (maxRightAngle < -angle) {
889 maxRightAngle = -angle;
893 if (maxLeftAngle < angle) {
894 maxLeftAngle = angle;
899 while (*pIn != out) {
900 extraWidthLeft += (*pIn)->getTotalWidth();
910 int wideLanesOut = 0;
911 for (
int i = 0; i < out->getNumLanes(); i++) {
912 if ((out->getPermissions(i) & large) != 0) {
916 laneDelta =
MAX2(laneDelta, abs(wideLanesOut - wideLanesIn));
922 double result = radius;
924 double maxTurnAngle = maxRightAngle;
925 double extraWidth = extraWidthRight;
926 if (maxRightAngle <
DEG2RAD(5)) {
927 maxTurnAngle = maxLeftAngle;
928 extraWidth = extraWidthLeft;
933 result =
MAX2(smallRadius, radius * tan(0.5 *
MIN2(0.5 *
M_PI, maxTurnAngle)) - extraWidth);
937 std::cout <<
"getDefaultRadius n=" <<
myNode.
getID() <<
" laneDelta=" << laneDelta
938 <<
" rightA=" <<
RAD2DEG(maxRightAngle)
939 <<
" leftA=" <<
RAD2DEG(maxLeftAngle)
940 <<
" maxA=" <<
RAD2DEG(maxTurnAngle)
941 <<
" extraWidth=" << extraWidth
942 <<
" result=" << result <<
"\n";
957 while (lane < e->getNumLanes() && (e->
getPermissions(lane) & exclude) == 0) {
static double relAngle(double angle1, double angle2)
computes the relative angle between the two angles
double myRadius
the computed node radius
static double getMinAngleDiff(double angle1, double angle2)
Returns the minimum distance (clockwise/counter-clockwise) between both angles.
LaneSpreadFunction getLaneSpreadFunction() const
Returns how this edge's lanes' lateral offset is computed.
static void initNeighbors(const EdgeVector &edges, const EdgeVector::const_iterator ¤t, GeomsMap &geomsCW, GeomsMap &geomsCCW, EdgeVector::const_iterator &cwi, EdgeVector::const_iterator &ccwi, double &cad, double &ccad)
Initialize neighbors and angles.
double getDefaultRadius(const OptionsCont &oc)
determine the default radius appropriate for the current junction
double length2D() const
Returns the length.
int getInt(const std::string &name) const
Returns the int-value of the named option (only for Option_Integer)
void append(const PositionVector &v, double sameThreshold=2.0)
double z() const
Returns the z-position.
void add(const Position &pos)
Adds the given position to this one.
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
PositionVector getSmoothCorner(PositionVector begShape, PositionVector endShape, const Position &begPoint, const Position &endPoint, int cornerDetail)
Compute smoothed corner shape.
Position positionAtOffset2D(double pos, double lateralOffset=0) const
Returns the position at the given length.
std::pair< PositionVector, PositionVector > splitAt(double where, bool use2D=false) const
Returns the two lists made when this list vector is splitted at the given point.
const double SUMO_const_laneWidth
double y() const
Returns the y-position.
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
The representation of a single edge during network building.
vehicle is a small delivery vehicle
PositionVector computeNodeShapeDefault(bool simpleContinuation)
Computes the node geometry Edges with the same direction are grouped. Then the node geometry is built...
The link is a 180 degree turn.
static const double UNSPECIFIED_RADIUS
unspecified lane width
double x() const
Returns the x-position.
void setStreetName(const std::string &name)
sets the street name of this edge
static T minValue(const std::vector< T > &v)
const NBNode & myNode
The node to compute the geometry for.
PositionVector reverse() const
reverse position vector
PositionVector interpolateZ(double zStart, double zEnd) const
returned vector that varies z smoothly over its length
static void nextCW(const EdgeVector &edges, EdgeVector::const_iterator &from)
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
const std::string & getID() const
Returns the id.
std::map< NBEdge *, PositionVector > GeomsMap
const SVCPermissions SVCAll
all VClasses are allowed
void set(double x, double y)
set positions x and y
std::string joinNamedToStringSorting(const std::set< T *> &ns, const T_BETWEEN &between)
static double getExtraWidth(const NBEdge *e, SVCPermissions exclude)
compute with of rightmost lanes that exlude the given permissions
#define WRITE_WARNING(msg)
static OptionsCont & getOptions()
Retrieves the options.
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges (The edges which start at this node)
NBNodeShapeComputer(const NBNode &node)
Constructor.
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
EdgeVector myAllEdges
Vector of incoming and outgoing edges.
void extrapolate2D(const double val, const bool onlyFirst=false)
extrapolate position vector in two dimensions (Z is ignored)
void push_front_noDoublePos(const Position &p)
insert in front a non double position
std::set< NBEdge * > EdgeSet
container for unique edges
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
A point in 2D or 3D with translation and scaling methods.
classes which drive on tracks
bool isConstantWidthTransition() const
detects whether a given junction splits or merges lanes while keeping constant road width ...
const EdgeVector & getEdges() const
Returns all edges which participate in this node (Edges that start or end at this node) ...
bool exists(const std::string &name) const
Returns the information whether the named option is known.
std::vector< double > intersectsAtLengths2D(const PositionVector &other) const
For all intersections between this vector and other, return the 2D-length of the subvector from this ...
PositionVector getSubpartByIndex(int beginIndex, int count) const
get subpart of a position vector using index and a cout
PositionVector compute()
Computes the shape of the assigned junction.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
void move2side(double amount)
move position vector to side using certain ammount
bool hasIncoming(const NBEdge *const e) const
Returns whether the given edge ends at this node.
double getDisplacementError() const
compute the displacement error during s-curve computation
LinkDirection getDirection(const NBEdge *const incoming, const NBEdge *const outgoing, bool leftHand=false) const
Returns the representation of the described stream's direction.
const PositionVector & getGeometry() const
Returns the geometry of the edge.
PositionVector getSubpart2D(double beginOffset, double endOffset) const
get subpart of a position vector in two dimensions (Z is ignored)
double getLaneWidth() const
Returns the default width of lanes of this edge.
double length() const
Returns the length.
~NBNodeShapeComputer()
Destructor.
PositionVector computeNodeShapeSmall()
Computes the node geometry using normals.
double getRadius() const
Returns the turning radius of this node.
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges (The edges which yield in this node)
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
double getTotalWidth() const
Returns the combined width of all lanes of this edge.
void joinSameDirectionEdges(std::map< NBEdge *, std::set< NBEdge *> > &same, GeomsMap &geomsCCW, GeomsMap &geomsCW)
Joins edges and computes ccw/cw boundaries.
A storage for options typed value containers)
double angleAt2D(int pos) const
get angle in certain position of position vector
bool badIntersection(const NBEdge *e1, const NBEdge *e2, double distance)
const Position & getPosition() const
Represents a single node (junction) during network building.
EdgeVector computeUniqueDirectionList(std::map< NBEdge *, std::set< NBEdge *> > &same, GeomsMap &geomsCCW, GeomsMap &geomsCW)
Joins edges and computes ccw/cw boundaries.
void push_back_noDoublePos(const Position &p)
insert in back a non double position
void computeSameEnd(PositionVector &l1, PositionVector &l2)
void mul(double val)
Multiplies both positions with the given value.
static T maxValue(const std::vector< T > &v)
double closestIntersection(const PositionVector &geom1, const PositionVector &geom2, double offset)
return the intersection point closest to the given offset
static double angleDiff(const double angle1, const double angle2)
Returns the difference of the second angle to the first angle in radiants.
void add(double xoff, double yoff, double zoff)
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
PositionVector computeSmoothShape(const PositionVector &begShape, const PositionVector &endShape, int numPoints, bool isTurnaround, double extrapolateBeg, double extrapolateEnd, NBNode *recordError=0, int shapeFlag=0) const
Compute a smooth curve between the given geometries.
NBNode * getToNode() const
Returns the destination node of the edge.
bool intersects(const Position &p1, const Position &p2) const
Returns the information whether this list of points interesects the given line.
bool isSimpleContinuation(bool checkLaneNumbers=true) const
check if node is a simple continuation
static const int AVOID_WIDE_LEFT_TURN
static const Position INVALID
used to indicate that a position is valid
void setz(double z)
set position z