69 #define EXTEND_CROSSING_ANGLE_THRESHOLD 35.0 // degrees 71 #define SPLIT_CROSSING_WIDTH_THRESHOLD 1.5 // meters 72 #define SPLIT_CROSSING_ANGLE_THRESHOLD 5 // degrees 75 #define MIN_WEAVE_LENGTH 20.0 78 #define DEBUGCOND true 96 myApproaching(approaching), myCurrentOutgoing(currentOutgoing) {
100 std::set<int> approachedLanes;
102 const std::vector<NBEdge::Connection> conns = (*it)->getConnections();
103 for (std::vector<NBEdge::Connection>::const_iterator it_con = conns.begin(); it_con != conns.end(); ++it_con) {
105 approachedLanes.insert((*it_con).toLane);
113 for (
int i = 0; i < currentOutgoing->
getNumLanes(); ++i) {
116 && approachedLanes.count(i) == 0) {
131 NBEdge* incomingEdge = (*myApproaching)[src];
135 std::vector<int> approachingLanes =
137 assert(approachingLanes.size() != 0);
138 std::deque<int>* approachedLanes =
spread(approachingLanes, dest);
141 for (
int i = 0; i < (int)approachedLanes->size(); i++) {
142 assert((
int)approachingLanes.size() > i);
147 delete approachedLanes;
154 std::deque<int>* ret =
new std::deque<int>();
155 int noLanes = (int) approachingLanes.size();
159 ret->push_back(dest);
165 ret->push_back(dest);
169 while (noSet < noLanes) {
175 if (noOutgoingLanes == noSet) {
184 if (dest + loffset >= noOutgoingLanes) {
187 for (
int i = 0; i < (int)ret->size(); i++) {
188 (*ret)[i] = (*ret)[i] - 1;
193 ret->push_back(dest + loffset);
198 if (noOutgoingLanes == noSet) {
203 if (noSet < noLanes) {
206 if (dest < roffset) {
209 for (
int i = 0; i < (int)ret->size(); i++) {
210 (*ret)[i] = (*ret)[i] + 1;
213 ret->push_front(dest - roffset);
263 bool updateEdgeGeometries) {
270 if (updateEdgeGeometries) {
274 (*i)->setGeometry(geom);
279 (*i)->setGeometry(geom);
300 (*it).shape.mirrorX();
303 (*it_wa).shape.mirrorX();
329 for (std::set<NBTrafficLightDefinition*>::const_iterator i = trafficLights.begin(); i != trafficLights.end(); ++i) {
341 if ((*i)->getID().find(
"joined") == 0) {
353 for (std::set<NBTrafficLightDefinition*>::iterator it = oldDefs.begin(); it != oldDefs.end(); ++it) {
355 if (dynamic_cast<NBOwnTLDef*>(orig) == 0) {
357 const std::vector<NBNode*>& nodes = orig->
getNodes();
358 while (!nodes.empty()) {
359 newDef->
addNode(nodes.front());
360 nodes.front()->removeTrafficLight(orig);
373 (*it)->shiftTLConnectionLaneIndex(edge, offset);
400 remapRemoved(tc, dummy, incomingConnected, outgoingConnected);
449 if (checkLaneNumbers && in->
getNumLanes() != (*opposite)->getNumLanes()) {
465 double extrapolateBeg,
466 double extrapolateEnd,
467 NBNode* recordError)
const {
471 #ifdef DEBUG_SMOOTH_GEOM 473 std::cout <<
"computeSmoothShape node " <<
getID() <<
" init=" << init <<
"\n";
476 if (init.size() == 0) {
478 ret.push_back(begShape.back());
479 ret.push_back(endShape.front());
482 return bezier(init, numPoints).smoothedZFront();
491 double extrapolateBeg,
492 double extrapolateEnd,
495 double straightThresh) {
497 const Position beg = begShape.back();
498 const Position end = endShape.front();
502 #ifdef DEBUG_SMOOTH_GEOM 503 if (
DEBUGCOND) std::cout <<
" bezierControlPoints failed beg=" << beg <<
" end=" << end
519 center.
sub(beg.
y() - end.
y(), end.
x() - beg.
x());
520 init.push_back(center);
525 endShapeBegLine.extrapolate2D(100,
true);
527 if (fabs(angle) <
M_PI / 4.) {
530 const double bendDeg =
RAD2DEG(fabs(displacementAngle - angle));
531 const double halfDistance = dist / 2;
532 if (fabs(displacementAngle) <= straightThresh && fabs(angle) <= straightThresh) {
533 #ifdef DEBUG_SMOOTH_GEOM 534 if (
DEBUGCOND) std::cout <<
" bezierControlPoints identified straight line beg=" << beg <<
" end=" << end
535 <<
" angle=" <<
RAD2DEG(angle) <<
" displacementAngle=" <<
RAD2DEG(displacementAngle) <<
"\n";
538 }
else if (bendDeg > 22.5 && pow(bendDeg / 45, 2) / dist > 0.13) {
541 #ifdef DEBUG_SMOOTH_GEOM 542 if (
DEBUGCOND) std::cout <<
" bezierControlPoints found extreme s-curve, falling back to straight line beg=" << beg <<
" end=" << end
543 <<
" angle=" <<
RAD2DEG(angle) <<
" displacementAngle=" <<
RAD2DEG(displacementAngle)
544 <<
" dist=" << dist <<
" bendDeg=" << bendDeg <<
" bd2=" << pow(bendDeg / 45, 2)
545 <<
" displacementError=" << sin(displacementAngle) * dist
546 <<
" begShape=" << begShape <<
" endShape=" << endShape <<
"\n";
549 if (recordError != 0) {
554 const double endLength = begShape[-2].distanceTo2D(begShape[-1]);
555 const double off1 = endLength +
MIN2(extrapolateBeg, halfDistance);
557 const double 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";
579 if (recordError != 0) {
585 const double minControlLength =
MIN2((
double)1.0, dist / 2);
586 const bool lengthenBeg = intersect.
distanceTo2D(beg) <= minControlLength;
587 const bool lengthenEnd = intersect.
distanceTo2D(end) <= minControlLength;
588 if (lengthenBeg && lengthenEnd) {
589 #ifdef DEBUG_SMOOTH_GEOM 590 if (
DEBUGCOND) std::cout <<
" bezierControlPoints failed beg=" << beg <<
" end=" << end <<
" intersect=" << intersect
593 if (recordError != 0) {
599 }
else if (lengthenBeg || lengthenEnd) {
601 init.push_back(endShapeBegLine.positionAtOffset2D(100 - minControlLength));
605 const double z2 = endShapeBegLine.positionAtOffset2D(endShapeBegLine.nearest_offset_to_point2D(intersect)).z();
606 const double z3 = 0.5 * (beg.
z() + end.
z());
610 if ((z1 <= z3 && z2 <= z3) || (z1 >= z3 && z2 >= z3)) {
615 intersect.
set(intersect.
x(), intersect.
y(), z);
616 init.push_back(intersect);
637 assert(con.
shape.size() > 0);
646 ret.append(it->second);
658 if (lane.endOffset > 0) {
680 if (thisRight && !rightTurnConflict) {
683 if (!(
foes(otherFromE, otherToE, fromE, toE) ||
myRequest == 0 || rightTurnConflict)) {
693 const bool bothLeft = thisLeft && otherLeft;
694 if (fromE == otherFromE && !thisRight) {
701 if (c.
tlID !=
"" && !bothLeft) {
704 if ((*it)->needsCont(fromE, toE, otherFromE, otherToE)) {
725 for (std::set<NBTrafficLightDefinition*>::const_iterator i = trafficLights.begin(); i != trafficLights.end(); ++i) {
727 if ((*i)->getNodes().size() > 1) {
729 (*i)->removeNode(
this);
730 (*i)->setParticipantsInformation();
731 (*i)->setTLControllingInformation();
759 }
else if (numConnections == 0) {
797 if (mismatchThreshold >= 0
830 for (
int i = inOffset; i < in->
getNumLanes(); ++i) {
862 std::swap(in1Offset, in2Offset);
891 std::swap(out1, out2);
892 std::swap(out1Offset, out2Offset);
915 for (
int i = inOffset; i < in->
getNumLanes(); ++i) {
939 inOffset += reduction;
940 for (
int i = outOffset; i < out->
getNumLanes(); ++i) {
952 EdgeVector::reverse_iterator i;
954 NBEdge* currentOutgoing = *i;
957 const int numApproaching = (int)approaching->size();
958 if (numApproaching != 0) {
972 const std::vector<NBEdge::Connection>& elv = incoming->
getConnections();
973 for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
975 if (c.
toEdge == currentOutgoing) {
978 unsatisfied &= ~satisfied;
981 if (unsatisfied != 0) {
984 while (unsatisfied != 0 && fromLane < incoming->getNumLanes()) {
986 for (
int toLane = 0; toLane < currentOutgoing->
getNumLanes(); ++toLane) {
991 unsatisfied &= ~satisfied;
1008 const std::vector<NBEdge::Connection> cons = (*i)->getConnections();
1009 for (std::vector<NBEdge::Connection>::const_iterator k = cons.begin(); k != cons.end(); ++k) {
1011 (*i)->removeFromConnections((*k).toEdge);
1022 (*i)->markAsInLane2LaneState();
1039 while (seen < minLength) {
1055 EdgeVector::const_iterator i = find(
myAllEdges.begin(),
1061 for (; *i != currentOutgoing;) {
1063 if ((*i)->getToNode() ==
this && (*i)->getTurnDestination() != currentOutgoing) {
1064 std::vector<int> connLanes = (*i)->getConnectionLanes(currentOutgoing);
1065 if (connLanes.size() != 0) {
1066 approaching->push_back(*i);
1097 for (EdgeVector::const_iterator i = which.begin(); i != which.end(); i++) {
1099 laneOff += (*i)->getNumLanes();
1129 for (EdgeVector::const_iterator i = which.begin(); i != which.end(); i++) {
1131 laneOff += (*i)->getNumLanes();
1146 int whichLaneOff,
int byLaneOff) {
1150 bool changed =
false;
1152 if (c.
replaceFrom(which, whichLaneOff, by, byLaneOff)) {
1155 if (c.
replaceTo(which, whichLaneOff, by, byLaneOff)) {
1169 for (NBConnectionVector::iterator k = prohibiting.begin(); k != prohibiting.end(); k++) {
1171 sprohibiting.
replaceFrom(which, whichLaneOff, by, byLaneOff);
1172 sprohibiting.
replaceTo(which, whichLaneOff, by, byLaneOff);
1232 if (find(edges.begin(), edges.end(), e) != edges.end()) {
1233 edges.erase(find(edges.begin(), edges.end(), e));
1235 if (edges.size() == 0) {
1250 if (mayDrive.
getFrom() == 0 ||
1251 mayDrive.
getTo() == 0 ||
1253 mustStop.
getTo() == 0) {
1255 WRITE_WARNING(
"Something went wrong during the building of a connection...");
1259 conn.push_back(mayDrive);
1266 int size = (int) edgeid.length();
1268 std::string
id = (*i)->
getID();
1269 if (
id.substr(0, size) == edgeid) {
1279 int size = (int) edgeid.length();
1281 std::string
id = (*i)->
getID();
1282 if (
id.substr(0, size) == edgeid) {
1307 if (removeFromConnections) {
1309 (*i)->removeFromConnections(edge);
1314 (*i)->replaceRemoved(edge, -1, 0, -1);
1323 EdgeVector::const_iterator i;
1325 NBNode* conn = (*i)->getFromNode();
1328 toAdd.
mul((
double) 1.0 / sqrt(toAdd.
x()*toAdd.
x() + toAdd.
y()*toAdd.
y()));
1332 NBNode* conn = (*i)->getToNode();
1335 toAdd.
mul((
double) 1.0 / sqrt(toAdd.
x()*toAdd.
x() + toAdd.
y()*toAdd.
y()));
1339 if (pos.
x() == 0 && pos.
y() == 0) {
1351 (*i)->invalidateConnections();
1359 (*i)->invalidateConnections();
1386 const NBEdge* prohibitorFrom,
const NBEdge* prohibitorTo,
int prohibitorFromLane,
1388 if (from != prohibitorFrom) {
1412 lefthand = !lefthand;
1419 if ((!lefthand && fromLane <= prohibitorFromLane) ||
1420 (lefthand && fromLane >= prohibitorFromLane)) {
1423 const double toAngleAtNode = fmod(to->
getStartAngle() + 180, (double)360.0);
1424 const double prohibitorToAngleAtNode = fmod(prohibitorTo->
getStartAngle() + 180, (double)360.0);
1442 std::vector<NBEdge*>::const_iterator i = std::find(
myAllEdges.begin(),
myAllEdges.end(), from);
1452 const NBEdge*
const possProhibitedFrom,
const NBEdge*
const possProhibitedTo,
1453 bool regardNonSignalisedLowerPriority)
const {
1455 possProhibitedFrom, possProhibitedTo,
1456 regardNonSignalisedLowerPriority);
1462 const NBEdge*
const from2,
const NBEdge*
const to2)
const {
1471 assert(find(incoming.begin(), incoming.end(), removed) == incoming.end());
1472 bool changed =
true;
1478 for (NBConnectionProhibits::iterator i = blockedConnectionsTmp.begin(); i != blockedConnectionsTmp.end(); i++) {
1483 bool blockedChanged =
false;
1485 NBConnectionVector::const_iterator j;
1486 for (j = blocked.begin(); j != blocked.end(); j++) {
1488 if (sblocked.
getFrom() == removed || sblocked.
getTo() == removed) {
1489 blockedChanged =
true;
1493 for (j = blocked.begin(); blockedChanged && j != blocked.end(); j++) {
1495 if (sblocked.
getFrom() == removed && sblocked.
getTo() == removed) {
1499 }
else if (sblocked.
getFrom() == removed) {
1500 assert(sblocked.
getTo() != removed);
1501 for (EdgeVector::const_iterator k = incoming.begin(); k != incoming.end(); k++) {
1504 }
else if (sblocked.
getTo() == removed) {
1505 assert(sblocked.
getFrom() != removed);
1506 for (EdgeVector::const_iterator k = outgoing.begin(); k != outgoing.end(); k++) {
1513 if (blockedChanged) {
1514 blockedConnectionsNew[blocker] = newBlocked;
1519 if (blocker.
getFrom() == removed && blocker.
getTo() == removed) {
1524 }
else if (blocker.
getFrom() == removed) {
1525 assert(blocker.
getTo() != removed);
1527 for (EdgeVector::const_iterator k = incoming.begin(); k != incoming.end(); k++) {
1530 }
else if (blocker.
getTo() == removed) {
1531 assert(blocker.
getFrom() != removed);
1533 for (EdgeVector::const_iterator k = outgoing.begin(); k != outgoing.end(); k++) {
1537 blockedConnectionsNew[blocker] = blocked;
1551 if (outgoing == 0) {
1562 if (
abs((
int) angle) + 1 < 45) {
1569 EdgeVector::const_iterator i =
1576 while ((*i) != incoming) {
1590 EdgeVector::const_iterator i =
1597 while ((*i) != incoming) {
1614 bool mayDefinitelyPass,
const std::string& tlID)
const {
1621 if (outgoing == 0) {
1633 if ((!incoming->
isInnerEdge() &&
mustBrake(incoming, outgoing, fromlane, toLane,
true)) && !mayDefinitelyPass) {
1647 EdgeVector::const_iterator i;
1660 std::set<NBNode*> origSet;
1662 origSet.insert((*i)->getFromNode());
1664 if (origSet.size() < 2) {
1672 if (opposite != 0) {
1676 if (!(*i)->expandableBy(continuation)) {
1692 std::vector<std::pair<NBEdge*, NBEdge*> >
1695 std::vector<std::pair<NBEdge*, NBEdge*> > ret;
1699 std::pair<NBEdge*, NBEdge*>(
1707 assert(opposite != 0);
1709 ret.push_back(std::pair<NBEdge*, NBEdge*>(*i, continuation));
1730 if (shape.size() > 1) {
1741 if ((*i)->getToNode() == n) {
1756 back_inserter(edges));
1758 back_inserter(edges));
1759 for (EdgeVector::const_iterator j = edges.begin(); j != edges.end(); ++j) {
1770 for (EdgeVector::const_iterator k = edges2.begin(); k != edges2.end(); ++k) {
1771 if ((*k)->getFromNode()->isDistrict() || (*k)->getToNode()->isDistrict()) {
1795 std::cout <<
"guess crossings for " <<
getID() <<
"\n";
1799 std::vector<std::pair<NBEdge*, bool> > normalizedLanes;
1800 for (EdgeVector::const_iterator it = allEdges.begin(); it != allEdges.end(); ++it) {
1802 const std::vector<NBEdge::Lane>& lanes = edge->
getLanes();
1804 for (std::vector<NBEdge::Lane>::const_reverse_iterator it_l = lanes.rbegin(); it_l != lanes.rend(); ++it_l) {
1805 normalizedLanes.push_back(std::make_pair(edge, ((*it_l).permissions &
SVC_PEDESTRIAN) != 0));
1808 for (std::vector<NBEdge::Lane>::const_iterator it_l = lanes.begin(); it_l != lanes.end(); ++it_l) {
1809 normalizedLanes.push_back(std::make_pair(edge, ((*it_l).permissions &
SVC_PEDESTRIAN) != 0));
1814 int firstSidewalk = -1;
1815 for (
int i = 0; i < (int)normalizedLanes.size(); ++i) {
1816 if (normalizedLanes[i].second) {
1821 int hadCandidates = 0;
1822 std::vector<int> connectedCandidates;
1823 if (firstSidewalk != -1) {
1825 std::vector<std::pair<NBEdge*, bool> > tmp;
1826 copy(normalizedLanes.begin() + firstSidewalk, normalizedLanes.end(), std::back_inserter(tmp));
1827 copy(normalizedLanes.begin(), normalizedLanes.begin() + firstSidewalk, std::back_inserter(tmp));
1828 normalizedLanes = tmp;
1831 for (
int i = 0; i < (int)normalizedLanes.size(); ++i) {
1832 NBEdge* edge = normalizedLanes[i].first;
1833 const bool allowsPed = normalizedLanes[i].second;
1835 std::cout <<
" cands=" <<
toString(candidates) <<
" edge=" << edge->
getID() <<
" allowsPed=" << allowsPed <<
"\n";
1837 if (!allowsPed && (candidates.size() == 0 || candidates.back() != edge)) {
1838 candidates.push_back(edge);
1839 }
else if (allowsPed) {
1840 if (candidates.size() > 0) {
1846 connectedCandidates.push_back(n);
1853 if (hadCandidates > 0 && candidates.size() > 0) {
1859 connectedCandidates.push_back(n);
1865 std::cout <<
" hadCandidates=" << hadCandidates <<
" connectedCandidates=" <<
toString(connectedCandidates) <<
"\n";
1867 if (hadCandidates == 2 && connectedCandidates.size() == 2) {
1869 if (connectedCandidates.back() <= connectedCandidates.front()) {
1870 numGuessed -= connectedCandidates.back();
1873 numGuessed -= connectedCandidates.front();
1879 std::cout <<
"guessedCrossings:\n";
1881 std::cout <<
" edges=" <<
toString((*it).edges) <<
"\n";
1891 std::cout <<
"checkCrossing candidates=" <<
toString(candidates) <<
"\n";
1893 if (candidates.size() == 0) {
1895 std::cout <<
"no crossing added (numCandidates=" << candidates.size() <<
")\n";
1900 double prevAngle = -100000;
1901 for (
int i = 0; i < (int)candidates.size(); ++i) {
1902 NBEdge* edge = candidates[i];
1907 std::cout <<
"no crossing added (found angle difference of " << fabs(angle - prevAngle) <<
" at i=" << i <<
"\n";
1913 std::cout <<
"no crossing added (uncontrolled, edge with speed > " << edge->
getSpeed() <<
")\n";
1919 if (candidates.size() == 1) {
1922 std::cout <<
"adding crossing: " <<
toString(candidates) <<
"\n";
1927 double prevAngle = -100000;
1928 for (EdgeVector::iterator it = candidates.begin(); it != candidates.end(); ++it) {
1929 double angle = (*it)->getCrossingAngle(
this);
1930 if (it != candidates.begin()) {
1931 NBEdge* prev = *(it - 1);
1936 double intermediateWidth = 0;
1939 prevPos = prev->
getLanes()[laneI].shape[-1];
1942 prevPos = prev->
getLanes()[laneI].shape[0];
1947 currPos = curr->
getLanes()[laneI].shape[0];
1950 currPos = curr->
getLanes()[laneI].shape[-1];
1956 <<
" prevAngle=" << prevAngle
1957 <<
" angle=" << angle
1958 <<
" intermediateWidth=" << intermediateWidth
1971 std::cout <<
"adding crossing: " <<
toString(candidates) <<
"\n";
1982 std::sort(edges.begin(), edges.end());
1987 std::sort(edgesOfCrossing.begin(), edgesOfCrossing.end());
1988 if (edgesOfCrossing == edges) {
1998 for (
int i = startIndex; i < (int)normalizedLanes.size(); ++i) {
1999 if (!normalizedLanes[i].second) {
2012 if (discardInvalid) {
2014 if ((*it).prevWalkingArea ==
"" || (*it).nextWalkingArea ==
"") {
2015 WRITE_WARNING(
"Discarding invalid crossing '" + (*it).id +
"' at junction '" +
getID() +
"' with edges '" +
toString((*it).edges) +
"'.");
2017 if ((*it_wa).nextCrossing == (*it).id) {
2018 (*it_wa).nextCrossing =
"";
2035 int noInternalNoSplits = 0;
2037 const std::vector<NBEdge::Connection>& elv = (*i)->getConnections();
2038 for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
2039 if ((*k).toEdge == 0) {
2042 noInternalNoSplits++;
2048 (*i)->buildInnerEdges(*
this, noInternalNoSplits, lno, splitNo);
2056 (*i)->buildInnerEdges(*
this, noInternalNoSplits, lno, splitNo);
2066 std::cout <<
"build crossings for " <<
getID() <<
":\n";
2076 (*it).nextWalkingArea =
"";
2077 (*it).prevWalkingArea =
"";
2080 std::cout <<
" crossing=" << (*it).id <<
" edges=" <<
toString(edges);
2086 std::cout <<
" sortedEdges=" <<
toString(edges) <<
"\n";
2089 double maxAngleDiff = 0;
2090 int maxAngleDiffIndex = 0;
2091 for (
int i = 0; i < (int) edges.size(); i++) {
2093 edges[(i + 1) % edges.size()]->getAngleAtNodeToCenter(
this));
2098 std::cout <<
" i=" << i <<
" a1=" << edges[i]->getAngleAtNodeToCenter(
this) <<
" a2=" << edges[(i + 1) % edges.size()]->getAngleAtNodeToCenter(
this) <<
" diff=" << diff <<
"\n";
2100 if (diff > maxAngleDiff) {
2101 maxAngleDiff = diff;
2102 maxAngleDiffIndex = i;
2105 if (maxAngleDiff > 2 && maxAngleDiff < 360 - 2) {
2107 std::rotate(edges.begin(), edges.begin() + (maxAngleDiffIndex + 1) % edges.size(), edges.end());
2109 std::cout <<
" rotatedEdges=" <<
toString(edges);
2113 std::reverse(edges.begin(), edges.end());
2115 std::cout <<
" finalEdges=" <<
toString(edges) <<
"\n";
2118 (*it).shape.clear();
2119 const int begDir = (edges.front()->getFromNode() ==
this ?
FORWARD :
BACKWARD);
2120 const int endDir = (edges.back()->getToNode() ==
this ?
FORWARD :
BACKWARD);
2121 if (edges.front()->getFirstNonPedestrianLaneIndex(begDir) < 0
2122 || edges.back()->getFirstNonPedestrianLaneIndex(endDir) < 0) {
2124 WRITE_WARNING(
"Discarding invalid crossing '" + (*it).id +
"' at junction '" +
getID() +
"' with edges '" +
toString((*it).edges) +
"'.");
2127 NBEdge::Lane crossingBeg = edges.front()->getFirstNonPedestrianLane(begDir);
2128 NBEdge::Lane crossingEnd = edges.back()->getFirstNonPedestrianLane(endDir);
2135 (*it).shape.push_back(crossingBeg.
shape[begDir ==
FORWARD ? 0 : -1]);
2136 (*it).shape.push_back(crossingEnd.
shape[endDir ==
FORWARD ? -1 : 0]);
2150 std::cout <<
"build walkingAreas for " <<
getID() <<
":\n";
2157 std::vector<std::pair<NBEdge*, NBEdge::Lane> > normalizedLanes;
2158 for (EdgeVector::const_iterator it = allEdges.begin(); it != allEdges.end(); ++it) {
2160 const std::vector<NBEdge::Lane>& lanes = edge->
getLanes();
2162 for (std::vector<NBEdge::Lane>::const_reverse_iterator it_l = lanes.rbegin(); it_l != lanes.rend(); ++it_l) {
2166 normalizedLanes.push_back(std::make_pair(edge, l));
2169 for (std::vector<NBEdge::Lane>::const_iterator it_l = lanes.begin(); it_l != lanes.end(); ++it_l) {
2174 normalizedLanes.push_back(std::make_pair(edge, l));
2180 std::vector<std::pair<int, int> > waIndices;
2182 NBEdge* prevEdge = normalizedLanes.back().first;
2183 for (
int i = 0; i < (int)normalizedLanes.size(); ++i) {
2184 NBEdge* edge = normalizedLanes[i].first;
2192 waIndices.push_back(std::make_pair(start, i - start));
2202 <<
" waI=" << waIndices.size() <<
" crossingBetween=" <<
crossingBetween(edge, prevEdge) <<
"\n";
2207 const int waNumLanes = (int)normalizedLanes.size() - start;
2208 if (waIndices.size() == 0) {
2209 waIndices.push_back(std::make_pair(start, waNumLanes));
2211 std::cout <<
" single wa, end at wrap-around\n";
2214 if (waIndices.front().first == 0) {
2215 NBEdge* edge = normalizedLanes.front().first;
2216 NBEdge* prevEdge = normalizedLanes.back().first;
2219 waIndices.push_back(std::make_pair(start, waNumLanes));
2221 std::cout <<
" do not wrap around, turn-around in between\n";
2225 waIndices.front().first = start;
2226 waIndices.front().second = waNumLanes + waIndices.front().second;
2228 std::cout <<
" wrapping around\n";
2233 waIndices.push_back(std::make_pair(start, waNumLanes));
2235 std::cout <<
" end at wrap-around\n";
2241 std::cout <<
" normalizedLanes=" << normalizedLanes.size() <<
" waIndices:\n";
2242 for (
int i = 0; i < (int)waIndices.size(); ++i) {
2243 std::cout <<
" " << waIndices[i].first <<
", " << waIndices[i].second <<
"\n";
2247 for (
int i = 0; i < (int)waIndices.size(); ++i) {
2248 const bool buildExtensions = waIndices[i].second != (int)normalizedLanes.size();
2249 const int start = waIndices[i].first;
2250 const int prev = start > 0 ? start - 1 : (int)normalizedLanes.size() - 1;
2251 const int count = waIndices[i].second;
2252 const int end = (start + count) % normalizedLanes.size();
2256 std::cout <<
"build walkingArea " << wa.
id <<
" start=" << start <<
" end=" << end <<
" count=" << count <<
" prev=" << prev <<
":\n";
2258 double endCrossingWidth = 0;
2259 double startCrossingWidth = 0;
2263 bool connectsCrossing =
false;
2264 std::vector<Position> connectedPoints;
2267 std::cout <<
" crossing=" << (*it).id <<
" sortedEdges=" <<
toString((*it).edges) <<
"\n";
2269 if ((*it).edges.back() == normalizedLanes[end].first
2270 && (normalizedLanes[end].second.permissions &
SVC_PEDESTRIAN) == 0) {
2272 if ((*it).nextWalkingArea !=
"") {
2274 +
"'; crossing '" + (*it).id
2275 +
"' targets '" + (*it).nextWalkingArea
2276 +
"' and '" + wa.
id +
"'.");
2278 (*it).nextWalkingArea = wa.
id;
2279 endCrossingWidth = (*it).width;
2280 endCrossingShape = (*it).shape;
2282 connectsCrossing =
true;
2283 connectedPoints.push_back((*it).shape[-1]);
2285 std::cout <<
" crossing " << (*it).id <<
" ends\n";
2288 if ((*it).edges.front() == normalizedLanes[prev].first
2289 && (normalizedLanes[prev].second.permissions &
SVC_PEDESTRIAN) == 0) {
2291 if ((*it).prevWalkingArea !=
"") {
2293 +
"'; crossing '" + (*it).id
2294 +
"' is targeted by '" + (*it).prevWalkingArea
2295 +
"' and '" + wa.
id +
"'.");
2297 (*it).prevWalkingArea = wa.
id;
2299 startCrossingWidth = (*it).width;
2300 startCrossingShape = (*it).shape;
2302 connectsCrossing =
true;
2303 connectedPoints.push_back((*it).shape[0]);
2305 std::cout <<
" crossing " << (*it).id <<
" starts\n";
2308 if (
gDebugFlag1) std::cout <<
" check connections to crossing " << (*it).id
2309 <<
" cFront=" << (*it).edges.front()->getID() <<
" cBack=" << (*it).edges.back()->getID()
2310 <<
" wEnd=" << normalizedLanes[end].first->getID() <<
" wStart=" << normalizedLanes[start].first->getID()
2311 <<
" wStartPrev=" << normalizedLanes[prev].first->getID()
2314 if (count < 2 && !connectsCrossing) {
2317 std::cout <<
" not relevant for walking: count=" << count <<
" connectsCrossing=" << connectsCrossing <<
"\n";
2322 std::set<NBEdge*> connected;
2323 for (
int j = 0; j < count; ++j) {
2324 const int nlI = (start + j) % normalizedLanes.size();
2325 NBEdge* edge = normalizedLanes[nlI].first;
2328 if (connected.count(edge) == 0) {
2336 connected.insert(edge);
2343 if (buildExtensions) {
2345 if (startCrossingShape.size() > 0) {
2347 std::cout <<
" extension at startCrossing shape=" << startCrossingShape <<
"\n";
2349 startCrossingShape.
move2side(startCrossingWidth / 2);
2351 startCrossingShape.
move2side(-startCrossingWidth);
2355 if (endCrossingShape.size() > 0) {
2357 std::cout <<
" extension at endCrossing shape=" << endCrossingShape <<
"\n";
2359 endCrossingShape.
move2side(endCrossingWidth / 2);
2361 endCrossingShape.
move2side(-endCrossingWidth);
2366 && normalizedLanes.size() == 2) {
2368 NBEdge* e1 = *connected.begin();
2369 NBEdge* e2 = *(++connected.begin());
2372 std::cout <<
" not building a walkingarea since normal connections exist\n";
2378 if (cornerDetail > 0) {
2379 int smoothEnd = end;
2380 int smoothPrev = prev;
2382 if (endCrossingWidth > 0 && normalizedLanes[smoothEnd].second.permissions == 0) {
2383 smoothEnd = (smoothEnd + 1) % normalizedLanes.size();
2385 if (startCrossingWidth > 0 && normalizedLanes[smoothPrev].second.permissions == 0) {
2386 if (smoothPrev == 0) {
2387 smoothPrev = (int)normalizedLanes.size() - 1;
2392 PositionVector begShape = normalizedLanes[smoothEnd].second.shape;
2393 begShape = begShape.
reverse();
2395 begShape.
move2side(normalizedLanes[smoothEnd].second.width / 2);
2396 PositionVector endShape = normalizedLanes[smoothPrev].second.shape;
2397 endShape.
move2side(normalizedLanes[smoothPrev].second.width / 2);
2401 <<
" end=" << smoothEnd <<
" prev=" << smoothPrev
2402 <<
" endCrossingWidth=" << endCrossingWidth <<
" startCrossingWidth=" << startCrossingWidth
2403 <<
" begShape=" << begShape <<
" endShape=" << endShape <<
" smooth curve=" << curve <<
"\n";
2404 if (curve.size() > 2) {
2405 curve.erase(curve.begin());
2407 if (endCrossingWidth > 0) {
2408 wa.
shape.pop_back();
2410 if (startCrossingWidth > 0) {
2417 double lengthSum = 0;
2418 int combinations = 0;
2419 for (std::vector<Position>::const_iterator it1 = connectedPoints.begin(); it1 != connectedPoints.end(); ++it1) {
2420 for (std::vector<Position>::const_iterator it2 = connectedPoints.begin(); it2 != connectedPoints.end(); ++it2) {
2430 std::cout <<
" combinations=" << combinations <<
" connectedPoints=" << connectedPoints <<
"\n";
2433 if (combinations > 0) {
2443 std::cout <<
" checkIntermediate: prev=" << prev.
id <<
" next=" << next.
id <<
" prev.nextWA=" << prev.
nextWalkingArea <<
"\n";
2447 WRITE_WARNING(
"Invalid pedestrian topology: crossing '" + prev.
id +
"' has no target.");
2457 wa.
shape.push_back(tmp[-1]);
2459 wa.
shape.push_back(tmp[-1]);
2463 wa.
shape.push_back(tmp[0]);
2465 wa.
shape.push_back(tmp[0]);
2470 std::cout <<
" build wa=" << wa.
id <<
"\n";
2484 EdgeVector::const_iterator it1 = find(edges.begin(), edges.end(), e1);
2485 EdgeVector::const_iterator it2 = find(edges.begin(), edges.end(), e2);
2486 if (it1 != edges.end() && it2 != edges.end()) {
2502 while (it != it_end) {
2503 result.push_back(*it);
2524 if (
MAX2(angle0, angle1) <= 160) {
2554 EdgeSet edgeSet(edges.begin(), edges.end());
2556 EdgeSet edgeSet2((*it).edges.begin(), (*it).edges.end());
2557 if (edgeSet == edgeSet2) {
2569 if ((*it).id ==
id) {
2573 throw ProcessError(
"Request for unknown crossing '" +
id +
"'");
2579 if ((*it).id ==
id) {
2583 throw ProcessError(
"Request for unknown crossing '" +
id +
"'");
2590 (*it).tlLinkNo = startIndex++;
2606 const std::vector<NBEdge::Connection>& elv = (*i)->getConnections();
2607 for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
2643 std::cout <<
" angles:\n";
2644 for (EdgeVector::const_iterator it = result.begin(); it != result.end(); ++it) {
2645 std::cout <<
" edge=" << (*it)->getID() <<
" edgeAngle=" << (*it)->getAngleAtNode(
this) <<
" angleToShape=" << (*it)->getAngleAtNodeToCenter(
this) <<
"\n";
2647 std::cout <<
" allEdges before: " <<
toString(result) <<
"\n";
2652 std::cout <<
" allEdges sorted: " <<
toString(result) <<
"\n";
2654 rotate(result.begin(), std::find(result.begin(), result.end(), *
myAllEdges.begin()), result.end());
2656 std::cout <<
" allEdges rotated: " <<
toString(result) <<
"\n";
2667 assert(
id[0] ==
':');
2668 std::string::size_type sep_index =
id.rfind(
'_');
2669 if (sep_index == std::string::npos) {
2670 WRITE_ERROR(
"Invalid lane id '" +
id +
"' (missing '_').");
2673 sep_index =
id.substr(0, sep_index).rfind(
'_');
2674 if (sep_index == std::string::npos) {
2675 WRITE_ERROR(
"Invalid lane id '" +
id +
"' (missing '_').");
2678 return id.substr(1, sep_index - 1);
2688 if (turnDest != 0) {
2709 if ((*i)->rightOnRedConflict(index, foeIndex)) {
2726 std::vector<NBNode::Crossing>& crossings =
myCrossings;
2734 std::vector<NBEdge*>::iterator j;
2735 for (j = allEdges.begin(); j != allEdges.end() - 1 && j != allEdges.end(); ++j) {
2738 if (allEdges.size() > 1 && j != allEdges.end()) {
2742 NBEdge* firstOfAll = allEdges.front();
2743 NBEdge* firstOfIncoming = incoming.size() > 0 ? incoming.front() : 0;
2744 NBEdge* firstOfOutgoing = outgoing.size() > 0 ? outgoing.front() : 0;
2750 rotate(allEdges.begin(), std::find(allEdges.begin(), allEdges.end(), firstOfAll), allEdges.end());
2751 if (firstOfIncoming != 0) {
2752 rotate(incoming.begin(), std::find(incoming.begin(), incoming.end(), firstOfIncoming), incoming.end());
2754 if (firstOfOutgoing != 0) {
2755 rotate(outgoing.begin(), std::find(outgoing.begin(), outgoing.end(), firstOfOutgoing), outgoing.end());
2760 if (incoming.size() == outgoing.size() && incoming.front() == allEdges.front()) {
2761 std::vector<NBEdge*>::const_iterator in, out;
2762 std::vector<NBEdge*> allTmp;
2763 for (in = incoming.begin(), out = outgoing.begin(); in != incoming.end(); ++in, ++out) {
2764 if ((*in)->isTurningDirectionAt(*out)) {
2765 allTmp.push_back(*in);
2766 allTmp.push_back(*out);
2771 if (allTmp.size() == allEdges.size()) {
static double relAngle(double angle1, double angle2)
computes the relative angle between the two angles
bool gDebugFlag1
global utility flags for debugging
bool around(const Position &p, double offset=0) const
Returns the information whether the position vector describes a polygon lying around the given point...
std::pair< int, int > getSizes() const
returns the number of the junction's lanes and the number of the junction's links in respect...
int getConnectionIndex(const NBEdge *from, const NBEdge::Connection &con) const
return the index of the given connection
The link is a partial left direction.
void replaceOutgoing(const EdgeVector &which, NBEdge *const by)
Replaces outgoing edges from the vector (source) by the given edge.
A structure which describes a connection between edges or lanes.
LinkState getLinkState(const NBEdge *incoming, NBEdge *outgoing, int fromLane, int toLane, bool mayDefinitelyPass, const std::string &tlID) const
get link state
int toLane
The lane the connections yields in.
void setRoundabout()
update the type of this node as a roundabout
int numNormalConnections() const
return the number of lane-to-lane connections at this junction (excluding crossings) ...
std::vector< Crossing > myCrossings
Vector of crossings.
bool foes(const NBEdge *const from1, const NBEdge *const to1, const NBEdge *const from2, const NBEdge *const to2) const
Returns the information whether the given flows cross.
ApproachingDivider(EdgeVector *approaching, NBEdge *currentOutgoing)
Constructor.
PositionVector shape
The lane's shape.
virtual void addNode(NBNode *node)
Adds a node to the traffic light logic.
int buildCrossings()
build pedestrian crossings
void append(const PositionVector &v, double sameThreshold=2.0)
double z() const
Returns the z-position.
bool isInStringVector(const std::string &optionName, const std::string &itemName)
Returns the named option is a list of string values containing the specified item.
Sorts incoming and outgoing edges clockwise around the given node.
std::string viaID
if Connection have a via, ID of it
double 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) ...
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
EdgeVector getIncomingEdges() const
Returns the list of incoming edges unsorted.
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)
the bresenham-callback
bool isConnectedTo(const NBEdge *e) const
Returns the information whethe a connection to the given edge has been added (or computed) ...
static double normRelAngle(double angle1, double angle2)
ensure that reverse relAngles (>=179.999) always count as turnarounds (-180)
bool isDistrict() const
check if node is a district
SumoXMLNodeType myType
The type of the junction.
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
A container for traffic light definitions and built programs.
void reinit(const Position &position, SumoXMLNodeType type, bool updateEdgeGeometries=false)
Resets initial values.
PositionVector computeInternalLaneShape(NBEdge *fromE, const NBEdge::Connection &con, int numPoints, NBNode *recordError=0) const
Compute the shape for an internal lane.
Position positionAtOffset2D(double pos, double lateralOffset=0) const
Returns the position at the given length.
Some static methods for string processing.
int getJunctionPriority(const NBNode *const node) const
Returns the junction priority (normalised for the node currently build)
int myCrossingsLoadedFromSumoNet
number of crossings loaded from a sumo net
This class computes shapes of junctions.
This is an uncontrolled, minor link, has to stop.
double length
This lane's width.
void removeEdge(NBEdge *edge, bool removeFromConnections=true)
Removes edge from this node and optionally removes connections as well.
const double SUMO_const_laneWidth
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.
double y() const
Returns the y-position.
void addIncomingEdge(NBEdge *edge)
adds an incoming edge
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
The representation of a single edge during network building.
TrafficLightType getType() const
get the algorithm type (static etc..)
static double getCCWAngleDiff(double angle1, double angle2)
Returns the distance of second angle from first angle counter-clockwise.
Class to sort edges by their angle in relation to the given edge.
bool replaceTo(NBEdge *which, NBEdge *by)
replaces the to-edge by the one given
static const double DEFAULT_CROSSING_WIDTH
default width of pedetrian crossings
The link is a 180 degree turn.
static const double UNSPECIFIED_RADIUS
unspecified lane width
double x() const
Returns the x-position.
A container for districts.
The base class for traffic light logic definitions.
static bool isLongEnough(NBEdge *out, double minLength)
check if is long enough
void buildBitfieldLogic()
bool isInnerEdge() const
Returns whether this edge was marked as being within an intersection.
void removeDoubleEdges()
remove duble edges
double angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position ...
#define SUMO_MAX_CONNECTIONS
the maximum number of connections across an intersection
bool rightOnRedConflict(int index, int foeIndex) const
whether the given index must yield to the foeIndex while turing right on a red light ...
NBEdge * getTurnDestination(bool possibleDestination=false) const
PositionVector shape
The lane's shape.
#define SPLIT_CROSSING_ANGLE_THRESHOLD
const std::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
PositionVector reverse() const
reverse position vector
void buildWalkingAreas(int cornerDetail)
build pedestrian walking areas and set connections from/to walkingAreas
NBEdge * getFrom() const
returns the from-edge (start of the connection)
This is an uncontrolled, right-before-left link.
static void nextCW(const EdgeVector &edges, EdgeVector::const_iterator &from)
bool isForbidden(SVCPermissions permissions)
Returns whether an edge with the given permission is a forbidden edge.
void remapConnections(const EdgeVector &incoming)
Remaps the connection in a way that allows the removal of it.
std::string id
the (edge)-id of this walkingArea
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
bool connectionsDone
Whether connection information for this lane is already completed.
const std::string & getID() const
Returns the id.
void mirrorX()
mirror coordinates along the x-axis
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission is a railway edge.
std::vector< int > getConnectionLanes(NBEdge *currentOutgoing) const
Returns the list of lanes that may be used to reach the given edge.
Lane & getLaneStruct(int lane)
void set(double x, double y)
set positions x and y
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
The container for connection block dependencies.
This is an uncontrolled, all-way stop link.
void addOutgoingEdge(NBEdge *edge)
adds an outgoing edge
const Crossing & getCrossing(const std::string &id) const
return the crossing with the given id
std::string getDescription(const NBEdge *parent) const
get string describing this connection
static const double UNSPECIFIED_WIDTH
unspecified lane width
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)
void sortEdges(bool useNodeShape)
sort all edge containers for this node
The connection was computed and validated.
static OptionsCont & getOptions()
Retrieves the options.
bool setConnection(int lane, NBEdge *destEdge, int destLane, Lane2LaneInfoType type, bool mayUseSameDestination=false, bool mayDefinitelyPass=false, bool keepClear=true, double contPos=UNSPECIFIED_CONTPOS, double visibility=UNSPECIFIED_VISIBILITY_DISTANCE)
Adds a connection to a certain lane of a certain edge.
Position getCenter() const
Returns a position that is guaranteed to lie within the node shape.
static bool rightTurnConflict(const NBEdge *from, const NBEdge *to, int fromLane, const NBEdge *prohibitorFrom, const NBEdge *prohibitorTo, int prohibitorFromLane, bool lefthand=false)
return whether the given laneToLane connection is a right turn which must yield to a bicycle crossing...
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges (The edges which start at this node)
NBRequest * myRequest
Node requests.
int getFirstNonPedestrianLaneIndex(int direction, bool exclusive=false) const
return the first lane with permissions other than SVC_PEDESTRIAN and 0
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)...
double area() const
Returns the area (0 for non-closed)
CustomShapeMap myCustomLaneShapes
custom lane shapes
The link is a straight direction.
SUMOTime getOffset()
Returns the offset.
PositionVector shape
shape of Connection
NBDistrict * myDistrict
The district the node is the centre of.
A class representing a single district.
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.
NBEdge * getConnectionTo(NBNode *n) const
get connection to certain node
An (internal) definition of a single lane of an edge.
static bool mustBrakeForCrossing(const NBNode *node, const NBEdge *const from, const NBEdge *const to, const NBNode::Crossing &crossing)
Returns the information whether the described flow must brake for the given crossing.
EdgeVector myAllEdges
Vector of incoming and outgoing edges.
SVCPermissions permissions
List of vehicle types that are allowed on this lane.
void computeLanes2Lanes()
computes the connections of lanes to edges
static void swapWhenReversed(const NBNode *const n, const std::vector< NBEdge *>::iterator &i1, const std::vector< NBEdge *>::iterator &i2)
Assures correct order for same-angle opposite-direction edges.
void extrapolate2D(const double val, const bool onlyFirst=false)
extrapolate position vector in two dimensions (Z is ignored)
bool isTLControlled() const
Returns whether this node is controlled by any tls.
bool writeLogic(OutputDevice &into, const bool checkLaneFoes) const
writes the XML-representation of the logic as a bitset-logic XML representation
void invalidateIncomingConnections()
invalidate incoming connections
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)
void computeNodeShape(double mismatchThreshold)
Compute the junction shape for this node.
bool replaceFrom(NBEdge *which, NBEdge *by)
replaces the from-edge by the one given
std::set< NBEdge * > EdgeSet
container for unique edges
Lanes to lanes - relationships are loaded; no recheck is necessary/wished.
std::string prevWalkingArea
the lane-id of the previous walkingArea
NBEdge * getPossiblySplittedIncoming(const std::string &edgeid)
get possibly splitted incoming edge
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
void buildCrossingsAndWalkingAreas(bool discardInvalid=true)
build crossings, and walkingareas. Also removes invalid loaded crossings if wished ...
int checkCrossing(EdgeVector candidates)
static const int FORWARD
edge directions (for pedestrian related stuff)
void remapRemoved(NBEdge *removed, const EdgeVector &incoming, const EdgeVector &outgoing)
Replaces occurences of the removed edge in incoming/outgoing edges of all definitions.
std::string tlID
The id of the traffic light that controls this connection.
bool forbids(const NBEdge *const possProhibitorFrom, const NBEdge *const possProhibitorTo, const NBEdge *const possProhibitedFrom, const NBEdge *const possProhibitedTo, bool regardNonSignalisedLowerPriority) const
Returns the information whether "prohibited" flow must let "prohibitor" flow pass.
void setCrossingTLIndices(const std::string &tlID, int startIndex)
set tl indices of this nodes crossing starting at the given index
This is an uncontrolled, minor link, has to brake.
int getNumLanes() const
Returns the number of lanes.
int fromLane
The lane the connections starts at.
A point in 2D or 3D with translation and scaling methods.
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.
static double getCWAngleDiff(double angle1, double angle2)
Returns the distance of second angle from first angle clockwise.
Position getPolygonCenter() const
Returns the arithmetic of all corner points.
bool crossingBetween(const NBEdge *e1, const NBEdge *e2) const
return true if the given edges are connected by a crossing
bool hasConnectionTo(NBEdge *destEdge, int destLane, int fromLane=-1) const
Retrieves info about a connection to a certain lane of a certain edge.
void invalidateOutgoingConnections()
invalidate outgoing connections
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
void removeTrafficLights()
Removes all references to traffic lights that control this tls.
EdgeVector * getEdgesThatApproach(NBEdge *currentOutgoing)
returns a list of edges which are connected to the given outgoing edge
bool geometryLike() const
whether this is structurally similar to a geometry node
std::set< NBTrafficLightDefinition * > myTrafficLights
traffic lights of node
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
std::string nextCrossing
the lane-id of the next crossing
The link is a (hard) right direction.
EdgeBuildingStep getStep() const
The building step of this edge.
double getAngleAtNode(const NBNode *const node) const
Returns the angle of the edge's geometry at the given node.
bool hasOutgoing(const NBEdge *const e) const
Returns whether the given edge starts at this node.
bool myDiscardAllCrossings
whether to discard all pedestrian crossings
PositionVector getSubpart(double beginOffset, double endOffset) const
get subpart of a position vector
void replaceInConnectionProhibitions(NBEdge *which, NBEdge *by, int whichLaneOff, int byLaneOff)
replace incoming connections prohibitions
PositionVector getSubpartByIndex(int beginIndex, int count) const
get subpart of a position vector using index and a cout
PositionVector compute()
Computes the shape of the assigned junction.
double myRadius
the turning radius (for all corners) at this node in m.
The link is a partial right direction.
double width
This lane's width.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
std::set< SVCPermissions > getPermissionVariants(int iStart, int iEnd) const
return all permission variants within the specified lane range [iStart, iEnd[
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
bool foes(const NBEdge *const from1, const NBEdge *const to1, const NBEdge *const from2, const NBEdge *const to2) const
Returns the information whether the given flows cross.
void move2side(double amount)
move position vector to side using certain ammount
virtual void removeNode(NBNode *node)
Removes the given node from the list of controlled nodes.
EdgeVector myIncomingEdges
Vector of incoming edges.
Base class for objects which have an id.
bool hasIncoming(const NBEdge *const e) const
Returns whether the given edge ends at this node.
std::vector< NBConnection > NBConnectionVector
Definition of a connection vector.
void avoidOverlap()
fix overlap
PositionVector computeSmoothShape(const PositionVector &begShape, const PositionVector &endShape, int numPoints, bool isTurnaround, double extrapolateBeg, double extrapolateEnd, NBNode *recordError=0) const
Compute a smooth curve between the given geometries.
NBEdge * getPossiblySplittedOutgoing(const std::string &edgeid)
get possibly splitted outgoing edge
LinkDirection getDirection(const NBEdge *const incoming, const NBEdge *const outgoing, bool leftHand=false) const
Returns the representation of the described stream's direction.
const PositionVector & getShape() const
retrieve the junction shape
double getSpeed() const
Returns the speed allowed on this edge.
NBEdge * getTo() const
returns the to-edge (end of the connection)
int internalLaneIndex
The lane index of this internal lane within the internal edge.
EdgeVector myOutgoingEdges
Vector of outgoing edges.
NBEdge * myCurrentOutgoing
The approached current edge.
double getLaneWidth() const
Returns the default width of lanes of this edge.
double myDisplacementError
geometry error after computation of internal lane shapes
static const int BACKWARD
std::string myID
The name of the object.
void extrapolate(const double val, const bool onlyFirst=false, const bool onlyLast=false)
extrapolate position vector
void addTrafficLight(NBTrafficLightDefinition *tlDef)
Adds a traffic light to the list of traffic lights that control this node.
double width
This lane's width.
bool myHaveCustomPoly
whether this nodes shape was set by the user
Position myPosition
The position the node lies at.
bool checkCrossingDuplicated(EdgeVector edges)
return true if already exist a crossing with the same edges as the input
std::map< NBConnection, NBConnectionVector > NBConnectionProhibits
Definition of a container for connection block dependencies Includes a list of all connections which ...
int removeSelfLoops(NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tc)
Removes edges which are both incoming and outgoing into this node.
PositionVector viaShape
shape of via
~ApproachingDivider()
Destructor.
std::vector< WalkingArea > myWalkingAreas
Vector of walking areas.
const PositionVector & getLaneShape(int i) const
Returns the shape of the nth lane.
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges (The edges which yield in this node)
const std::vector< Connection > & getConnections() const
Returns the connections.
void replaceIncoming(NBEdge *which, NBEdge *by, int laneOff)
Replaces occurences of the first edge within the list of incoming by the second Connections are remap...
SumoXMLNodeType
Numbers representing special SUMO-XML-attribute values for representing node- (junction-) types used ...
bool isNearDistrict() const
if node is near district
bool myKeepClear
whether the junction area must be kept clear
std::vector< int > myAvailableLanes
The available lanes to which connections shall be built.
double getCrossingAngle(NBNode *node)
return the angle for computing pedestrian crossings at the given node
The link is controlled by a tls which is off and blinks, has to brake.
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
bool forbids(const NBEdge *const possProhibitorFrom, const NBEdge *const possProhibitorTo, const NBEdge *const possProhibitedFrom, const NBEdge *const possProhibitedTo, bool regardNonSignalisedLowerPriority) const
Returns the information whether "prohibited" flow must let "prohibitor" flow pass.
void buildInnerEdges()
build internal lanes, pedestrian crossings and walking areas
static const int UNSPECIFIED_INTERNAL_LANE_INDEX
internal lane computation not yet done
void writeLogic(std::string key, OutputDevice &into, const bool checkLaneFoes) const
A definition of a pedestrian walking area.
EdgeVector * myApproaching
The list of edges that approach the current edge.
const std::vector< NBNode * > & getNodes() const
Returns the list of controlled nodes.
A storage for options typed value containers)
double angleAt2D(int pos) const
get angle in certain position of position vector
void erase(NBDistrictCont &dc, NBEdge *edge)
Removes the given edge from the container (deleting it)
Position getEmptyDir() const
Returns something like the most unused direction Should only be used to add source or sink nodes...
This is an uncontrolled, major link, may pass.
bool needsCont(const NBEdge *fromE, const NBEdge *otherFromE, const NBEdge::Connection &c, const NBEdge::Connection &otherC) const
whether an internal junction should be built at from and respect other
double getStartAngle() const
Returns the angle at the start of the edge (relative to the node shape center) The angle is computed ...
int numAvailableLanes() const
@ get number of avaliable lanes
EdgeVector getEdgesSortedByAngleAtNodeCenter() const
returns the list of all edges sorted clockwise by getAngleAtNodeToCenter
bool isTurningDirectionAt(const NBEdge *const edge) const
Returns whether the given edge is the opposite direction to this edge.
The connection was computed.
const Position & getPosition() const
Represents a single node (junction) during network building.
bool removeFully(const std::string id)
Removes a logic definition (and all programs) from the dictionary.
void addCrossing(EdgeVector edges, double width, bool priority, bool fromSumoNet=false)
add a pedestrian crossing to this node
Lanes to lanes - relationships are computed; no recheck is necessary/wished.
The link is a 180 degree turn (left-hand network)
int guessCrossings()
guess pedestrian crossings and return how many were guessed
A definition of a pedestrian crossing.
bool insert(NBTrafficLightDefinition *logic, bool forceInsert=false)
Adds a logic definition to the dictionary.
void replaceInConnections(NBEdge *which, NBEdge *by, int laneOff)
replace in current connections of edge
Crossing & getCrossingRef(const std::string &id)
return a reference to the crossing with the given id
void addSortedLinkFoes(const NBConnection &mayDrive, const NBConnection &mustStop)
add shorted link FOES
EdgeVector getConnectedEdges() const
Returns the list of outgoing edges unsorted.
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.
bool mustBrakeForCrossing(const NBEdge *const from, const NBEdge *const to, const Crossing &crossing) const
Returns the information whether the described flow must brake for the given crossing.
NBEdge * getOppositeIncoming(NBEdge *e) const
returns the opposite incoming edge of certain edge
bool isJoinedTLSControlled() const
Returns whether this node is controlled by a tls that spans over more than one node.
void push_back_noDoublePos(const Position &p)
insert in back a non double position
bool isLeftMover(const NBEdge *const from, const NBEdge *const to) const
Computes whether the given connection is a left mover across the junction.
#define SPLIT_CROSSING_WIDTH_THRESHOLD
NBNode * getFromNode() const
Returns the origin node of the edge.
void computeLogic(const NBEdgeCont &ec, OptionsCont &oc)
computes the node's type, logic and traffic light
void mul(double val)
Multiplies both positions with the given value.
std::string getInternalLaneID() const
get ID of internal lane
static double angleDiff(const double angle1, const double angle2)
Returns the difference of the second angle to the first angle in radiants.
A traffic light logics which must be computed (only nodes/edges are given)
double getLoadedLength() const
Returns the length was set explicitly or the computed length if it wasn't set.
void add(double xoff, double yoff, double zoff)
void invalidateTLS(NBTrafficLightLogicCont &tlCont)
causes the traffic light to be computed anew
std::string nextWalkingArea
the lane-id of the next walkingArea
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
std::deque< int > * spread(const std::vector< int > &approachingLanes, int dest) const
the method that spreads the wished number of lanes from the the lane given by the bresenham-call to b...
void closePolygon()
ensures that the last position equals the first
Lanes to edges - relationships are computed/loaded.
bool checkIsRemovable() const
check if node is removable
NBNode(const std::string &id, const Position &position, SumoXMLNodeType type)
Constructor.
std::vector< std::pair< NBEdge *, NBEdge * > > getEdgesToJoin() const
get edges to join
static PositionVector bezierControlPoints(const PositionVector &begShape, const PositionVector &endShape, bool isTurnaround, double extrapolateBeg, double extrapolateEnd, bool &ok, NBNode *recordError=0, double straightThresh=DEG2RAD(5))
get bezier control points
NBNode * getToNode() const
Returns the destination node of the edge.
std::vector< std::string > prevSidewalks
the lane-id of the previous sidewalk lane or ""
static bool isTrafficLight(SumoXMLNodeType type)
return whether the given type is a traffic light
void shiftPositionAtNode(NBNode *node, NBEdge *opposite)
shift geometry at the given node to avoid overlap
std::vector< std::string > nextSidewalks
the lane-id of the next sidewalk lane or ""
static void nextCCW(const EdgeVector &edges, EdgeVector::const_iterator &from)
bool isSimpleContinuation(bool checkLaneNumbers=true) const
check if node is a simple continuation
void reshiftPosition(double xoff, double yoff)
Applies an offset to the node.
void remapRemoved(NBTrafficLightLogicCont &tc, NBEdge *removed, const EdgeVector &incoming, const EdgeVector &outgoing)
remap removed
PositionVector shape
The polygonal shape.
static const Position INVALID
used to indicate that a position is valid
double getEndAngle() const
Returns the angle at the end of the edge (relative to the node shape center) The angle is computed in...
void replaceIncoming(const EdgeVector &which, NBEdge *const by)
Replaces incoming edges from the vector (sinks) by the given edge.
The link has no direction (is a dead end link)
double width
This lane's width.
bool forbidsPedestriansAfter(std::vector< std::pair< NBEdge *, bool > > normalizedLanes, int startIndex)
return whether there is a non-sidewalk lane after the given index;
void bezier(int npts, double b[], int cpts, double p[])
void sub(double dx, double dy)
Substracts the given position from this one.
EdgeVector edgesBetween(const NBEdge *e1, const NBEdge *e2) const
return all edges that lie clockwise between the given edges
static std::string getNodeIDFromInternalLane(const std::string id)
returns the node id for internal lanes, crossings and walkingareas