68 #ifdef CHECK_MEMORY_LEAKS 70 #endif // CHECK_MEMORY_LEAKS 73 #define EXTEND_CROSSING_ANGLE_THRESHOLD 35.0 // degrees 75 #define SPLIT_CROSSING_WIDTH_THRESHOLD 1.5 // meters 76 #define SPLIT_CROSSING_ANGLE_THRESHOLD 5 // degrees 79 #define MIN_WEAVE_LENGTH 20.0 82 #define DEBUGCOND true 100 myApproaching(approaching), myCurrentOutgoing(currentOutgoing) {
104 std::set<int> approachedLanes;
106 const std::vector<NBEdge::Connection> conns = (*it)->getConnections();
107 for (std::vector<NBEdge::Connection>::const_iterator it_con = conns.begin(); it_con != conns.end(); ++it_con) {
109 approachedLanes.insert((*it_con).toLane);
117 for (
int i = 0; i < currentOutgoing->
getNumLanes(); ++i) {
120 && approachedLanes.count(i) == 0) {
135 NBEdge* incomingEdge = (*myApproaching)[src];
139 std::vector<int> approachingLanes =
141 assert(approachingLanes.size() != 0);
142 std::deque<int>* approachedLanes =
spread(approachingLanes, dest);
145 for (
int i = 0; i < (int)approachedLanes->size(); i++) {
146 assert((
int)approachingLanes.size() > i);
151 delete approachedLanes;
158 std::deque<int>* ret =
new std::deque<int>();
159 int noLanes = (int) approachingLanes.size();
163 ret->push_back(dest);
169 ret->push_back(dest);
173 while (noSet < noLanes) {
179 if (noOutgoingLanes == noSet) {
188 if (dest + loffset >= noOutgoingLanes) {
191 for (
int i = 0; i < (int)ret->size(); i++) {
192 (*ret)[i] = (*ret)[i] - 1;
197 ret->push_back(dest + loffset);
202 if (noOutgoingLanes == noSet) {
207 if (noSet < noLanes) {
210 if (dest < roffset) {
213 for (
int i = 0; i < (int)ret->size(); i++) {
214 (*ret)[i] = (*ret)[i] + 1;
217 ret->push_front(dest - roffset);
265 bool updateEdgeGeometries) {
272 if (updateEdgeGeometries) {
276 (*i)->setGeometry(geom);
281 (*i)->setGeometry(geom);
302 (*it).shape.mirrorX();
305 (*it_wa).shape.mirrorX();
331 for (std::set<NBTrafficLightDefinition*>::const_iterator i = trafficLights.begin(); i != trafficLights.end(); ++i) {
343 if ((*i)->getID().find(
"joined") == 0) {
355 for (std::set<NBTrafficLightDefinition*>::iterator it = oldDefs.begin(); it != oldDefs.end(); ++it) {
357 if (dynamic_cast<NBOwnTLDef*>(orig) == 0) {
359 const std::vector<NBNode*>& nodes = orig->
getNodes();
360 while (!nodes.empty()) {
361 newDef->
addNode(nodes.front());
362 nodes.front()->removeTrafficLight(orig);
375 (*it)->shiftTLConnectionLaneIndex(edge, offset);
399 if ((*i)->isConnectedTo(dummy) && *i != dummy) {
400 incomingConnected.push_back(*i);
407 outgoingConnected.push_back(*i);
412 remapRemoved(tc, dummy, incomingConnected, outgoingConnected);
461 if (in->
getNumLanes() != (*opposite)->getNumLanes()) {
481 #ifdef DEBUG_SMOOTH_GEOM 482 if (
DEBUGCOND) std::cout <<
"computeSmoothShape node " <<
getID() <<
" init=" << init <<
"\n";
484 if (init.size() == 0) {
486 ret.push_back(begShape.back());
487 ret.push_back(endShape.front());
491 return bezier(init, numPoints);
503 const Position beg = begShape.back();
504 const Position end = endShape.front();
508 #ifdef DEBUG_SMOOTH_GEOM 509 if (
DEBUGCOND) std::cout <<
" bezierControlPoints failed beg=" << beg <<
" end=" << end
524 center.
sub(beg.
y() - end.
y(), end.
x() - beg.
x());
525 init.push_back(center);
530 endShapeBegLine.extrapolate2D(100,
true);
532 if (fabs(angle) <
M_PI / 4.) {
536 const SUMOReal halfDistance = dist / 2;
537 if (fabs(displacementAngle) <=
DEG2RAD(5)) {
538 #ifdef DEBUG_SMOOTH_GEOM 539 if (
DEBUGCOND) std::cout <<
" bezierControlPoints identified straight line beg=" << beg <<
" end=" << end
540 <<
" angle=" <<
RAD2DEG(angle) <<
" displacementAngle=" <<
RAD2DEG(displacementAngle) <<
"\n";
543 }
else if (bendDeg > 22.5 && pow(bendDeg / 45, 2) / dist > 0.13) {
546 #ifdef DEBUG_SMOOTH_GEOM 547 if (
DEBUGCOND) std::cout <<
" bezierControlPoints found extreme s-curve (consider changing junction shape), falling back to straight line beg=" << beg <<
" end=" << end
548 <<
" angle=" <<
RAD2DEG(angle) <<
" displacementAngle=" <<
RAD2DEG(displacementAngle)
549 <<
" dist=" << dist <<
" bendDeg=" << bendDeg <<
" bd2=" << pow(bendDeg / 45, 2)
554 const SUMOReal endLength = begShape[-2].distanceTo2D(begShape[-1]);
555 const SUMOReal off1 = endLength +
MIN2(extrapolateBeg, halfDistance);
557 const SUMOReal off2 = 100. -
MIN2(extrapolateEnd, halfDistance);
559 #ifdef DEBUG_SMOOTH_GEOM 560 if (
DEBUGCOND) std::cout <<
" bezierControlPoints found s-curve beg=" << beg <<
" end=" << end
561 <<
" angle=" <<
RAD2DEG(angle) <<
" displacementAngle=" <<
RAD2DEG(displacementAngle)
562 <<
" halfDistance=" << halfDistance <<
"\n";
571 Position intersect = endShapeBegLine.intersectionPosition2D(begShapeEndLineRev);
573 #ifdef DEBUG_SMOOTH_GEOM 575 std::cout <<
" bezierControlPoints failed beg=" << beg <<
" end=" << end <<
" intersect=" << intersect <<
"\n";
581 const bool lengthenBeg = intersect.
distanceTo2D(beg) <= minControlLength;
582 const bool lengthenEnd = intersect.
distanceTo2D(end) <= minControlLength;
583 if (lengthenBeg && lengthenEnd) {
584 #ifdef DEBUG_SMOOTH_GEOM 585 if (
DEBUGCOND) std::cout <<
" bezierControlPoints failed beg=" << beg <<
" end=" << end <<
" intersect=" << intersect
589 }
else if (lengthenBeg || lengthenEnd) {
591 init.push_back(endShapeBegLine.positionAtOffset2D(100 - minControlLength));
595 const SUMOReal z2 = endShapeBegLine.positionAtOffset2D(endShapeBegLine.nearest_offset_to_point2D(intersect)).z();
596 const SUMOReal z3 = 0.5 * (beg.
z() + end.
z());
600 if ((z1 <= z3 && z2 <= z3) || (z1 >= z3 && z2 >= z3)) {
605 intersect.
set(intersect.
x(), intersect.
y(), z);
606 init.push_back(intersect);
627 assert(con.
shape.size() > 0);
636 ret.append(it->second);
648 if (lane.endOffset > 0) {
670 if (thisRight && !rightTurnConflict) {
673 if (!(
foes(otherFromE, otherToE, fromE, toE) ||
myRequest == 0 || rightTurnConflict)) {
683 const bool bothLeft = thisLeft && otherLeft;
684 if (fromE == otherFromE && !thisRight) {
691 if (c.
tlID !=
"" && !bothLeft) {
694 if ((*it)->needsCont(fromE, toE, otherFromE, otherToE)) {
716 for (std::set<NBTrafficLightDefinition*>::const_iterator i = trafficLights.begin(); i != trafficLights.end(); ++i) {
717 (*i)->setParticipantsInformation();
718 (*i)->setTLControllingInformation();
745 }
else if (numConnections == 0) {
783 if (mismatchThreshold >= 0
816 for (
int i = inOffset; i < in->
getNumLanes(); ++i) {
848 std::swap(in1Offset, in2Offset);
877 std::swap(out1, out2);
878 std::swap(out1Offset, out2Offset);
901 for (
int i = inOffset; i < in->
getNumLanes(); ++i) {
923 for (
int i = inOffset; i < in->
getNumLanes(); ++i) {
935 EdgeVector::reverse_iterator i;
937 NBEdge* currentOutgoing = *i;
940 const int numApproaching = (int)approaching->size();
941 if (numApproaching != 0) {
955 const std::vector<NBEdge::Connection>& elv = incoming->
getConnections();
956 for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
958 if (c.
toEdge == currentOutgoing) {
961 unsatisfied &= ~satisfied;
964 if (unsatisfied != 0) {
967 while (unsatisfied != 0 && fromLane < incoming->getNumLanes()) {
969 for (
int toLane = 0; toLane < currentOutgoing->
getNumLanes(); ++toLane) {
971 if (satisfied != 0) {
974 unsatisfied &= ~satisfied;
991 const std::vector<NBEdge::Connection> cons = (*i)->getConnections();
992 for (std::vector<NBEdge::Connection>::const_iterator k = cons.begin(); k != cons.end(); ++k) {
994 (*i)->removeFromConnections((*k).toEdge);
1005 (*i)->markAsInLane2LaneState();
1022 while (seen < minLength) {
1038 EdgeVector::const_iterator i = find(
myAllEdges.begin(),
1044 for (; *i != currentOutgoing;) {
1046 if ((*i)->getToNode() ==
this && (*i)->getTurnDestination() != currentOutgoing) {
1047 std::vector<int> connLanes = (*i)->getConnectionLanes(currentOutgoing);
1048 if (connLanes.size() != 0) {
1049 approaching->push_back(*i);
1080 for (EdgeVector::const_iterator i = which.begin(); i != which.end(); i++) {
1082 laneOff += (*i)->getNumLanes();
1112 for (EdgeVector::const_iterator i = which.begin(); i != which.end(); i++) {
1114 laneOff += (*i)->getNumLanes();
1129 int whichLaneOff,
int byLaneOff) {
1133 bool changed =
false;
1135 if (c.
replaceFrom(which, whichLaneOff, by, byLaneOff)) {
1138 if (c.
replaceTo(which, whichLaneOff, by, byLaneOff)) {
1152 for (NBConnectionVector::iterator k = prohibiting.begin(); k != prohibiting.end(); k++) {
1154 sprohibiting.
replaceFrom(which, whichLaneOff, by, byLaneOff);
1155 sprohibiting.
replaceTo(which, whichLaneOff, by, byLaneOff);
1215 if (find(edges.begin(), edges.end(), e) != edges.end()) {
1216 edges.erase(find(edges.begin(), edges.end(), e));
1218 if (edges.size() == 0) {
1233 if (mayDrive.
getFrom() == 0 ||
1234 mayDrive.
getTo() == 0 ||
1236 mustStop.
getTo() == 0) {
1238 WRITE_WARNING(
"Something went wrong during the building of a connection...");
1242 conn.push_back(mayDrive);
1249 int size = (int) edgeid.length();
1251 std::string
id = (*i)->
getID();
1252 if (
id.substr(0, size) == edgeid) {
1262 int size = (int) edgeid.length();
1264 std::string
id = (*i)->
getID();
1265 if (
id.substr(0, size) == edgeid) {
1290 if (removeFromConnections) {
1292 (*i)->removeFromConnections(edge);
1297 (*i)->replaceRemoved(edge, -1, 0, -1);
1306 EdgeVector::const_iterator i;
1308 NBNode* conn = (*i)->getFromNode();
1311 toAdd.
mul((
SUMOReal) 1.0 / sqrt(toAdd.
x()*toAdd.
x() + toAdd.
y()*toAdd.
y()));
1315 NBNode* conn = (*i)->getToNode();
1318 toAdd.
mul((
SUMOReal) 1.0 / sqrt(toAdd.
x()*toAdd.
x() + toAdd.
y()*toAdd.
y()));
1322 if (pos.
x() == 0 && pos.
y() == 0) {
1334 (*i)->invalidateConnections();
1342 (*i)->invalidateConnections();
1369 const NBEdge* prohibitorFrom,
const NBEdge* prohibitorTo,
int prohibitorFromLane,
1371 if (from != prohibitorFrom) {
1395 lefthand = !lefthand;
1402 if ((!lefthand && fromLane <= prohibitorFromLane) ||
1403 (lefthand && fromLane >= prohibitorFromLane)) {
1425 std::vector<NBEdge*>::const_iterator i = std::find(
myAllEdges.begin(),
myAllEdges.end(), from);
1435 const NBEdge*
const possProhibitedFrom,
const NBEdge*
const possProhibitedTo,
1436 bool regardNonSignalisedLowerPriority)
const {
1438 possProhibitedFrom, possProhibitedTo,
1439 regardNonSignalisedLowerPriority);
1445 const NBEdge*
const from2,
const NBEdge*
const to2)
const {
1454 assert(find(incoming.begin(), incoming.end(), removed) == incoming.end());
1455 bool changed =
true;
1461 for (NBConnectionProhibits::iterator i = blockedConnectionsTmp.begin(); i != blockedConnectionsTmp.end(); i++) {
1466 bool blockedChanged =
false;
1468 NBConnectionVector::const_iterator j;
1469 for (j = blocked.begin(); j != blocked.end(); j++) {
1471 if (sblocked.
getFrom() == removed || sblocked.
getTo() == removed) {
1472 blockedChanged =
true;
1476 for (j = blocked.begin(); blockedChanged && j != blocked.end(); j++) {
1478 if (sblocked.
getFrom() == removed && sblocked.
getTo() == removed) {
1482 }
else if (sblocked.
getFrom() == removed) {
1483 assert(sblocked.
getTo() != removed);
1484 for (EdgeVector::const_iterator k = incoming.begin(); k != incoming.end(); k++) {
1487 }
else if (sblocked.
getTo() == removed) {
1488 assert(sblocked.
getFrom() != removed);
1489 for (EdgeVector::const_iterator k = outgoing.begin(); k != outgoing.end(); k++) {
1496 if (blockedChanged) {
1497 blockedConnectionsNew[blocker] = newBlocked;
1502 if (blocker.
getFrom() == removed && blocker.
getTo() == removed) {
1507 }
else if (blocker.
getFrom() == removed) {
1508 assert(blocker.
getTo() != removed);
1510 for (EdgeVector::const_iterator k = incoming.begin(); k != incoming.end(); k++) {
1513 }
else if (blocker.
getTo() == removed) {
1514 assert(blocker.
getFrom() != removed);
1516 for (EdgeVector::const_iterator k = outgoing.begin(); k != outgoing.end(); k++) {
1520 blockedConnectionsNew[blocker] = blocked;
1534 if (outgoing == 0) {
1545 if (
abs((
int) angle) + 1 < 45) {
1552 EdgeVector::const_iterator i =
1559 while ((*i) != incoming) {
1573 EdgeVector::const_iterator i =
1580 while ((*i) != incoming) {
1597 bool mayDefinitelyPass,
const std::string& tlID)
const {
1604 if (outgoing == 0) {
1616 if ((!incoming->
isInnerEdge() &&
mustBrake(incoming, outgoing, fromlane, toLane,
true)) && !mayDefinitelyPass) {
1630 EdgeVector::const_iterator i;
1643 std::set<NBNode*> origSet;
1645 origSet.insert((*i)->getFromNode());
1647 if (origSet.size() < 2) {
1655 if (opposite != 0) {
1659 if (!(*i)->expandableBy(continuation)) {
1675 std::vector<std::pair<NBEdge*, NBEdge*> >
1678 std::vector<std::pair<NBEdge*, NBEdge*> > ret;
1682 std::pair<NBEdge*, NBEdge*>(
1690 assert(opposite != 0);
1692 ret.push_back(std::pair<NBEdge*, NBEdge*>(*i, continuation));
1713 if (shape.size() > 1) {
1724 if ((*i)->getToNode() == n) {
1739 back_inserter(edges));
1741 back_inserter(edges));
1742 for (EdgeVector::const_iterator j = edges.begin(); j != edges.end(); ++j) {
1753 for (EdgeVector::const_iterator k = edges2.begin(); k != edges2.end(); ++k) {
1754 if ((*k)->getFromNode()->isDistrict() || (*k)->getToNode()->isDistrict()) {
1778 std::cout <<
"guess crossings for " <<
getID() <<
"\n";
1782 std::vector<std::pair<NBEdge*, bool> > normalizedLanes;
1783 for (EdgeVector::const_iterator it = allEdges.begin(); it != allEdges.end(); ++it) {
1785 const std::vector<NBEdge::Lane>& lanes = edge->
getLanes();
1787 for (std::vector<NBEdge::Lane>::const_reverse_iterator it_l = lanes.rbegin(); it_l != lanes.rend(); ++it_l) {
1788 normalizedLanes.push_back(std::make_pair(edge, ((*it_l).permissions &
SVC_PEDESTRIAN) != 0));
1791 for (std::vector<NBEdge::Lane>::const_iterator it_l = lanes.begin(); it_l != lanes.end(); ++it_l) {
1792 normalizedLanes.push_back(std::make_pair(edge, ((*it_l).permissions &
SVC_PEDESTRIAN) != 0));
1797 int firstSidewalk = -1;
1798 for (
int i = 0; i < (int)normalizedLanes.size(); ++i) {
1799 if (normalizedLanes[i].second) {
1804 int hadCandidates = 0;
1805 std::vector<int> connectedCandidates;
1806 if (firstSidewalk != -1) {
1808 std::vector<std::pair<NBEdge*, bool> > tmp;
1809 copy(normalizedLanes.begin() + firstSidewalk, normalizedLanes.end(), std::back_inserter(tmp));
1810 copy(normalizedLanes.begin(), normalizedLanes.begin() + firstSidewalk, std::back_inserter(tmp));
1811 normalizedLanes = tmp;
1814 for (
int i = 0; i < (int)normalizedLanes.size(); ++i) {
1815 NBEdge* edge = normalizedLanes[i].first;
1816 const bool allowsPed = normalizedLanes[i].second;
1818 std::cout <<
" cands=" <<
toString(candidates) <<
" edge=" << edge->
getID() <<
" allowsPed=" << allowsPed <<
"\n";
1820 if (!allowsPed && (candidates.size() == 0 || candidates.back() != edge)) {
1821 candidates.push_back(edge);
1822 }
else if (allowsPed) {
1823 if (candidates.size() > 0) {
1829 connectedCandidates.push_back(n);
1836 if (hadCandidates > 0 && candidates.size() > 0) {
1842 connectedCandidates.push_back(n);
1848 std::cout <<
" hadCandidates=" << hadCandidates <<
" connectedCandidates=" <<
toString(connectedCandidates) <<
"\n";
1850 if (hadCandidates == 2 && connectedCandidates.size() == 2) {
1852 if (connectedCandidates.back() <= connectedCandidates.front()) {
1853 numGuessed -= connectedCandidates.back();
1856 numGuessed -= connectedCandidates.front();
1862 std::cout <<
"guessedCrossings:\n";
1864 std::cout <<
" edges=" <<
toString((*it).edges) <<
"\n";
1874 std::cout <<
"checkCrossing candidates=" <<
toString(candidates) <<
"\n";
1876 if (candidates.size() == 0) {
1878 std::cout <<
"no crossing added (numCandidates=" << candidates.size() <<
")\n";
1884 for (
int i = 0; i < (int)candidates.size(); ++i) {
1885 NBEdge* edge = candidates[i];
1890 std::cout <<
"no crossing added (found angle difference of " << fabs(angle - prevAngle) <<
" at i=" << i <<
"\n";
1896 std::cout <<
"no crossing added (uncontrolled, edge with speed > " << edge->
getSpeed() <<
")\n";
1902 if (candidates.size() == 1) {
1905 std::cout <<
"adding crossing: " <<
toString(candidates) <<
"\n";
1911 for (EdgeVector::iterator it = candidates.begin(); it != candidates.end(); ++it) {
1912 SUMOReal angle = (*it)->getCrossingAngle(
this);
1913 if (it != candidates.begin()) {
1914 NBEdge* prev = *(it - 1);
1922 prevPos = prev->
getLanes()[laneI].shape[-1];
1925 prevPos = prev->
getLanes()[laneI].shape[0];
1930 currPos = curr->
getLanes()[laneI].shape[0];
1933 currPos = curr->
getLanes()[laneI].shape[-1];
1939 <<
" prevAngle=" << prevAngle
1940 <<
" angle=" << angle
1941 <<
" intermediateWidth=" << intermediateWidth
1954 std::cout <<
"adding crossing: " <<
toString(candidates) <<
"\n";
1964 for (
int i = startIndex; i < (int)normalizedLanes.size(); ++i) {
1965 if (!normalizedLanes[i].second) {
1979 if ((*it).prevWalkingArea ==
"" || (*it).nextWalkingArea ==
"") {
1980 WRITE_WARNING(
"Discarding invalid crossing '" + (*it).id +
"' at junction '" +
getID() +
"' with edges '" +
toString((*it).edges) +
"'.");
1982 if ((*it_wa).nextCrossing == (*it).id) {
1983 (*it_wa).nextCrossing =
"";
1997 int noInternalNoSplits = 0;
1999 const std::vector<NBEdge::Connection>& elv = (*i)->getConnections();
2000 for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
2001 if ((*k).toEdge == 0) {
2004 noInternalNoSplits++;
2010 (*i)->buildInnerEdges(*
this, noInternalNoSplits, lno, splitNo);
2018 (*i)->buildInnerEdges(*
this, noInternalNoSplits, lno, splitNo);
2028 std::cout <<
"build crossings for " <<
getID() <<
":\n";
2038 (*it).nextWalkingArea =
"";
2039 (*it).prevWalkingArea =
"";
2042 std::cout <<
" crossing=" << (*it).id <<
" edges=" <<
toString(edges);
2048 std::cout <<
" sortedEdges=" <<
toString(edges) <<
"\n";
2052 int maxAngleDiffIndex = 0;
2053 for (
int i = 0; i < (int) edges.size(); i++) {
2055 edges[(i + 1) % edges.size()]->getAngleAtNodeToCenter(
this));
2060 std::cout <<
" i=" << i <<
" a1=" << edges[i]->getAngleAtNodeToCenter(
this) <<
" a2=" << edges[(i + 1) % edges.size()]->getAngleAtNodeToCenter(
this) <<
" diff=" << diff <<
"\n";
2062 if (diff > maxAngleDiff) {
2063 maxAngleDiff = diff;
2064 maxAngleDiffIndex = i;
2067 if (maxAngleDiff > 2 && maxAngleDiff < 360 - 2) {
2069 std::rotate(edges.begin(), edges.begin() + (maxAngleDiffIndex + 1) % edges.size(), edges.end());
2071 std::cout <<
" rotatedEdges=" <<
toString(edges);
2075 std::reverse(edges.begin(), edges.end());
2077 std::cout <<
" finalEdges=" <<
toString(edges) <<
"\n";
2080 (*it).shape.clear();
2081 const int begDir = (edges.front()->getFromNode() ==
this ?
FORWARD :
BACKWARD);
2082 const int endDir = (edges.back()->getToNode() ==
this ?
FORWARD :
BACKWARD);
2083 if (edges.front()->getFirstNonPedestrianLaneIndex(begDir) < 0
2084 || edges.back()->getFirstNonPedestrianLaneIndex(endDir) < 0) {
2086 WRITE_WARNING(
"Discarding invalid crossing '" + (*it).id +
"' at junction '" +
getID() +
"' with edges '" +
toString((*it).edges) +
"'.");
2089 NBEdge::Lane crossingBeg = edges.front()->getFirstNonPedestrianLane(begDir);
2090 NBEdge::Lane crossingEnd = edges.back()->getFirstNonPedestrianLane(endDir);
2097 (*it).shape.push_back(crossingBeg.
shape[begDir ==
FORWARD ? 0 : -1]);
2098 (*it).shape.push_back(crossingEnd.
shape[endDir ==
FORWARD ? -1 : 0]);
2112 std::cout <<
"build walkingAreas for " <<
getID() <<
":\n";
2119 std::vector<std::pair<NBEdge*, NBEdge::Lane> > normalizedLanes;
2120 for (EdgeVector::const_iterator it = allEdges.begin(); it != allEdges.end(); ++it) {
2122 const std::vector<NBEdge::Lane>& lanes = edge->
getLanes();
2124 for (std::vector<NBEdge::Lane>::const_reverse_iterator it_l = lanes.rbegin(); it_l != lanes.rend(); ++it_l) {
2128 normalizedLanes.push_back(std::make_pair(edge, l));
2131 for (std::vector<NBEdge::Lane>::const_iterator it_l = lanes.begin(); it_l != lanes.end(); ++it_l) {
2136 normalizedLanes.push_back(std::make_pair(edge, l));
2142 std::vector<std::pair<int, int> > waIndices;
2144 NBEdge* prevEdge = normalizedLanes.back().first;
2145 for (
int i = 0; i < (int)normalizedLanes.size(); ++i) {
2146 NBEdge* edge = normalizedLanes[i].first;
2154 waIndices.push_back(std::make_pair(start, i - start));
2164 <<
" waI=" << waIndices.size() <<
" crossingBetween=" <<
crossingBetween(edge, prevEdge) <<
"\n";
2169 const int waNumLanes = (int)normalizedLanes.size() - start;
2170 if (waIndices.size() == 0) {
2171 waIndices.push_back(std::make_pair(start, waNumLanes));
2173 std::cout <<
" single wa, end at wrap-around\n";
2176 if (waIndices.front().first == 0) {
2177 NBEdge* edge = normalizedLanes.front().first;
2178 NBEdge* prevEdge = normalizedLanes.back().first;
2181 waIndices.push_back(std::make_pair(start, waNumLanes));
2183 std::cout <<
" do not wrap around, turn-around in between\n";
2187 waIndices.front().first = start;
2188 waIndices.front().second = waNumLanes + waIndices.front().second;
2190 std::cout <<
" wrapping around\n";
2195 waIndices.push_back(std::make_pair(start, waNumLanes));
2197 std::cout <<
" end at wrap-around\n";
2203 std::cout <<
" normalizedLanes=" << normalizedLanes.size() <<
" waIndices:\n";
2204 for (
int i = 0; i < (int)waIndices.size(); ++i) {
2205 std::cout <<
" " << waIndices[i].first <<
", " << waIndices[i].second <<
"\n";
2209 for (
int i = 0; i < (int)waIndices.size(); ++i) {
2210 const bool buildExtensions = waIndices[i].second != (int)normalizedLanes.size();
2211 const int start = waIndices[i].first;
2212 const int prev = start > 0 ? start - 1 : (int)normalizedLanes.size() - 1;
2213 const int count = waIndices[i].second;
2214 const int end = (start + count) % normalizedLanes.size();
2218 std::cout <<
"build walkingArea " << wa.
id <<
" start=" << start <<
" end=" << end <<
" count=" << count <<
" prev=" << prev <<
":\n";
2225 bool connectsCrossing =
false;
2226 std::vector<Position> connectedPoints;
2229 std::cout <<
" crossing=" << (*it).id <<
" sortedEdges=" <<
toString((*it).edges) <<
"\n";
2231 if ((*it).edges.back() == normalizedLanes[end].first
2232 && (normalizedLanes[end].second.permissions &
SVC_PEDESTRIAN) == 0) {
2234 if ((*it).nextWalkingArea !=
"") {
2236 +
"'; crossing '" + (*it).id
2237 +
"' targets '" + (*it).nextWalkingArea
2238 +
"' and '" + wa.
id +
"'.");
2240 (*it).nextWalkingArea = wa.
id;
2241 endCrossingWidth = (*it).width;
2242 endCrossingShape = (*it).shape;
2244 connectsCrossing =
true;
2245 connectedPoints.push_back((*it).shape[-1]);
2247 std::cout <<
" crossing " << (*it).id <<
" ends\n";
2250 if ((*it).edges.front() == normalizedLanes[prev].first
2251 && (normalizedLanes[prev].second.permissions &
SVC_PEDESTRIAN) == 0) {
2253 if ((*it).prevWalkingArea !=
"") {
2255 +
"'; crossing '" + (*it).id
2256 +
"' is targeted by '" + (*it).prevWalkingArea
2257 +
"' and '" + wa.
id +
"'.");
2259 (*it).prevWalkingArea = wa.
id;
2261 startCrossingWidth = (*it).width;
2262 startCrossingShape = (*it).shape;
2264 connectsCrossing =
true;
2265 connectedPoints.push_back((*it).shape[0]);
2267 std::cout <<
" crossing " << (*it).id <<
" starts\n";
2270 if (
gDebugFlag1) std::cout <<
" check connections to crossing " << (*it).id
2271 <<
" cFront=" << (*it).edges.front()->getID() <<
" cBack=" << (*it).edges.back()->getID()
2272 <<
" wEnd=" << normalizedLanes[end].first->getID() <<
" wStart=" << normalizedLanes[start].first->getID()
2273 <<
" wStartPrev=" << normalizedLanes[prev].first->getID()
2276 if (count < 2 && !connectsCrossing) {
2279 std::cout <<
" not relevant for walking: count=" << count <<
" connectsCrossing=" << connectsCrossing <<
"\n";
2284 std::set<NBEdge*> connected;
2285 for (
int j = 0; j < count; ++j) {
2286 const int nlI = (start + j) % normalizedLanes.size();
2287 NBEdge* edge = normalizedLanes[nlI].first;
2290 if (connected.count(edge) == 0) {
2298 connected.insert(edge);
2305 if (buildExtensions) {
2307 if (startCrossingShape.size() > 0) {
2309 std::cout <<
" extension at startCrossing shape=" << startCrossingShape <<
"\n";
2311 startCrossingShape.
move2side(startCrossingWidth / 2);
2313 startCrossingShape.
move2side(-startCrossingWidth);
2317 if (endCrossingShape.size() > 0) {
2319 std::cout <<
" extension at endCrossing shape=" << endCrossingShape <<
"\n";
2321 endCrossingShape.
move2side(endCrossingWidth / 2);
2323 endCrossingShape.
move2side(-endCrossingWidth);
2328 && normalizedLanes.size() == 2) {
2330 NBEdge* e1 = *connected.begin();
2331 NBEdge* e2 = *(++connected.begin());
2334 std::cout <<
" not building a walkingarea since normal connections exist\n";
2340 if (cornerDetail > 0) {
2341 int smoothEnd = end;
2342 int smoothPrev = prev;
2344 if (endCrossingWidth > 0 && normalizedLanes[smoothEnd].second.permissions == 0) {
2345 smoothEnd = (smoothEnd + 1) % normalizedLanes.size();
2347 if (startCrossingWidth > 0 && normalizedLanes[smoothPrev].second.permissions == 0) {
2348 if (smoothPrev == 0) {
2349 smoothPrev = (int)normalizedLanes.size() - 1;
2354 PositionVector begShape = normalizedLanes[smoothEnd].second.shape;
2355 begShape = begShape.
reverse();
2357 begShape.
move2side(normalizedLanes[smoothEnd].second.width / 2);
2358 PositionVector endShape = normalizedLanes[smoothPrev].second.shape;
2359 endShape.
move2side(normalizedLanes[smoothPrev].second.width / 2);
2363 <<
" end=" << smoothEnd <<
" prev=" << smoothPrev
2364 <<
" endCrossingWidth=" << endCrossingWidth <<
" startCrossingWidth=" << startCrossingWidth
2365 <<
" begShape=" << begShape <<
" endShape=" << endShape <<
" smooth curve=" << curve <<
"\n";
2366 if (curve.size() > 2) {
2367 curve.erase(curve.begin());
2369 if (endCrossingWidth > 0) {
2370 wa.
shape.pop_back();
2372 if (startCrossingWidth > 0) {
2380 int combinations = 0;
2381 for (std::vector<Position>::const_iterator it1 = connectedPoints.begin(); it1 != connectedPoints.end(); ++it1) {
2382 for (std::vector<Position>::const_iterator it2 = connectedPoints.begin(); it2 != connectedPoints.end(); ++it2) {
2392 std::cout <<
" combinations=" << combinations <<
" connectedPoints=" << connectedPoints <<
"\n";
2395 if (combinations > 0) {
2405 std::cout <<
" checkIntermediate: prev=" << prev.
id <<
" next=" << next.
id <<
" prev.nextWA=" << prev.
nextWalkingArea <<
"\n";
2409 WRITE_WARNING(
"Invalid pedestrian topology: crossing '" + prev.
id +
"' has no target.");
2419 wa.
shape.push_back(tmp[-1]);
2421 wa.
shape.push_back(tmp[-1]);
2425 wa.
shape.push_back(tmp[0]);
2427 wa.
shape.push_back(tmp[0]);
2432 std::cout <<
" build wa=" << wa.
id <<
"\n";
2446 EdgeVector::const_iterator it1 = find(edges.begin(), edges.end(), e1);
2447 EdgeVector::const_iterator it2 = find(edges.begin(), edges.end(), e2);
2448 if (it1 != edges.end() && it2 != edges.end()) {
2464 while (it != it_end) {
2465 result.push_back(*it);
2486 if (
MAX2(angle0, angle1) <= 160) {
2516 EdgeSet edgeSet(edges.begin(), edges.end());
2518 EdgeSet edgeSet2((*it).edges.begin(), (*it).edges.end());
2519 if (edgeSet == edgeSet2) {
2531 if ((*it).id ==
id) {
2535 throw ProcessError(
"Request for unknown crossing '" +
id +
"'");
2542 (*it).tlLinkNo = startIndex++;
2574 std::cout <<
" angles:\n";
2575 for (EdgeVector::const_iterator it = result.begin(); it != result.end(); ++it) {
2576 std::cout <<
" edge=" << (*it)->getID() <<
" edgeAngle=" << (*it)->getAngleAtNode(
this) <<
" angleToShape=" << (*it)->getAngleAtNodeToCenter(
this) <<
"\n";
2578 std::cout <<
" allEdges before: " <<
toString(result) <<
"\n";
2583 std::cout <<
" allEdges sorted: " <<
toString(result) <<
"\n";
2585 rotate(result.begin(), std::find(result.begin(), result.end(), *
myAllEdges.begin()), result.end());
2587 std::cout <<
" allEdges rotated: " <<
toString(result) <<
"\n";
2598 assert(
id[0] ==
':');
2599 std::string::size_type sep_index =
id.rfind(
'_');
2600 if (sep_index == std::string::npos) {
2601 WRITE_ERROR(
"Invalid lane id '" +
id +
"' (missing '_').");
2604 sep_index =
id.substr(0, sep_index).rfind(
'_');
2605 if (sep_index == std::string::npos) {
2606 WRITE_ERROR(
"Invalid lane id '" +
id +
"' (missing '_').");
2609 return id.substr(1, sep_index - 1);
2619 if (turnDest != 0) {
2640 if ((*i)->rightOnRedConflict(index, foeIndex)) {
bool gDebugFlag1
global utility flags for debugging
void sub(SUMOReal dx, SUMOReal dy)
Substracts the given position from this one.
The link is a partial left direction.
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges.
void replaceOutgoing(const EdgeVector &which, NBEdge *const by)
Replaces outgoing edges from the vector (source) by the given edge.
Position getEmptyDir() const
Returns something like the most unused direction Should only be used to add source or sink nodes...
static SUMOReal getCWAngleDiff(SUMOReal angle1, SUMOReal angle2)
Returns the distance of second angle from first angle clockwise.
A structure which describes a connection between edges or lanes.
int numAvailableLanes() const
int toLane
The lane the connections yields in.
void setRoundabout()
update the type of this node as a roundabout
std::vector< Crossing > myCrossings
Vector of crossings.
Position getCenter() const
Returns a position that is guaranteed to lie within the node shape.
static const SUMOReal UNSPECIFIED_WIDTH
unspecified lane width
SUMOReal width
This lane's width.
ApproachingDivider(EdgeVector *approaching, NBEdge *currentOutgoing)
Constructor.
static SUMOReal getCCWAngleDiff(SUMOReal angle1, SUMOReal angle2)
Returns the distance of second angle from first angle counter-clockwise.
PositionVector shape
The lane's shape.
const SUMOReal SUMO_const_laneWidth
virtual void addNode(NBNode *node)
Adds a node to the traffic light logic.
SUMOReal nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
bool isInStringVector(const std::string &optionName, const std::string &itemName)
Returns the named option is a list of string values containing the specified item.
NBEdge * toEdge
The edge the connections yields in.
#define EXTEND_CROSSING_ANGLE_THRESHOLD
Sorts crossings by minimum clockwise clockwise edge angle. Use the ordering found in myAllEdges of th...
void shiftTLConnectionLaneIndex(NBEdge *edge, int offset)
patches loaded signal plans by modifying lane indices
std::string id
the (edge)-id of this crossing
void add(const Position &pos)
Adds the given position to this one.
PositionVector myPoly
the (outer) shape of the junction
void execute(const int src, const int dest)
NBEdge * getOppositeIncoming(NBEdge *e) const
SUMOReal myRadius
the turning radius (for all corners) at this node in m.
SumoXMLNodeType myType
The type of the junction.
bool setConnection(int lane, NBEdge *destEdge, int destLane, Lane2LaneInfoType type, bool mayUseSameDestination=false, bool mayDefinitelyPass=false, bool keepClear=true, SUMOReal contPos=UNSPECIFIED_CONTPOS)
Adds a connection to a certain lane of a certain edge.
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 (relative to the node shape center) The angle is computed in...
void addIncomingEdge(NBEdge *edge)
adds an incoming edge
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
The representation of a single edge during network building.
Class to sort edges by their angle in relation to the given edge.
bool replaceTo(NBEdge *which, NBEdge *by)
replaces the to-edge by the one given
void setCrossingTLIndices(int startIndex)
set tl indices of this nodes crossing starting at the given index
The link is a 180 degree turn.
int numNormalConnections() const
return the number of lane-to-lane connections at this junction (excluding crossings) ...
bool hasOutgoing(const NBEdge *const e) const
Returns whether the given edge starts at this node.
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 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.
#define SUMO_MAX_CONNECTIONS
the maximum number of connections across an intersection
PositionVector shape
The lane's shape.
#define SPLIT_CROSSING_ANGLE_THRESHOLD
PositionVector getSubpartByIndex(int beginIndex, int count) const
get subpart of a position vector using index and a cout
void buildWalkingAreas(int cornerDetail)
bool isInnerEdge() const
Returns whether this edge was marked as being within an intersection.
This is an uncontrolled, right-before-left link.
SUMOReal getFloat(const std::string &name) const
Returns the SUMOReal-value of the named option (only for Option_Float)
static void nextCW(const EdgeVector &edges, EdgeVector::const_iterator &from)
bool isForbidden(SVCPermissions permissions)
Returns whether an edge with the given permission is a forbidden edge.
void remapConnections(const EdgeVector &incoming)
Remaps the connection in a way that allows the removal of it.
std::string id
the (edge)-id of this walkingArea
EdgeVector getEdgesSortedByAngleAtNodeCenter() const
returns the list of all edges sorted clockwise by getAngleAtNodeToCenter
bool checkIsRemovable() const
void mirrorX()
mirror coordinates along the x-axis
bool around(const Position &p, SUMOReal offset=0) const
Returns the information whether the position vector describes a polygon lying around the given point...
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission is a railway edge.
Lane & getLaneStruct(int lane)
void removeTrafficLight(NBTrafficLightDefinition *tlDef)
Removes the given traffic light from this node.
void setCustomShape(const PositionVector &shape)
set the junction shape
The link is controlled by a tls which is off, not blinking, may pass.
static SUMOReal angleDiff(const SUMOReal angle1, const SUMOReal angle2)
Returns the difference of the second angle to the first angle in radiants.
NBConnectionProhibits myBlockedConnections
void writeLogic(std::string key, OutputDevice &into, const bool checkLaneFoes) const
bool hasIncoming(const NBEdge *const e) const
Returns whether the given edge ends at this node.
SUMOReal x() const
Returns the x-position.
This is an uncontrolled, all-way stop link.
void addOutgoingEdge(NBEdge *edge)
adds an outgoing edge
NBEdge * getFrom() const
returns the from-edge (start of the connection)
Position positionAtOffset2D(SUMOReal pos, SUMOReal lateralOffset=0) const
Returns the position at the given length.
void replaceOutgoing(NBEdge *which, NBEdge *by, int laneOff)
Replaces occurences of the first edge within the list of outgoing by the second Connections are remap...
This is an uncontrolled, zipper-merge link.
The link is a (hard) left direction.
#define WRITE_WARNING(msg)
The connection was computed and validated.
SUMOReal distance2D(const Position &p, bool perpendicular=false) const
closest 2D-distance to point p (or -1 if perpendicular is true and the point is beyond this vector) ...
static OptionsCont & getOptions()
Retrieves the options.
static bool rightTurnConflict(const NBEdge *from, const NBEdge *to, int fromLane, const NBEdge *prohibitorFrom, const NBEdge *prohibitorTo, int prohibitorFromLane, bool lefthand=false)
return whether the given laneToLane connection is a right turn which must yield to a bicycle crossing...
PositionVector reverse() const
reverse position vector
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.
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges.
void extrapolate2D(const SUMOReal val, const bool onlyFirst=false)
extrapolate position vector in two dimensions (Z is ignored)
SUMOReal getLoadedLength() const
Returns the length was set explicitly or the computed length if it wasn't set.
An (internal) definition of a single lane of an edge.
static bool mustBrakeForCrossing(const NBNode *node, const NBEdge *const from, const NBEdge *const to, const NBNode::Crossing &crossing)
Returns the information whether the described flow must brake for the given crossing.
const std::string & getID() const
Returns the id.
EdgeVector myAllEdges
Vector of incoming and outgoing edges.
SVCPermissions permissions
List of vehicle types that are allowed on this lane.
bool needsCont(const NBEdge *fromE, const NBEdge *otherFromE, const NBEdge::Connection &c, const NBEdge::Connection &otherC) const
whether an internal junction should be built at from and respect other
void computeLanes2Lanes()
computes the connections of lanes to edges
void invalidateIncomingConnections()
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)
insert in front a non double position
void removeCrossing(const EdgeVector &edges)
remove a pedestrian crossing from this node (identified by its edges)
const Position & getPosition() const
Returns the position of this node.
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 hasConnectionTo(NBEdge *destEdge, int destLane, int fromLane=-1) const
Retrieves info about a connection to a certain lane of a certain edge.
bool isSimpleContinuation() const
int checkCrossing(EdgeVector candidates)
static const int FORWARD
edge directions (for pedestrian related stuff)
void remapRemoved(NBEdge *removed, const EdgeVector &incoming, const EdgeVector &outgoing)
Replaces occurences of the removed edge in incoming/outgoing edges of all definitions.
std::string tlID
The id of the traffic light that controls this connection.
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.
std::pair< int, int > getSizes() const
returns the number of the junction's lanes and the number of the junction's links in respect...
bool mustBrake(const NBEdge *const possProhibitorFrom, const NBEdge *const possProhibitorTo, const NBEdge *const possProhibitedFrom, const NBEdge *const possProhibitedTo) const
Returns the information whether "prohibited" flow must let "prohibitor" flow pass.
void add(SUMOReal xoff, SUMOReal yoff, SUMOReal zoff)
bool addLane2LaneConnections(int fromLane, NBEdge *dest, int toLane, int no, Lane2LaneInfoType type, bool invalidatePrevious=false, bool mayDefinitelyPass=false)
Builds no connections starting at the given lanes.
void buildCrossingsAndWalkingAreas()
SUMOReal z() const
Returns the z-position.
bool geometryLike() const
whether this is structurally similar to a geometry node
void invalidateOutgoingConnections()
int getNumLanes() const
Returns the number of lanes.
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
EdgeBuildingStep getStep() const
The building step of this edge.
bool isTurningDirectionAt(const NBEdge *const edge) const
Returns whether the given edge is the opposite direction to this edge.
void removeTrafficLights()
Removes all references to traffic lights that control this tls.
EdgeVector * getEdgesThatApproach(NBEdge *currentOutgoing)
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
The link is a (hard) right direction.
LinkState getLinkState(const NBEdge *incoming, NBEdge *outgoing, int fromLane, int toLane, bool mayDefinitelyPass, const std::string &tlID) const
bool rightOnRedConflict(int index, int foeIndex) const
whether the given index must yield to the foeIndex while turing right on a red light ...
bool myDiscardAllCrossings
whether to discard all pedestrian crossings
void replaceInConnectionProhibitions(NBEdge *which, NBEdge *by, int whichLaneOff, int byLaneOff)
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.
NBEdge * getConnectionTo(NBNode *n) const
const std::vector< NBNode * > & getNodes() const
Returns the list of controlled nodes.
virtual void removeNode(NBNode *node)
Removes the given node from the list of controlled nodes.
EdgeVector myIncomingEdges
Vector of incoming edges.
bool isLeftMover(const NBEdge *const from, const NBEdge *const to) const
Computes whether the given connection is a left mover across the junction.
Base class for objects which have an id.
std::vector< NBConnection > NBConnectionVector
Definition of a connection vector.
std::vector< std::pair< NBEdge *, NBEdge * > > getEdgesToJoin() const
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)
EdgeVector myOutgoingEdges
Vector of outgoing edges.
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
SUMOReal getCrossingAngle(NBNode *node)
return the angle for computing pedestrian crossings at the given node
NBEdge * myCurrentOutgoing
The approached current edge.
static const int BACKWARD
std::string myID
The name of the object.
NBNode * getToNode() const
Returns the destination node of the edge.
void addTrafficLight(NBTrafficLightDefinition *tlDef)
Adds a traffic light to the list of traffic lights that control this node.
bool isNearDistrict() const
PositionVector computeInternalLaneShape(NBEdge *fromE, const NBEdge::Connection &con, int numPoints) const
Compute the shape for an internal lane.
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 ...
int removeSelfLoops(NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tc)
Removes edges which are both incoming and outgoing into this node.
SUMOReal angleAt2D(int pos) const
get angle in certain position of position vector
~ApproachingDivider()
Destructor.
std::vector< WalkingArea > myWalkingAreas
Vector of walking areas.
void replaceIncoming(NBEdge *which, NBEdge *by, int laneOff)
Replaces occurences of the first edge within the list of incoming by the second Connections are remap...
SumoXMLNodeType
Numbers representing special SUMO-XML-attribute values for representing node- (junction-) types used ...
bool mustBrake(const NBEdge *const from, const NBEdge *const to, int fromLane, int toLane, bool includePedCrossings) const
Returns the information whether the described flow must let any other flow pass.
bool myKeepClear
whether the junction area must be kept clear
std::vector< int > myAvailableLanes
The available lanes to which connections shall be built.
The link is controlled by a tls which is off and blinks, has to brake.
std::vector< NBEdge * > EdgeVector
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.
A storage for options typed value containers)
void set(SUMOReal x, SUMOReal y)
static const SUMOReal DEFAULT_CROSSING_WIDTH
default width of pedetrian crossings
void erase(NBDistrictCont &dc, NBEdge *edge)
Removes the given edge from the container (deleting it)
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.
bool removeFully(const std::string id)
Removes a logic definition (and all programs) from the dictionary.
bool foes(const NBEdge *const from1, const NBEdge *const to1, const NBEdge *const from2, const NBEdge *const to2) const
Returns the information whether the given flows cross.
Lanes to lanes - relationships are computed; no recheck is necessary/wished.
SUMOReal distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
The link is a 180 degree turn (left-hand network)
int guessCrossings()
guess pedestrian crossings and return how many were guessed
A definition of a pedestrian crossing.
void move2side(SUMOReal amount)
move position vector to side using certain ammount
bool insert(NBTrafficLightDefinition *logic, bool forceInsert=false)
Adds a logic definition to the dictionary.
void replaceInConnections(NBEdge *which, NBEdge *by, int laneOff)
void addSortedLinkFoes(const NBConnection &mayDrive, const NBConnection &mustStop)
Static storage of an output device and its base (abstract) implementation.
static void compute(BresenhamCallBack *callBack, const int val1, const int val2)
Computes lane-2-lane connections.
static const SUMOReal UNSPECIFIED_RADIUS
unspecified lane width
bool writeLogic(OutputDevice &into, const bool checkLaneFoes) const
static SUMOReal relAngle(SUMOReal angle1, SUMOReal angle2)
void push_back_noDoublePos(const Position &p)
insert in back a non double position
static PositionVector bezierControlPoints(const PositionVector &begShape, const PositionVector &endShape, bool isTurnaround, SUMOReal extrapolateBeg, SUMOReal extrapolateEnd)
#define SPLIT_CROSSING_WIDTH_THRESHOLD
void computeLogic(const NBEdgeCont &ec, OptionsCont &oc)
computes the node's type, logic and traffic light
SUMOReal getSpeed() const
Returns the speed allowed on this edge.
SUMOReal getStartAngle() const
Returns the angle at the start of the edge (relative to the node shape center) The angle is computed ...
Position getPolygonCenter() const
Returns the arithmetic of all corner points.
A traffic light logics which must be computed (only nodes/edges are given)
bool foes(const NBEdge *const from1, const NBEdge *const to1, const NBEdge *const from2, const NBEdge *const to2) const
Returns the information whether the given flows cross.
void invalidateTLS(NBTrafficLightLogicCont &tlCont)
causes the traffic light to be computed anew
std::string nextWalkingArea
the lane-id of the next walkingArea
std::set< SVCPermissions > getPermissionVariants(int iStart, int iEnd) const
return all permission variants within the specified lane range [iStart, iEnd[
void closePolygon()
ensures that the last position equals the first
Lanes to edges - relationships are computed/loaded.
NBNode(const std::string &id, const Position &position, SumoXMLNodeType type)
Constructor.
const std::vector< Connection > & getConnections() const
Returns the connections.
NBEdge * getTurnDestination(bool possibleDestination=false) const
PositionVector getSubpart(SUMOReal beginOffset, SUMOReal endOffset) const
get subpart of a position vector
const PositionVector & getLaneShape(int i) const
Returns the shape of the nth lane.
std::vector< std::string > prevSidewalks
the lane-id of the previous sidewalk lane or ""
static bool isTrafficLight(SumoXMLNodeType type)
return whether the given type is a traffic light
void shiftPositionAtNode(NBNode *node, NBEdge *opposite)
shift geometry at the given node to avoid overlap
std::vector< std::string > nextSidewalks
the lane-id of the next sidewalk lane or ""
static void nextCCW(const EdgeVector &edges, EdgeVector::const_iterator &from)
void reshiftPosition(SUMOReal xoff, SUMOReal yoff)
Applies an offset to the node.
void computeNodeShape(SUMOReal mismatchThreshold)
Compute the junction shape for this node.
SUMOReal angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position ...
void append(const PositionVector &v, SUMOReal sameThreshold=2.0)
SUMOReal width
This lane's width.
void extrapolate(const SUMOReal val, const bool onlyFirst=false)
extrapolate position vector
void remapRemoved(NBTrafficLightLogicCont &tc, NBEdge *removed, const EdgeVector &incoming, const EdgeVector &outgoing)
PositionVector shape
The polygonal shape.
static const Position INVALID
void replaceIncoming(const EdgeVector &which, NBEdge *const by)
Replaces incoming edges from the vector (sinks) by the given edge.
SUMOReal getAngleAtNode(const NBNode *const node) const
Returns the angle of the edge's geometry at the given node.
bool forbids(const NBEdge *const possProhibitorFrom, const NBEdge *const possProhibitorTo, const NBEdge *const possProhibitedFrom, const NBEdge *const possProhibitedTo, bool regardNonSignalisedLowerPriority) const
Returns the information whether "prohibited" flow must let "prohibitor" flow pass.
The link has no direction (is a dead end link)
bool forbidsPedestriansAfter(std::vector< std::pair< NBEdge *, bool > > normalizedLanes, int startIndex)
return whether there is a non-sidewalk lane after the given index;
static bool isLongEnough(NBEdge *out, SUMOReal minLength)
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.