46 #ifdef CHECK_MEMORY_LEAKS 48 #endif // CHECK_MEMORY_LEAKS 66 bool singleDirection =
false;
68 singleDirection =
true;
72 singleDirection =
true;
75 if (singleDirection) {
88 for (EdgeVector::const_iterator i = incoming.begin(); i != incoming.end(); ++i) {
90 for (EdgeVector::const_iterator j = outgoing.begin(); j != outgoing.end(); ++j) {
94 maxAngle =
MAX2(ad, maxAngle);
98 if (maxAngle > 22.5) {
106 if (ret.size() < 3) {
115 assert(l1[0].distanceTo2D(l1[1]) >= 100.);
116 assert(l2[0].distanceTo2D(l2[1]) >= 100.);
119 tmp.push_back(l1[1]);
121 tmp[1].set(-tmp[1].y(), tmp[1].x());
129 l2.erase(l2.begin(), l2.begin() + (l2.size() - tl2.size()));
148 EdgeVector::const_iterator i;
150 std::map<NBEdge*, std::set<NBEdge*> > same;
156 std::map<NBEdge*, NBEdge*> ccwBoundary;
157 std::map<NBEdge*, NBEdge*> cwBoundary;
160 ccwBoundary[*i] = *i;
167 if (newAll.size() < 2) {
176 std::map<NBEdge*, SUMOReal> distances;
177 std::map<NBEdge*, bool> myExtended;
179 for (i = newAll.begin(); i != newAll.end(); ++i) {
180 EdgeVector::const_iterator cwi = i;
181 EdgeVector::const_iterator ccwi = i;
184 initNeighbors(newAll, i, geomsCW, geomsCCW, cwi, ccwi, cad, ccad);
185 assert(geomsCCW.find(*i) != geomsCCW.end());
186 assert(geomsCW.find(*ccwi) != geomsCW.end());
187 assert(geomsCW.find(*cwi) != geomsCW.end());
193 (simpleContinuation && fabs(ccad - cad) < (
SUMOReal) 0.1)
196 || (!simpleContinuation && fabs(ccad - cad) <
DEG2RAD(22.5)))
200 if (myExtended.find(*ccwi) != myExtended.end()) {
201 p = geomsCCW[*ccwi][0];
202 p.
add(geomsCW[*ccwi][0]);
205 p = geomsCCW[*ccwi][0];
206 p.
add(geomsCW[*ccwi][0]);
207 p.
add(geomsCCW[*i][0]);
208 p.
add(geomsCW[*i][0]);
212 SUMOReal dist = geomsCCW[*i].nearest_offset_to_point2D(p);
224 (*i)->setGeometry(g);
226 geomsCCW[*i] = (*i)->getCCWBoundaryLine(
myNode);
227 geomsCCW[*i].extrapolate(100);
228 geomsCW[*i] = (*i)->getCWBoundaryLine(
myNode);
229 geomsCW[*i].extrapolate(100);
232 myExtended[*i] =
true;
234 if (!simpleContinuation) {
242 distances[*i] = dist;
248 const bool ccwCloser = ccad < cad;
250 const PositionVector& currGeom = ccwCloser ? geomsCCW[*i] : geomsCW[*i];
252 const PositionVector& currGeom2 = ccwCloser ? geomsCW[*i] : geomsCCW[*i];
254 const PositionVector& neighGeom = ccwCloser ? geomsCW[*ccwi] : geomsCCW[*cwi];
256 const PositionVector& neighGeom2 = ccwCloser ? geomsCCW[*cwi] : geomsCW[*ccwi];
257 if (!simpleContinuation) {
260 if (*cwi != *ccwi && currGeom2.
intersects(neighGeom2)) {
261 const SUMOReal farAngleDist = ccwCloser ? cad : ccad;
265 SUMOReal mmin =
MIN2(distances[*cwi], distances[*ccwi]);
266 if (mmin > 100 && mmin < 205) {
269 }
else if (fabs(a2 - a1) < 10 || farAngleDist <
DEG2RAD(135)) {
270 distances[*i] =
MAX2(a1, a2);
274 if (*cwi != *ccwi && currGeom2.
intersects(neighGeom2)) {
277 distances[*i] = 100 + radius;
290 for (i = newAll.begin(); i != newAll.end(); ++i) {
291 if (distances.find(*i) == distances.end()) {
299 for (i = newAll.begin(); i != newAll.end(); ++i) {
313 if (i != newAll.begin()) {
329 ret.
append(
getSmoothCorner(geomsCW[*(newAll.end() - 1)], geomsCCW[*newAll.begin()], ret[-1], ret[0], cornerDetail));
338 for (std::vector<SUMOReal>::iterator it = intersections.begin() + 1; it != intersections.end(); ++it) {
339 if (fabs(*it - offset) < fabs(result - offset)) {
351 if (cornerDetail > 0) {
353 begShape[-1] = begPoint;
354 endShape[0] = endPoint;
356 if (curve.size() > 2) {
357 curve.erase(curve.begin());
369 EdgeVector::const_iterator i, j;
374 geomsCCW[*i] = (*i)->getCCWBoundaryLine(
myNode);
376 WRITE_WARNING(std::string(
"While computing intersection geometry: ") + std::string(e.what()));
377 geomsCCW[*i] = (*i)->getGeometry();
380 geomsCW[*i] = (*i)->getCWBoundaryLine(
myNode);
382 WRITE_WARNING(std::string(
"While computing intersection geometry: ") + std::string(e.what()));
383 geomsCW[*i] = (*i)->getGeometry();
388 ? (*i)->getCCWBoundaryLine(
myNode)
389 : (*i)->getCWBoundaryLine(
myNode);
390 geomsCCW[*i].extrapolate2D(100,
true);
391 geomsCW[*i].extrapolate2D(100,
true);
394 geomsCCW[*j] = (*j)->getCCWBoundaryLine(
myNode);
395 geomsCW[*j] = (*j)->getCWBoundaryLine(
myNode);
398 ? (*j)->getCCWBoundaryLine(
myNode)
399 : (*j)->getCWBoundaryLine(
myNode);
400 geomsCCW[*j].extrapolate2D(100,
true);
401 geomsCW[*j].extrapolate2D(100,
true);
407 const SUMOReal angleChangeLookahead = 35;
410 EdgeVector::const_iterator j = i + 1;
414 const bool incoming = (*i)->getToNode() == &
myNode;
415 const bool incoming2 = (*j)->getToNode() == &
myNode;
416 const Position positionAtNode = (*i)->getGeometry()[incoming ? -1 : 0];
417 const Position positionAtNode2 = (*j)->getGeometry()[incoming2 ? -1 : 0];
420 const SUMOReal angle1further = (g1.size() > 2 && g1[0].distanceTo2D(g1[1]) < angleChangeLookahead ?
422 const SUMOReal angle2further = (g2.size() > 2 && g2[0].distanceTo2D(g2[1]) < angleChangeLookahead ?
426 const bool ambiguousGeometry = ((angleDiff > 0 && angleDiffFurther < 0) || (angleDiff < 0 && angleDiffFurther > 0));
427 const bool differentDirs = (incoming != incoming2);
432 if (fabs(angleDiff) <
DEG2RAD(20)) {
433 const bool isOpposite = differentDirs && foundOpposite.count(*i) == 0;
435 foundOpposite.insert(*i);
436 foundOpposite.insert(*j);
438 if (isOpposite || ambiguousGeometry ||
badIntersection(*i, *j, geomsCW[*i], geomsCCW[*j], 100)) {
440 for (std::set<NBEdge*>::iterator k = same[*i].begin(); k != same[*i].end(); ++k) {
446 for (std::set<NBEdge*>::iterator k = same[*j].begin(); k != same[*j].end(); ++k) {
478 geom1 = geom1.reverse();
485 std::vector<SUMOReal> distances = geom1.
distances(geom2,
true);
489 const bool onTop = maxDist -
POSITION_EPS < minDistanceThreshold;
490 const bool curvingTowards = geom1[0].distanceTo2D(geom2[0]) > minDistanceThreshold && minDist < minDistanceThreshold;
491 const bool intersects = e1cw.
intersects(e2ccw);
492 return onTop || curvingTowards || !intersects;
498 std::map<
NBEdge*, std::set<NBEdge*> >& same,
501 std::map<NBEdge*, NBEdge*>& ccwBoundary,
502 std::map<NBEdge*, NBEdge*>& cwBoundary) {
507 for (EdgeVector::iterator i2 = newAll.begin(); i2 != newAll.end(); ++i2) {
508 std::set<NBEdge*> other = same[*i2];
509 for (std::set<NBEdge*>::const_iterator j = other.begin(); j != other.end(); ++j) {
510 EdgeVector::iterator k = find(newAll.begin(), newAll.end(), *j);
511 if (k != newAll.end()) {
514 geomsCW[*i2] = geomsCW[*j];
515 cwBoundary[*i2] = *j;
520 ccwBoundary[*i2] = *j;
521 geomsCCW[*i2] = geomsCCW[*j];
542 EdgeVector::const_iterator& cwi,
543 EdgeVector::const_iterator& ccwi,
549 if (cwi == edges.end()) {
550 std::advance(cwi, -((
int)edges.size()));
553 if (ccwi == edges.begin()) {
554 std::advance(ccwi, edges.size() - 1);
559 const SUMOReal angleCurCCW = geomsCCW[*current].angleAt2D(0);
560 const SUMOReal angleCurCW = geomsCW[*current].angleAt2D(0);
561 const SUMOReal angleCCW = geomsCW[*ccwi].angleAt2D(0);
562 const SUMOReal angleCW = geomsCCW[*cwi].angleAt2D(0);
563 ccad = angleCCW - angleCurCCW;
567 cad = angleCurCW - angleCW;
578 EdgeVector::const_iterator i;
583 Position delta = edgebound1[1] - edgebound1[0];
584 delta.
set(-delta.
y(), delta.
x());
587 edgebound1.extrapolate2D(500);
589 if (cross.intersects(edgebound1)) {
590 Position np = cross.intersectionPosition2D(edgebound1);
594 if (cross.intersects(edgebound2)) {
595 Position np = cross.intersectionPosition2D(edgebound2);
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges.
PositionVector getSubpart2D(SUMOReal beginOffset, SUMOReal endOffset) const
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.
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...
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.
PositionVector getSubpartByIndex(int beginIndex, int count) const
SUMOReal getFloat(const std::string &name) const
Returns the SUMOReal-value of the named option (only for Option_Float)
std::map< NBEdge *, PositionVector > GeomsMap
static SUMOReal angleDiff(const SUMOReal angle1, const SUMOReal angle2)
Returns the difference of the second angle to the first angle in radiants.
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 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.
void extrapolate2D(const SUMOReal val, const bool onlyFirst=false)
NBNodeShapeComputer(const NBNode &node)
Constructor.
SUMOReal length2D() const
Returns the length.
std::vector< SUMOReal > distances(const PositionVector &s, bool perpendicular=false) const
EdgeVector myAllEdges
Vector of incoming and outgoing edges.
void push_front_noDoublePos(const Position &p)
const Position & getPosition() const
Returns the position of this node.
std::set< NBEdge * > EdgeSet
bool isSimpleContinuation() const
A point in 2D or 3D with translation and scaling methods.
void add(SUMOReal xoff, SUMOReal yoff, SUMOReal zoff)
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()
Computes the shape of the assigned junction.
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.
SUMOReal angleAt2D(int pos) const
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 move2side(SUMOReal amount)
static const SUMOReal UNSPECIFIED_RADIUS
unspecified lane width
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 ...
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.