46 #ifdef CHECK_MEMORY_LEAKS
48 #endif // CHECK_MEMORY_LEAKS
67 bool singleDirection =
false;
69 singleDirection =
true;
73 singleDirection =
true;
76 if (singleDirection) {
89 for (EdgeVector::const_iterator i = incoming.begin(); i != incoming.end(); ++i) {
91 for (EdgeVector::const_iterator j = outgoing.begin(); j != outgoing.end(); ++j) {
95 maxAngle =
MAX2(ad, maxAngle);
99 if (maxAngle > 22.5) {
107 if (ret.size() < 3) {
118 tmp.rotateAtP1(
M_PI / 2);
119 tmp.extrapolateBy2D(100);
150 EdgeVector::const_iterator i;
152 std::map<NBEdge*, std::set<NBEdge*> > same;
158 std::map<NBEdge*, NBEdge*> ccwBoundary;
159 std::map<NBEdge*, NBEdge*> cwBoundary;
162 ccwBoundary[*i] = *i;
169 if (newAll.size() < 2) {
178 std::map<NBEdge*, SUMOReal> distances;
179 std::map<NBEdge*, bool> myExtended;
181 for (i = newAll.begin(); i != newAll.end(); ++i) {
182 EdgeVector::const_iterator cwi = i;
183 EdgeVector::const_iterator ccwi = i;
186 initNeighbors(newAll, i, geomsCW, geomsCCW, cwi, ccwi, cad, ccad);
187 assert(geomsCCW.find(*i) != geomsCCW.end());
188 assert(geomsCW.find(*ccwi) != geomsCW.end());
189 assert(geomsCW.find(*cwi) != geomsCW.end());
195 (simpleContinuation && fabs(ccad - cad) < (
SUMOReal) 0.1)
198 || (!simpleContinuation && fabs(ccad - cad) <
DEG2RAD(22.5)))
202 if (myExtended.find(*ccwi) != myExtended.end()) {
203 p = geomsCCW[*ccwi][0];
204 p.
add(geomsCW[*ccwi][0]);
207 p = geomsCCW[*ccwi][0];
208 p.
add(geomsCW[*ccwi][0]);
209 p.
add(geomsCCW[*i][0]);
210 p.
add(geomsCW[*i][0]);
214 SUMOReal dist = geomsCCW[*i].nearest_offset_to_point2D(p);
226 (*i)->setGeometry(g);
228 geomsCCW[*i] = (*i)->getCCWBoundaryLine(
myNode);
229 geomsCCW[*i].extrapolate(100);
230 geomsCW[*i] = (*i)->getCWBoundaryLine(
myNode);
231 geomsCW[*i].extrapolate(100);
234 myExtended[*i] =
true;
236 if (!simpleContinuation) {
244 distances[*i] = dist;
250 const bool ccwCloser = ccad < cad;
252 const PositionVector& currGeom = ccwCloser ? geomsCCW[*i] : geomsCW[*i];
254 const PositionVector& currGeom2 = ccwCloser ? geomsCW[*i] : geomsCCW[*i];
256 const PositionVector& neighGeom = ccwCloser ? geomsCW[*ccwi] : geomsCCW[*cwi];
258 const PositionVector& neighGeom2 = ccwCloser ? geomsCCW[*cwi] : geomsCW[*ccwi];
259 if (!simpleContinuation) {
262 if (*cwi != *ccwi && currGeom2.
intersects(neighGeom2)) {
263 const SUMOReal farAngleDist = ccwCloser ? cad : ccad;
267 SUMOReal mmin =
MIN2(distances[*cwi], distances[*ccwi]);
271 }
else if (fabs(a2 - a1) < 10 || farAngleDist <
DEG2RAD(135)) {
272 distances[*i] =
MAX2(a1, a2);
276 if (*cwi != *ccwi && currGeom2.
intersects(neighGeom2)) {
279 distances[*i] = 100 + radius;
292 for (i = newAll.begin(); i != newAll.end(); ++i) {
293 if (distances.find(*i) == distances.end()) {
301 for (i = newAll.begin(); i != newAll.end(); ++i) {
315 if (i != newAll.begin()) {
331 ret.
append(
getSmoothCorner(geomsCW[*(newAll.end() - 1)], geomsCCW[*newAll.begin()], ret[-1], ret[0], cornerDetail));
340 for (std::vector<SUMOReal>::iterator it = intersections.begin() + 1; it != intersections.end(); ++it) {
341 if (fabs(*it - offset) < fabs(result - offset)) {
353 if (cornerDetail > 0) {
355 begShape[-1] = begPoint;
356 endShape[0] = endPoint;
358 if (curve.size() > 2) {
371 EdgeVector::const_iterator i, j;
376 geomsCCW[*i] = (*i)->getCCWBoundaryLine(
myNode);
378 WRITE_WARNING(std::string(
"While computing intersection geometry: ") + std::string(e.what()));
379 geomsCCW[*i] = (*i)->getGeometry();
382 geomsCW[*i] = (*i)->getCWBoundaryLine(
myNode);
384 WRITE_WARNING(std::string(
"While computing intersection geometry: ") + std::string(e.what()));
385 geomsCW[*i] = (*i)->getGeometry();
390 ? (*i)->getCCWBoundaryLine(
myNode)
391 : (*i)->getCWBoundaryLine(
myNode);
393 Line tmp = geomsCCW[*i].lineAt(0);
395 geomsCCW[*i].replaceAt(0, tmp.
p1());
396 tmp = geomsCW[*i].lineAt(0);
398 geomsCW[*i].replaceAt(0, tmp.
p1());
401 geomsCCW[*j] = (*j)->getCCWBoundaryLine(
myNode);
402 geomsCW[*j] = (*j)->getCWBoundaryLine(
myNode);
405 ? (*j)->getCCWBoundaryLine(
myNode)
406 : (*j)->getCWBoundaryLine(
myNode);
408 tmp = geomsCCW[*j].lineAt(0);
410 geomsCCW[*j].replaceAt(0, tmp.
p1());
411 tmp = geomsCW[*j].lineAt(0);
413 geomsCW[*j].replaceAt(0, tmp.
p1());
419 const SUMOReal angleChangeLookahead = 35;
422 EdgeVector::const_iterator j = i + 1;
426 const bool incoming = (*i)->getToNode() == &
myNode;
427 const bool incoming2 = (*j)->getToNode() == &
myNode;
428 const Position positionAtNode = (*i)->getGeometry()[incoming ? -1 : 0];
429 const Position positionAtNode2 = (*j)->getGeometry()[incoming2 ? -1 : 0];
434 const SUMOReal angle1further = (g1.size() > 2 && l1.
length2D() < angleChangeLookahead ?
436 const SUMOReal angle2further = (g2.size() > 2 && l2.
length2D() < angleChangeLookahead ?
440 const bool ambiguousGeometry = ((angleDiff > 0 && angleDiffFurther < 0) || (angleDiff < 0 && angleDiffFurther > 0));
441 const bool differentDirs = (incoming != incoming2);
446 if (fabs(angleDiff) < 20) {
447 const bool isOpposite = differentDirs && foundOpposite.count(*i) == 0;
449 foundOpposite.insert(*i);
450 foundOpposite.insert(*j);
452 if (isOpposite || ambiguousGeometry ||
badIntersection(*i, *j, geomsCW[*i], geomsCCW[*j], 100)) {
454 for (std::set<NBEdge*>::iterator k = same[*i].begin(); k != same[*i].end(); ++k) {
460 for (std::set<NBEdge*>::iterator k = same[*j].begin(); k != same[*j].end(); ++k) {
492 geom1 = geom1.reverse();
499 std::vector<SUMOReal> distances = geom1.
distances(geom2,
true);
503 const bool onTop = maxDist -
POSITION_EPS < minDistanceThreshold;
504 const bool curvingTowards = geom1[0].distanceTo2D(geom2[0]) > minDistanceThreshold && minDist < minDistanceThreshold;
505 const bool intersects = e1cw.
intersects(e2ccw);
506 return onTop || curvingTowards || !intersects;
512 std::map<
NBEdge*, std::set<NBEdge*> >& same,
515 std::map<NBEdge*, NBEdge*>& ccwBoundary,
516 std::map<NBEdge*, NBEdge*>& cwBoundary) {
518 std::set<NBEdge*>::const_iterator j;
519 EdgeVector::iterator i2;
520 std::map<NBEdge*, EdgeVector >::iterator k;
524 for (i2 = newAll.begin(); !changed && i2 != newAll.end();) {
525 std::set<NBEdge*> other = same[*i2];
526 for (j = other.begin(); j != other.end(); ++j) {
527 EdgeVector::iterator k = find(newAll.begin(), newAll.end(), *j);
528 if (k != newAll.end()) {
531 geomsCW[*i2] = geomsCW[*j];
532 cwBoundary[*i2] = *j;
537 ccwBoundary[*i2] = *j;
538 geomsCCW[*i2] = geomsCCW[*j];
559 EdgeVector::const_iterator& cwi,
560 EdgeVector::const_iterator& ccwi,
566 if (cwi == edges.end()) {
567 std::advance(cwi, -((
int)edges.size()));
570 if (ccwi == edges.begin()) {
571 std::advance(ccwi, edges.size() - 1);
576 const SUMOReal angleCurCCW = geomsCCW[*current].lineAt(0).atan2PositiveAngle();
577 const SUMOReal angleCurCW = geomsCW[*current].lineAt(0).atan2PositiveAngle();
578 const SUMOReal angleCCW = geomsCW[*ccwi].lineAt(0).atan2PositiveAngle();
579 const SUMOReal angleCW = geomsCCW[*cwi].lineAt(0).atan2PositiveAngle();
580 if (angleCurCCW > angleCCW) {
581 ccad = angleCurCCW - angleCCW;
583 ccad = twoPI - (angleCCW - angleCurCCW);
586 if (angleCurCW > angleCW) {
587 cad = twoPI - (angleCurCW - angleCW);
589 cad = angleCW - angleCurCW;
611 EdgeVector::const_iterator i;
614 Line edgebound1 = (*i)->getCCWBoundaryLine(
myNode).lineAt(0);
615 Line edgebound2 = (*i)->getCWBoundaryLine(
myNode).lineAt(0);
616 Line cross(edgebound1);
SUMOReal length2D() const
SUMOReal atan2DegreeAngle() const
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges.
PositionVector getSubpart2D(SUMOReal beginOffset, SUMOReal endOffset) const
void replaceAt(int index, const Position &by)
SUMOReal getRadius() const
Returns the turning radius of this node.
void add(const Position &pos)
Adds the given position to this one.
PositionVector getSmoothCorner(PositionVector begShape, PositionVector endShape, const Position &begPoint, const Position &endPoint, int cornerDetail)
Compute smoothed corner shape.
Position getPositionAtDistance2D(SUMOReal offset) const
The representation of a single edge during network building.
PositionVector computeNodeShapeDefault(bool simpleContinuation)
Computes the node geometry Edges with the same direction are grouped. Then the node geometry is built...
void rotateAtP1(SUMOReal rot)
bool intersects(const Position &p1, const Position &p2) const
SUMOReal getTotalWidth() const
Returns the combined width of all lanes of this edge.
static T minValue(const std::vector< T > &v)
const NBNode & myNode
The node to compute the geometry for.
std::map< NBEdge *, PositionVector > GeomsMap
bool hasIncoming(const NBEdge *const e) const
Returns whether the given edge ends at this node.
SUMOReal x() const
Returns the x-position.
Position positionAtOffset2D(SUMOReal pos, SUMOReal lateralOffset=0) const
Returns the position at the given length.
#define UNUSED_PARAMETER(x)
#define WRITE_WARNING(msg)
static OptionsCont & getOptions()
Retrieves the options.
SUMOReal closestIntersection(const PositionVector &geom1, const PositionVector &geom2, SUMOReal offset)
return the intersection point closest to the given offset
PositionVector reverse() const
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges.
NBNodeShapeComputer(const NBNode &node)
Constructor.
std::vector< SUMOReal > distances(const PositionVector &s, bool perpendicular=false) const
EdgeVector myAllEdges
Vector of incoming and outgoing edges.
Line lineAt(int pos) const
void push_front_noDoublePos(const Position &p)
const Position & getPosition() const
Returns the position of this node.
const Position & p1() const
std::set< NBEdge * > EdgeSet
bool isSimpleContinuation() const
A point in 2D or 3D with translation and scaling methods.
SUMOReal z() const
Returns the z-position.
PositionVector computeSmoothShape(const PositionVector &begShape, const PositionVector &endShape, int numPoints, bool isTurnaround, SUMOReal extrapolateBeg, SUMOReal extrapolateEnd) const
Compute a smooth curve between the given geometries.
PositionVector compute(bool leftHand)
Computes the shape of the assigned junction.
bool intersects(const Line &l) const
SUMOReal length() const
Returns the length.
NBNode * getToNode() const
Returns the destination node of the edge.
~NBNodeShapeComputer()
Destructor.
PositionVector computeNodeShapeSmall()
Computes the node geometry using normals.
std::vector< NBEdge * > EdgeVector
const PositionVector & getGeometry() const
Returns the geometry of the edge.
SUMOReal y() const
Returns the y-position.
static SUMOReal getMinAngleDiff(SUMOReal angle1, SUMOReal angle2)
Returns the minimum distance (clockwise/counter-clockwise) between both angles.
void set(SUMOReal x, SUMOReal y)
static void initNeighbors(const EdgeVector &edges, const EdgeVector::const_iterator ¤t, GeomsMap &geomsCW, GeomsMap &geomsCCW, EdgeVector::const_iterator &cwi, EdgeVector::const_iterator &ccwi, SUMOReal &cad, SUMOReal &ccad)
Initialize neighbors and angles.
void mul(SUMOReal val)
Multiplies both positions with the given value.
bool badIntersection(const NBEdge *e1, const NBEdge *e2, const PositionVector &e1cw, const PositionVector &e2ccw, SUMOReal distance)
void joinSameDirectionEdges(std::map< NBEdge *, std::set< NBEdge * > > &same, GeomsMap &geomsCCW, GeomsMap &geomsCW)
Joins edges and computes ccw/cw boundaries.
LaneSpreadFunction getLaneSpreadFunction() const
Returns how this edge's lanes' lateral offset is computed.
Represents a single node (junction) during network building.
void extrapolateBy2D(SUMOReal length)
static const SUMOReal DEFAULT_RADIUS
the default turning radius at intersections in m
void move2side(SUMOReal amount)
static const SUMOReal UNSPECIFIED_RADIUS
unspecified lane width
static SUMOReal relAngle(SUMOReal angle1, SUMOReal angle2)
void push_back_noDoublePos(const Position &p)
void computeSameEnd(PositionVector &l1, PositionVector &l2)
static T maxValue(const std::vector< T > &v)
int getInt(const std::string &name) const
Returns the int-value of the named option (only for Option_Integer)
std::vector< SUMOReal > intersectsAtLengths2D(const PositionVector &other) const
For all intersections between this vector and other, return the 2D-length of the subvector from this ...
Position intersectsAt(const Line &l) const
void add(SUMOReal x, SUMOReal y)
void append(const PositionVector &v, SUMOReal sameThreshold=2.0)
EdgeVector computeUniqueDirectionList(std::map< NBEdge *, std::set< NBEdge * > > &same, GeomsMap &geomsCCW, GeomsMap &geomsCW, std::map< NBEdge *, NBEdge * > &ccwBoundary, std::map< NBEdge *, NBEdge * > &cwBoundary)
Joins edges and computes ccw/cw boundaries.