69 #ifdef CHECK_MEMORY_LEAKS
71 #endif // CHECK_MEMORY_LEAKS
74 #define EXTEND_CROSSING_ANGLE_THRESHOLD 35.0 // degrees
76 #define SPLIT_CROSSING_WIDTH_THRESHOLD 1.5 // meters
77 #define SPLIT_CROSSING_ANGLE_THRESHOLD 5 // degrees
79 #define UNCONTROLLED_CROSSING_SPEED_THRESHOLD 13.89 // meters/second
101 myApproaching(approaching), myCurrentOutgoing(currentOutgoing) {
105 std::set<int> approachedLanes;
107 const std::vector<NBEdge::Connection> conns = (*it)->getConnections();
108 for (std::vector<NBEdge::Connection>::const_iterator it_con = conns.begin(); it_con != conns.end(); ++it_con) {
110 approachedLanes.insert((*it_con).toLane);
118 for (
int i = 0; i < (int)currentOutgoing->
getNumLanes(); ++i) {
121 && approachedLanes.count(i) == 0) {
134 assert(myApproaching->size() > src);
136 NBEdge* incomingEdge = (*myApproaching)[src];
140 std::vector<int> approachingLanes =
142 assert(approachingLanes.size() != 0);
143 std::deque<int>* approachedLanes = spread(approachingLanes, dest);
144 assert(approachedLanes->size() <= myAvailableLanes.size());
146 for (
unsigned int i = 0; i < approachedLanes->size(); i++) {
147 assert(approachedLanes->size() > i);
148 assert(approachingLanes.size() > i);
149 unsigned int approached = myAvailableLanes[(*approachedLanes)[i]];
150 incomingEdge->setConnection((
unsigned int) approachingLanes[i], myCurrentOutgoing,
153 delete approachedLanes;
160 std::deque<int>* ret =
new std::deque<int>();
161 unsigned int noLanes = (
unsigned int) approachingLanes.size();
165 ret->push_back(dest);
169 unsigned int noOutgoingLanes = (
unsigned int)myAvailableLanes.size();
171 ret->push_back(dest);
172 unsigned int noSet = 1;
175 while (noSet < noLanes) {
181 if (noOutgoingLanes == noSet) {
190 if (dest + loffset >= static_cast<int>(noOutgoingLanes)) {
193 for (
unsigned int i = 0; i < ret->size(); i++) {
194 (*ret)[i] = (*ret)[i] - 1;
199 ret->push_back(dest + loffset);
204 if (noOutgoingLanes == noSet) {
209 if (noSet < noLanes) {
212 if (dest < roffset) {
215 for (
unsigned int i = 0; i < ret->size(); i++) {
216 (*ret)[i] = (*ret)[i] + 1;
219 ret->push_front(dest - roffset);
248 myPosition(position),
250 myDistrict(district),
251 myHaveCustomPoly(false),
253 myRadius(UNSPECIFIED_RADIUS),
254 myKeepClear(
OptionsCont::getOptions().getBool(
"default.junctions.keep-clear")),
255 myDiscardAllCrossings(false),
256 myCrossingsLoadedFromSumoNet(0)
267 bool updateEdgeGeometries) {
274 if (updateEdgeGeometries) {
278 (*i)->setGeometry(geom);
283 (*i)->setGeometry(geom);
325 for (std::set<NBTrafficLightDefinition*>::const_iterator i = trafficLights.begin(); i != trafficLights.end(); ++i) {
337 if ((*i)->getID().find(
"joined") == 0) {
349 for (std::set<NBTrafficLightDefinition*>::iterator it = oldDefs.begin(); it != oldDefs.end(); ++it) {
351 if (dynamic_cast<NBOwnTLDef*>(orig) == 0) {
353 const std::vector<NBNode*>& nodes = orig->
getNodes();
354 while (!nodes.empty()) {
355 newDef->
addNode(nodes.front());
356 nodes.front()->removeTrafficLight(orig);
369 (*it)->shiftTLConnectionLaneIndex(edge, offset);
376 unsigned int ret = 0;
377 unsigned int pos = 0;
393 if ((*i)->isConnectedTo(dummy) && *i != dummy) {
394 incomingConnected.push_back(*i);
401 outgoingConnected.push_back(*i);
406 remapRemoved(tc, dummy, incomingConnected, outgoingConnected);
455 if (in->
getNumLanes() != (*opposite)->getNumLanes()) {
474 const Position beg = begShape.back();
475 const Position end = endShape.front();
478 unsigned int numInitialPoints = 0;
479 bool noSpline =
false;
490 numInitialPoints = 3;
492 Line straightConn(begShape[-1], endShape[0]);
495 Line cross(straightConn);
496 cross.
sub(cross.
p1().
x(), cross.
p1().
y());
498 center.
sub(cross.
p2());
503 if (angle < M_PI / 4. || angle > 7. / 4.*
M_PI) {
505 numInitialPoints = 4;
533 numInitialPoints = 3;
552 for (
int i = 0; i < (int) init.size(); ++i) {
554 def[i * 3 + 1] = init[i].x();
556 def[i * 3 + 3] = init[i].y();
559 bezier(numInitialPoints, def, numPoints, ret_buf);
562 for (
int i = 0; i < (int) numPoints; i++) {
564 if (prev != current && !
ISNAN(current.x()) && !
ISNAN(current.y())) {
586 assert(con.
shape.size() > 0);
607 if (lane.endOffset > 0) {
629 if (thisRight && !rightTurnConflict) {
632 if (!(
foes(otherFromE, otherToE, fromE, toE) ||
myRequest == 0 || rightTurnConflict)) {
642 const bool bothLeft = thisLeft && otherLeft;
643 if (fromE == otherFromE && !thisRight) {
650 if (c.
tlID !=
"" && !bothLeft) {
670 for (std::set<NBTrafficLightDefinition*>::const_iterator i = trafficLights.begin(); i != trafficLights.end(); ++i) {
671 (*i)->setParticipantsInformation();
672 (*i)->setTLControllingInformation(ec);
699 }
else if (numConnections == 0) {
737 if (mismatchThreshold >= 0
770 for (
int i = inOffset; i < (int) in->
getNumLanes(); ++i) {
801 std::swap(in1Offset, in2Offset);
826 std::swap(out1, out2);
827 std::swap(out1Offset, out2Offset);
839 EdgeVector::reverse_iterator i;
841 NBEdge* currentOutgoing = *i;
844 const unsigned int numApproaching = (
unsigned int)approaching->size();
845 if (numApproaching != 0) {
856 (*i)->markAsInLane2LaneState();
874 EdgeVector::const_iterator i = find(
myAllEdges.begin(),
880 for (; *i != currentOutgoing;) {
882 if ((*i)->getToNode() ==
this && (*i)->getTurnDestination() != currentOutgoing) {
883 std::vector<int> connLanes = (*i)->getConnectionLanes(currentOutgoing);
884 if (connLanes.size() != 0) {
885 approaching->push_back(*i);
915 unsigned int laneOff = 0;
916 for (EdgeVector::const_iterator i = which.begin(); i != which.end(); i++) {
918 laneOff += (*i)->getNumLanes();
947 unsigned int laneOff = 0;
948 for (EdgeVector::const_iterator i = which.begin(); i != which.end(); i++) {
950 laneOff += (*i)->getNumLanes();
965 unsigned int whichLaneOff,
unsigned int byLaneOff) {
969 bool changed =
false;
971 if (c.
replaceFrom(which, whichLaneOff, by, byLaneOff)) {
974 if (c.
replaceTo(which, whichLaneOff, by, byLaneOff)) {
988 for (NBConnectionVector::iterator k = prohibiting.begin(); k != prohibiting.end(); k++) {
990 sprohibiting.
replaceFrom(which, whichLaneOff, by, byLaneOff);
991 sprohibiting.
replaceTo(which, whichLaneOff, by, byLaneOff);
1052 if (find(edges.begin(), edges.end(), e) != edges.end()) {
1053 edges.erase(find(edges.begin(), edges.end(), e));
1055 if (edges.size() == 0) {
1070 if (mayDrive.
getFrom() == 0 ||
1071 mayDrive.
getTo() == 0 ||
1073 mustStop.
getTo() == 0) {
1075 WRITE_WARNING(
"Something went wrong during the building of a connection...");
1079 conn.push_back(mayDrive);
1086 unsigned int size = (
unsigned int) edgeid.length();
1088 std::string
id = (*i)->
getID();
1089 if (
id.substr(0, size) == edgeid) {
1099 unsigned int size = (
unsigned int) edgeid.length();
1101 std::string
id = (*i)->
getID();
1102 if (
id.substr(0, size) == edgeid) {
1127 if (removeFromConnections) {
1129 (*i)->removeFromConnections(edge);
1139 EdgeVector::const_iterator i;
1141 NBNode* conn = (*i)->getFromNode();
1144 toAdd.
mul((
SUMOReal) 1.0 / sqrt(toAdd.
x()*toAdd.
x() + toAdd.
y()*toAdd.
y()));
1148 NBNode* conn = (*i)->getToNode();
1151 toAdd.
mul((
SUMOReal) 1.0 / sqrt(toAdd.
x()*toAdd.
x() + toAdd.
y()*toAdd.
y()));
1155 if (pos.
x() == 0 && pos.
y() == 0) {
1167 (*i)->invalidateConnections();
1175 (*i)->invalidateConnections();
1202 const NBEdge* prohibitorFrom,
const NBEdge* prohibitorTo,
int prohibitorFromLane,
1204 if (from != prohibitorFrom) {
1228 lefthand = !lefthand;
1235 if ((!lefthand && fromLane <= prohibitorFromLane) ||
1236 (lefthand && fromLane >= prohibitorFromLane)) {
1258 std::vector<NBEdge*>::const_iterator i = std::find(
myAllEdges.begin(),
myAllEdges.end(), from);
1268 const NBEdge*
const possProhibitedFrom,
const NBEdge*
const possProhibitedTo,
1269 bool regardNonSignalisedLowerPriority)
const {
1271 possProhibitedFrom, possProhibitedTo,
1272 regardNonSignalisedLowerPriority);
1278 const NBEdge*
const from2,
const NBEdge*
const to2)
const {
1287 assert(find(incoming.begin(), incoming.end(), removed) == incoming.end());
1288 bool changed =
true;
1294 for (NBConnectionProhibits::iterator i = blockedConnectionsTmp.begin(); i != blockedConnectionsTmp.end(); i++) {
1299 bool blockedChanged =
false;
1301 NBConnectionVector::const_iterator j;
1302 for (j = blocked.begin(); j != blocked.end(); j++) {
1304 if (sblocked.
getFrom() == removed || sblocked.
getTo() == removed) {
1305 blockedChanged =
true;
1309 for (j = blocked.begin(); blockedChanged && j != blocked.end(); j++) {
1311 if (sblocked.
getFrom() == removed && sblocked.
getTo() == removed) {
1315 }
else if (sblocked.
getFrom() == removed) {
1316 assert(sblocked.
getTo() != removed);
1317 for (EdgeVector::const_iterator k = incoming.begin(); k != incoming.end(); k++) {
1320 }
else if (sblocked.
getTo() == removed) {
1321 assert(sblocked.
getFrom() != removed);
1322 for (EdgeVector::const_iterator k = outgoing.begin(); k != outgoing.end(); k++) {
1329 if (blockedChanged) {
1330 blockedConnectionsNew[blocker] = newBlocked;
1335 if (blocker.
getFrom() == removed && blocker.
getTo() == removed) {
1340 }
else if (blocker.
getFrom() == removed) {
1341 assert(blocker.
getTo() != removed);
1343 for (EdgeVector::const_iterator k = incoming.begin(); k != incoming.end(); k++) {
1346 }
else if (blocker.
getTo() == removed) {
1347 assert(blocker.
getFrom() != removed);
1349 for (EdgeVector::const_iterator k = outgoing.begin(); k != outgoing.end(); k++) {
1353 blockedConnectionsNew[blocker] = blocked;
1367 if (outgoing == 0) {
1378 if (
abs((
int) angle) + 1 < 45) {
1385 EdgeVector::const_iterator i =
1392 while ((*i) != incoming) {
1406 EdgeVector::const_iterator i =
1413 while ((*i) != incoming) {
1430 bool mayDefinitelyPass,
const std::string& tlID)
const {
1434 if (outgoing == 0) {
1443 if ((!incoming->
isInnerEdge() &&
mustBrake(incoming, outgoing, fromlane,
true)) && !mayDefinitelyPass) {
1457 EdgeVector::const_iterator i;
1470 std::set<NBNode*> origSet;
1472 origSet.insert((*i)->getFromNode());
1474 if (origSet.size() < 2) {
1482 if (opposite != 0) {
1486 if (!(*i)->expandableBy(continuation)) {
1502 std::vector<std::pair<NBEdge*, NBEdge*> >
1505 std::vector<std::pair<NBEdge*, NBEdge*> > ret;
1509 std::pair<NBEdge*, NBEdge*>(
1517 assert(opposite != 0);
1519 ret.push_back(std::pair<NBEdge*, NBEdge*>(*i, continuation));
1540 if (shape.size() > 1) {
1551 if ((*i)->getToNode() == n) {
1566 back_inserter(edges));
1568 back_inserter(edges));
1569 for (EdgeVector::const_iterator j = edges.begin(); j != edges.end(); ++j) {
1580 for (EdgeVector::const_iterator k = edges2.begin(); k != edges2.end(); ++k) {
1581 if ((*k)->getFromNode()->isDistrict() || (*k)->getToNode()->isDistrict()) {
1605 std::cout <<
"guess crossings for " <<
getID() <<
"\n";
1609 std::vector<std::pair<NBEdge*, bool> > normalizedLanes;
1610 for (EdgeVector::const_iterator it = allEdges.begin(); it != allEdges.end(); ++it) {
1612 const std::vector<NBEdge::Lane>& lanes = edge->
getLanes();
1614 for (std::vector<NBEdge::Lane>::const_reverse_iterator it_l = lanes.rbegin(); it_l != lanes.rend(); ++it_l) {
1615 normalizedLanes.push_back(std::make_pair(edge, ((*it_l).permissions &
SVC_PEDESTRIAN) != 0));
1618 for (std::vector<NBEdge::Lane>::const_iterator it_l = lanes.begin(); it_l != lanes.end(); ++it_l) {
1619 normalizedLanes.push_back(std::make_pair(edge, ((*it_l).permissions &
SVC_PEDESTRIAN) != 0));
1624 int firstSidewalk = -1;
1625 for (
int i = 0; i < (int)normalizedLanes.size(); ++i) {
1626 if (normalizedLanes[i].second) {
1631 int hadCandidates = 0;
1632 std::vector<int> connectedCandidates;
1633 if (firstSidewalk != -1) {
1635 std::vector<std::pair<NBEdge*, bool> > tmp;
1636 copy(normalizedLanes.begin() + firstSidewalk, normalizedLanes.end(), std::back_inserter(tmp));
1637 copy(normalizedLanes.begin(), normalizedLanes.begin() + firstSidewalk, std::back_inserter(tmp));
1638 normalizedLanes = tmp;
1641 for (
int i = 0; i < (int)normalizedLanes.size(); ++i) {
1642 NBEdge* edge = normalizedLanes[i].first;
1643 const bool allowsPed = normalizedLanes[i].second;
1645 std::cout <<
" cands=" <<
toString(candidates) <<
" edge=" << edge->
getID() <<
" allowsPed=" << allowsPed <<
"\n";
1647 if (!allowsPed && (candidates.size() == 0 || candidates.back() != edge)) {
1648 candidates.push_back(edge);
1649 }
else if (allowsPed) {
1650 if (candidates.size() > 0) {
1656 connectedCandidates.push_back(n);
1663 if (hadCandidates > 0 && candidates.size() > 0) {
1669 connectedCandidates.push_back(n);
1675 std::cout <<
" hadCandidates=" << hadCandidates <<
" connectedCandidates=" <<
toString(connectedCandidates) <<
"\n";
1677 if (hadCandidates == 2 && connectedCandidates.size() == 2) {
1679 if (connectedCandidates.back() <= connectedCandidates.front()) {
1680 numGuessed -= connectedCandidates.back();
1683 numGuessed -= connectedCandidates.front();
1689 std::cout <<
"guessedCrossings:\n";
1691 std::cout <<
" edges=" <<
toString((*it).edges) <<
"\n";
1701 std::cout <<
"checkCrossing candidates=" <<
toString(candidates) <<
"\n";
1703 if (candidates.size() == 0) {
1705 std::cout <<
"no crossing added (numCandidates=" << candidates.size() <<
")\n";
1711 for (
size_t i = 0; i < candidates.size(); ++i) {
1712 NBEdge* edge = candidates[i];
1717 std::cout <<
"no crossing added (found angle difference of " << fabs(angle - prevAngle) <<
" at i=" << i <<
"\n";
1723 std::cout <<
"no crossing added (uncontrolled, edge with speed=" << edge->
getSpeed() <<
")\n";
1729 if (candidates.size() == 1) {
1732 std::cout <<
"adding crossing: " <<
toString(candidates) <<
"\n";
1738 for (EdgeVector::iterator it = candidates.begin(); it != candidates.end(); ++it) {
1739 SUMOReal angle = (*it)->getCrossingAngle(
this);
1740 if (it != candidates.begin()) {
1741 NBEdge* prev = *(it - 1);
1749 prevPos = prev->
getLanes()[laneI].shape[-1];
1752 prevPos = prev->
getLanes()[laneI].shape[0];
1757 currPos = curr->
getLanes()[laneI].shape[0];
1760 currPos = curr->
getLanes()[laneI].shape[-1];
1766 <<
" prevAngle=" << prevAngle
1767 <<
" angle=" << angle
1768 <<
" intermediateWidth=" << intermediateWidth
1781 std::cout <<
"adding crossing: " <<
toString(candidates) <<
"\n";
1791 for (
int i = startIndex; i < (int)normalizedLanes.size(); ++i) {
1792 if (!normalizedLanes[i].second) {
1806 if ((*it).prevWalkingArea ==
"" || (*it).nextWalkingArea ==
"") {
1807 WRITE_WARNING(
"Discarding Invalid crossing '" + (*it).id +
"' at node '" +
getID() +
"' with edges '" +
toString((*it).edges) +
"'.");
1819 unsigned int noInternalNoSplits = 0;
1821 const std::vector<NBEdge::Connection>& elv = (*i)->getConnections();
1822 for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
1823 if ((*k).toEdge == 0) {
1826 noInternalNoSplits++;
1829 unsigned int lno = 0;
1830 unsigned int splitNo = 0;
1832 (*i)->buildInnerEdges(*
this, noInternalNoSplits, lno, splitNo);
1837 unsigned int lno = 0;
1838 unsigned int splitNo = 0;
1840 (*i)->buildInnerEdges(*
this, noInternalNoSplits, lno, splitNo);
1850 std::cout <<
"build crossings for " <<
getID() <<
":\n";
1855 unsigned int index = 0;
1860 (*it).nextWalkingArea =
"";
1861 (*it).prevWalkingArea =
"";
1864 std::cout <<
" crossing=" << (*it).id <<
" edges=" <<
toString(edges);
1870 std::cout <<
" sortedEdges=" <<
toString(edges) <<
"\n";
1874 int maxAngleDiffIndex = 0;
1875 for (
int i = 0; i < (int) edges.size(); i++) {
1877 edges[(i + 1) % edges.size()]->getAngleAtNodeToCenter(
this));
1882 std::cout <<
" i=" << i <<
" a1=" << edges[i]->getAngleAtNodeToCenter(
this) <<
" a2=" << edges[(i + 1) % edges.size()]->getAngleAtNodeToCenter(
this) <<
" diff=" << diff <<
"\n";
1884 if (diff > maxAngleDiff) {
1885 maxAngleDiff = diff;
1886 maxAngleDiffIndex = i;
1889 if (maxAngleDiff > 2 && maxAngleDiff < 360 - 2) {
1891 std::rotate(edges.begin(), edges.begin() + (maxAngleDiffIndex + 1) % edges.size(), edges.end());
1893 std::cout <<
" rotatedEdges=" <<
toString(edges);
1897 std::reverse(edges.begin(), edges.end());
1899 std::cout <<
" finalEdges=" <<
toString(edges) <<
"\n";
1902 (*it).shape.clear();
1903 const int begDir = (edges.front()->getFromNode() ==
this ?
FORWARD :
BACKWARD);
1904 const int endDir = (edges.back()->getToNode() ==
this ?
FORWARD :
BACKWARD);
1905 if (edges.front()->getFirstNonPedestrianLaneIndex(begDir) < 0
1906 || edges.back()->getFirstNonPedestrianLaneIndex(endDir) < 0) {
1908 WRITE_WARNING(
"Discarding Invalid crossing '" + (*it).id +
"' at node '" +
getID() +
"' with edges '" +
toString((*it).edges) +
"'.");
1911 NBEdge::Lane crossingBeg = edges.front()->getFirstNonPedestrianLane(begDir);
1912 NBEdge::Lane crossingEnd = edges.back()->getFirstNonPedestrianLane(endDir);
1919 (*it).shape.push_back(crossingBeg.
shape[begDir ==
FORWARD ? 0 : -1]);
1920 (*it).shape.push_back(crossingEnd.
shape[endDir ==
FORWARD ? -1 : 0]);
1931 unsigned int index = 0;
1934 std::cout <<
"build walkingAreas for " <<
getID() <<
":\n";
1941 std::vector<std::pair<NBEdge*, NBEdge::Lane> > normalizedLanes;
1942 for (EdgeVector::const_iterator it = allEdges.begin(); it != allEdges.end(); ++it) {
1944 const std::vector<NBEdge::Lane>& lanes = edge->
getLanes();
1946 for (std::vector<NBEdge::Lane>::const_reverse_iterator it_l = lanes.rbegin(); it_l != lanes.rend(); ++it_l) {
1950 normalizedLanes.push_back(std::make_pair(edge, l));
1953 for (std::vector<NBEdge::Lane>::const_iterator it_l = lanes.begin(); it_l != lanes.end(); ++it_l) {
1958 normalizedLanes.push_back(std::make_pair(edge, l));
1964 std::vector<std::pair<int, int> > waIndices;
1966 NBEdge* prevEdge = normalizedLanes.back().first;
1967 for (
int i = 0; i < (int)normalizedLanes.size(); ++i) {
1968 NBEdge* edge = normalizedLanes[i].first;
1976 waIndices.push_back(std::make_pair(start, i - start));
1986 <<
" waI=" << waIndices.size() <<
" crossingBetween=" <<
crossingBetween(edge, prevEdge) <<
"\n";
1991 const int waNumLanes = (int)normalizedLanes.size() - start;
1992 if (waIndices.size() == 0) {
1993 waIndices.push_back(std::make_pair(start, waNumLanes));
1995 std::cout <<
" single wa, end at wrap-around\n";
1998 if (waIndices.front().first == 0) {
1999 NBEdge* edge = normalizedLanes.front().first;
2000 NBEdge* prevEdge = normalizedLanes.back().first;
2003 waIndices.push_back(std::make_pair(start, waNumLanes));
2005 std::cout <<
" do not wrap around, turn-around in between\n";
2009 waIndices.front().first = start;
2010 waIndices.front().second = waNumLanes + waIndices.front().second;
2012 std::cout <<
" wrapping around\n";
2017 waIndices.push_back(std::make_pair(start, waNumLanes));
2019 std::cout <<
" end at wrap-around\n";
2025 std::cout <<
" normalizedLanes=" << normalizedLanes.size() <<
" waIndices:\n";
2026 for (
int i = 0; i < (int)waIndices.size(); ++i) {
2027 std::cout <<
" " << waIndices[i].first <<
", " << waIndices[i].second <<
"\n";
2031 for (
int i = 0; i < (int)waIndices.size(); ++i) {
2032 const bool buildExtensions = waIndices[i].second != (int)normalizedLanes.size();
2033 const int start = waIndices[i].first;
2034 const int prev = start > 0 ? start - 1 : (int)normalizedLanes.size() - 1;
2035 const int count = waIndices[i].second;
2036 const int end = (start + count) % normalizedLanes.size();
2040 std::cout <<
"build walkingArea " << wa.
id <<
" start=" << start <<
" end=" << end <<
" count=" << count <<
" prev=" << prev <<
":\n";
2047 bool connectsCrossing =
false;
2048 std::vector<Position> connectedPoints;
2051 std::cout <<
" crossing=" << (*it).id <<
" sortedEdges=" <<
toString((*it).edges) <<
"\n";
2053 if ((*it).edges.back() == normalizedLanes[end].first
2054 && (normalizedLanes[end].second.permissions &
SVC_PEDESTRIAN) == 0) {
2056 (*it).nextWalkingArea = wa.
id;
2057 endCrossingWidth = (*it).width;
2058 endCrossingShape = (*it).shape;
2060 connectsCrossing =
true;
2061 connectedPoints.push_back((*it).shape[-1]);
2063 std::cout <<
" crossing " << (*it).id <<
" ends\n";
2066 if ((*it).edges.front() == normalizedLanes[prev].first
2067 && (normalizedLanes[prev].second.permissions &
SVC_PEDESTRIAN) == 0) {
2069 (*it).prevWalkingArea = wa.
id;
2071 startCrossingWidth = (*it).width;
2072 startCrossingShape = (*it).shape;
2074 connectsCrossing =
true;
2075 connectedPoints.push_back((*it).shape[0]);
2077 std::cout <<
" crossing " << (*it).id <<
" starts\n";
2080 if (
gDebugFlag1) std::cout <<
" check connections to crossing " << (*it).id
2081 <<
" cFront=" << (*it).edges.front()->getID() <<
" cBack=" << (*it).edges.back()->getID()
2082 <<
" wEnd=" << normalizedLanes[end].first->getID() <<
" wStart=" << normalizedLanes[start].first->getID()
2083 <<
" wStartPrev=" << normalizedLanes[prev].first->getID()
2086 if (count < 2 && !connectsCrossing) {
2091 std::set<NBEdge*> connected;
2092 for (
int j = 0; j < count; ++j) {
2093 const int nlI = (start + j) % normalizedLanes.size();
2094 NBEdge* edge = normalizedLanes[nlI].first;
2097 if (connected.count(edge) == 0) {
2105 connected.insert(edge);
2112 if (buildExtensions) {
2114 if (startCrossingShape.size() > 0) {
2116 std::cout <<
" extension at startCrossing shape=" << startCrossingShape <<
"\n";
2118 startCrossingShape.
move2side(startCrossingWidth / 2);
2120 startCrossingShape.
move2side(-startCrossingWidth);
2124 if (endCrossingShape.size() > 0) {
2126 std::cout <<
" extension at endCrossing shape=" << endCrossingShape <<
"\n";
2128 endCrossingShape.
move2side(endCrossingWidth / 2);
2130 endCrossingShape.
move2side(-endCrossingWidth);
2136 NBEdge* e1 = *connected.begin();
2137 NBEdge* e2 = *(++connected.begin());
2143 if (cornerDetail > 0) {
2144 int smoothEnd = end;
2145 int smoothPrev = prev;
2147 if (endCrossingWidth > 0 && normalizedLanes[smoothEnd].second.permissions == 0) {
2148 smoothEnd = (smoothEnd + 1) % normalizedLanes.size();
2150 if (startCrossingWidth > 0 && normalizedLanes[smoothPrev].second.permissions == 0) {
2151 if (smoothPrev == 0) {
2152 smoothPrev = (int)normalizedLanes.size() - 1;
2157 PositionVector begShape = normalizedLanes[smoothEnd].second.shape;
2158 begShape = begShape.
reverse();
2160 begShape.
move2side(normalizedLanes[smoothEnd].second.width / 2);
2161 PositionVector endShape = normalizedLanes[smoothPrev].second.shape;
2162 endShape.
move2side(normalizedLanes[smoothPrev].second.width / 2);
2166 <<
" end=" << smoothEnd <<
" prev=" << smoothPrev
2167 <<
" endCrossingWidth=" << endCrossingWidth <<
" startCrossingWidth=" << startCrossingWidth
2168 <<
" begShape=" << begShape <<
" endShape=" << endShape <<
" smooth curve=" << curve <<
"\n";
2169 if (curve.size() > 2) {
2172 if (endCrossingWidth > 0) {
2175 if (startCrossingWidth > 0) {
2183 int combinations = 0;
2184 for (std::vector<Position>::const_iterator it1 = connectedPoints.begin(); it1 != connectedPoints.end(); ++it1) {
2185 for (std::vector<Position>::const_iterator it2 = connectedPoints.begin(); it2 != connectedPoints.end(); ++it2) {
2195 std::cout <<
" combinations=" << combinations <<
" connectedPoints=" << connectedPoints <<
"\n";
2198 if (combinations > 0) {
2208 std::cout <<
" checkIntermediate: prev=" << prev.
id <<
" next=" << next.
id <<
" prev.nextWA=" << prev.
nextWalkingArea <<
"\n";
2231 std::cout <<
" build wa=" << wa.
id <<
"\n";
2245 EdgeVector::const_iterator it1 = find(edges.begin(), edges.end(), e1);
2246 EdgeVector::const_iterator it2 = find(edges.begin(), edges.end(), e2);
2247 if (it1 != edges.end() && it2 != edges.end()) {
2263 while (it != it_end) {
2264 result.push_back(*it);
2285 if (
MAX2(angle0, angle1) <= 160) {
2315 EdgeSet edgeSet(edges.begin(), edges.end());
2317 EdgeSet edgeSet2((*it).edges.begin(), (*it).edges.end());
2318 if (edgeSet == edgeSet2) {
2330 if ((*it).id ==
id) {
2334 throw ProcessError(
"Request for unknown crossing '" +
id +
"'");
2341 (*it).tlLinkNo = startIndex++;
2373 std::cout <<
" angles:\n";
2374 for (EdgeVector::const_iterator it = result.begin(); it != result.end(); ++it) {
2375 std::cout <<
" edge=" << (*it)->getID() <<
" edgeAngle=" << (*it)->getAngleAtNode(
this) <<
" angleToShape=" << (*it)->getAngleAtNodeToCenter(
this) <<
"\n";
2377 std::cout <<
" allEdges before: " <<
toString(result) <<
"\n";
2382 std::cout <<
" allEdges sorted: " <<
toString(result) <<
"\n";
2384 rotate(result.begin(), std::find(result.begin(), result.end(), *
myAllEdges.begin()), result.end());
2386 std::cout <<
" allEdges rotated: " <<
toString(result) <<
"\n";
2397 assert(
id[0] ==
':');
2398 size_t sep_index =
id.rfind(
'_');
2399 if (sep_index == std::string::npos) {
2400 WRITE_ERROR(
"Invalid lane id '" +
id +
"' (missing '_').");
2403 sep_index =
id.substr(0, sep_index).rfind(
'_');
2404 if (sep_index == std::string::npos) {
2405 WRITE_ERROR(
"Invalid lane id '" +
id +
"' (missing '_').");
2408 return id.substr(1, sep_index - 1);
2418 if (turnDest != 0) {
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 PositionVector & getLaneShape(unsigned int i) const
Returns the shape of the nth lane.
void replaceIncoming(NBEdge *which, NBEdge *by, unsigned int laneOff)
Replaces occurences of the first edge within the list of incoming by the second Connections are remap...
const Position & p2() const
bool hasConnectionTo(NBEdge *destEdge, unsigned int destLane, int fromLane=-1) const
Retrieves info about a connection to a certain lane of a certain edge.
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges.
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 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.
SUMOReal distance(const Position &p, bool perpendicular=false) const
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.
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
NBEdge * getOppositeIncoming(NBEdge *e) const
void setConnection(unsigned int lane, NBEdge *destEdge, unsigned int destLane, Lane2LaneInfoType type, bool mayUseSameDestination=false, bool mayDefinitelyPass=false, bool keepClear=true)
Adds a connection to a certain lane of a certain edge.
void execute(const unsigned int src, const unsigned 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.
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.
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 The angle is computed in computeAngle()
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
The link is a 180 degree turn.
int numNormalConnections() const
return the number of lane-to-lane connections at this junction (excluding crossings) ...
void rotateAtP1(SUMOReal rot)
bool hasOutgoing(const NBEdge *const e) const
Returns whether the given edge starts at this node.
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
bool addLane2LaneConnections(unsigned int fromLane, NBEdge *dest, unsigned int toLane, unsigned int no, Lane2LaneInfoType type, bool invalidatePrevious=false, bool mayDefinitelyPass=false)
Builds no connections starting at the given lanes.
bool mustBrake(const NBEdge *const from, const NBEdge *const to, int fromLane, bool includePedCrossings) const
Returns the information whether the described flow must let any other flow pass.
bool isJoinedTLSControlled() const
Returns whether this node is controlled by a tls that spans over more than one node.
void buildBitfieldLogic()
SUMOReal getLaneWidth() const
Returns the default width of lanes of this edge.
void extrapolateFirstBy(SUMOReal length)
PositionVector shape
The lane's shape.
#define SPLIT_CROSSING_ANGLE_THRESHOLD
PositionVector getSubpartByIndex(int beginIndex, int count) const
void buildWalkingAreas(int cornerDetail)
static const int MAX_CONNECTIONS
maximum number of connections allowed
bool isInnerEdge() const
Returns whether this edge was marked as being within an intersection.
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
SUMOReal distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimension
EdgeVector getEdgesSortedByAngleAtNodeCenter() const
returns the list of all edges sorted clockwise by getAngleAtNodeToCenter
bool checkIsRemovable() const
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 ...
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.
NBConnectionProhibits myBlockedConnections
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)
unsigned int numAvailableLanes() const
The link is a (hard) left direction.
#define WRITE_WARNING(msg)
The connection was computed and validated.
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
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.
NBDistrict * myDistrict
The district the node is the centre of.
A class representing a single district.
PositionVector computeInternalLaneShape(NBEdge *fromE, const NBEdge::Connection &con, int numPoints=5) const
Compute the shape for an internal lane.
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges.
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
Position getPositionAtDistance(SUMOReal offset) const
void invalidateIncomingConnections()
bool isConnectedTo(NBEdge *e)
Returns the information whethe a connection to the given edge has been added (or computed) ...
void push_front_noDoublePos(const Position &p)
void removeCrossing(const EdgeVector &edges)
remove a pedestrian crossing from this node (identified by its edges)
const Position & getPosition() const
Returns the position of this node.
const Position & p1() const
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)
bool isSimpleContinuation() const
int checkCrossing(EdgeVector candidates)
static const int FORWARD
edge directions (for pedestrian related stuff)
std::vector< unsigned int > myAvailableLanes
The available lanes to which connections shall be built.
void remapRemoved(NBEdge *removed, const EdgeVector &incoming, const EdgeVector &outgoing)
Replaces occurences of the removed edge in incoming/outgoing edges of all definitions.
void mirrorX()
mirror coordinates along the x-axis
std::string tlID
The id of the traffic light that controls this connection.
std::string getInternalLaneID() const
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.
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)
void buildCrossingsAndWalkingAreas()
unsigned int getNumLanes() const
Returns the number of lanes.
SUMOReal z() const
Returns the z-position.
bool geometryLike() const
whether this is structurally similar to a geometry node
void invalidateOutgoingConnections()
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)
std::set< NBTrafficLightDefinition * > myTrafficLights
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[])
PositionVector computeSmoothShape(const PositionVector &begShape, const PositionVector &endShape, int numPoints, bool isTurnaround, SUMOReal extrapolateBeg, SUMOReal extrapolateEnd) const
Compute a smooth curve between the given geometries.
std::string nextCrossing
the lane-id of the next crossing
void setCrossingTLIndices(unsigned int startIndex)
set tl indices of this nodes crossing starting at the given index
The link is a (hard) right direction.
bool myDiscardAllCrossings
whether to discard all pedestrian crossings
LinkDirection getDirection(const NBEdge *const incoming, const NBEdge *const outgoing, bool leftHand=false) const
Returns the representation of the described stream's direction.
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
PositionVector compute()
Computes the shape of the assigned junction.
const PositionVector & getShape() const
retrieve the junction shape
The link is a partial right direction.
static void compute(BresenhamCallBack *callBack, const unsigned int val1, const unsigned int val2)
NBEdge * getConnectionTo(NBNode *n) const
const std::vector< NBNode * > & getNodes() const
Returns the list of controlled nodes.
SUMOReal atan2Angle() const
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
bool intersects(const Line &l) const
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)
unsigned int removeSelfLoops(NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tc)
Removes edges which are both incoming and outgoing into this node.
void extrapolate(SUMOReal val)
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.
void push_back(const PositionVector &p)
Appends all positions from the given vector.
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.
void extrapolateSecondBy(SUMOReal length)
bool isNearDistrict() const
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.
std::map< NBConnection, NBConnectionVector > NBConnectionProhibits
Definition of a container for connection block dependencies Includes a list of all connections which ...
void replaceOutgoing(NBEdge *which, NBEdge *by, unsigned int laneOff)
Replaces occurences of the first edge within the list of outgoing by the second Connections are remap...
~ApproachingDivider()
Destructor.
std::vector< WalkingArea > myWalkingAreas
Vector of walking areas.
LinkState getLinkState(const NBEdge *incoming, NBEdge *outgoing, int fromLane, bool mayDefinitelyPass, const std::string &tlID) const
SumoXMLNodeType
Numbers representing special SUMO-XML-attribute values for representing node- (junction-) types used ...
unsigned int buildCrossings()
bool myKeepClear
whether the junction area must be kept clear
void replaceInConnectionProhibitions(NBEdge *which, NBEdge *by, unsigned int whichLaneOff, unsigned int byLaneOff)
The link is controlled by a tls which is off and blinks, has to brake.
std::vector< NBEdge * > EdgeVector
void buildInnerEdges()
build internal lanes, pedestrian crossings and walking areas
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.
void sub(SUMOReal x, SUMOReal y)
A storage for options typed value containers)
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)
void replaceInConnections(NBEdge *which, NBEdge *by, unsigned int laneOff)
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
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.
static const SUMOReal DEFAULT_RADIUS
the default turning radius at intersections in m
bool removeFully(const std::string id)
Removes a logic definition (and all programs) from the dictionary.
Lane & getLaneStruct(unsigned int 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.
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)
bool insert(NBTrafficLightDefinition *logic, bool forceInsert=false)
Adds a logic definition to the dictionary.
void addSortedLinkFoes(const NBConnection &mayDrive, const NBConnection &mustStop)
Static storage of an output device and its base (abstract) implementation.
Computes lane-2-lane connections.
static const SUMOReal UNSPECIFIED_RADIUS
unspecified lane width
bool writeLogic(OutputDevice &into, const bool checkLaneFoes) const
static SUMOReal relAngle(SUMOReal angle1, SUMOReal angle2)
void push_back_noDoublePos(const Position &p)
#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 The angle is computed in computeAngle() ...
Position getPolygonCenter() const
Returns the arithmetic of all corner points.
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
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.
NBEdge * getTurnDestination(bool possibleDestination=false) const
Position intersectsAt(const Line &l) const
PositionVector getSubpart(SUMOReal beginOffset, SUMOReal endOffset) const
std::vector< std::string > prevSidewalks
the lane-id of the previous sidewalk lane or ""
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.
void append(const PositionVector &v, SUMOReal sameThreshold=2.0)
SUMOReal width
This lane's width.
void remapRemoved(NBTrafficLightLogicCont &tc, NBEdge *removed, const EdgeVector &incoming, const EdgeVector &outgoing)
std::pair< unsigned int, unsigned int > getSizes() const
returns the number of the junction's lanes and the number of the junction's links in respect...
PositionVector shape
The polygonal shape.
#define UNCONTROLLED_CROSSING_SPEED_THRESHOLD
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 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.