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);
401 if ((*i)->isConnectedTo(dummy) && *i != dummy) {
402 incomingConnected.push_back(*i);
409 outgoingConnected.push_back(*i);
414 remapRemoved(tc, dummy, incomingConnected, outgoingConnected);
463 if (checkLaneNumbers && in->
getNumLanes() != (*opposite)->getNumLanes()) {
481 NBNode* recordError)
const {
485 #ifdef DEBUG_SMOOTH_GEOM 487 std::cout <<
"computeSmoothShape node " <<
getID() <<
" init=" << init <<
"\n";
490 if (init.size() == 0) {
492 ret.push_back(begShape.back());
493 ret.push_back(endShape.front());
496 return bezier(init, numPoints);
510 const Position beg = begShape.back();
511 const Position end = endShape.front();
515 #ifdef DEBUG_SMOOTH_GEOM 516 if (
DEBUGCOND) std::cout <<
" bezierControlPoints failed beg=" << beg <<
" end=" << end
532 center.
sub(beg.
y() - end.
y(), end.
x() - beg.
x());
533 init.push_back(center);
538 endShapeBegLine.extrapolate2D(100,
true);
540 if (fabs(angle) <
M_PI / 4.) {
544 const SUMOReal halfDistance = dist / 2;
545 if (fabs(displacementAngle) <=
DEG2RAD(5)) {
546 #ifdef DEBUG_SMOOTH_GEOM 547 if (
DEBUGCOND) std::cout <<
" bezierControlPoints identified straight line beg=" << beg <<
" end=" << end
548 <<
" angle=" <<
RAD2DEG(angle) <<
" displacementAngle=" <<
RAD2DEG(displacementAngle) <<
"\n";
551 }
else if (bendDeg > 22.5 && pow(bendDeg / 45, 2) / dist > 0.13) {
554 #ifdef DEBUG_SMOOTH_GEOM 555 if (
DEBUGCOND) std::cout <<
" bezierControlPoints found extreme s-curve, falling back to straight line beg=" << beg <<
" end=" << end
556 <<
" angle=" <<
RAD2DEG(angle) <<
" displacementAngle=" <<
RAD2DEG(displacementAngle)
557 <<
" dist=" << dist <<
" bendDeg=" << bendDeg <<
" bd2=" << pow(bendDeg / 45, 2)
558 <<
" displacementError=" << sin(displacementAngle) * dist
559 <<
" begShape=" << begShape <<
" endShape=" << endShape <<
"\n";
562 if (recordError != 0) {
567 const SUMOReal endLength = begShape[-2].distanceTo2D(begShape[-1]);
568 const SUMOReal off1 = endLength +
MIN2(extrapolateBeg, halfDistance);
570 const SUMOReal off2 = 100. -
MIN2(extrapolateEnd, halfDistance);
572 #ifdef DEBUG_SMOOTH_GEOM 573 if (
DEBUGCOND) std::cout <<
" bezierControlPoints found s-curve beg=" << beg <<
" end=" << end
574 <<
" angle=" <<
RAD2DEG(angle) <<
" displacementAngle=" <<
RAD2DEG(displacementAngle)
575 <<
" halfDistance=" << halfDistance <<
"\n";
584 Position intersect = endShapeBegLine.intersectionPosition2D(begShapeEndLineRev);
586 #ifdef DEBUG_SMOOTH_GEOM 588 std::cout <<
" bezierControlPoints failed beg=" << beg <<
" end=" << end <<
" intersect=" << intersect <<
"\n";
592 if (recordError != 0) {
599 const bool lengthenBeg = intersect.
distanceTo2D(beg) <= minControlLength;
600 const bool lengthenEnd = intersect.
distanceTo2D(end) <= minControlLength;
601 if (lengthenBeg && lengthenEnd) {
602 #ifdef DEBUG_SMOOTH_GEOM 603 if (
DEBUGCOND) std::cout <<
" bezierControlPoints failed beg=" << beg <<
" end=" << end <<
" intersect=" << intersect
606 if (recordError != 0) {
612 }
else if (lengthenBeg || lengthenEnd) {
614 init.push_back(endShapeBegLine.positionAtOffset2D(100 - minControlLength));
618 const SUMOReal z2 = endShapeBegLine.positionAtOffset2D(endShapeBegLine.nearest_offset_to_point2D(intersect)).z();
619 const SUMOReal z3 = 0.5 * (beg.
z() + end.
z());
623 if ((z1 <= z3 && z2 <= z3) || (z1 >= z3 && z2 >= z3)) {
628 intersect.
set(intersect.
x(), intersect.
y(), z);
629 init.push_back(intersect);
650 assert(con.
shape.size() > 0);
659 ret.append(it->second);
671 if (lane.endOffset > 0) {
693 if (thisRight && !rightTurnConflict) {
696 if (!(
foes(otherFromE, otherToE, fromE, toE) ||
myRequest == 0 || rightTurnConflict)) {
706 const bool bothLeft = thisLeft && otherLeft;
707 if (fromE == otherFromE && !thisRight) {
714 if (c.
tlID !=
"" && !bothLeft) {
717 if ((*it)->needsCont(fromE, toE, otherFromE, otherToE)) {
739 for (std::set<NBTrafficLightDefinition*>::const_iterator i = trafficLights.begin(); i != trafficLights.end(); ++i) {
740 (*i)->setParticipantsInformation();
741 (*i)->setTLControllingInformation();
768 }
else if (numConnections == 0) {
806 if (mismatchThreshold >= 0
839 for (
int i = inOffset; i < in->
getNumLanes(); ++i) {
871 std::swap(in1Offset, in2Offset);
900 std::swap(out1, out2);
901 std::swap(out1Offset, out2Offset);
924 for (
int i = inOffset; i < in->
getNumLanes(); ++i) {
946 for (
int i = inOffset; i < in->
getNumLanes(); ++i) {
958 EdgeVector::reverse_iterator i;
960 NBEdge* currentOutgoing = *i;
963 const int numApproaching = (int)approaching->size();
964 if (numApproaching != 0) {
978 const std::vector<NBEdge::Connection>& elv = incoming->
getConnections();
979 for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
981 if (c.
toEdge == currentOutgoing) {
984 unsatisfied &= ~satisfied;
987 if (unsatisfied != 0) {
990 while (unsatisfied != 0 && fromLane < incoming->getNumLanes()) {
992 for (
int toLane = 0; toLane < currentOutgoing->
getNumLanes(); ++toLane) {
994 if (satisfied != 0) {
997 unsatisfied &= ~satisfied;
1014 const std::vector<NBEdge::Connection> cons = (*i)->getConnections();
1015 for (std::vector<NBEdge::Connection>::const_iterator k = cons.begin(); k != cons.end(); ++k) {
1017 (*i)->removeFromConnections((*k).toEdge);
1028 (*i)->markAsInLane2LaneState();
1045 while (seen < minLength) {
1061 EdgeVector::const_iterator i = find(
myAllEdges.begin(),
1067 for (; *i != currentOutgoing;) {
1069 if ((*i)->getToNode() ==
this && (*i)->getTurnDestination() != currentOutgoing) {
1070 std::vector<int> connLanes = (*i)->getConnectionLanes(currentOutgoing);
1071 if (connLanes.size() != 0) {
1072 approaching->push_back(*i);
1103 for (EdgeVector::const_iterator i = which.begin(); i != which.end(); i++) {
1105 laneOff += (*i)->getNumLanes();
1135 for (EdgeVector::const_iterator i = which.begin(); i != which.end(); i++) {
1137 laneOff += (*i)->getNumLanes();
1152 int whichLaneOff,
int byLaneOff) {
1156 bool changed =
false;
1158 if (c.
replaceFrom(which, whichLaneOff, by, byLaneOff)) {
1161 if (c.
replaceTo(which, whichLaneOff, by, byLaneOff)) {
1175 for (NBConnectionVector::iterator k = prohibiting.begin(); k != prohibiting.end(); k++) {
1177 sprohibiting.
replaceFrom(which, whichLaneOff, by, byLaneOff);
1178 sprohibiting.
replaceTo(which, whichLaneOff, by, byLaneOff);
1238 if (find(edges.begin(), edges.end(), e) != edges.end()) {
1239 edges.erase(find(edges.begin(), edges.end(), e));
1241 if (edges.size() == 0) {
1256 if (mayDrive.
getFrom() == 0 ||
1257 mayDrive.
getTo() == 0 ||
1259 mustStop.
getTo() == 0) {
1261 WRITE_WARNING(
"Something went wrong during the building of a connection...");
1265 conn.push_back(mayDrive);
1272 int size = (int) edgeid.length();
1274 std::string
id = (*i)->
getID();
1275 if (
id.substr(0, size) == edgeid) {
1285 int size = (int) edgeid.length();
1287 std::string
id = (*i)->
getID();
1288 if (
id.substr(0, size) == edgeid) {
1313 if (removeFromConnections) {
1315 (*i)->removeFromConnections(edge);
1320 (*i)->replaceRemoved(edge, -1, 0, -1);
1329 EdgeVector::const_iterator i;
1331 NBNode* conn = (*i)->getFromNode();
1334 toAdd.
mul((
SUMOReal) 1.0 / sqrt(toAdd.
x()*toAdd.
x() + toAdd.
y()*toAdd.
y()));
1338 NBNode* conn = (*i)->getToNode();
1341 toAdd.
mul((
SUMOReal) 1.0 / sqrt(toAdd.
x()*toAdd.
x() + toAdd.
y()*toAdd.
y()));
1345 if (pos.
x() == 0 && pos.
y() == 0) {
1357 (*i)->invalidateConnections();
1365 (*i)->invalidateConnections();
1392 const NBEdge* prohibitorFrom,
const NBEdge* prohibitorTo,
int prohibitorFromLane,
1394 if (from != prohibitorFrom) {
1418 lefthand = !lefthand;
1425 if ((!lefthand && fromLane <= prohibitorFromLane) ||
1426 (lefthand && fromLane >= prohibitorFromLane)) {
1448 std::vector<NBEdge*>::const_iterator i = std::find(
myAllEdges.begin(),
myAllEdges.end(), from);
1458 const NBEdge*
const possProhibitedFrom,
const NBEdge*
const possProhibitedTo,
1459 bool regardNonSignalisedLowerPriority)
const {
1461 possProhibitedFrom, possProhibitedTo,
1462 regardNonSignalisedLowerPriority);
1468 const NBEdge*
const from2,
const NBEdge*
const to2)
const {
1477 assert(find(incoming.begin(), incoming.end(), removed) == incoming.end());
1478 bool changed =
true;
1484 for (NBConnectionProhibits::iterator i = blockedConnectionsTmp.begin(); i != blockedConnectionsTmp.end(); i++) {
1489 bool blockedChanged =
false;
1491 NBConnectionVector::const_iterator j;
1492 for (j = blocked.begin(); j != blocked.end(); j++) {
1494 if (sblocked.
getFrom() == removed || sblocked.
getTo() == removed) {
1495 blockedChanged =
true;
1499 for (j = blocked.begin(); blockedChanged && j != blocked.end(); j++) {
1501 if (sblocked.
getFrom() == removed && sblocked.
getTo() == removed) {
1505 }
else if (sblocked.
getFrom() == removed) {
1506 assert(sblocked.
getTo() != removed);
1507 for (EdgeVector::const_iterator k = incoming.begin(); k != incoming.end(); k++) {
1510 }
else if (sblocked.
getTo() == removed) {
1511 assert(sblocked.
getFrom() != removed);
1512 for (EdgeVector::const_iterator k = outgoing.begin(); k != outgoing.end(); k++) {
1519 if (blockedChanged) {
1520 blockedConnectionsNew[blocker] = newBlocked;
1525 if (blocker.
getFrom() == removed && blocker.
getTo() == removed) {
1530 }
else if (blocker.
getFrom() == removed) {
1531 assert(blocker.
getTo() != removed);
1533 for (EdgeVector::const_iterator k = incoming.begin(); k != incoming.end(); k++) {
1536 }
else if (blocker.
getTo() == removed) {
1537 assert(blocker.
getFrom() != removed);
1539 for (EdgeVector::const_iterator k = outgoing.begin(); k != outgoing.end(); k++) {
1543 blockedConnectionsNew[blocker] = blocked;
1557 if (outgoing == 0) {
1568 if (
abs((
int) angle) + 1 < 45) {
1575 EdgeVector::const_iterator i =
1582 while ((*i) != incoming) {
1596 EdgeVector::const_iterator i =
1603 while ((*i) != incoming) {
1620 bool mayDefinitelyPass,
const std::string& tlID)
const {
1627 if (outgoing == 0) {
1639 if ((!incoming->
isInnerEdge() &&
mustBrake(incoming, outgoing, fromlane, toLane,
true)) && !mayDefinitelyPass) {
1653 EdgeVector::const_iterator i;
1666 std::set<NBNode*> origSet;
1668 origSet.insert((*i)->getFromNode());
1670 if (origSet.size() < 2) {
1678 if (opposite != 0) {
1682 if (!(*i)->expandableBy(continuation)) {
1698 std::vector<std::pair<NBEdge*, NBEdge*> >
1701 std::vector<std::pair<NBEdge*, NBEdge*> > ret;
1705 std::pair<NBEdge*, NBEdge*>(
1713 assert(opposite != 0);
1715 ret.push_back(std::pair<NBEdge*, NBEdge*>(*i, continuation));
1736 if (shape.size() > 1) {
1747 if ((*i)->getToNode() == n) {
1762 back_inserter(edges));
1764 back_inserter(edges));
1765 for (EdgeVector::const_iterator j = edges.begin(); j != edges.end(); ++j) {
1776 for (EdgeVector::const_iterator k = edges2.begin(); k != edges2.end(); ++k) {
1777 if ((*k)->getFromNode()->isDistrict() || (*k)->getToNode()->isDistrict()) {
1801 std::cout <<
"guess crossings for " <<
getID() <<
"\n";
1805 std::vector<std::pair<NBEdge*, bool> > normalizedLanes;
1806 for (EdgeVector::const_iterator it = allEdges.begin(); it != allEdges.end(); ++it) {
1808 const std::vector<NBEdge::Lane>& lanes = edge->
getLanes();
1810 for (std::vector<NBEdge::Lane>::const_reverse_iterator it_l = lanes.rbegin(); it_l != lanes.rend(); ++it_l) {
1811 normalizedLanes.push_back(std::make_pair(edge, ((*it_l).permissions &
SVC_PEDESTRIAN) != 0));
1814 for (std::vector<NBEdge::Lane>::const_iterator it_l = lanes.begin(); it_l != lanes.end(); ++it_l) {
1815 normalizedLanes.push_back(std::make_pair(edge, ((*it_l).permissions &
SVC_PEDESTRIAN) != 0));
1820 int firstSidewalk = -1;
1821 for (
int i = 0; i < (int)normalizedLanes.size(); ++i) {
1822 if (normalizedLanes[i].second) {
1827 int hadCandidates = 0;
1828 std::vector<int> connectedCandidates;
1829 if (firstSidewalk != -1) {
1831 std::vector<std::pair<NBEdge*, bool> > tmp;
1832 copy(normalizedLanes.begin() + firstSidewalk, normalizedLanes.end(), std::back_inserter(tmp));
1833 copy(normalizedLanes.begin(), normalizedLanes.begin() + firstSidewalk, std::back_inserter(tmp));
1834 normalizedLanes = tmp;
1837 for (
int i = 0; i < (int)normalizedLanes.size(); ++i) {
1838 NBEdge* edge = normalizedLanes[i].first;
1839 const bool allowsPed = normalizedLanes[i].second;
1841 std::cout <<
" cands=" <<
toString(candidates) <<
" edge=" << edge->
getID() <<
" allowsPed=" << allowsPed <<
"\n";
1843 if (!allowsPed && (candidates.size() == 0 || candidates.back() != edge)) {
1844 candidates.push_back(edge);
1845 }
else if (allowsPed) {
1846 if (candidates.size() > 0) {
1852 connectedCandidates.push_back(n);
1859 if (hadCandidates > 0 && candidates.size() > 0) {
1865 connectedCandidates.push_back(n);
1871 std::cout <<
" hadCandidates=" << hadCandidates <<
" connectedCandidates=" <<
toString(connectedCandidates) <<
"\n";
1873 if (hadCandidates == 2 && connectedCandidates.size() == 2) {
1875 if (connectedCandidates.back() <= connectedCandidates.front()) {
1876 numGuessed -= connectedCandidates.back();
1879 numGuessed -= connectedCandidates.front();
1885 std::cout <<
"guessedCrossings:\n";
1887 std::cout <<
" edges=" <<
toString((*it).edges) <<
"\n";
1897 std::cout <<
"checkCrossing candidates=" <<
toString(candidates) <<
"\n";
1899 if (candidates.size() == 0) {
1901 std::cout <<
"no crossing added (numCandidates=" << candidates.size() <<
")\n";
1907 for (
int i = 0; i < (int)candidates.size(); ++i) {
1908 NBEdge* edge = candidates[i];
1913 std::cout <<
"no crossing added (found angle difference of " << fabs(angle - prevAngle) <<
" at i=" << i <<
"\n";
1919 std::cout <<
"no crossing added (uncontrolled, edge with speed > " << edge->
getSpeed() <<
")\n";
1925 if (candidates.size() == 1) {
1928 std::cout <<
"adding crossing: " <<
toString(candidates) <<
"\n";
1934 for (EdgeVector::iterator it = candidates.begin(); it != candidates.end(); ++it) {
1935 SUMOReal angle = (*it)->getCrossingAngle(
this);
1936 if (it != candidates.begin()) {
1937 NBEdge* prev = *(it - 1);
1945 prevPos = prev->
getLanes()[laneI].shape[-1];
1948 prevPos = prev->
getLanes()[laneI].shape[0];
1953 currPos = curr->
getLanes()[laneI].shape[0];
1956 currPos = curr->
getLanes()[laneI].shape[-1];
1962 <<
" prevAngle=" << prevAngle
1963 <<
" angle=" << angle
1964 <<
" intermediateWidth=" << intermediateWidth
1977 std::cout <<
"adding crossing: " <<
toString(candidates) <<
"\n";
1987 for (
int i = startIndex; i < (int)normalizedLanes.size(); ++i) {
1988 if (!normalizedLanes[i].second) {
2002 if ((*it).prevWalkingArea ==
"" || (*it).nextWalkingArea ==
"") {
2003 WRITE_WARNING(
"Discarding invalid crossing '" + (*it).id +
"' at junction '" +
getID() +
"' with edges '" +
toString((*it).edges) +
"'.");
2005 if ((*it_wa).nextCrossing == (*it).id) {
2006 (*it_wa).nextCrossing =
"";
2022 int noInternalNoSplits = 0;
2024 const std::vector<NBEdge::Connection>& elv = (*i)->getConnections();
2025 for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
2026 if ((*k).toEdge == 0) {
2029 noInternalNoSplits++;
2035 (*i)->buildInnerEdges(*
this, noInternalNoSplits, lno, splitNo);
2043 (*i)->buildInnerEdges(*
this, noInternalNoSplits, lno, splitNo);
2053 std::cout <<
"build crossings for " <<
getID() <<
":\n";
2063 (*it).nextWalkingArea =
"";
2064 (*it).prevWalkingArea =
"";
2067 std::cout <<
" crossing=" << (*it).id <<
" edges=" <<
toString(edges);
2073 std::cout <<
" sortedEdges=" <<
toString(edges) <<
"\n";
2077 int maxAngleDiffIndex = 0;
2078 for (
int i = 0; i < (int) edges.size(); i++) {
2080 edges[(i + 1) % edges.size()]->getAngleAtNodeToCenter(
this));
2085 std::cout <<
" i=" << i <<
" a1=" << edges[i]->getAngleAtNodeToCenter(
this) <<
" a2=" << edges[(i + 1) % edges.size()]->getAngleAtNodeToCenter(
this) <<
" diff=" << diff <<
"\n";
2087 if (diff > maxAngleDiff) {
2088 maxAngleDiff = diff;
2089 maxAngleDiffIndex = i;
2092 if (maxAngleDiff > 2 && maxAngleDiff < 360 - 2) {
2094 std::rotate(edges.begin(), edges.begin() + (maxAngleDiffIndex + 1) % edges.size(), edges.end());
2096 std::cout <<
" rotatedEdges=" <<
toString(edges);
2100 std::reverse(edges.begin(), edges.end());
2102 std::cout <<
" finalEdges=" <<
toString(edges) <<
"\n";
2105 (*it).shape.clear();
2106 const int begDir = (edges.front()->getFromNode() ==
this ?
FORWARD :
BACKWARD);
2107 const int endDir = (edges.back()->getToNode() ==
this ?
FORWARD :
BACKWARD);
2108 if (edges.front()->getFirstNonPedestrianLaneIndex(begDir) < 0
2109 || edges.back()->getFirstNonPedestrianLaneIndex(endDir) < 0) {
2111 WRITE_WARNING(
"Discarding invalid crossing '" + (*it).id +
"' at junction '" +
getID() +
"' with edges '" +
toString((*it).edges) +
"'.");
2114 NBEdge::Lane crossingBeg = edges.front()->getFirstNonPedestrianLane(begDir);
2115 NBEdge::Lane crossingEnd = edges.back()->getFirstNonPedestrianLane(endDir);
2122 (*it).shape.push_back(crossingBeg.
shape[begDir ==
FORWARD ? 0 : -1]);
2123 (*it).shape.push_back(crossingEnd.
shape[endDir ==
FORWARD ? -1 : 0]);
2137 std::cout <<
"build walkingAreas for " <<
getID() <<
":\n";
2144 std::vector<std::pair<NBEdge*, NBEdge::Lane> > normalizedLanes;
2145 for (EdgeVector::const_iterator it = allEdges.begin(); it != allEdges.end(); ++it) {
2147 const std::vector<NBEdge::Lane>& lanes = edge->
getLanes();
2149 for (std::vector<NBEdge::Lane>::const_reverse_iterator it_l = lanes.rbegin(); it_l != lanes.rend(); ++it_l) {
2153 normalizedLanes.push_back(std::make_pair(edge, l));
2156 for (std::vector<NBEdge::Lane>::const_iterator it_l = lanes.begin(); it_l != lanes.end(); ++it_l) {
2161 normalizedLanes.push_back(std::make_pair(edge, l));
2167 std::vector<std::pair<int, int> > waIndices;
2169 NBEdge* prevEdge = normalizedLanes.back().first;
2170 for (
int i = 0; i < (int)normalizedLanes.size(); ++i) {
2171 NBEdge* edge = normalizedLanes[i].first;
2179 waIndices.push_back(std::make_pair(start, i - start));
2189 <<
" waI=" << waIndices.size() <<
" crossingBetween=" <<
crossingBetween(edge, prevEdge) <<
"\n";
2194 const int waNumLanes = (int)normalizedLanes.size() - start;
2195 if (waIndices.size() == 0) {
2196 waIndices.push_back(std::make_pair(start, waNumLanes));
2198 std::cout <<
" single wa, end at wrap-around\n";
2201 if (waIndices.front().first == 0) {
2202 NBEdge* edge = normalizedLanes.front().first;
2203 NBEdge* prevEdge = normalizedLanes.back().first;
2206 waIndices.push_back(std::make_pair(start, waNumLanes));
2208 std::cout <<
" do not wrap around, turn-around in between\n";
2212 waIndices.front().first = start;
2213 waIndices.front().second = waNumLanes + waIndices.front().second;
2215 std::cout <<
" wrapping around\n";
2220 waIndices.push_back(std::make_pair(start, waNumLanes));
2222 std::cout <<
" end at wrap-around\n";
2228 std::cout <<
" normalizedLanes=" << normalizedLanes.size() <<
" waIndices:\n";
2229 for (
int i = 0; i < (int)waIndices.size(); ++i) {
2230 std::cout <<
" " << waIndices[i].first <<
", " << waIndices[i].second <<
"\n";
2234 for (
int i = 0; i < (int)waIndices.size(); ++i) {
2235 const bool buildExtensions = waIndices[i].second != (int)normalizedLanes.size();
2236 const int start = waIndices[i].first;
2237 const int prev = start > 0 ? start - 1 : (int)normalizedLanes.size() - 1;
2238 const int count = waIndices[i].second;
2239 const int end = (start + count) % normalizedLanes.size();
2243 std::cout <<
"build walkingArea " << wa.
id <<
" start=" << start <<
" end=" << end <<
" count=" << count <<
" prev=" << prev <<
":\n";
2250 bool connectsCrossing =
false;
2251 std::vector<Position> connectedPoints;
2254 std::cout <<
" crossing=" << (*it).id <<
" sortedEdges=" <<
toString((*it).edges) <<
"\n";
2256 if ((*it).edges.back() == normalizedLanes[end].first
2257 && (normalizedLanes[end].second.permissions &
SVC_PEDESTRIAN) == 0) {
2259 if ((*it).nextWalkingArea !=
"") {
2261 +
"'; crossing '" + (*it).id
2262 +
"' targets '" + (*it).nextWalkingArea
2263 +
"' and '" + wa.
id +
"'.");
2265 (*it).nextWalkingArea = wa.
id;
2266 endCrossingWidth = (*it).width;
2267 endCrossingShape = (*it).shape;
2269 connectsCrossing =
true;
2270 connectedPoints.push_back((*it).shape[-1]);
2272 std::cout <<
" crossing " << (*it).id <<
" ends\n";
2275 if ((*it).edges.front() == normalizedLanes[prev].first
2276 && (normalizedLanes[prev].second.permissions &
SVC_PEDESTRIAN) == 0) {
2278 if ((*it).prevWalkingArea !=
"") {
2280 +
"'; crossing '" + (*it).id
2281 +
"' is targeted by '" + (*it).prevWalkingArea
2282 +
"' and '" + wa.
id +
"'.");
2284 (*it).prevWalkingArea = wa.
id;
2286 startCrossingWidth = (*it).width;
2287 startCrossingShape = (*it).shape;
2289 connectsCrossing =
true;
2290 connectedPoints.push_back((*it).shape[0]);
2292 std::cout <<
" crossing " << (*it).id <<
" starts\n";
2295 if (
gDebugFlag1) std::cout <<
" check connections to crossing " << (*it).id
2296 <<
" cFront=" << (*it).edges.front()->getID() <<
" cBack=" << (*it).edges.back()->getID()
2297 <<
" wEnd=" << normalizedLanes[end].first->getID() <<
" wStart=" << normalizedLanes[start].first->getID()
2298 <<
" wStartPrev=" << normalizedLanes[prev].first->getID()
2301 if (count < 2 && !connectsCrossing) {
2304 std::cout <<
" not relevant for walking: count=" << count <<
" connectsCrossing=" << connectsCrossing <<
"\n";
2309 std::set<NBEdge*> connected;
2310 for (
int j = 0; j < count; ++j) {
2311 const int nlI = (start + j) % normalizedLanes.size();
2312 NBEdge* edge = normalizedLanes[nlI].first;
2315 if (connected.count(edge) == 0) {
2323 connected.insert(edge);
2330 if (buildExtensions) {
2332 if (startCrossingShape.size() > 0) {
2334 std::cout <<
" extension at startCrossing shape=" << startCrossingShape <<
"\n";
2336 startCrossingShape.
move2side(startCrossingWidth / 2);
2338 startCrossingShape.
move2side(-startCrossingWidth);
2342 if (endCrossingShape.size() > 0) {
2344 std::cout <<
" extension at endCrossing shape=" << endCrossingShape <<
"\n";
2346 endCrossingShape.
move2side(endCrossingWidth / 2);
2348 endCrossingShape.
move2side(-endCrossingWidth);
2353 && normalizedLanes.size() == 2) {
2355 NBEdge* e1 = *connected.begin();
2356 NBEdge* e2 = *(++connected.begin());
2359 std::cout <<
" not building a walkingarea since normal connections exist\n";
2365 if (cornerDetail > 0) {
2366 int smoothEnd = end;
2367 int smoothPrev = prev;
2369 if (endCrossingWidth > 0 && normalizedLanes[smoothEnd].second.permissions == 0) {
2370 smoothEnd = (smoothEnd + 1) % normalizedLanes.size();
2372 if (startCrossingWidth > 0 && normalizedLanes[smoothPrev].second.permissions == 0) {
2373 if (smoothPrev == 0) {
2374 smoothPrev = (int)normalizedLanes.size() - 1;
2379 PositionVector begShape = normalizedLanes[smoothEnd].second.shape;
2380 begShape = begShape.
reverse();
2382 begShape.
move2side(normalizedLanes[smoothEnd].second.width / 2);
2383 PositionVector endShape = normalizedLanes[smoothPrev].second.shape;
2384 endShape.
move2side(normalizedLanes[smoothPrev].second.width / 2);
2388 <<
" end=" << smoothEnd <<
" prev=" << smoothPrev
2389 <<
" endCrossingWidth=" << endCrossingWidth <<
" startCrossingWidth=" << startCrossingWidth
2390 <<
" begShape=" << begShape <<
" endShape=" << endShape <<
" smooth curve=" << curve <<
"\n";
2391 if (curve.size() > 2) {
2392 curve.erase(curve.begin());
2394 if (endCrossingWidth > 0) {
2395 wa.
shape.pop_back();
2397 if (startCrossingWidth > 0) {
2405 int combinations = 0;
2406 for (std::vector<Position>::const_iterator it1 = connectedPoints.begin(); it1 != connectedPoints.end(); ++it1) {
2407 for (std::vector<Position>::const_iterator it2 = connectedPoints.begin(); it2 != connectedPoints.end(); ++it2) {
2417 std::cout <<
" combinations=" << combinations <<
" connectedPoints=" << connectedPoints <<
"\n";
2420 if (combinations > 0) {
2430 std::cout <<
" checkIntermediate: prev=" << prev.
id <<
" next=" << next.
id <<
" prev.nextWA=" << prev.
nextWalkingArea <<
"\n";
2434 WRITE_WARNING(
"Invalid pedestrian topology: crossing '" + prev.
id +
"' has no target.");
2444 wa.
shape.push_back(tmp[-1]);
2446 wa.
shape.push_back(tmp[-1]);
2450 wa.
shape.push_back(tmp[0]);
2452 wa.
shape.push_back(tmp[0]);
2457 std::cout <<
" build wa=" << wa.
id <<
"\n";
2471 EdgeVector::const_iterator it1 = find(edges.begin(), edges.end(), e1);
2472 EdgeVector::const_iterator it2 = find(edges.begin(), edges.end(), e2);
2473 if (it1 != edges.end() && it2 != edges.end()) {
2489 while (it != it_end) {
2490 result.push_back(*it);
2511 if (
MAX2(angle0, angle1) <= 160) {
2541 EdgeSet edgeSet(edges.begin(), edges.end());
2543 EdgeSet edgeSet2((*it).edges.begin(), (*it).edges.end());
2544 if (edgeSet == edgeSet2) {
2556 if ((*it).id ==
id) {
2560 throw ProcessError(
"Request for unknown crossing '" +
id +
"'");
2567 (*it).tlLinkNo = startIndex++;
2599 std::cout <<
" angles:\n";
2600 for (EdgeVector::const_iterator it = result.begin(); it != result.end(); ++it) {
2601 std::cout <<
" edge=" << (*it)->getID() <<
" edgeAngle=" << (*it)->getAngleAtNode(
this) <<
" angleToShape=" << (*it)->getAngleAtNodeToCenter(
this) <<
"\n";
2603 std::cout <<
" allEdges before: " <<
toString(result) <<
"\n";
2608 std::cout <<
" allEdges sorted: " <<
toString(result) <<
"\n";
2610 rotate(result.begin(), std::find(result.begin(), result.end(), *
myAllEdges.begin()), result.end());
2612 std::cout <<
" allEdges rotated: " <<
toString(result) <<
"\n";
2623 assert(
id[0] ==
':');
2624 std::string::size_type sep_index =
id.rfind(
'_');
2625 if (sep_index == std::string::npos) {
2626 WRITE_ERROR(
"Invalid lane id '" +
id +
"' (missing '_').");
2629 sep_index =
id.substr(0, sep_index).rfind(
'_');
2630 if (sep_index == std::string::npos) {
2631 WRITE_ERROR(
"Invalid lane id '" +
id +
"' (missing '_').");
2634 return id.substr(1, sep_index - 1);
2644 if (turnDest != 0) {
2665 if ((*i)->rightOnRedConflict(index, foeIndex)) {
bool gDebugFlag1
global utility flags for debugging
std::pair< int, int > getSizes() const
returns the number of the junction's lanes and the number of the junction's links in respect...
void sub(SUMOReal dx, SUMOReal dy)
Substracts the given position from this one.
The link is a partial left direction.
void replaceOutgoing(const EdgeVector &which, NBEdge *const by)
Replaces outgoing edges from the vector (source) by the given edge.
SUMOReal getEndAngle() const
Returns the angle at the end of the edge (relative to the node shape center) The angle is computed in...
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.
SUMOReal getStartAngle() const
Returns the angle at the start of the edge (relative to the node shape center) The angle is computed ...
LinkState getLinkState(const NBEdge *incoming, NBEdge *outgoing, int fromLane, int toLane, bool mayDefinitelyPass, const std::string &tlID) const
int toLane
The lane the connections yields in.
void setRoundabout()
update the type of this node as a roundabout
int numNormalConnections() const
return the number of lane-to-lane connections at this junction (excluding crossings) ...
std::vector< Crossing > myCrossings
Vector of crossings.
static const SUMOReal UNSPECIFIED_WIDTH
unspecified lane width
SUMOReal width
This lane's width.
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.
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.
bool isInStringVector(const std::string &optionName, const std::string &itemName)
Returns the named option is a list of string values containing the specified item.
SUMOReal angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position ...
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.
PositionVector myPoly
the (outer) shape of the junction
void execute(const int src, const int dest)
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.
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.
SUMOReal width
This lane's width.
static SUMOReal normRelAngle(SUMOReal angle1, SUMOReal angle2)
ensure that reverse relAngles (>=179.999) always count as turnarounds (-180)
PositionVector computeInternalLaneShape(NBEdge *fromE, const NBEdge::Connection &con, int numPoints, NBNode *recordError=0) const
Compute the shape for an internal lane.
Some static methods for string processing.
int getJunctionPriority(const NBNode *const node) const
Returns the junction priority (normalised for the node currently build)
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.
void removeEdge(NBEdge *edge, bool removeFromConnections=true)
Removes edge from this node and optionally removes connections as well.
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.
void addIncomingEdge(NBEdge *edge)
adds an incoming edge
The representation of a single edge during network building.
TrafficLightType getType() const
get the algorithm type (static etc..)
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
void setCrossingTLIndices(int startIndex)
set tl indices of this nodes crossing starting at the given index
The link is a 180 degree turn.
A container for districts.
The base class for traffic light logic definitions.
void buildBitfieldLogic()
bool isInnerEdge() const
Returns whether this edge was marked as being within an intersection.
#define SUMO_MAX_CONNECTIONS
the maximum number of connections across an intersection
bool rightOnRedConflict(int index, int foeIndex) const
whether the given index must yield to the foeIndex while turing right on a red light ...
NBEdge * getTurnDestination(bool possibleDestination=false) const
PositionVector shape
The lane's shape.
#define SPLIT_CROSSING_ANGLE_THRESHOLD
const std::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
PositionVector reverse() const
reverse position vector
void buildWalkingAreas(int cornerDetail)
NBEdge * getFrom() const
returns the from-edge (start of the connection)
This is an uncontrolled, right-before-left link.
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
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.
void mirrorX()
mirror coordinates along the x-axis
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission is a railway edge.
std::vector< int > getConnectionLanes(NBEdge *currentOutgoing) const
Returns the list of lanes that may be used to reach the given 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
This is an uncontrolled, all-way stop link.
void addOutgoingEdge(NBEdge *edge)
adds an outgoing edge
const Crossing & getCrossing(const std::string &id) const
return the crossing with the given id
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)
The connection was computed and validated.
static OptionsCont & getOptions()
Retrieves the options.
Position getCenter() const
Returns a position that is guaranteed to lie within the node shape.
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...
SUMOReal nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges.
int getFirstNonPedestrianLaneIndex(int direction, bool exclusive=false) const
return the first lane with permissions other than SVC_PEDESTRIAN and 0
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)...
CustomShapeMap myCustomLaneShapes
The link is a straight direction.
SUMOTime getOffset()
Returns the offset.
SUMOReal distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
PositionVector shape
shape of Connection
NBDistrict * myDistrict
The district the node is the centre of.
A class representing a single district.
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 extrapolate2D(const SUMOReal val, const bool onlyFirst=false)
extrapolate position vector in two dimensions (Z is ignored)
NBEdge * getConnectionTo(NBNode *n) const
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.
EdgeVector myAllEdges
Vector of incoming and outgoing edges.
SVCPermissions permissions
List of vehicle types that are allowed on this lane.
void computeLanes2Lanes()
computes the connections of lanes to edges
bool isTLControlled() const
Returns whether this node is controlled by any tls.
bool writeLogic(OutputDevice &into, const bool checkLaneFoes) const
void invalidateIncomingConnections()
bool isConnectedTo(NBEdge *e)
Returns the information whethe a connection to the given edge has been added (or computed) ...
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)
bool replaceFrom(NBEdge *which, NBEdge *by)
replaces the from-edge by the one given
std::set< NBEdge * > EdgeSet
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)
SUMOReal angleAt2D(int pos) const
get angle in certain position of position vector
int checkCrossing(EdgeVector candidates)
static const int FORWARD
edge directions (for pedestrian related stuff)
SUMOReal z() const
Returns the z-position.
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.
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.
This is an uncontrolled, minor link, has to brake.
int getNumLanes() const
Returns the number of lanes.
int fromLane
The lane the connections starts at.
A point in 2D or 3D with translation and scaling methods.
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.
void buildCrossingsAndWalkingAreas()
Position getPolygonCenter() const
Returns the arithmetic of all corner points.
bool crossingBetween(const NBEdge *e1, const NBEdge *e2) const
return true if the given edges are connected by a crossing
bool hasConnectionTo(NBEdge *destEdge, int destLane, int fromLane=-1) const
Retrieves info about a connection to a certain lane of a certain edge.
void invalidateOutgoingConnections()
SUMOReal getAngleAtNode(const NBNode *const node) const
Returns the angle of the edge's geometry at the given node.
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
void removeTrafficLights()
Removes all references to traffic lights that control this tls.
EdgeVector * getEdgesThatApproach(NBEdge *currentOutgoing)
bool geometryLike() const
whether this is structurally similar to a geometry node
std::set< NBTrafficLightDefinition * > myTrafficLights
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
PositionVector getSubpart(SUMOReal beginOffset, SUMOReal endOffset) const
get subpart of a position vector
SUMOReal x() const
Returns the x-position.
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.
EdgeBuildingStep getStep() const
The building step of this edge.
bool hasOutgoing(const NBEdge *const e) const
Returns whether the given edge starts at this node.
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) ...
bool myDiscardAllCrossings
whether to discard all pedestrian crossings
void replaceInConnectionProhibitions(NBEdge *which, NBEdge *by, int whichLaneOff, int byLaneOff)
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
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.
static PositionVector bezierControlPoints(const PositionVector &begShape, const PositionVector &endShape, bool isTurnaround, SUMOReal extrapolateBeg, SUMOReal extrapolateEnd, bool &ok, NBNode *recordError=0)
The link is a partial right direction.
std::set< SVCPermissions > getPermissionVariants(int iStart, int iEnd) const
return all permission variants within the specified lane range [iStart, iEnd[
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
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.
virtual void removeNode(NBNode *node)
Removes the given node from the list of controlled nodes.
EdgeVector myIncomingEdges
Vector of incoming edges.
Base class for objects which have an id.
bool hasIncoming(const NBEdge *const e) const
Returns whether the given edge ends at this node.
std::vector< NBConnection > NBConnectionVector
Definition of a connection vector.
void avoidOverlap()
fix overlap
NBEdge * getPossiblySplittedOutgoing(const std::string &edgeid)
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 & getShape() const
retrieve the junction shape
NBEdge * getTo() const
returns the to-edge (end of the connection)
int internalLaneIndex
The lane index of this internal lane within the internal edge.
EdgeVector myOutgoingEdges
Vector of outgoing edges.
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.
void addTrafficLight(NBTrafficLightDefinition *tlDef)
Adds a traffic light to the list of traffic lights that control this node.
bool myHaveCustomPoly
whether this nodes shape was set by the user
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.
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
~ApproachingDivider()
Destructor.
std::vector< WalkingArea > myWalkingAreas
Vector of walking areas.
const PositionVector & getLaneShape(int i) const
Returns the shape of the nth lane.
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges.
const std::vector< Connection > & getConnections() const
Returns the connections.
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 isNearDistrict() const
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
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.
void buildInnerEdges()
build internal lanes, pedestrian crossings and walking areas
static const int UNSPECIFIED_INTERNAL_LANE_INDEX
internal lane computation not yet done
void writeLogic(std::string key, OutputDevice &into, const bool checkLaneFoes) const
A definition of a pedestrian walking area.
EdgeVector * myApproaching
The list of edges that approach the current edge.
bool around(const Position &p, SUMOReal offset=0) const
Returns the information whether the position vector describes a polygon lying around the given point...
const std::vector< NBNode * > & getNodes() const
Returns the list of controlled nodes.
A storage for options typed value containers)
void set(SUMOReal x, SUMOReal 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)
Position getEmptyDir() const
Returns something like the most unused direction Should only be used to add source or sink nodes...
This is an uncontrolled, major link, may pass.
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 mul(SUMOReal val)
Multiplies both positions with the given value.
SUMOReal getSpeed() const
Returns the speed allowed on this edge.
int numAvailableLanes() const
EdgeVector getEdgesSortedByAngleAtNodeCenter() const
returns the list of all edges sorted clockwise by getAngleAtNodeToCenter
bool isTurningDirectionAt(const NBEdge *const edge) const
Returns whether the given edge is the opposite direction to this edge.
The connection was computed.
const Position & getPosition() const
Returns the position of this node.
Represents a single node (junction) during network building.
bool removeFully(const std::string id)
Removes a logic definition (and all programs) from the dictionary.
Position positionAtOffset2D(SUMOReal pos, SUMOReal lateralOffset=0) const
Returns the position at the given length.
Lanes to lanes - relationships are computed; no recheck is necessary/wished.
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
void addSortedLinkFoes(const NBConnection &mayDrive, const NBConnection &mustStop)
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 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.
NBEdge * getOppositeIncoming(NBEdge *e) const
static SUMOReal relAngle(SUMOReal angle1, SUMOReal angle2)
bool isJoinedTLSControlled() const
Returns whether this node is controlled by a tls that spans over more than one node.
void push_back_noDoublePos(const Position &p)
insert in back a non double position
bool isLeftMover(const NBEdge *const from, const NBEdge *const to) const
Computes whether the given connection is a left mover across the junction.
#define SPLIT_CROSSING_WIDTH_THRESHOLD
NBNode * getFromNode() const
Returns the origin node of the edge.
void computeLogic(const NBEdgeCont &ec, OptionsCont &oc)
computes the node's type, logic and traffic light
std::string getInternalLaneID() const
get ID of internal lnae
A traffic light logics which must be computed (only nodes/edges are given)
SUMOReal getLoadedLength() const
Returns the length was set explicitly or the computed length if it wasn't set.
SUMOReal y() const
Returns the y-position.
void invalidateTLS(NBTrafficLightLogicCont &tlCont)
causes the traffic light to be computed anew
std::string nextWalkingArea
the lane-id of the next walkingArea
std::deque< int > * spread(const std::vector< int > &approachingLanes, int dest) const
void closePolygon()
ensures that the last position equals the first
Lanes to edges - relationships are computed/loaded.
bool checkIsRemovable() const
NBNode(const std::string &id, const Position &position, SumoXMLNodeType type)
Constructor.
std::vector< std::pair< NBEdge *, NBEdge * > > getEdgesToJoin() const
SUMOReal getLaneWidth() const
Returns the default width of lanes of this edge.
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.
NBNode * getToNode() const
Returns the destination node of the edge.
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.
bool isSimpleContinuation(bool checkLaneNumbers=true) const
void computeNodeShape(SUMOReal mismatchThreshold)
Compute the junction shape for this node.
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
SUMOReal getFloat(const std::string &name) const
Returns the SUMOReal-value of the named option (only for Option_Float)
void remapRemoved(NBTrafficLightLogicCont &tc, NBEdge *removed, const EdgeVector &incoming, const EdgeVector &outgoing)
PositionVector shape
The polygonal shape.
static const Position INVALID
void replaceIncoming(const EdgeVector &which, NBEdge *const by)
Replaces incoming edges from the vector (sinks) by the given edge.
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)
EdgeVector edgesBetween(const NBEdge *e1, const NBEdge *e2) const
return all edges that lie clockwise between the given edges
static std::string getNodeIDFromInternalLane(const std::string id)
returns the node id for internal lanes, crossings and walkingareas