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
100 EdgeVector* approaching,
NBEdge* currentOutgoing,
const bool buildCrossingsAndWalkingAreas) :
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]];
151 incomingEdge->setConnection((
unsigned int) approachingLanes[i], myCurrentOutgoing,
154 delete approachedLanes;
161 std::deque<int>* ret =
new std::deque<int>();
162 unsigned int noLanes = (
unsigned int) approachingLanes.size();
166 ret->push_back(dest);
170 unsigned int noOutgoingLanes = (
unsigned int)myAvailableLanes.size();
172 ret->push_back(dest);
173 unsigned int noSet = 1;
176 while (noSet < noLanes) {
182 if (noOutgoingLanes == noSet) {
191 if (dest + loffset >= static_cast<int>(noOutgoingLanes)) {
194 for (
unsigned int i = 0; i < ret->size(); i++) {
195 (*ret)[i] = (*ret)[i] - 1;
200 ret->push_back(dest + loffset);
205 if (noOutgoingLanes == noSet) {
210 if (noSet < noLanes) {
213 if (dest < roffset) {
216 for (
unsigned int i = 0; i < ret->size(); i++) {
217 (*ret)[i] = (*ret)[i] + 1;
220 ret->push_front(dest - roffset);
246 myPosition(position),
248 myDistrict(district),
249 myHaveCustomPoly(false),
251 myRadius(UNSPECIFIED_RADIUS)
262 bool updateEdgeGeometries) {
269 if (updateEdgeGeometries) {
273 (*i)->setGeometry(geom);
278 (*i)->setGeometry(geom);
313 for (std::set<NBTrafficLightDefinition*>::const_iterator i = trafficLights.begin(); i != trafficLights.end(); ++i) {
325 if ((*i)->getID().find(
"joined") == 0) {
337 for (std::set<NBTrafficLightDefinition*>::iterator it = oldDefs.begin(); it != oldDefs.end(); ++it) {
339 if (dynamic_cast<NBOwnTLDef*>(orig) == 0) {
341 const std::vector<NBNode*>& nodes = orig->
getNodes();
342 while (!nodes.empty()) {
343 nodes.front()->removeTrafficLight(orig);
344 newDef->
addNode(nodes.front());
357 (*it)->shiftTLConnectionLaneIndex(edge, offset);
364 unsigned int ret = 0;
365 unsigned int pos = 0;
381 if ((*i)->isConnectedTo(dummy) && *i != dummy) {
382 incomingConnected.push_back(*i);
389 outgoingConnected.push_back(*i);
394 remapRemoved(tc, dummy, incomingConnected, outgoingConnected);
443 if (in->
getNumLanes() != (*opposite)->getNumLanes()) {
462 const Position beg = begShape.back();
463 const Position end = endShape.front();
466 unsigned int noInitialPoints = 0;
467 bool noSpline =
false;
478 Line straightConn(begShape[-1], endShape[0]);
481 Line cross(straightConn);
482 cross.
sub(cross.
p1().
x(), cross.
p1().
y());
484 center.
sub(cross.
p2());
489 if (angle < M_PI / 4. || angle > 7. / 4.*
M_PI) {
530 WRITE_WARNING(
"Could not use edge geometry for internal lane, node '" +
getID() +
"'.");
547 for (
int i = 0; i < (int) init.size(); ++i) {
549 def[i * 3 + 1] = init[i].x();
551 def[i * 3 + 3] = init[i].y();
554 bezier(noInitialPoints, def, numPoints, ret_buf);
557 for (
int i = 0; i < (int) numPoints; i++) {
559 if (prev != current && !
ISNAN(current.x()) && !
ISNAN(current.y())) {
581 assert(con.
shape.size() > 0);
602 if (lane.endOffset > 0) {
624 if (thisRight && !rightTurnConflict) {
627 if (!(
foes(otherFromE, otherToE, fromE, toE) ||
myRequest == 0 || rightTurnConflict)) {
637 const bool bothLeft = thisLeft && otherLeft;
638 if (fromE == otherFromE && !thisRight) {
645 if (c.
tlID !=
"" && !bothLeft) {
665 for (std::set<NBTrafficLightDefinition*>::const_iterator i = trafficLights.begin(); i != trafficLights.end(); ++i) {
666 (*i)->setParticipantsInformation();
667 (*i)->setTLControllingInformation(ec);
685 WRITE_WARNING(
"Junction '" +
getID() +
"' is too complicated (#links>64); will be set to unregulated.");
689 }
else if (numConnections == 0) {
727 if (mismatchThreshold >= 0
759 for (
int i = 0; i < (int) incoming->
getNumLanes(); ++i) {
810 std::swap(out1, out2);
825 EdgeVector::reverse_iterator i;
827 NBEdge* currentOutgoing = *i;
830 const unsigned int numApproaching = (
unsigned int)approaching->size();
831 if (numApproaching != 0) {
832 ApproachingDivider divider(approaching, currentOutgoing, buildCrossingsAndWalkingAreas);
842 (*i)->markAsInLane2LaneState();
860 EdgeVector::const_iterator i = find(
myAllEdges.begin(),
866 for (; *i != currentOutgoing;) {
868 if ((*i)->getToNode() ==
this && (*i)->getTurnDestination() != currentOutgoing) {
869 std::vector<int> connLanes = (*i)->getConnectionLanes(currentOutgoing);
870 if (connLanes.size() != 0) {
871 approaching->push_back(*i);
901 unsigned int laneOff = 0;
902 for (EdgeVector::const_iterator i = which.begin(); i != which.end(); i++) {
904 laneOff += (*i)->getNumLanes();
933 unsigned int laneOff = 0;
934 for (EdgeVector::const_iterator i = which.begin(); i != which.end(); i++) {
936 laneOff += (*i)->getNumLanes();
951 unsigned int whichLaneOff,
unsigned int byLaneOff) {
955 bool changed =
false;
957 if (c.
replaceFrom(which, whichLaneOff, by, byLaneOff)) {
960 if (c.
replaceTo(which, whichLaneOff, by, byLaneOff)) {
974 for (NBConnectionVector::iterator k = prohibiting.begin(); k != prohibiting.end(); k++) {
976 sprohibiting.
replaceFrom(which, whichLaneOff, by, byLaneOff);
977 sprohibiting.
replaceTo(which, whichLaneOff, by, byLaneOff);
1038 if (find(edges.begin(), edges.end(), e) != edges.end()) {
1039 edges.erase(find(edges.begin(), edges.end(), e));
1041 if (edges.size() == 0) {
1056 if (mayDrive.
getFrom() == 0 ||
1057 mayDrive.
getTo() == 0 ||
1059 mustStop.
getTo() == 0) {
1061 WRITE_WARNING(
"Something went wrong during the building of a connection...");
1065 conn.push_back(mayDrive);
1072 unsigned int size = (
unsigned int) edgeid.length();
1074 std::string
id = (*i)->
getID();
1075 if (
id.substr(0, size) == edgeid) {
1085 unsigned int size = (
unsigned int) edgeid.length();
1087 std::string
id = (*i)->
getID();
1088 if (
id.substr(0, size) == edgeid) {
1113 if (removeFromConnections) {
1115 (*i)->removeFromConnections(edge);
1125 EdgeVector::const_iterator i;
1127 NBNode* conn = (*i)->getFromNode();
1130 toAdd.
mul((
SUMOReal) 1.0 / sqrt(toAdd.
x()*toAdd.
x() + toAdd.
y()*toAdd.
y()));
1134 NBNode* conn = (*i)->getToNode();
1137 toAdd.
mul((
SUMOReal) 1.0 / sqrt(toAdd.
x()*toAdd.
x() + toAdd.
y()*toAdd.
y()));
1141 if (pos.
x() == 0 && pos.
y() == 0) {
1153 (*i)->invalidateConnections();
1161 (*i)->invalidateConnections();
1188 const NBEdge* prohibitorFrom,
const NBEdge* prohibitorTo,
int prohibitorFromLane)
const {
1204 std::vector<NBEdge*>::const_iterator i = std::find(
myAllEdges.begin(),
myAllEdges.end(), from);
1214 const NBEdge*
const possProhibitedFrom,
const NBEdge*
const possProhibitedTo,
1215 bool regardNonSignalisedLowerPriority)
const {
1217 possProhibitedFrom, possProhibitedTo,
1218 regardNonSignalisedLowerPriority);
1224 const NBEdge*
const from2,
const NBEdge*
const to2)
const {
1233 assert(find(incoming.begin(), incoming.end(), removed) == incoming.end());
1234 bool changed =
true;
1240 for (NBConnectionProhibits::iterator i = blockedConnectionsTmp.begin(); i != blockedConnectionsTmp.end(); i++) {
1245 bool blockedChanged =
false;
1247 NBConnectionVector::const_iterator j;
1248 for (j = blocked.begin(); j != blocked.end(); j++) {
1250 if (sblocked.
getFrom() == removed || sblocked.
getTo() == removed) {
1251 blockedChanged =
true;
1255 for (j = blocked.begin(); blockedChanged && j != blocked.end(); j++) {
1257 if (sblocked.
getFrom() == removed && sblocked.
getTo() == removed) {
1261 }
else if (sblocked.
getFrom() == removed) {
1262 assert(sblocked.
getTo() != removed);
1263 for (EdgeVector::const_iterator k = incoming.begin(); k != incoming.end(); k++) {
1266 }
else if (sblocked.
getTo() == removed) {
1267 assert(sblocked.
getFrom() != removed);
1268 for (EdgeVector::const_iterator k = outgoing.begin(); k != outgoing.end(); k++) {
1275 if (blockedChanged) {
1276 blockedConnectionsNew[blocker] = newBlocked;
1281 if (blocker.
getFrom() == removed && blocker.
getTo() == removed) {
1286 }
else if (blocker.
getFrom() == removed) {
1287 assert(blocker.
getTo() != removed);
1289 for (EdgeVector::const_iterator k = incoming.begin(); k != incoming.end(); k++) {
1292 }
else if (blocker.
getTo() == removed) {
1293 assert(blocker.
getFrom() != removed);
1295 for (EdgeVector::const_iterator k = outgoing.begin(); k != outgoing.end(); k++) {
1299 blockedConnectionsNew[blocker] = blocked;
1313 if (outgoing == 0) {
1324 if (
abs((
int) angle) + 1 < 45) {
1331 EdgeVector::const_iterator i =
1334 while ((*i) != incoming) {
1335 if ((*i)->getFromNode() ==
this) {
1343 EdgeVector::const_iterator i =
1346 while ((*i) != incoming) {
1358 bool mayDefinitelyPass,
const std::string& tlID)
const {
1362 if (outgoing == 0) {
1371 if ((!incoming->
isInnerEdge() &&
mustBrake(incoming, outgoing, fromlane,
true)) && !mayDefinitelyPass) {
1385 EdgeVector::const_iterator i;
1398 std::set<NBNode*> origSet;
1400 origSet.insert((*i)->getFromNode());
1402 if (origSet.size() < 2) {
1409 NBNode* origin = (*i)->getFromNode();
1411 EdgeVector::const_iterator j =
1420 if (!(*i)->expandableBy(*j)) {
1436 std::vector<std::pair<NBEdge*, NBEdge*> >
1439 std::vector<std::pair<NBEdge*, NBEdge*> > ret;
1443 std::pair<NBEdge*, NBEdge*>(
1449 NBNode* origin = (*i)->getFromNode();
1450 EdgeVector::const_iterator j =
1454 ret.push_back(std::pair<NBEdge*, NBEdge*>(*i, *j));
1475 if (shape.size() > 1) {
1486 if ((*i)->getToNode() == n) {
1501 back_inserter(edges));
1503 back_inserter(edges));
1504 for (EdgeVector::const_iterator j = edges.begin(); j != edges.end(); ++j) {
1515 for (EdgeVector::const_iterator k = edges2.begin(); k != edges2.end(); ++k) {
1516 if ((*k)->getFromNode()->isDistrict() || (*k)->getToNode()->isDistrict()) {
1540 std::cout <<
"guess crossings for " <<
getID() <<
"\n";
1544 std::vector<std::pair<NBEdge*, bool> > normalizedLanes;
1545 for (EdgeVector::const_iterator it = allEdges.begin(); it != allEdges.end(); ++it) {
1547 const std::vector<NBEdge::Lane>& lanes = edge->
getLanes();
1549 for (std::vector<NBEdge::Lane>::const_reverse_iterator it_l = lanes.rbegin(); it_l != lanes.rend(); ++it_l) {
1550 normalizedLanes.push_back(std::make_pair(edge, ((*it_l).permissions &
SVC_PEDESTRIAN) != 0));
1553 for (std::vector<NBEdge::Lane>::const_iterator it_l = lanes.begin(); it_l != lanes.end(); ++it_l) {
1554 normalizedLanes.push_back(std::make_pair(edge, ((*it_l).permissions &
SVC_PEDESTRIAN) != 0));
1559 int firstSidewalk = -1;
1560 for (
int i = 0; i < (int)normalizedLanes.size(); ++i) {
1561 if (normalizedLanes[i].second) {
1566 if (firstSidewalk != -1) {
1568 std::vector<std::pair<NBEdge*, bool> > tmp;
1569 copy(normalizedLanes.begin() + firstSidewalk, normalizedLanes.end(), std::back_inserter(tmp));
1570 copy(normalizedLanes.begin(), normalizedLanes.begin() + firstSidewalk, std::back_inserter(tmp));
1571 normalizedLanes = tmp;
1574 bool hadCandidates =
false;
1575 for (
int i = 0; i < (int)normalizedLanes.size(); ++i) {
1576 NBEdge* edge = normalizedLanes[i].first;
1577 const bool allowsPed = normalizedLanes[i].second;
1579 std::cout <<
" cands=" <<
toString(candidates) <<
" edge=" << edge->
getID() <<
" allowsPed=" << allowsPed <<
"\n";
1581 if (!allowsPed && (candidates.size() == 0 || candidates.back() != edge)) {
1582 candidates.push_back(edge);
1583 }
else if (allowsPed) {
1584 if (candidates.size() > 0) {
1586 hadCandidates =
true;
1593 if (hadCandidates) {
1606 std::cout <<
"checkCrossing candidates=" <<
toString(candidates) <<
"\n";
1608 if (candidates.size() == 0) {
1610 std::cout <<
"no crossing added (numCandidates=" << candidates.size() <<
")\n";
1616 for (
size_t i = 0; i < candidates.size(); ++i) {
1617 NBEdge* edge = candidates[i];
1622 std::cout <<
"no crossing added (found angle difference of " << fabs(angle - prevAngle) <<
" at i=" << i <<
"\n";
1628 std::cout <<
"no crossing added (uncontrolled, edge with speed=" << edge->
getSpeed() <<
")\n";
1634 if (candidates.size() == 1) {
1637 std::cout <<
"adding crossing: " <<
toString(candidates) <<
"\n";
1643 for (EdgeVector::iterator it = candidates.begin(); it != candidates.end(); ++it) {
1644 SUMOReal angle = (*it)->getCrossingAngle(
this);
1645 if (it != candidates.begin()) {
1646 NBEdge* prev = *(it - 1);
1654 prevPos = prev->
getLanes()[laneI].shape[-1];
1657 prevPos = prev->
getLanes()[laneI].shape[0];
1662 currPos = curr->
getLanes()[laneI].shape[0];
1665 currPos = curr->
getLanes()[laneI].shape[-1];
1671 <<
" prevAngle=" << prevAngle
1672 <<
" angle=" << angle
1673 <<
" intermediateWidth=" << intermediateWidth
1686 std::cout <<
"adding crossing: " <<
toString(candidates) <<
"\n";
1696 for (
int i = startIndex; i < (int)normalizedLanes.size(); ++i) {
1697 if (!normalizedLanes[i].second) {
1707 if (buildCrossingsAndWalkingAreas) {
1712 if ((*it).prevWalkingArea ==
"" || (*it).nextWalkingArea ==
"") {
1716 throw ProcessError(
"Invalid crossing '" + (*it).id +
"' at node '" +
getID() +
"' with edges '" +
toString((*it).edges) +
"'.");
1721 unsigned int noInternalNoSplits = 0;
1723 const std::vector<NBEdge::Connection>& elv = (*i)->getConnections();
1724 for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
1725 if ((*k).toEdge == 0) {
1728 noInternalNoSplits++;
1731 unsigned int lno = 0;
1732 unsigned int splitNo = 0;
1734 (*i)->buildInnerEdges(*
this, noInternalNoSplits, lno, splitNo);
1739 unsigned int lno = 0;
1740 unsigned int splitNo = 0;
1742 (*i)->buildInnerEdges(*
this, noInternalNoSplits, lno, splitNo);
1752 std::cout <<
"build crossings for " <<
getID() <<
":\n";
1754 unsigned int index = 0;
1759 std::cout <<
" crossing=" << (*it).id <<
" edges=" <<
toString(edges);
1765 std::cout <<
" sortedEdges=" <<
toString(edges) <<
"\n";
1769 int maxAngleDiffIndex = 0;
1770 for (
int i = 0; i < (int) edges.size(); i++) {
1772 edges[(i + 1) % edges.size()]->getAngleAtNodeToCenter(
this));
1777 std::cout <<
" i=" << i <<
" a1=" << edges[i]->getAngleAtNodeToCenter(
this) <<
" a2=" << edges[(i + 1) % edges.size()]->getAngleAtNodeToCenter(
this) <<
" diff=" << diff <<
"\n";
1779 if (diff > maxAngleDiff) {
1780 maxAngleDiff = diff;
1781 maxAngleDiffIndex = i;
1784 if (maxAngleDiff > 2 && maxAngleDiff < 360 - 2) {
1786 std::rotate(edges.begin(), edges.begin() + (maxAngleDiffIndex + 1) % edges.size(), edges.end());
1788 std::cout <<
" rotatedEdges=" <<
toString(edges);
1792 std::reverse(edges.begin(), edges.end());
1794 std::cout <<
" finalEdges=" <<
toString(edges) <<
"\n";
1797 (*it).shape.clear();
1798 const int begDir = (edges.front()->getFromNode() ==
this ?
FORWARD :
BACKWARD);
1799 const int endDir = (edges.back()->getToNode() ==
this ?
FORWARD :
BACKWARD);
1800 NBEdge::Lane crossingBeg = edges.front()->getFirstNonPedestrianLane(begDir);
1801 NBEdge::Lane crossingEnd = edges.back()->getFirstNonPedestrianLane(endDir);
1808 (*it).shape.push_back(crossingBeg.
shape[begDir ==
FORWARD ? 0 : -1]);
1809 (*it).shape.push_back(crossingEnd.
shape[endDir ==
FORWARD ? -1 : 0]);
1818 unsigned int index = 0;
1821 std::cout <<
"build walkingAreas for " <<
getID() <<
":\n";
1828 std::vector<std::pair<NBEdge*, NBEdge::Lane> > normalizedLanes;
1829 for (EdgeVector::const_iterator it = allEdges.begin(); it != allEdges.end(); ++it) {
1831 const std::vector<NBEdge::Lane>& lanes = edge->
getLanes();
1833 for (std::vector<NBEdge::Lane>::const_reverse_iterator it_l = lanes.rbegin(); it_l != lanes.rend(); ++it_l) {
1837 normalizedLanes.push_back(std::make_pair(edge, l));
1840 for (std::vector<NBEdge::Lane>::const_iterator it_l = lanes.begin(); it_l != lanes.end(); ++it_l) {
1845 normalizedLanes.push_back(std::make_pair(edge, l));
1851 std::vector<std::pair<int, int> > waIndices;
1853 NBEdge* prevEdge = normalizedLanes.back().first;
1854 for (
int i = 0; i < (int)normalizedLanes.size(); ++i) {
1855 NBEdge* edge = normalizedLanes[i].first;
1863 waIndices.push_back(std::make_pair(start, i - start));
1873 <<
" waI=" << waIndices.size() <<
" crossingBetween=" <<
crossingBetween(edge, prevEdge) <<
"\n";
1878 const int waNumLanes = (int)normalizedLanes.size() - start;
1879 if (waIndices.size() == 0) {
1880 waIndices.push_back(std::make_pair(start, waNumLanes));
1882 std::cout <<
" single wa, end at wrap-around\n";
1885 if (waIndices.front().first == 0) {
1886 NBEdge* edge = normalizedLanes.front().first;
1887 NBEdge* prevEdge = normalizedLanes.back().first;
1890 waIndices.push_back(std::make_pair(start, waNumLanes));
1892 std::cout <<
" do not wrap around, turn-around in between\n";
1896 waIndices.front().first = start;
1897 waIndices.front().second = waNumLanes + waIndices.front().second;
1899 std::cout <<
" wrapping around\n";
1904 waIndices.push_back(std::make_pair(start, waNumLanes));
1906 std::cout <<
" end at wrap-around\n";
1912 std::cout <<
" normalizedLanes=" << normalizedLanes.size() <<
" waIndices:\n";
1913 for (
int i = 0; i < (int)waIndices.size(); ++i) {
1914 std::cout <<
" " << waIndices[i].first <<
", " << waIndices[i].second <<
"\n";
1918 for (
int i = 0; i < (int)waIndices.size(); ++i) {
1919 const bool buildExtensions = waIndices[i].second != (int)normalizedLanes.size();
1920 const int start = waIndices[i].first;
1921 const int prev = start > 0 ? start - 1 : (int)normalizedLanes.size() - 1;
1922 const int count = waIndices[i].second;
1923 const int end = (start + count) % normalizedLanes.size();
1927 std::cout <<
"build walkingArea " << wa.
id <<
" start=" << start <<
" end=" << end <<
" count=" << count <<
" prev=" << prev <<
":\n";
1934 bool connectsCrossing =
false;
1935 std::vector<Position> connectedPoints;
1938 std::cout <<
" crossing=" << (*it).id <<
" sortedEdges=" <<
toString((*it).edges) <<
"\n";
1940 if ((*it).edges.back() == normalizedLanes[end].first
1941 && (normalizedLanes[end].second.permissions &
SVC_PEDESTRIAN) == 0) {
1943 (*it).nextWalkingArea = wa.
id;
1944 endCrossingWidth = (*it).width;
1945 endCrossingShape = (*it).shape;
1947 connectsCrossing =
true;
1948 connectedPoints.push_back((*it).shape[-1]);
1950 std::cout <<
" crossing " << (*it).id <<
" ends\n";
1953 if ((*it).edges.front() == normalizedLanes[prev].first
1954 && (normalizedLanes[prev].second.permissions &
SVC_PEDESTRIAN) == 0) {
1956 (*it).prevWalkingArea = wa.
id;
1958 startCrossingWidth = (*it).width;
1959 startCrossingShape = (*it).shape;
1961 connectsCrossing =
true;
1965 connectedPoints.push_back((*it).shape[0]);
1967 std::cout <<
" crossing " << (*it).id <<
" starts\n";
1970 if (
gDebugFlag1) std::cout <<
" check connections to crossing " << (*it).id
1971 <<
" cFront=" << (*it).edges.front()->getID() <<
" cBack=" << (*it).edges.back()->getID()
1972 <<
" wEnd=" << normalizedLanes[end].first->getID() <<
" wStart=" << normalizedLanes[start].first->getID()
1973 <<
" wStartPrev=" << normalizedLanes[prev].first->getID()
1976 if (count < 2 && !connectsCrossing) {
1981 std::set<NBEdge*> connected;
1982 for (
int j = 0; j < count; ++j) {
1983 const int nlI = (start + j) % normalizedLanes.size();
1984 NBEdge* edge = normalizedLanes[nlI].first;
1987 if (connected.count(edge) == 0) {
1995 connected.insert(edge);
2002 if (buildExtensions) {
2004 if (startCrossingShape.size() > 0) {
2006 std::cout <<
" extension at startCrossing shape=" << startCrossingShape <<
"\n";
2008 startCrossingShape.
move2side(startCrossingWidth / 2);
2010 startCrossingShape.
move2side(-startCrossingWidth);
2014 if (endCrossingShape.size() > 0) {
2016 std::cout <<
" extension at endCrossing shape=" << endCrossingShape <<
"\n";
2018 endCrossingShape.
move2side(endCrossingWidth / 2);
2020 endCrossingShape.
move2side(-endCrossingWidth);
2026 NBEdge* e1 = *connected.begin();
2027 NBEdge* e2 = *(++connected.begin());
2033 if (cornerDetail > 0) {
2034 int smoothEnd = end;
2035 int smoothPrev = prev;
2037 if (endCrossingWidth > 0 && normalizedLanes[smoothEnd].second.permissions == 0) {
2038 smoothEnd = (smoothEnd + 1) % normalizedLanes.size();
2040 if (startCrossingWidth > 0 && normalizedLanes[smoothPrev].second.permissions == 0) {
2041 if (smoothPrev == 0) {
2042 smoothPrev = (int)normalizedLanes.size() - 1;
2047 PositionVector begShape = normalizedLanes[smoothEnd].second.shape;
2048 begShape = begShape.
reverse();
2050 begShape.
move2side(normalizedLanes[smoothEnd].second.width / 2);
2051 PositionVector endShape = normalizedLanes[smoothPrev].second.shape;
2052 endShape.
move2side(normalizedLanes[smoothPrev].second.width / 2);
2056 <<
" end=" << smoothEnd <<
" prev=" << smoothPrev
2057 <<
" endCrossingWidth=" << endCrossingWidth <<
" startCrossingWidth=" << startCrossingWidth
2058 <<
" begShape=" << begShape <<
" endShape=" << endShape <<
" smooth curve=" << curve <<
"\n";
2059 if (curve.size() > 2) {
2062 if (endCrossingWidth > 0) {
2065 if (startCrossingWidth > 0) {
2073 int combinations = 0;
2074 for (std::vector<Position>::const_iterator it1 = connectedPoints.begin(); it1 != connectedPoints.end(); ++it1) {
2075 for (std::vector<Position>::const_iterator it2 = connectedPoints.begin(); it2 != connectedPoints.end(); ++it2) {
2085 std::cout <<
" combinations=" << combinations <<
" connectedPoints=" << connectedPoints <<
"\n";
2088 if (combinations > 0) {
2098 std::cout <<
" checkIntermediate: prev=" << prev.
id <<
" next=" << next.
id <<
" prev.nextWA=" << prev.
nextWalkingArea <<
"\n";
2124 std::cout <<
" build wa=" << wa.
id <<
"\n";
2138 EdgeVector::const_iterator it1 = find(edges.begin(), edges.end(), e1);
2139 EdgeVector::const_iterator it2 = find(edges.begin(), edges.end(), e2);
2140 if (it1 != edges.end() && it2 != edges.end()) {
2156 while (it != it_end) {
2157 result.push_back(*it);
2178 if (
MAX2(angle0, angle1) <= 160) {
2205 EdgeSet edgeSet(edges.begin(), edges.end());
2207 EdgeSet edgeSet2((*it).edges.begin(), (*it).edges.end());
2208 if (edgeSet == edgeSet2) {
2220 if ((*it).id ==
id) {
2224 throw ProcessError(
"Request for unknown crossing '" +
id +
"'");
2231 (*it).tlLinkNo = startIndex++;
2263 std::cout <<
" angles:\n";
2264 for (EdgeVector::const_iterator it = result.begin(); it != result.end(); ++it) {
2265 std::cout <<
" edge=" << (*it)->getID() <<
" edgeAngle=" << (*it)->getAngleAtNode(
this) <<
" angleToShape=" << (*it)->getAngleAtNodeToCenter(
this) <<
"\n";
2267 std::cout <<
" allEdges before: " <<
toString(result) <<
"\n";
2272 std::cout <<
" allEdges sorted: " <<
toString(result) <<
"\n";
2274 rotate(result.begin(), std::find(result.begin(), result.end(), *
myAllEdges.begin()), result.end());
2276 std::cout <<
" allEdges rotated: " <<
toString(result) <<
"\n";
2287 assert(
id[0] ==
':');
2288 size_t sep_index =
id.rfind(
'_');
2289 if (sep_index == std::string::npos) {
2290 WRITE_ERROR(
"Invalid lane id '" +
id +
"' (missing '_').");
2293 sep_index =
id.substr(0, sep_index).rfind(
'_');
2294 if (sep_index == std::string::npos) {
2295 WRITE_ERROR(
"Invalid lane id '" +
id +
"' (missing '_').");
2298 return id.substr(1, sep_index - 1);
2308 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.
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 mustBrakeForCrossing(const NBEdge *const from, const NBEdge *const to, const NBNode::Crossing &crossing) const
Returns the information whether the described flow must brake for the given crossing.
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 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.
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.
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)
ApproachingDivider(EdgeVector *approaching, NBEdge *currentOutgoing, const bool buildCrossingsAndWalkingAreas)
Constructor.
void addCrossing(EdgeVector edges, SUMOReal width, bool priority)
add a pedestrian crossing to this node
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.
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 computeLanes2Lanes(const bool buildCrossingsAndWalkingAreas)
computes the connections of lanes to edges
bool around(const Position &p, SUMOReal offset=0) const
Returns the information whether the position vector describes a polygon lying around the given point ...
bool almostSame(const Position &p2, SUMOReal maxDiv=POSITION_EPS) const
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.
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.
const std::string & getID() const
Returns the id.
bool rightTurnConflict(const NBEdge *from, const NBEdge *to, int fromLane, const NBEdge *prohibitorFrom, const NBEdge *prohibitorTo, int prohibitorFromLane) const
return whether the given laneToLane connection is a right turn which must yield to a bicycle crossing...
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
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)
void computeNodeShape(bool leftHand, SUMOReal mismatchThreshold)
Compute the junction shape for this node.
const std::set< NBTrafficLightDefinition * > & getControllingTLS() const
Returns the traffic lights that were assigned to this node.
bool isSimpleContinuation() const
void buildBitfieldLogic(bool leftHanded)
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.
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)
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.
PositionVector compute(bool leftHand)
Computes the shape of the assigned junction.
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
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.
bool rightTurnConflict(const NBEdge *from, const NBEdge *to, int fromLane, const NBEdge *prohibitorFrom, const NBEdge *prohibitorTo, int prohibitorFromLane) const
return whether the given laneToLane connection is a right turn which must yield to a bicycle crossing...
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.
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 isLeftHanded() const
Returns whether the built edges are left-handed.
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
std::string tlID
the traffic light id of the next crossing or ""
A definition of a pedestrian walking area.
EdgeVector * myApproaching
The list of edges that approach the current edge.
SUMOReal y() const
Returns the y-position.
A storage for options typed value containers)
void sub(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)
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
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.
Position getPolygonCenter() const
Returns the arithmetic of all corner points.
void setConnection(unsigned int lane, NBEdge *destEdge, unsigned int destLane, Lane2LaneInfoType type, bool mayUseSameDestination=false, bool mayDefinitelyPass=false)
Adds a connection to a certain lane of a certain edge.
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 buildInnerEdges(bool buildCrossingsAndWalkingAreas)
build internal lanes, pedestrian crossings and walking areas
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 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;
LinkDirection getDirection(const NBEdge *const incoming, const NBEdge *const outgoing) const
Returns the representation of the described stream's direction.
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.