68 #ifdef CHECK_MEMORY_LEAKS 70 #endif // CHECK_MEMORY_LEAKS 73 #define EXTEND_CROSSING_ANGLE_THRESHOLD 35.0 // degrees 75 #define SPLIT_CROSSING_WIDTH_THRESHOLD 1.5 // meters 76 #define SPLIT_CROSSING_ANGLE_THRESHOLD 5 // degrees 79 #define MIN_WEAVE_LENGTH 20.0 82 #define DEBUGCOND true 100 myApproaching(approaching), myCurrentOutgoing(currentOutgoing) {
104 std::set<int> approachedLanes;
106 const std::vector<NBEdge::Connection> conns = (*it)->getConnections();
107 for (std::vector<NBEdge::Connection>::const_iterator it_con = conns.begin(); it_con != conns.end(); ++it_con) {
109 approachedLanes.insert((*it_con).toLane);
117 for (
int i = 0; i < currentOutgoing->
getNumLanes(); ++i) {
120 && approachedLanes.count(i) == 0) {
135 NBEdge* incomingEdge = (*myApproaching)[src];
139 std::vector<int> approachingLanes =
141 assert(approachingLanes.size() != 0);
142 std::deque<int>* approachedLanes =
spread(approachingLanes, dest);
145 for (
int i = 0; i < (int)approachedLanes->size(); i++) {
146 assert((
int)approachingLanes.size() > i);
151 delete approachedLanes;
158 std::deque<int>* ret =
new std::deque<int>();
159 int noLanes = (int) approachingLanes.size();
163 ret->push_back(dest);
169 ret->push_back(dest);
173 while (noSet < noLanes) {
179 if (noOutgoingLanes == noSet) {
188 if (dest + loffset >= noOutgoingLanes) {
191 for (
int i = 0; i < (int)ret->size(); i++) {
192 (*ret)[i] = (*ret)[i] - 1;
197 ret->push_back(dest + loffset);
202 if (noOutgoingLanes == noSet) {
207 if (noSet < noLanes) {
210 if (dest < roffset) {
213 for (
int i = 0; i < (int)ret->size(); i++) {
214 (*ret)[i] = (*ret)[i] + 1;
217 ret->push_front(dest - roffset);
267 bool updateEdgeGeometries) {
274 if (updateEdgeGeometries) {
278 (*i)->setGeometry(geom);
283 (*i)->setGeometry(geom);
304 (*it).shape.mirrorX();
307 (*it_wa).shape.mirrorX();
333 for (std::set<NBTrafficLightDefinition*>::const_iterator i = trafficLights.begin(); i != trafficLights.end(); ++i) {
345 if ((*i)->getID().find(
"joined") == 0) {
357 for (std::set<NBTrafficLightDefinition*>::iterator it = oldDefs.begin(); it != oldDefs.end(); ++it) {
359 if (dynamic_cast<NBOwnTLDef*>(orig) == 0) {
361 const std::vector<NBNode*>& nodes = orig->
getNodes();
362 while (!nodes.empty()) {
363 newDef->
addNode(nodes.front());
364 nodes.front()->removeTrafficLight(orig);
377 (*it)->shiftTLConnectionLaneIndex(edge, offset);
404 remapRemoved(tc, dummy, incomingConnected, outgoingConnected);
453 if (checkLaneNumbers && in->
getNumLanes() != (*opposite)->getNumLanes()) {
471 NBNode* recordError)
const {
475 #ifdef DEBUG_SMOOTH_GEOM 477 std::cout <<
"computeSmoothShape node " <<
getID() <<
" init=" << init <<
"\n";
480 if (init.size() == 0) {
482 ret.push_back(begShape.back());
483 ret.push_back(endShape.front());
486 return bezier(init, numPoints).smoothedZFront();
501 const Position beg = begShape.back();
502 const Position end = endShape.front();
506 #ifdef DEBUG_SMOOTH_GEOM 507 if (
DEBUGCOND) std::cout <<
" bezierControlPoints failed beg=" << beg <<
" end=" << end
523 center.
sub(beg.
y() - end.
y(), end.
x() - beg.
x());
524 init.push_back(center);
529 endShapeBegLine.extrapolate2D(100,
true);
531 if (fabs(angle) <
M_PI / 4.) {
535 const SUMOReal halfDistance = dist / 2;
536 if (fabs(displacementAngle) <= straightThresh && fabs(angle) <= straightThresh) {
537 #ifdef DEBUG_SMOOTH_GEOM 538 if (
DEBUGCOND) std::cout <<
" bezierControlPoints identified straight line beg=" << beg <<
" end=" << end
539 <<
" angle=" <<
RAD2DEG(angle) <<
" displacementAngle=" <<
RAD2DEG(displacementAngle) <<
"\n";
542 }
else if (bendDeg > 22.5 && pow(bendDeg / 45, 2) / dist > 0.13) {
545 #ifdef DEBUG_SMOOTH_GEOM 546 if (
DEBUGCOND) std::cout <<
" bezierControlPoints found extreme s-curve, falling back to straight line beg=" << beg <<
" end=" << end
547 <<
" angle=" <<
RAD2DEG(angle) <<
" displacementAngle=" <<
RAD2DEG(displacementAngle)
548 <<
" dist=" << dist <<
" bendDeg=" << bendDeg <<
" bd2=" << pow(bendDeg / 45, 2)
549 <<
" displacementError=" << sin(displacementAngle) * dist
550 <<
" begShape=" << begShape <<
" endShape=" << endShape <<
"\n";
553 if (recordError != 0) {
558 const SUMOReal endLength = begShape[-2].distanceTo2D(begShape[-1]);
559 const SUMOReal off1 = endLength +
MIN2(extrapolateBeg, halfDistance);
561 const SUMOReal off2 = 100. -
MIN2(extrapolateEnd, halfDistance);
563 #ifdef DEBUG_SMOOTH_GEOM 564 if (
DEBUGCOND) std::cout <<
" bezierControlPoints found s-curve beg=" << beg <<
" end=" << end
565 <<
" angle=" <<
RAD2DEG(angle) <<
" displacementAngle=" <<
RAD2DEG(displacementAngle)
566 <<
" halfDistance=" << halfDistance <<
"\n";
575 Position intersect = endShapeBegLine.intersectionPosition2D(begShapeEndLineRev);
577 #ifdef DEBUG_SMOOTH_GEOM 579 std::cout <<
" bezierControlPoints failed beg=" << beg <<
" end=" << end <<
" intersect=" << intersect <<
"\n";
583 if (recordError != 0) {
590 const bool lengthenBeg = intersect.
distanceTo2D(beg) <= minControlLength;
591 const bool lengthenEnd = intersect.
distanceTo2D(end) <= minControlLength;
592 if (lengthenBeg && lengthenEnd) {
593 #ifdef DEBUG_SMOOTH_GEOM 594 if (
DEBUGCOND) std::cout <<
" bezierControlPoints failed beg=" << beg <<
" end=" << end <<
" intersect=" << intersect
597 if (recordError != 0) {
603 }
else if (lengthenBeg || lengthenEnd) {
605 init.push_back(endShapeBegLine.positionAtOffset2D(100 - minControlLength));
609 const SUMOReal z2 = endShapeBegLine.positionAtOffset2D(endShapeBegLine.nearest_offset_to_point2D(intersect)).z();
610 const SUMOReal z3 = 0.5 * (beg.
z() + end.
z());
614 if ((z1 <= z3 && z2 <= z3) || (z1 >= z3 && z2 >= z3)) {
619 intersect.
set(intersect.
x(), intersect.
y(), z);
620 init.push_back(intersect);
641 assert(con.
shape.size() > 0);
650 ret.append(it->second);
662 if (lane.endOffset > 0) {
684 if (thisRight && !rightTurnConflict) {
687 if (!(
foes(otherFromE, otherToE, fromE, toE) ||
myRequest == 0 || rightTurnConflict)) {
697 const bool bothLeft = thisLeft && otherLeft;
698 if (fromE == otherFromE && !thisRight) {
705 if (c.
tlID !=
"" && !bothLeft) {
708 if ((*it)->needsCont(fromE, toE, otherFromE, otherToE)) {
729 for (std::set<NBTrafficLightDefinition*>::const_iterator i = trafficLights.begin(); i != trafficLights.end(); ++i) {
731 if ((*i)->getNodes().size() > 1) {
733 (*i)->removeNode(
this);
734 (*i)->setParticipantsInformation();
735 (*i)->setTLControllingInformation();
763 }
else if (numConnections == 0) {
801 if (mismatchThreshold >= 0
834 for (
int i = inOffset; i < in->
getNumLanes(); ++i) {
866 std::swap(in1Offset, in2Offset);
895 std::swap(out1, out2);
896 std::swap(out1Offset, out2Offset);
919 for (
int i = inOffset; i < in->
getNumLanes(); ++i) {
943 inOffset += reduction;
944 for (
int i = outOffset; i < out->
getNumLanes(); ++i) {
956 EdgeVector::reverse_iterator i;
958 NBEdge* currentOutgoing = *i;
961 const int numApproaching = (int)approaching->size();
962 if (numApproaching != 0) {
976 const std::vector<NBEdge::Connection>& elv = incoming->
getConnections();
977 for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
979 if (c.
toEdge == currentOutgoing) {
982 unsatisfied &= ~satisfied;
985 if (unsatisfied != 0) {
988 while (unsatisfied != 0 && fromLane < incoming->getNumLanes()) {
990 for (
int toLane = 0; toLane < currentOutgoing->
getNumLanes(); ++toLane) {
992 if (satisfied != 0) {
995 unsatisfied &= ~satisfied;
1012 const std::vector<NBEdge::Connection> cons = (*i)->getConnections();
1013 for (std::vector<NBEdge::Connection>::const_iterator k = cons.begin(); k != cons.end(); ++k) {
1015 (*i)->removeFromConnections((*k).toEdge);
1026 (*i)->markAsInLane2LaneState();
1043 while (seen < minLength) {
1059 EdgeVector::const_iterator i = find(
myAllEdges.begin(),
1065 for (; *i != currentOutgoing;) {
1067 if ((*i)->getToNode() ==
this && (*i)->getTurnDestination() != currentOutgoing) {
1068 std::vector<int> connLanes = (*i)->getConnectionLanes(currentOutgoing);
1069 if (connLanes.size() != 0) {
1070 approaching->push_back(*i);
1101 for (EdgeVector::const_iterator i = which.begin(); i != which.end(); i++) {
1103 laneOff += (*i)->getNumLanes();
1133 for (EdgeVector::const_iterator i = which.begin(); i != which.end(); i++) {
1135 laneOff += (*i)->getNumLanes();
1150 int whichLaneOff,
int byLaneOff) {
1154 bool changed =
false;
1156 if (c.
replaceFrom(which, whichLaneOff, by, byLaneOff)) {
1159 if (c.
replaceTo(which, whichLaneOff, by, byLaneOff)) {
1173 for (NBConnectionVector::iterator k = prohibiting.begin(); k != prohibiting.end(); k++) {
1175 sprohibiting.
replaceFrom(which, whichLaneOff, by, byLaneOff);
1176 sprohibiting.
replaceTo(which, whichLaneOff, by, byLaneOff);
1236 if (find(edges.begin(), edges.end(), e) != edges.end()) {
1237 edges.erase(find(edges.begin(), edges.end(), e));
1239 if (edges.size() == 0) {
1254 if (mayDrive.
getFrom() == 0 ||
1255 mayDrive.
getTo() == 0 ||
1257 mustStop.
getTo() == 0) {
1259 WRITE_WARNING(
"Something went wrong during the building of a connection...");
1263 conn.push_back(mayDrive);
1270 int size = (int) edgeid.length();
1272 std::string
id = (*i)->
getID();
1273 if (
id.substr(0, size) == edgeid) {
1283 int size = (int) edgeid.length();
1285 std::string
id = (*i)->
getID();
1286 if (
id.substr(0, size) == edgeid) {
1311 if (removeFromConnections) {
1313 (*i)->removeFromConnections(edge);
1318 (*i)->replaceRemoved(edge, -1, 0, -1);
1327 EdgeVector::const_iterator i;
1329 NBNode* conn = (*i)->getFromNode();
1332 toAdd.
mul((
SUMOReal) 1.0 / sqrt(toAdd.
x()*toAdd.
x() + toAdd.
y()*toAdd.
y()));
1336 NBNode* conn = (*i)->getToNode();
1339 toAdd.
mul((
SUMOReal) 1.0 / sqrt(toAdd.
x()*toAdd.
x() + toAdd.
y()*toAdd.
y()));
1343 if (pos.
x() == 0 && pos.
y() == 0) {
1355 (*i)->invalidateConnections();
1363 (*i)->invalidateConnections();
1390 const NBEdge* prohibitorFrom,
const NBEdge* prohibitorTo,
int prohibitorFromLane,
1392 if (from != prohibitorFrom) {
1416 lefthand = !lefthand;
1423 if ((!lefthand && fromLane <= prohibitorFromLane) ||
1424 (lefthand && fromLane >= prohibitorFromLane)) {
1446 std::vector<NBEdge*>::const_iterator i = std::find(
myAllEdges.begin(),
myAllEdges.end(), from);
1456 const NBEdge*
const possProhibitedFrom,
const NBEdge*
const possProhibitedTo,
1457 bool regardNonSignalisedLowerPriority)
const {
1459 possProhibitedFrom, possProhibitedTo,
1460 regardNonSignalisedLowerPriority);
1466 const NBEdge*
const from2,
const NBEdge*
const to2)
const {
1475 assert(find(incoming.begin(), incoming.end(), removed) == incoming.end());
1476 bool changed =
true;
1482 for (NBConnectionProhibits::iterator i = blockedConnectionsTmp.begin(); i != blockedConnectionsTmp.end(); i++) {
1487 bool blockedChanged =
false;
1489 NBConnectionVector::const_iterator j;
1490 for (j = blocked.begin(); j != blocked.end(); j++) {
1492 if (sblocked.
getFrom() == removed || sblocked.
getTo() == removed) {
1493 blockedChanged =
true;
1497 for (j = blocked.begin(); blockedChanged && j != blocked.end(); j++) {
1499 if (sblocked.
getFrom() == removed && sblocked.
getTo() == removed) {
1503 }
else if (sblocked.
getFrom() == removed) {
1504 assert(sblocked.
getTo() != removed);
1505 for (EdgeVector::const_iterator k = incoming.begin(); k != incoming.end(); k++) {
1508 }
else if (sblocked.
getTo() == removed) {
1509 assert(sblocked.
getFrom() != removed);
1510 for (EdgeVector::const_iterator k = outgoing.begin(); k != outgoing.end(); k++) {
1517 if (blockedChanged) {
1518 blockedConnectionsNew[blocker] = newBlocked;
1523 if (blocker.
getFrom() == removed && blocker.
getTo() == removed) {
1528 }
else if (blocker.
getFrom() == removed) {
1529 assert(blocker.
getTo() != removed);
1531 for (EdgeVector::const_iterator k = incoming.begin(); k != incoming.end(); k++) {
1534 }
else if (blocker.
getTo() == removed) {
1535 assert(blocker.
getFrom() != removed);
1537 for (EdgeVector::const_iterator k = outgoing.begin(); k != outgoing.end(); k++) {
1541 blockedConnectionsNew[blocker] = blocked;
1555 if (outgoing == 0) {
1566 if (
abs((
int) angle) + 1 < 45) {
1573 EdgeVector::const_iterator i =
1580 while ((*i) != incoming) {
1594 EdgeVector::const_iterator i =
1601 while ((*i) != incoming) {
1618 bool mayDefinitelyPass,
const std::string& tlID)
const {
1625 if (outgoing == 0) {
1637 if ((!incoming->
isInnerEdge() &&
mustBrake(incoming, outgoing, fromlane, toLane,
true)) && !mayDefinitelyPass) {
1651 EdgeVector::const_iterator i;
1664 std::set<NBNode*> origSet;
1666 origSet.insert((*i)->getFromNode());
1668 if (origSet.size() < 2) {
1676 if (opposite != 0) {
1680 if (!(*i)->expandableBy(continuation)) {
1696 std::vector<std::pair<NBEdge*, NBEdge*> >
1699 std::vector<std::pair<NBEdge*, NBEdge*> > ret;
1703 std::pair<NBEdge*, NBEdge*>(
1711 assert(opposite != 0);
1713 ret.push_back(std::pair<NBEdge*, NBEdge*>(*i, continuation));
1734 if (shape.size() > 1) {
1745 if ((*i)->getToNode() == n) {
1760 back_inserter(edges));
1762 back_inserter(edges));
1763 for (EdgeVector::const_iterator j = edges.begin(); j != edges.end(); ++j) {
1774 for (EdgeVector::const_iterator k = edges2.begin(); k != edges2.end(); ++k) {
1775 if ((*k)->getFromNode()->isDistrict() || (*k)->getToNode()->isDistrict()) {
1799 std::cout <<
"guess crossings for " <<
getID() <<
"\n";
1803 std::vector<std::pair<NBEdge*, bool> > normalizedLanes;
1804 for (EdgeVector::const_iterator it = allEdges.begin(); it != allEdges.end(); ++it) {
1806 const std::vector<NBEdge::Lane>& lanes = edge->
getLanes();
1808 for (std::vector<NBEdge::Lane>::const_reverse_iterator it_l = lanes.rbegin(); it_l != lanes.rend(); ++it_l) {
1809 normalizedLanes.push_back(std::make_pair(edge, ((*it_l).permissions &
SVC_PEDESTRIAN) != 0));
1812 for (std::vector<NBEdge::Lane>::const_iterator it_l = lanes.begin(); it_l != lanes.end(); ++it_l) {
1813 normalizedLanes.push_back(std::make_pair(edge, ((*it_l).permissions &
SVC_PEDESTRIAN) != 0));
1818 int firstSidewalk = -1;
1819 for (
int i = 0; i < (int)normalizedLanes.size(); ++i) {
1820 if (normalizedLanes[i].second) {
1825 int hadCandidates = 0;
1826 std::vector<int> connectedCandidates;
1827 if (firstSidewalk != -1) {
1829 std::vector<std::pair<NBEdge*, bool> > tmp;
1830 copy(normalizedLanes.begin() + firstSidewalk, normalizedLanes.end(), std::back_inserter(tmp));
1831 copy(normalizedLanes.begin(), normalizedLanes.begin() + firstSidewalk, std::back_inserter(tmp));
1832 normalizedLanes = tmp;
1835 for (
int i = 0; i < (int)normalizedLanes.size(); ++i) {
1836 NBEdge* edge = normalizedLanes[i].first;
1837 const bool allowsPed = normalizedLanes[i].second;
1839 std::cout <<
" cands=" <<
toString(candidates) <<
" edge=" << edge->
getID() <<
" allowsPed=" << allowsPed <<
"\n";
1841 if (!allowsPed && (candidates.size() == 0 || candidates.back() != edge)) {
1842 candidates.push_back(edge);
1843 }
else if (allowsPed) {
1844 if (candidates.size() > 0) {
1850 connectedCandidates.push_back(n);
1857 if (hadCandidates > 0 && candidates.size() > 0) {
1863 connectedCandidates.push_back(n);
1869 std::cout <<
" hadCandidates=" << hadCandidates <<
" connectedCandidates=" <<
toString(connectedCandidates) <<
"\n";
1871 if (hadCandidates == 2 && connectedCandidates.size() == 2) {
1873 if (connectedCandidates.back() <= connectedCandidates.front()) {
1874 numGuessed -= connectedCandidates.back();
1877 numGuessed -= connectedCandidates.front();
1883 std::cout <<
"guessedCrossings:\n";
1885 std::cout <<
" edges=" <<
toString((*it).edges) <<
"\n";
1895 std::cout <<
"checkCrossing candidates=" <<
toString(candidates) <<
"\n";
1897 if (candidates.size() == 0) {
1899 std::cout <<
"no crossing added (numCandidates=" << candidates.size() <<
")\n";
1905 for (
int i = 0; i < (int)candidates.size(); ++i) {
1906 NBEdge* edge = candidates[i];
1911 std::cout <<
"no crossing added (found angle difference of " << fabs(angle - prevAngle) <<
" at i=" << i <<
"\n";
1917 std::cout <<
"no crossing added (uncontrolled, edge with speed > " << edge->
getSpeed() <<
")\n";
1923 if (candidates.size() == 1) {
1926 std::cout <<
"adding crossing: " <<
toString(candidates) <<
"\n";
1932 for (EdgeVector::iterator it = candidates.begin(); it != candidates.end(); ++it) {
1933 SUMOReal angle = (*it)->getCrossingAngle(
this);
1934 if (it != candidates.begin()) {
1935 NBEdge* prev = *(it - 1);
1943 prevPos = prev->
getLanes()[laneI].shape[-1];
1946 prevPos = prev->
getLanes()[laneI].shape[0];
1951 currPos = curr->
getLanes()[laneI].shape[0];
1954 currPos = curr->
getLanes()[laneI].shape[-1];
1960 <<
" prevAngle=" << prevAngle
1961 <<
" angle=" << angle
1962 <<
" intermediateWidth=" << intermediateWidth
1975 std::cout <<
"adding crossing: " <<
toString(candidates) <<
"\n";
1986 std::sort(edges.begin(), edges.end());
1991 std::sort(edgesOfCrossing.begin(), edgesOfCrossing.end());
1992 if (edgesOfCrossing == edges) {
2002 for (
int i = startIndex; i < (int)normalizedLanes.size(); ++i) {
2003 if (!normalizedLanes[i].second) {
2016 if (discardInvalid) {
2018 if ((*it).prevWalkingArea ==
"" || (*it).nextWalkingArea ==
"") {
2019 WRITE_WARNING(
"Discarding invalid crossing '" + (*it).id +
"' at junction '" +
getID() +
"' with edges '" +
toString((*it).edges) +
"'.");
2021 if ((*it_wa).nextCrossing == (*it).id) {
2022 (*it_wa).nextCrossing =
"";
2039 int noInternalNoSplits = 0;
2041 const std::vector<NBEdge::Connection>& elv = (*i)->getConnections();
2042 for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
2043 if ((*k).toEdge == 0) {
2046 noInternalNoSplits++;
2052 (*i)->buildInnerEdges(*
this, noInternalNoSplits, lno, splitNo);
2060 (*i)->buildInnerEdges(*
this, noInternalNoSplits, lno, splitNo);
2070 std::cout <<
"build crossings for " <<
getID() <<
":\n";
2080 (*it).nextWalkingArea =
"";
2081 (*it).prevWalkingArea =
"";
2084 std::cout <<
" crossing=" << (*it).id <<
" edges=" <<
toString(edges);
2090 std::cout <<
" sortedEdges=" <<
toString(edges) <<
"\n";
2094 int maxAngleDiffIndex = 0;
2095 for (
int i = 0; i < (int) edges.size(); i++) {
2097 edges[(i + 1) % edges.size()]->getAngleAtNodeToCenter(
this));
2102 std::cout <<
" i=" << i <<
" a1=" << edges[i]->getAngleAtNodeToCenter(
this) <<
" a2=" << edges[(i + 1) % edges.size()]->getAngleAtNodeToCenter(
this) <<
" diff=" << diff <<
"\n";
2104 if (diff > maxAngleDiff) {
2105 maxAngleDiff = diff;
2106 maxAngleDiffIndex = i;
2109 if (maxAngleDiff > 2 && maxAngleDiff < 360 - 2) {
2111 std::rotate(edges.begin(), edges.begin() + (maxAngleDiffIndex + 1) % edges.size(), edges.end());
2113 std::cout <<
" rotatedEdges=" <<
toString(edges);
2117 std::reverse(edges.begin(), edges.end());
2119 std::cout <<
" finalEdges=" <<
toString(edges) <<
"\n";
2122 (*it).shape.clear();
2123 const int begDir = (edges.front()->getFromNode() ==
this ?
FORWARD :
BACKWARD);
2124 const int endDir = (edges.back()->getToNode() ==
this ?
FORWARD :
BACKWARD);
2125 if (edges.front()->getFirstNonPedestrianLaneIndex(begDir) < 0
2126 || edges.back()->getFirstNonPedestrianLaneIndex(endDir) < 0) {
2128 WRITE_WARNING(
"Discarding invalid crossing '" + (*it).id +
"' at junction '" +
getID() +
"' with edges '" +
toString((*it).edges) +
"'.");
2131 NBEdge::Lane crossingBeg = edges.front()->getFirstNonPedestrianLane(begDir);
2132 NBEdge::Lane crossingEnd = edges.back()->getFirstNonPedestrianLane(endDir);
2139 (*it).shape.push_back(crossingBeg.
shape[begDir ==
FORWARD ? 0 : -1]);
2140 (*it).shape.push_back(crossingEnd.
shape[endDir ==
FORWARD ? -1 : 0]);
2154 std::cout <<
"build walkingAreas for " <<
getID() <<
":\n";
2161 std::vector<std::pair<NBEdge*, NBEdge::Lane> > normalizedLanes;
2162 for (EdgeVector::const_iterator it = allEdges.begin(); it != allEdges.end(); ++it) {
2164 const std::vector<NBEdge::Lane>& lanes = edge->
getLanes();
2166 for (std::vector<NBEdge::Lane>::const_reverse_iterator it_l = lanes.rbegin(); it_l != lanes.rend(); ++it_l) {
2170 normalizedLanes.push_back(std::make_pair(edge, l));
2173 for (std::vector<NBEdge::Lane>::const_iterator it_l = lanes.begin(); it_l != lanes.end(); ++it_l) {
2178 normalizedLanes.push_back(std::make_pair(edge, l));
2184 std::vector<std::pair<int, int> > waIndices;
2186 NBEdge* prevEdge = normalizedLanes.back().first;
2187 for (
int i = 0; i < (int)normalizedLanes.size(); ++i) {
2188 NBEdge* edge = normalizedLanes[i].first;
2196 waIndices.push_back(std::make_pair(start, i - start));
2206 <<
" waI=" << waIndices.size() <<
" crossingBetween=" <<
crossingBetween(edge, prevEdge) <<
"\n";
2211 const int waNumLanes = (int)normalizedLanes.size() - start;
2212 if (waIndices.size() == 0) {
2213 waIndices.push_back(std::make_pair(start, waNumLanes));
2215 std::cout <<
" single wa, end at wrap-around\n";
2218 if (waIndices.front().first == 0) {
2219 NBEdge* edge = normalizedLanes.front().first;
2220 NBEdge* prevEdge = normalizedLanes.back().first;
2223 waIndices.push_back(std::make_pair(start, waNumLanes));
2225 std::cout <<
" do not wrap around, turn-around in between\n";
2229 waIndices.front().first = start;
2230 waIndices.front().second = waNumLanes + waIndices.front().second;
2232 std::cout <<
" wrapping around\n";
2237 waIndices.push_back(std::make_pair(start, waNumLanes));
2239 std::cout <<
" end at wrap-around\n";
2245 std::cout <<
" normalizedLanes=" << normalizedLanes.size() <<
" waIndices:\n";
2246 for (
int i = 0; i < (int)waIndices.size(); ++i) {
2247 std::cout <<
" " << waIndices[i].first <<
", " << waIndices[i].second <<
"\n";
2251 for (
int i = 0; i < (int)waIndices.size(); ++i) {
2252 const bool buildExtensions = waIndices[i].second != (int)normalizedLanes.size();
2253 const int start = waIndices[i].first;
2254 const int prev = start > 0 ? start - 1 : (int)normalizedLanes.size() - 1;
2255 const int count = waIndices[i].second;
2256 const int end = (start + count) % normalizedLanes.size();
2260 std::cout <<
"build walkingArea " << wa.
id <<
" start=" << start <<
" end=" << end <<
" count=" << count <<
" prev=" << prev <<
":\n";
2267 bool connectsCrossing =
false;
2268 std::vector<Position> connectedPoints;
2271 std::cout <<
" crossing=" << (*it).id <<
" sortedEdges=" <<
toString((*it).edges) <<
"\n";
2273 if ((*it).edges.back() == normalizedLanes[end].first
2274 && (normalizedLanes[end].second.permissions &
SVC_PEDESTRIAN) == 0) {
2276 if ((*it).nextWalkingArea !=
"") {
2278 +
"'; crossing '" + (*it).id
2279 +
"' targets '" + (*it).nextWalkingArea
2280 +
"' and '" + wa.
id +
"'.");
2282 (*it).nextWalkingArea = wa.
id;
2283 endCrossingWidth = (*it).width;
2284 endCrossingShape = (*it).shape;
2286 connectsCrossing =
true;
2287 connectedPoints.push_back((*it).shape[-1]);
2289 std::cout <<
" crossing " << (*it).id <<
" ends\n";
2292 if ((*it).edges.front() == normalizedLanes[prev].first
2293 && (normalizedLanes[prev].second.permissions &
SVC_PEDESTRIAN) == 0) {
2295 if ((*it).prevWalkingArea !=
"") {
2297 +
"'; crossing '" + (*it).id
2298 +
"' is targeted by '" + (*it).prevWalkingArea
2299 +
"' and '" + wa.
id +
"'.");
2301 (*it).prevWalkingArea = wa.
id;
2303 startCrossingWidth = (*it).width;
2304 startCrossingShape = (*it).shape;
2306 connectsCrossing =
true;
2307 connectedPoints.push_back((*it).shape[0]);
2309 std::cout <<
" crossing " << (*it).id <<
" starts\n";
2312 if (
gDebugFlag1) std::cout <<
" check connections to crossing " << (*it).id
2313 <<
" cFront=" << (*it).edges.front()->getID() <<
" cBack=" << (*it).edges.back()->getID()
2314 <<
" wEnd=" << normalizedLanes[end].first->getID() <<
" wStart=" << normalizedLanes[start].first->getID()
2315 <<
" wStartPrev=" << normalizedLanes[prev].first->getID()
2318 if (count < 2 && !connectsCrossing) {
2321 std::cout <<
" not relevant for walking: count=" << count <<
" connectsCrossing=" << connectsCrossing <<
"\n";
2326 std::set<NBEdge*> connected;
2327 for (
int j = 0; j < count; ++j) {
2328 const int nlI = (start + j) % normalizedLanes.size();
2329 NBEdge* edge = normalizedLanes[nlI].first;
2332 if (connected.count(edge) == 0) {
2340 connected.insert(edge);
2347 if (buildExtensions) {
2349 if (startCrossingShape.size() > 0) {
2351 std::cout <<
" extension at startCrossing shape=" << startCrossingShape <<
"\n";
2353 startCrossingShape.
move2side(startCrossingWidth / 2);
2355 startCrossingShape.
move2side(-startCrossingWidth);
2359 if (endCrossingShape.size() > 0) {
2361 std::cout <<
" extension at endCrossing shape=" << endCrossingShape <<
"\n";
2363 endCrossingShape.
move2side(endCrossingWidth / 2);
2365 endCrossingShape.
move2side(-endCrossingWidth);
2370 && normalizedLanes.size() == 2) {
2372 NBEdge* e1 = *connected.begin();
2373 NBEdge* e2 = *(++connected.begin());
2376 std::cout <<
" not building a walkingarea since normal connections exist\n";
2382 if (cornerDetail > 0) {
2383 int smoothEnd = end;
2384 int smoothPrev = prev;
2386 if (endCrossingWidth > 0 && normalizedLanes[smoothEnd].second.permissions == 0) {
2387 smoothEnd = (smoothEnd + 1) % normalizedLanes.size();
2389 if (startCrossingWidth > 0 && normalizedLanes[smoothPrev].second.permissions == 0) {
2390 if (smoothPrev == 0) {
2391 smoothPrev = (int)normalizedLanes.size() - 1;
2396 PositionVector begShape = normalizedLanes[smoothEnd].second.shape;
2397 begShape = begShape.
reverse();
2399 begShape.
move2side(normalizedLanes[smoothEnd].second.width / 2);
2400 PositionVector endShape = normalizedLanes[smoothPrev].second.shape;
2401 endShape.
move2side(normalizedLanes[smoothPrev].second.width / 2);
2405 <<
" end=" << smoothEnd <<
" prev=" << smoothPrev
2406 <<
" endCrossingWidth=" << endCrossingWidth <<
" startCrossingWidth=" << startCrossingWidth
2407 <<
" begShape=" << begShape <<
" endShape=" << endShape <<
" smooth curve=" << curve <<
"\n";
2408 if (curve.size() > 2) {
2409 curve.erase(curve.begin());
2411 if (endCrossingWidth > 0) {
2412 wa.
shape.pop_back();
2414 if (startCrossingWidth > 0) {
2422 int combinations = 0;
2423 for (std::vector<Position>::const_iterator it1 = connectedPoints.begin(); it1 != connectedPoints.end(); ++it1) {
2424 for (std::vector<Position>::const_iterator it2 = connectedPoints.begin(); it2 != connectedPoints.end(); ++it2) {
2434 std::cout <<
" combinations=" << combinations <<
" connectedPoints=" << connectedPoints <<
"\n";
2437 if (combinations > 0) {
2447 std::cout <<
" checkIntermediate: prev=" << prev.
id <<
" next=" << next.
id <<
" prev.nextWA=" << prev.
nextWalkingArea <<
"\n";
2451 WRITE_WARNING(
"Invalid pedestrian topology: crossing '" + prev.
id +
"' has no target.");
2461 wa.
shape.push_back(tmp[-1]);
2463 wa.
shape.push_back(tmp[-1]);
2467 wa.
shape.push_back(tmp[0]);
2469 wa.
shape.push_back(tmp[0]);
2474 std::cout <<
" build wa=" << wa.
id <<
"\n";
2488 EdgeVector::const_iterator it1 = find(edges.begin(), edges.end(), e1);
2489 EdgeVector::const_iterator it2 = find(edges.begin(), edges.end(), e2);
2490 if (it1 != edges.end() && it2 != edges.end()) {
2506 while (it != it_end) {
2507 result.push_back(*it);
2528 if (
MAX2(angle0, angle1) <= 160) {
2558 EdgeSet edgeSet(edges.begin(), edges.end());
2560 EdgeSet edgeSet2((*it).edges.begin(), (*it).edges.end());
2561 if (edgeSet == edgeSet2) {
2573 if ((*it).id ==
id) {
2577 throw ProcessError(
"Request for unknown crossing '" +
id +
"'");
2583 if ((*it).id ==
id) {
2587 throw ProcessError(
"Request for unknown crossing '" +
id +
"'");
2594 (*it).tlLinkNo = startIndex++;
2627 std::cout <<
" angles:\n";
2628 for (EdgeVector::const_iterator it = result.begin(); it != result.end(); ++it) {
2629 std::cout <<
" edge=" << (*it)->getID() <<
" edgeAngle=" << (*it)->getAngleAtNode(
this) <<
" angleToShape=" << (*it)->getAngleAtNodeToCenter(
this) <<
"\n";
2631 std::cout <<
" allEdges before: " <<
toString(result) <<
"\n";
2636 std::cout <<
" allEdges sorted: " <<
toString(result) <<
"\n";
2638 rotate(result.begin(), std::find(result.begin(), result.end(), *
myAllEdges.begin()), result.end());
2640 std::cout <<
" allEdges rotated: " <<
toString(result) <<
"\n";
2651 assert(
id[0] ==
':');
2652 std::string::size_type sep_index =
id.rfind(
'_');
2653 if (sep_index == std::string::npos) {
2654 WRITE_ERROR(
"Invalid lane id '" +
id +
"' (missing '_').");
2657 sep_index =
id.substr(0, sep_index).rfind(
'_');
2658 if (sep_index == std::string::npos) {
2659 WRITE_ERROR(
"Invalid lane id '" +
id +
"' (missing '_').");
2662 return id.substr(1, sep_index - 1);
2672 if (turnDest != 0) {
2693 if ((*i)->rightOnRedConflict(index, foeIndex)) {
2710 std::vector<NBNode::Crossing>& crossings =
myCrossings;
2718 std::vector<NBEdge*>::iterator j;
2719 for (j = allEdges.begin(); j != allEdges.end() - 1 && j != allEdges.end(); ++j) {
2722 if (allEdges.size() > 1 && j != allEdges.end()) {
2726 NBEdge* firstOfAll = allEdges.front();
2727 NBEdge* firstOfIncoming = incoming.size() > 0 ? incoming.front() : 0;
2728 NBEdge* firstOfOutgoing = outgoing.size() > 0 ? outgoing.front() : 0;
2734 rotate(allEdges.begin(), std::find(allEdges.begin(), allEdges.end(), firstOfAll), allEdges.end());
2735 if (firstOfIncoming != 0) {
2736 rotate(incoming.begin(), std::find(incoming.begin(), incoming.end(), firstOfIncoming), incoming.end());
2738 if (firstOfOutgoing != 0) {
2739 rotate(outgoing.begin(), std::find(outgoing.begin(), outgoing.end(), firstOfOutgoing), outgoing.end());
2744 if (incoming.size() == outgoing.size() && incoming.front() == allEdges.front()) {
2745 std::vector<NBEdge*>::const_iterator in, out;
2746 std::vector<NBEdge*> allTmp;
2747 for (in = incoming.begin(), out = outgoing.begin(); in != incoming.end(); ++in, ++out) {
2748 if ((*in)->isTurningDirectionAt(*out)) {
2749 allTmp.push_back(*in);
2750 allTmp.push_back(*out);
2755 if (allTmp.size() == allEdges.size()) {
bool gDebugFlag1
global utility flags for debugging
void sub(SUMOReal dx, SUMOReal dy)
Substracts the given position from this one.
The link is a partial left direction.
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges (The edges which yield in this node)
void replaceOutgoing(const EdgeVector &which, NBEdge *const by)
Replaces outgoing edges from the vector (source) by the given edge.
Position getEmptyDir() const
Returns something like the most unused direction Should only be used to add source or sink nodes...
static SUMOReal getCWAngleDiff(SUMOReal angle1, SUMOReal angle2)
Returns the distance of second angle from first angle clockwise.
A structure which describes a connection between edges or lanes.
int numAvailableLanes() const
@ get number of avaliable lanes
int toLane
The lane the connections yields in.
void setRoundabout()
update the type of this node as a roundabout
std::vector< Crossing > myCrossings
Vector of crossings.
Position getCenter() const
Returns a position that is guaranteed to lie within the node shape.
static const SUMOReal UNSPECIFIED_WIDTH
unspecified lane width
SUMOReal width
This lane's width.
ApproachingDivider(EdgeVector *approaching, NBEdge *currentOutgoing)
Constructor.
static SUMOReal getCCWAngleDiff(SUMOReal angle1, SUMOReal angle2)
Returns the distance of second angle from first angle counter-clockwise.
PositionVector shape
The lane's shape.
const SUMOReal SUMO_const_laneWidth
virtual void addNode(NBNode *node)
Adds a node to the traffic light logic.
int buildCrossings()
build pedestrian crossings
SUMOReal nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
bool isInStringVector(const std::string &optionName, const std::string &itemName)
Returns the named option is a list of string values containing the specified item.
Sorts incoming and outgoing edges clockwise around the given node.
std::string viaID
if Connection have a via, ID of it
NBEdge * toEdge
The edge the connections yields in.
#define EXTEND_CROSSING_ANGLE_THRESHOLD
Sorts crossings by minimum clockwise clockwise edge angle. Use the ordering found in myAllEdges of th...
void shiftTLConnectionLaneIndex(NBEdge *edge, int offset)
patches loaded signal plans by modifying lane indices
std::string id
the (edge)-id of this crossing
void add(const Position &pos)
Adds the given position to this one.
bool isDistrict() const
check if node is a district
PositionVector myPoly
the (outer) shape of the junction
void execute(const int src, const int dest)
the bresenham-callback
NBEdge * getOppositeIncoming(NBEdge *e) const
returns the opposite incoming edge of certain edge
SUMOReal myRadius
the turning radius (for all corners) at this node in m.
SumoXMLNodeType myType
The type of the junction.
A container for traffic light definitions and built programs.
SUMOReal length
This lane's width.
void reinit(const Position &position, SumoXMLNodeType type, bool updateEdgeGeometries=false)
Resets initial values.
SUMOReal width
This lane's width.
static SUMOReal normRelAngle(SUMOReal angle1, SUMOReal angle2)
ensure that reverse relAngles (>=179.999) always count as turnarounds (-180)
bool isTLControlled() const
Returns whether this node is controlled by any tls.
static PositionVector bezierControlPoints(const PositionVector &begShape, const PositionVector &endShape, bool isTurnaround, SUMOReal extrapolateBeg, SUMOReal extrapolateEnd, bool &ok, NBNode *recordError=0, SUMOReal straightThresh=DEG2RAD(5))
get bezier control points
Some static methods for string processing.
bool forbids(const NBEdge *const possProhibitorFrom, const NBEdge *const possProhibitorTo, const NBEdge *const possProhibitedFrom, const NBEdge *const possProhibitedTo, bool regardNonSignalisedLowerPriority) const
Returns the information whether "prohibited" flow must let "prohibitor" flow pass.
TrafficLightType getType() const
get the algorithm type (static etc..)
const std::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
int myCrossingsLoadedFromSumoNet
number of crossings loaded from a sumo net
This class computes shapes of junctions.
This is an uncontrolled, minor link, has to stop.
const Crossing & getCrossing(const std::string &id) const
return the crossing with the given id
void removeEdge(NBEdge *edge, bool removeFromConnections=true)
Removes edge from this node and optionally removes connections as well.
SUMOReal getEndAngle() const
Returns the angle at the end of the edge (relative to the node shape center) The angle is computed in...
void addIncomingEdge(NBEdge *edge)
adds an incoming edge
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
The representation of a single edge during network building.
Class to sort edges by their angle in relation to the given edge.
bool replaceTo(NBEdge *which, NBEdge *by)
replaces the to-edge by the one given
static void swapWhenReversed(const NBNode *const n, const std::vector< NBEdge * >::iterator &i1, const std::vector< NBEdge * >::iterator &i2)
Assures correct order for same-angle opposite-direction edges.
The link is a 180 degree turn.
int numNormalConnections() const
return the number of lane-to-lane connections at this junction (excluding crossings) ...
bool hasOutgoing(const NBEdge *const e) const
Returns whether the given edge starts at this node.
std::string getDescription(const NBEdge *parent) const
get string describing this connection
A container for districts.
The base class for traffic light logic definitions.
EdgeVector edgesBetween(const NBEdge *e1, const NBEdge *e2) const
return all edges that lie clockwise between the given edges
EdgeVector getIncomingEdges() const
Returns the list of incoming edges unsorted.
bool isJoinedTLSControlled() const
Returns whether this node is controlled by a tls that spans over more than one node.
void buildBitfieldLogic()
PositionVector computeInternalLaneShape(NBEdge *fromE, const NBEdge::Connection &con, int numPoints, NBNode *recordError=0) const
Compute the shape for an internal lane.
void removeDoubleEdges()
remove duble edges
SUMOReal getLaneWidth() const
Returns the default width of lanes of this edge.
#define SUMO_MAX_CONNECTIONS
the maximum number of connections across an intersection
PositionVector shape
The lane's shape.
#define SPLIT_CROSSING_ANGLE_THRESHOLD
PositionVector getSubpartByIndex(int beginIndex, int count) const
get subpart of a position vector using index and a cout
void buildWalkingAreas(int cornerDetail)
build pedestrian walking areas and set connections from/to walkingAreas
bool isInnerEdge() const
Returns whether this edge was marked as being within an intersection.
This is an uncontrolled, right-before-left link.
SUMOReal getFloat(const std::string &name) const
Returns the SUMOReal-value of the named option (only for Option_Float)
static void nextCW(const EdgeVector &edges, EdgeVector::const_iterator &from)
bool isForbidden(SVCPermissions permissions)
Returns whether an edge with the given permission is a forbidden edge.
void remapConnections(const EdgeVector &incoming)
Remaps the connection in a way that allows the removal of it.
std::string id
the (edge)-id of this walkingArea
EdgeVector getEdgesSortedByAngleAtNodeCenter() const
returns the list of all edges sorted clockwise by getAngleAtNodeToCenter
bool checkIsRemovable() const
check if node is removable
void mirrorX()
mirror coordinates along the x-axis
bool around(const Position &p, SUMOReal offset=0) const
Returns the information whether the position vector describes a polygon lying around the given point...
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission is a railway edge.
Lane & getLaneStruct(int lane)
void removeTrafficLight(NBTrafficLightDefinition *tlDef)
Removes the given traffic light from this node.
void setCustomShape(const PositionVector &shape)
set the junction shape
The link is controlled by a tls which is off, not blinking, may pass.
static SUMOReal angleDiff(const SUMOReal angle1, const SUMOReal angle2)
Returns the difference of the second angle to the first angle in radiants.
NBConnectionProhibits myBlockedConnections
The container for connection block dependencies.
void writeLogic(std::string key, OutputDevice &into, const bool checkLaneFoes) const
bool hasIncoming(const NBEdge *const e) const
Returns whether the given edge ends at this node.
SUMOReal x() const
Returns the x-position.
This is an uncontrolled, all-way stop link.
void addOutgoingEdge(NBEdge *edge)
adds an outgoing edge
NBEdge * getFrom() const
returns the from-edge (start of the connection)
Position positionAtOffset2D(SUMOReal pos, SUMOReal lateralOffset=0) const
Returns the position at the given length.
void replaceOutgoing(NBEdge *which, NBEdge *by, int laneOff)
Replaces occurences of the first edge within the list of outgoing by the second Connections are remap...
This is an uncontrolled, zipper-merge link.
The link is a (hard) left direction.
#define WRITE_WARNING(msg)
bool isConnectedTo(const NBEdge *e) const
Returns the information whethe a connection to the given edge has been added (or computed) ...
void sortEdges(bool useNodeShape)
sort all edge containers for this node
The connection was computed and validated.
SUMOReal distance2D(const Position &p, bool perpendicular=false) const
closest 2D-distance to point p (or -1 if perpendicular is true and the point is beyond this vector) ...
static OptionsCont & getOptions()
Retrieves the options.
static bool rightTurnConflict(const NBEdge *from, const NBEdge *to, int fromLane, const NBEdge *prohibitorFrom, const NBEdge *prohibitorTo, int prohibitorFromLane, bool lefthand=false)
return whether the given laneToLane connection is a right turn which must yield to a bicycle crossing...
PositionVector reverse() const
reverse position vector
NBRequest * myRequest
Node requests.
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)...
CustomShapeMap myCustomLaneShapes
custom lane shapes
EdgeVector getConnectedEdges() const
Returns the list of outgoing edges unsorted.
The link is a straight direction.
SUMOTime getOffset()
Returns the offset.
PositionVector shape
shape of Connection
NBDistrict * myDistrict
The district the node is the centre of.
A class representing a single district.
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges (The edges which start at this node)
void extrapolate2D(const SUMOReal val, const bool onlyFirst=false)
extrapolate position vector in two dimensions (Z is ignored)
SUMOReal getLoadedLength() const
Returns the length was set explicitly or the computed length if it wasn't set.
An (internal) definition of a single lane of an edge.
static bool mustBrakeForCrossing(const NBNode *node, const NBEdge *const from, const NBEdge *const to, const NBNode::Crossing &crossing)
Returns the information whether the described flow must brake for the given crossing.
const std::string & getID() const
Returns the id.
EdgeVector myAllEdges
Vector of incoming and outgoing edges.
SVCPermissions permissions
List of vehicle types that are allowed on this lane.
bool needsCont(const NBEdge *fromE, const NBEdge *otherFromE, const NBEdge::Connection &c, const NBEdge::Connection &otherC) const
whether an internal junction should be built at from and respect other
void computeLanes2Lanes()
computes the connections of lanes to edges
void invalidateIncomingConnections()
invalidate incoming connections
SUMOReal myDisplacementError
geometry error after computation of internal lane shapes
void push_front_noDoublePos(const Position &p)
insert in front a non double position
void removeCrossing(const EdgeVector &edges)
remove a pedestrian crossing from this node (identified by its edges)
const Position & getPosition() const
bool replaceFrom(NBEdge *which, NBEdge *by)
replaces the from-edge by the one given
std::set< NBEdge * > EdgeSet
container for unique edges
Lanes to lanes - relationships are loaded; no recheck is necessary/wished.
std::string prevWalkingArea
the lane-id of the previous walkingArea
NBEdge * getPossiblySplittedIncoming(const std::string &edgeid)
get possibly splitted incoming edge
bool hasConnectionTo(NBEdge *destEdge, int destLane, int fromLane=-1) const
Retrieves info about a connection to a certain lane of a certain edge.
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
void buildCrossingsAndWalkingAreas(bool discardInvalid=true)
build crossings, and walkingareas. Also removes invalid loaded crossings if wished ...
int checkCrossing(EdgeVector candidates)
static const int FORWARD
edge directions (for pedestrian related stuff)
void remapRemoved(NBEdge *removed, const EdgeVector &incoming, const EdgeVector &outgoing)
Replaces occurences of the removed edge in incoming/outgoing edges of all definitions.
std::string tlID
The id of the traffic light that controls this connection.
void setCrossingTLIndices(const std::string &tlID, int startIndex)
set tl indices of this nodes crossing starting at the given index
std::string getInternalLaneID() const
get ID of internal lane
This is an uncontrolled, minor link, has to brake.
int fromLane
The lane the connections starts at.
A point in 2D or 3D with translation and scaling methods.
bool mustBrakeForCrossing(const NBEdge *const from, const NBEdge *const to, const Crossing &crossing) const
Returns the information whether the described flow must brake for the given crossing.
std::pair< int, int > getSizes() const
returns the number of the junction's lanes and the number of the junction's links in respect...
bool mustBrake(const NBEdge *const possProhibitorFrom, const NBEdge *const possProhibitorTo, const NBEdge *const possProhibitedFrom, const NBEdge *const possProhibitedTo) const
Returns the information whether "prohibited" flow must let "prohibitor" flow pass.
void add(SUMOReal xoff, SUMOReal yoff, SUMOReal zoff)
bool addLane2LaneConnections(int fromLane, NBEdge *dest, int toLane, int no, Lane2LaneInfoType type, bool invalidatePrevious=false, bool mayDefinitelyPass=false)
Builds no connections starting at the given lanes.
SUMOReal z() const
Returns the z-position.
bool geometryLike() const
whether this is structurally similar to a geometry node
void invalidateOutgoingConnections()
invalidate outgoing connections
int getNumLanes() const
Returns the number of lanes.
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
EdgeBuildingStep getStep() const
The building step of this edge.
bool isTurningDirectionAt(const NBEdge *const edge) const
Returns whether the given edge is the opposite direction to this edge.
void removeTrafficLights()
Removes all references to traffic lights that control this tls.
EdgeVector * getEdgesThatApproach(NBEdge *currentOutgoing)
returns a list of edges which are connected to the given outgoing edge
std::set< NBTrafficLightDefinition * > myTrafficLights
traffic lights of node
int getFirstNonPedestrianLaneIndex(int direction, bool exclusive=false) const
return the first lane with permissions other than SVC_PEDESTRIAN and 0
Storage for edges, including some functionality operating on multiple edges.
void setCustomLaneShape(const std::string &laneID, const PositionVector &shape)
sets a custom shape for an internal lane
void bezier(int npts, SUMOReal b[], int cpts, SUMOReal p[])
std::string nextCrossing
the lane-id of the next crossing
The link is a (hard) right direction.
LinkState getLinkState(const NBEdge *incoming, NBEdge *outgoing, int fromLane, int toLane, bool mayDefinitelyPass, const std::string &tlID) const
get link state
bool rightOnRedConflict(int index, int foeIndex) const
whether the given index must yield to the foeIndex while turing right on a red light ...
bool myDiscardAllCrossings
whether to discard all pedestrian crossings
void replaceInConnectionProhibitions(NBEdge *which, NBEdge *by, int whichLaneOff, int byLaneOff)
replace incoming connections prohibitions
LinkDirection getDirection(const NBEdge *const incoming, const NBEdge *const outgoing, bool leftHand=false) const
Returns the representation of the described stream's direction.
PositionVector compute()
Computes the shape of the assigned junction.
const PositionVector & getShape() const
retrieve the junction shape
The link is a partial right direction.
NBEdge * getConnectionTo(NBNode *n) const
get connection to certain node
const std::vector< NBNode * > & getNodes() const
Returns the list of controlled nodes.
virtual void removeNode(NBNode *node)
Removes the given node from the list of controlled nodes.
EdgeVector myIncomingEdges
Vector of incoming edges.
bool isLeftMover(const NBEdge *const from, const NBEdge *const to) const
Computes whether the given connection is a left mover across the junction.
Base class for objects which have an id.
std::vector< NBConnection > NBConnectionVector
Definition of a connection vector.
std::vector< std::pair< NBEdge *, NBEdge * > > getEdgesToJoin() const
get edges to join
int getJunctionPriority(const NBNode *const node) const
Returns the junction priority (normalised for the node currently build)
void avoidOverlap()
fix overlap
NBEdge * getPossiblySplittedOutgoing(const std::string &edgeid)
get possibly splitted outgoing edge
int internalLaneIndex
The lane index of this internal lane within the internal edge.
EdgeVector myOutgoingEdges
Vector of outgoing edges.
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
SUMOReal getCrossingAngle(NBNode *node)
return the angle for computing pedestrian crossings at the given node
NBEdge * myCurrentOutgoing
The approached current edge.
static const int BACKWARD
std::string myID
The name of the object.
NBNode * getToNode() const
Returns the destination node of the edge.
void addTrafficLight(NBTrafficLightDefinition *tlDef)
Adds a traffic light to the list of traffic lights that control this node.
bool isNearDistrict() const
if node is near district
bool myHaveCustomPoly
whether this nodes shape was set by the user
std::vector< int > getConnectionLanes(NBEdge *currentOutgoing) const
Returns the list of lanes that may be used to reach the given edge.
void addCrossing(EdgeVector edges, SUMOReal width, bool priority, bool fromSumoNet=false)
add a pedestrian crossing to this node
Position myPosition
The position the node lies at.
bool checkCrossingDuplicated(EdgeVector edges)
return true if already exist a crossing with the same edges as the input
std::map< NBConnection, NBConnectionVector > NBConnectionProhibits
Definition of a container for connection block dependencies Includes a list of all connections which ...
int removeSelfLoops(NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tc)
Removes edges which are both incoming and outgoing into this node.
PositionVector viaShape
shape of via
SUMOReal angleAt2D(int pos) const
get angle in certain position of position vector
~ApproachingDivider()
Destructor.
PositionVector computeSmoothShape(const PositionVector &begShape, const PositionVector &endShape, int numPoints, bool isTurnaround, SUMOReal extrapolateBeg, SUMOReal extrapolateEnd, NBNode *recordError=0) const
Compute a smooth curve between the given geometries.
std::vector< WalkingArea > myWalkingAreas
Vector of walking areas.
void replaceIncoming(NBEdge *which, NBEdge *by, int laneOff)
Replaces occurences of the first edge within the list of incoming by the second Connections are remap...
SumoXMLNodeType
Numbers representing special SUMO-XML-attribute values for representing node- (junction-) types used ...
bool mustBrake(const NBEdge *const from, const NBEdge *const to, int fromLane, int toLane, bool includePedCrossings) const
Returns the information whether the described flow must let any other flow pass.
bool myKeepClear
whether the junction area must be kept clear
std::vector< int > myAvailableLanes
The available lanes to which connections shall be built.
The link is controlled by a tls which is off and blinks, has to brake.
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
void buildInnerEdges()
build internal lanes, pedestrian crossings and walking areas
static const int UNSPECIFIED_INTERNAL_LANE_INDEX
internal lane computation not yet done
A definition of a pedestrian walking area.
EdgeVector * myApproaching
The list of edges that approach the current edge.
SUMOReal y() const
Returns the y-position.
A storage for options typed value containers)
void set(SUMOReal x, SUMOReal y)
set positions x and y
static const SUMOReal DEFAULT_CROSSING_WIDTH
default width of pedetrian crossings
void erase(NBDistrictCont &dc, NBEdge *edge)
Removes the given edge from the container (deleting it)
This is an uncontrolled, major link, may pass.
void mul(SUMOReal val)
Multiplies both positions with the given value.
std::deque< int > * spread(const std::vector< int > &approachingLanes, int dest) const
the method that spreads the wished number of lanes from the the lane given by the bresenham-call to b...
NBEdge * getTo() const
returns the to-edge (end of the connection)
The connection was computed.
bool crossingBetween(const NBEdge *e1, const NBEdge *e2) const
return true if the given edges are connected by a crossing
Represents a single node (junction) during network building.
bool removeFully(const std::string id)
Removes a logic definition (and all programs) from the dictionary.
bool isSimpleContinuation(bool checkLaneNumbers=true) const
check if node is a simple continuation
bool foes(const NBEdge *const from1, const NBEdge *const to1, const NBEdge *const from2, const NBEdge *const to2) const
Returns the information whether the given flows cross.
Lanes to lanes - relationships are computed; no recheck is necessary/wished.
SUMOReal distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
The link is a 180 degree turn (left-hand network)
int guessCrossings()
guess pedestrian crossings and return how many were guessed
A definition of a pedestrian crossing.
void move2side(SUMOReal amount)
move position vector to side using certain ammount
bool insert(NBTrafficLightDefinition *logic, bool forceInsert=false)
Adds a logic definition to the dictionary.
void replaceInConnections(NBEdge *which, NBEdge *by, int laneOff)
replace in current connections of edge
Crossing & getCrossingRef(const std::string &id)
return a reference to the crossing with the given id
void addSortedLinkFoes(const NBConnection &mayDrive, const NBConnection &mustStop)
add shorted link FOES
Static storage of an output device and its base (abstract) implementation.
static void compute(BresenhamCallBack *callBack, const int val1, const int val2)
Computes lane-2-lane connections.
static const SUMOReal UNSPECIFIED_RADIUS
unspecified lane width
bool writeLogic(OutputDevice &into, const bool checkLaneFoes) const
writes the XML-representation of the logic as a bitset-logic XML representation
static SUMOReal relAngle(SUMOReal angle1, SUMOReal angle2)
computes the relative angle between the two angles
void push_back_noDoublePos(const Position &p)
insert in back a non double position
#define SPLIT_CROSSING_WIDTH_THRESHOLD
void computeLogic(const NBEdgeCont &ec, OptionsCont &oc)
computes the node's type, logic and traffic light
SUMOReal getSpeed() const
Returns the speed allowed on this edge.
SUMOReal getStartAngle() const
Returns the angle at the start of the edge (relative to the node shape center) The angle is computed ...
Position getPolygonCenter() const
Returns the arithmetic of all corner points.
SUMOReal area() const
Returns the area (0 for non-closed)
A traffic light logics which must be computed (only nodes/edges are given)
bool foes(const NBEdge *const from1, const NBEdge *const to1, const NBEdge *const from2, const NBEdge *const to2) const
Returns the information whether the given flows cross.
void invalidateTLS(NBTrafficLightLogicCont &tlCont)
causes the traffic light to be computed anew
std::string nextWalkingArea
the lane-id of the next walkingArea
std::set< SVCPermissions > getPermissionVariants(int iStart, int iEnd) const
return all permission variants within the specified lane range [iStart, iEnd[
void closePolygon()
ensures that the last position equals the first
Lanes to edges - relationships are computed/loaded.
NBNode(const std::string &id, const Position &position, SumoXMLNodeType type)
Constructor.
const std::vector< Connection > & getConnections() const
Returns the connections.
NBEdge * getTurnDestination(bool possibleDestination=false) const
bool setConnection(int lane, NBEdge *destEdge, int destLane, Lane2LaneInfoType type, bool mayUseSameDestination=false, bool mayDefinitelyPass=false, bool keepClear=true, SUMOReal contPos=UNSPECIFIED_CONTPOS, SUMOReal visibility=UNSPECIFIED_VISIBILITY_DISTANCE)
Adds a connection to a certain lane of a certain edge.
PositionVector getSubpart(SUMOReal beginOffset, SUMOReal endOffset) const
get subpart of a position vector
const PositionVector & getLaneShape(int i) const
Returns the shape of the nth lane.
std::vector< std::string > prevSidewalks
the lane-id of the previous sidewalk lane or ""
static bool isTrafficLight(SumoXMLNodeType type)
return whether the given type is a traffic light
void shiftPositionAtNode(NBNode *node, NBEdge *opposite)
shift geometry at the given node to avoid overlap
std::vector< std::string > nextSidewalks
the lane-id of the next sidewalk lane or ""
static void nextCCW(const EdgeVector &edges, EdgeVector::const_iterator &from)
void reshiftPosition(SUMOReal xoff, SUMOReal yoff)
Applies an offset to the node.
void computeNodeShape(SUMOReal mismatchThreshold)
Compute the junction shape for this node.
SUMOReal angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position ...
void append(const PositionVector &v, SUMOReal sameThreshold=2.0)
SUMOReal width
This lane's width.
void extrapolate(const SUMOReal val, const bool onlyFirst=false)
extrapolate position vector
void remapRemoved(NBTrafficLightLogicCont &tc, NBEdge *removed, const EdgeVector &incoming, const EdgeVector &outgoing)
remap removed
PositionVector shape
The polygonal shape.
static const Position INVALID
used to indicate that a position is valid
void replaceIncoming(const EdgeVector &which, NBEdge *const by)
Replaces incoming edges from the vector (sinks) by the given edge.
SUMOReal getAngleAtNode(const NBNode *const node) const
Returns the angle of the edge's geometry at the given node.
bool forbids(const NBEdge *const possProhibitorFrom, const NBEdge *const possProhibitorTo, const NBEdge *const possProhibitedFrom, const NBEdge *const possProhibitedTo, bool regardNonSignalisedLowerPriority) const
Returns the information whether "prohibited" flow must let "prohibitor" flow pass.
The link has no direction (is a dead end link)
bool forbidsPedestriansAfter(std::vector< std::pair< NBEdge *, bool > > normalizedLanes, int startIndex)
return whether there is a non-sidewalk lane after the given index;
static bool isLongEnough(NBEdge *out, SUMOReal minLength)
check if is long enough
static std::string getNodeIDFromInternalLane(const std::string id)
returns the node id for internal lanes, crossings and walkingareas
NBNode * getFromNode() const
Returns the origin node of the edge.