70 #define EXTEND_CROSSING_ANGLE_THRESHOLD 35.0 // degrees 72 #define SPLIT_CROSSING_WIDTH_THRESHOLD 1.5 // meters 73 #define SPLIT_CROSSING_ANGLE_THRESHOLD 5 // degrees 76 #define MIN_WEAVE_LENGTH 20.0 80 #define DEBUGCOND true 98 myApproaching(approaching), myCurrentOutgoing(currentOutgoing) {
102 std::set<int> approachedLanes;
104 const std::vector<NBEdge::Connection> conns = (*it)->getConnections();
105 for (std::vector<NBEdge::Connection>::const_iterator it_con = conns.begin(); it_con != conns.end(); ++it_con) {
107 approachedLanes.insert((*it_con).toLane);
115 for (
int i = 0; i < currentOutgoing->
getNumLanes(); ++i) {
118 && approachedLanes.count(i) == 0) {
133 NBEdge* incomingEdge = (*myApproaching)[src];
137 std::vector<int> approachingLanes =
139 assert(approachingLanes.size() != 0);
140 std::deque<int>* approachedLanes =
spread(approachingLanes, dest);
143 for (
int i = 0; i < (int)approachedLanes->size(); i++) {
144 assert((
int)approachingLanes.size() > i);
149 delete approachedLanes;
156 std::deque<int>* ret =
new std::deque<int>();
157 int noLanes = (int) approachingLanes.size();
161 ret->push_back(dest);
167 ret->push_back(dest);
171 while (noSet < noLanes) {
177 if (noOutgoingLanes == noSet) {
186 if (dest + loffset >= noOutgoingLanes) {
189 for (
int i = 0; i < (int)ret->size(); i++) {
190 (*ret)[i] = (*ret)[i] - 1;
195 ret->push_back(dest + loffset);
200 if (noOutgoingLanes == noSet) {
205 if (noSet < noLanes) {
208 if (dest < roffset) {
211 for (
int i = 0; i < (int)ret->size(); i++) {
212 (*ret)[i] = (*ret)[i] + 1;
215 ret->push_front(dest - roffset);
265 bool updateEdgeGeometries) {
272 if (updateEdgeGeometries) {
276 (*i)->setGeometry(geom);
281 (*i)->setGeometry(geom);
305 (*it_wa).shape.mirrorX();
331 for (std::set<NBTrafficLightDefinition*>::const_iterator i = trafficLights.begin(); i != trafficLights.end(); ++i) {
341 for (std::set<NBTrafficLightDefinition*>::iterator it = oldDefs.begin(); it != oldDefs.end(); ++it) {
343 if (dynamic_cast<NBLoadedSUMOTLDef*>(orig) != 0) {
344 dynamic_cast<NBLoadedSUMOTLDef*
>(orig)->registerModifications(removedConnections, addedConnections);
345 }
else if (dynamic_cast<NBOwnTLDef*>(orig) == 0) {
347 const std::vector<NBNode*>& nodes = orig->
getNodes();
348 while (!nodes.empty()) {
349 newDef->
addNode(nodes.front());
350 nodes.front()->removeTrafficLight(orig);
363 (*it)->shiftTLConnectionLaneIndex(edge, offset);
390 remapRemoved(tc, dummy, incomingConnected, outgoingConnected);
439 if (checkLaneNumbers && in->
getNumLanes() != (*opposite)->getNumLanes()) {
455 double extrapolateBeg,
456 double extrapolateEnd,
457 NBNode* recordError)
const {
461 #ifdef DEBUG_SMOOTH_GEOM 463 std::cout <<
"computeSmoothShape node " <<
getID() <<
" init=" << init <<
"\n";
466 if (init.size() == 0) {
468 ret.push_back(begShape.back());
469 ret.push_back(endShape.front());
472 return bezier(init, numPoints).smoothedZFront();
481 double extrapolateBeg,
482 double extrapolateEnd,
485 double straightThresh) {
487 const Position beg = begShape.back();
488 const Position end = endShape.front();
492 #ifdef DEBUG_SMOOTH_GEOM 493 if (
DEBUGCOND) std::cout <<
" bezierControlPoints failed beg=" << beg <<
" end=" << end
509 center.
sub(beg.
y() - end.
y(), end.
x() - beg.
x());
510 init.push_back(center);
515 endShapeBegLine.extrapolate2D(100,
true);
517 if (fabs(angle) <
M_PI / 4.) {
520 const double bendDeg =
RAD2DEG(fabs(displacementAngle - angle));
521 const double halfDistance = dist / 2;
522 if (fabs(displacementAngle) <= straightThresh && fabs(angle) <= straightThresh) {
523 #ifdef DEBUG_SMOOTH_GEOM 524 if (
DEBUGCOND) std::cout <<
" bezierControlPoints identified straight line beg=" << beg <<
" end=" << end
525 <<
" angle=" <<
RAD2DEG(angle) <<
" displacementAngle=" <<
RAD2DEG(displacementAngle) <<
"\n";
528 }
else if (bendDeg > 22.5 && pow(bendDeg / 45, 2) / dist > 0.13) {
531 #ifdef DEBUG_SMOOTH_GEOM 532 if (
DEBUGCOND) std::cout <<
" bezierControlPoints found extreme s-curve, falling back to straight line beg=" << beg <<
" end=" << end
533 <<
" angle=" <<
RAD2DEG(angle) <<
" displacementAngle=" <<
RAD2DEG(displacementAngle)
534 <<
" dist=" << dist <<
" bendDeg=" << bendDeg <<
" bd2=" << pow(bendDeg / 45, 2)
535 <<
" displacementError=" << sin(displacementAngle) * dist
536 <<
" begShape=" << begShape <<
" endShape=" << endShape <<
"\n";
539 if (recordError != 0) {
544 const double endLength = begShape[-2].distanceTo2D(begShape[-1]);
545 const double off1 = endLength +
MIN2(extrapolateBeg, halfDistance);
547 const double off2 = 100. -
MIN2(extrapolateEnd, halfDistance);
549 #ifdef DEBUG_SMOOTH_GEOM 550 if (
DEBUGCOND) std::cout <<
" bezierControlPoints found s-curve beg=" << beg <<
" end=" << end
551 <<
" angle=" <<
RAD2DEG(angle) <<
" displacementAngle=" <<
RAD2DEG(displacementAngle)
552 <<
" halfDistance=" << halfDistance <<
"\n";
561 Position intersect = endShapeBegLine.intersectionPosition2D(begShapeEndLineRev);
563 #ifdef DEBUG_SMOOTH_GEOM 565 std::cout <<
" bezierControlPoints failed beg=" << beg <<
" end=" << end <<
" intersect=" << intersect <<
"\n";
569 if (recordError != 0) {
575 const double minControlLength =
MIN2((
double)1.0, dist / 2);
576 const bool lengthenBeg = intersect.
distanceTo2D(beg) <= minControlLength;
577 const bool lengthenEnd = intersect.
distanceTo2D(end) <= minControlLength;
578 if (lengthenBeg && lengthenEnd) {
579 #ifdef DEBUG_SMOOTH_GEOM 580 if (
DEBUGCOND) std::cout <<
" bezierControlPoints failed beg=" << beg <<
" end=" << end <<
" intersect=" << intersect
583 if (recordError != 0) {
589 }
else if (lengthenBeg || lengthenEnd) {
591 init.push_back(endShapeBegLine.positionAtOffset2D(100 - minControlLength));
595 const double z2 = endShapeBegLine.positionAtOffset2D(endShapeBegLine.nearest_offset_to_point2D(intersect)).z();
596 const double 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)) {
715 for (std::set<NBTrafficLightDefinition*>::const_iterator i = trafficLights.begin(); i != trafficLights.end(); ++i) {
717 if ((*i)->getNodes().size() > 1) {
719 (*i)->removeNode(
this);
720 (*i)->setParticipantsInformation();
721 (*i)->setTLControllingInformation();
749 }
else if (numConnections == 0) {
787 if (mismatchThreshold >= 0
820 for (
int i = inOffset; i < in->
getNumLanes(); ++i) {
852 std::swap(in1Offset, in2Offset);
881 std::swap(out1, out2);
882 std::swap(out1Offset, out2Offset);
905 for (
int i = inOffset; i < in->
getNumLanes(); ++i) {
929 inOffset += reduction;
930 for (
int i = outOffset; i < out->
getNumLanes(); ++i) {
942 EdgeVector::reverse_iterator i;
944 NBEdge* currentOutgoing = *i;
947 const int numApproaching = (int)approaching->size();
948 if (numApproaching != 0) {
962 const std::vector<NBEdge::Connection>& elv = incoming->
getConnections();
963 for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
965 if (c.
toEdge == currentOutgoing) {
968 unsatisfied &= ~satisfied;
971 if (unsatisfied != 0) {
974 while (unsatisfied != 0 && fromLane < incoming->getNumLanes()) {
976 for (
int toLane = 0; toLane < currentOutgoing->
getNumLanes(); ++toLane) {
981 unsatisfied &= ~satisfied;
998 const std::vector<NBEdge::Connection> cons = (*i)->getConnections();
999 for (std::vector<NBEdge::Connection>::const_iterator k = cons.begin(); k != cons.end(); ++k) {
1001 (*i)->removeFromConnections((*k).toEdge);
1012 (*i)->markAsInLane2LaneState();
1029 while (seen < minLength) {
1045 EdgeVector::const_iterator i = find(
myAllEdges.begin(),
1051 for (; *i != currentOutgoing;) {
1053 if ((*i)->getToNode() ==
this && (*i)->getTurnDestination() != currentOutgoing) {
1054 std::vector<int> connLanes = (*i)->getConnectionLanes(currentOutgoing);
1055 if (connLanes.size() != 0) {
1056 approaching->push_back(*i);
1087 for (EdgeVector::const_iterator i = which.begin(); i != which.end(); i++) {
1089 laneOff += (*i)->getNumLanes();
1119 for (EdgeVector::const_iterator i = which.begin(); i != which.end(); i++) {
1121 laneOff += (*i)->getNumLanes();
1136 int whichLaneOff,
int byLaneOff) {
1140 bool changed =
false;
1142 if (c.
replaceFrom(which, whichLaneOff, by, byLaneOff)) {
1145 if (c.
replaceTo(which, whichLaneOff, by, byLaneOff)) {
1159 for (NBConnectionVector::iterator k = prohibiting.begin(); k != prohibiting.end(); k++) {
1161 sprohibiting.
replaceFrom(which, whichLaneOff, by, byLaneOff);
1162 sprohibiting.
replaceTo(which, whichLaneOff, by, byLaneOff);
1222 if (find(edges.begin(), edges.end(), e) != edges.end()) {
1223 edges.erase(find(edges.begin(), edges.end(), e));
1225 if (edges.size() == 0) {
1240 if (mayDrive.
getFrom() == 0 ||
1241 mayDrive.
getTo() == 0 ||
1243 mustStop.
getTo() == 0) {
1245 WRITE_WARNING(
"Something went wrong during the building of a connection...");
1249 conn.push_back(mayDrive);
1256 int size = (int) edgeid.length();
1258 std::string
id = (*i)->
getID();
1259 if (
id.substr(0, size) == edgeid) {
1269 int size = (int) edgeid.length();
1271 std::string
id = (*i)->
getID();
1272 if (
id.substr(0, size) == edgeid) {
1297 if (removeFromConnections) {
1299 (*i)->removeFromConnections(edge);
1304 (*i)->replaceRemoved(edge, -1, 0, -1);
1313 EdgeVector::const_iterator i;
1315 NBNode* conn = (*i)->getFromNode();
1318 toAdd.
mul((
double) 1.0 / sqrt(toAdd.
x()*toAdd.
x() + toAdd.
y()*toAdd.
y()));
1322 NBNode* conn = (*i)->getToNode();
1325 toAdd.
mul((
double) 1.0 / sqrt(toAdd.
x()*toAdd.
x() + toAdd.
y()*toAdd.
y()));
1329 if (pos.
x() == 0 && pos.
y() == 0) {
1341 (*i)->invalidateConnections();
1349 (*i)->invalidateConnections();
1376 const NBEdge* prohibitorFrom,
const NBEdge* prohibitorTo,
int prohibitorFromLane,
1378 if (from != prohibitorFrom) {
1402 lefthand = !lefthand;
1409 if ((!lefthand && fromLane <= prohibitorFromLane) ||
1410 (lefthand && fromLane >= prohibitorFromLane)) {
1413 const double toAngleAtNode = fmod(to->
getStartAngle() + 180, (double)360.0);
1414 const double prohibitorToAngleAtNode = fmod(prohibitorTo->
getStartAngle() + 180, (double)360.0);
1432 std::vector<NBEdge*>::const_iterator i = std::find(
myAllEdges.begin(),
myAllEdges.end(), from);
1442 const NBEdge*
const possProhibitedFrom,
const NBEdge*
const possProhibitedTo,
1443 bool regardNonSignalisedLowerPriority)
const {
1445 possProhibitedFrom, possProhibitedTo,
1446 regardNonSignalisedLowerPriority);
1452 const NBEdge*
const from2,
const NBEdge*
const to2)
const {
1461 assert(find(incoming.begin(), incoming.end(), removed) == incoming.end());
1462 bool changed =
true;
1468 for (NBConnectionProhibits::iterator i = blockedConnectionsTmp.begin(); i != blockedConnectionsTmp.end(); i++) {
1473 bool blockedChanged =
false;
1475 NBConnectionVector::const_iterator j;
1476 for (j = blocked.begin(); j != blocked.end(); j++) {
1478 if (sblocked.
getFrom() == removed || sblocked.
getTo() == removed) {
1479 blockedChanged =
true;
1483 for (j = blocked.begin(); blockedChanged && j != blocked.end(); j++) {
1485 if (sblocked.
getFrom() == removed && sblocked.
getTo() == removed) {
1489 }
else if (sblocked.
getFrom() == removed) {
1490 assert(sblocked.
getTo() != removed);
1491 for (EdgeVector::const_iterator k = incoming.begin(); k != incoming.end(); k++) {
1494 }
else if (sblocked.
getTo() == removed) {
1495 assert(sblocked.
getFrom() != removed);
1496 for (EdgeVector::const_iterator k = outgoing.begin(); k != outgoing.end(); k++) {
1503 if (blockedChanged) {
1504 blockedConnectionsNew[blocker] = newBlocked;
1509 if (blocker.
getFrom() == removed && blocker.
getTo() == removed) {
1514 }
else if (blocker.
getFrom() == removed) {
1515 assert(blocker.
getTo() != removed);
1517 for (EdgeVector::const_iterator k = incoming.begin(); k != incoming.end(); k++) {
1520 }
else if (blocker.
getTo() == removed) {
1521 assert(blocker.
getFrom() != removed);
1523 for (EdgeVector::const_iterator k = outgoing.begin(); k != outgoing.end(); k++) {
1527 blockedConnectionsNew[blocker] = blocked;
1541 if (outgoing == 0) {
1555 if (
abs((
int) angle) + 1 < 45) {
1562 EdgeVector::const_iterator i =
1569 while ((*i) != incoming) {
1583 EdgeVector::const_iterator i =
1590 while ((*i) != incoming) {
1607 bool mayDefinitelyPass,
const std::string& tlID)
const {
1614 if (outgoing == 0) {
1626 if ((!incoming->
isInnerEdge() &&
mustBrake(incoming, outgoing, fromlane, toLane,
true)) && !mayDefinitelyPass) {
1647 reason =
"crossing";
1650 EdgeVector::const_iterator i;
1655 reason =
"edges incompatible: " + reason;
1659 reason =
"turnaround";
1667 std::set<NBNode*> origSet;
1669 origSet.insert((*i)->getFromNode());
1671 if (origSet.size() < 2) {
1679 if (opposite != 0) {
1683 if (!(*i)->expandableBy(continuation, reason)) {
1684 reason =
"edges incompatible: " + reason;
1690 reason =
"not opposites";
1697 reason =
"intersection";
1702 std::vector<std::pair<NBEdge*, NBEdge*> >
1705 std::vector<std::pair<NBEdge*, NBEdge*> > ret;
1709 std::pair<NBEdge*, NBEdge*>(
1717 assert(opposite != 0);
1719 ret.push_back(std::pair<NBEdge*, NBEdge*>(*i, continuation));
1737 (*i)->resetNodeBorder(
this);
1745 if (shape.size() > 1) {
1756 if ((*i)->getToNode() == n) {
1771 back_inserter(edges));
1773 back_inserter(edges));
1774 for (EdgeVector::const_iterator j = edges.begin(); j != edges.end(); ++j) {
1785 for (EdgeVector::const_iterator k = edges2.begin(); k != edges2.end(); ++k) {
1786 if ((*k)->getFromNode()->isDistrict() || (*k)->getToNode()->isDistrict()) {
1803 #ifdef DEBUG_PED_STRUCTURES 1812 std::cout <<
"guess crossings for " <<
getID() <<
"\n";
1816 std::vector<std::pair<NBEdge*, bool> > normalizedLanes;
1817 for (EdgeVector::const_iterator it = allEdges.begin(); it != allEdges.end(); ++it) {
1819 const std::vector<NBEdge::Lane>& lanes = edge->
getLanes();
1821 for (std::vector<NBEdge::Lane>::const_reverse_iterator it_l = lanes.rbegin(); it_l != lanes.rend(); ++it_l) {
1822 normalizedLanes.push_back(std::make_pair(edge, ((*it_l).permissions &
SVC_PEDESTRIAN) != 0));
1825 for (std::vector<NBEdge::Lane>::const_iterator it_l = lanes.begin(); it_l != lanes.end(); ++it_l) {
1826 normalizedLanes.push_back(std::make_pair(edge, ((*it_l).permissions &
SVC_PEDESTRIAN) != 0));
1831 int firstSidewalk = -1;
1832 for (
int i = 0; i < (int)normalizedLanes.size(); ++i) {
1833 if (normalizedLanes[i].second) {
1838 int hadCandidates = 0;
1839 std::vector<int> connectedCandidates;
1840 if (firstSidewalk != -1) {
1842 std::vector<std::pair<NBEdge*, bool> > tmp;
1843 copy(normalizedLanes.begin() + firstSidewalk, normalizedLanes.end(), std::back_inserter(tmp));
1844 copy(normalizedLanes.begin(), normalizedLanes.begin() + firstSidewalk, std::back_inserter(tmp));
1845 normalizedLanes = tmp;
1848 for (
int i = 0; i < (int)normalizedLanes.size(); ++i) {
1849 NBEdge* edge = normalizedLanes[i].first;
1850 const bool allowsPed = normalizedLanes[i].second;
1852 std::cout <<
" cands=" <<
toString(candidates) <<
" edge=" << edge->
getID() <<
" allowsPed=" << allowsPed <<
"\n";
1854 if (!allowsPed && (candidates.size() == 0 || candidates.back() != edge)) {
1855 candidates.push_back(edge);
1856 }
else if (allowsPed) {
1857 if (candidates.size() > 0) {
1863 connectedCandidates.push_back(n);
1870 if (hadCandidates > 0 && candidates.size() > 0) {
1876 connectedCandidates.push_back(n);
1882 std::cout <<
" hadCandidates=" << hadCandidates <<
" connectedCandidates=" <<
toString(connectedCandidates) <<
"\n";
1884 if (hadCandidates == 2 && connectedCandidates.size() == 2) {
1886 if (connectedCandidates.back() <= connectedCandidates.front()) {
1887 numGuessed -= connectedCandidates.back();
1890 numGuessed -= connectedCandidates.front();
1896 std::cout <<
"guessedCrossings:\n";
1898 std::cout <<
" edges=" <<
toString(crossing->edges) <<
"\n";
1908 std::cout <<
"checkCrossing candidates=" <<
toString(candidates) <<
"\n";
1910 if (candidates.size() == 0) {
1912 std::cout <<
"no crossing added (numCandidates=" << candidates.size() <<
")\n";
1917 double prevAngle = -100000;
1918 for (
int i = 0; i < (int)candidates.size(); ++i) {
1919 NBEdge* edge = candidates[i];
1924 std::cout <<
"no crossing added (found angle difference of " << fabs(angle - prevAngle) <<
" at i=" << i <<
"\n";
1930 std::cout <<
"no crossing added (uncontrolled, edge with speed > " << edge->
getSpeed() <<
")\n";
1936 if (candidates.size() == 1) {
1939 std::cout <<
"adding crossing: " <<
toString(candidates) <<
"\n";
1944 double prevAngle = -100000;
1945 for (EdgeVector::iterator it = candidates.begin(); it != candidates.end(); ++it) {
1946 double angle = (*it)->getCrossingAngle(
this);
1947 if (it != candidates.begin()) {
1948 NBEdge* prev = *(it - 1);
1953 double intermediateWidth = 0;
1956 prevPos = prev->
getLanes()[laneI].shape[-1];
1959 prevPos = prev->
getLanes()[laneI].shape[0];
1964 currPos = curr->
getLanes()[laneI].shape[0];
1967 currPos = curr->
getLanes()[laneI].shape[-1];
1973 <<
" prevAngle=" << prevAngle
1974 <<
" angle=" << angle
1975 <<
" intermediateWidth=" << intermediateWidth
1988 std::cout <<
"adding crossing: " <<
toString(candidates) <<
"\n";
1999 std::sort(edges.begin(), edges.end());
2003 EdgeVector edgesOfCrossing = crossing->edges;
2004 std::sort(edgesOfCrossing.begin(), edgesOfCrossing.end());
2005 if (edgesOfCrossing == edges) {
2015 for (
int i = startIndex; i < (int)normalizedLanes.size(); ++i) {
2016 if (!normalizedLanes[i].second) {
2030 if (crossing->prevWalkingArea ==
"" || crossing->nextWalkingArea ==
"" || !crossing->valid) {
2031 if (crossing->valid) {
2032 WRITE_WARNING(
"Discarding invalid crossing '" + crossing->id +
"' at junction '" +
getID() +
"' with edges '" +
toString(crossing->edges) +
"' (no walkingarea found).");
2035 if ((*it_wa).nextCrossing == crossing->id) {
2036 (*it_wa).nextCrossing =
"";
2039 crossing->valid =
false;
2040 crossing->prevWalkingArea =
"";
2041 crossing->nextWalkingArea =
"";
2046 std::vector<NBNode::Crossing*>
2048 std::vector<Crossing*> result;
2051 result.push_back(c);
2069 myCrossings.clear();
2081 int noInternalNoSplits = 0;
2083 const std::vector<NBEdge::Connection>& elv = (*i)->getConnections();
2084 for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
2085 if ((*k).toEdge == 0) {
2088 noInternalNoSplits++;
2094 (*i)->buildInnerEdges(*
this, noInternalNoSplits, lno, splitNo);
2102 (*i)->buildInnerEdges(*
this, noInternalNoSplits, lno, splitNo);
2110 #ifdef DEBUG_PED_STRUCTURES 2114 std::cout <<
"build crossings for " <<
getID() <<
":\n";
2126 c->nextWalkingArea =
"";
2127 c->prevWalkingArea =
"";
2130 std::cout <<
" crossing=" << c->id <<
" edges=" <<
toString(edges);
2136 std::cout <<
" sortedEdges=" <<
toString(edges) <<
"\n";
2139 double maxAngleDiff = 0;
2140 int maxAngleDiffIndex = 0;
2141 for (
int i = 0; i < (int) edges.size(); i++) {
2143 edges[(i + 1) % edges.size()]->getAngleAtNodeToCenter(
this));
2148 std::cout <<
" i=" << i <<
" a1=" << edges[i]->getAngleAtNodeToCenter(
this) <<
" a2=" << edges[(i + 1) % edges.size()]->getAngleAtNodeToCenter(
this) <<
" diff=" << diff <<
"\n";
2150 if (diff > maxAngleDiff) {
2151 maxAngleDiff = diff;
2152 maxAngleDiffIndex = i;
2155 if (maxAngleDiff > 2 && maxAngleDiff < 360 - 2) {
2157 std::rotate(edges.begin(), edges.begin() + (maxAngleDiffIndex + 1) % edges.size(), edges.end());
2159 std::cout <<
" rotatedEdges=" <<
toString(edges);
2163 std::reverse(edges.begin(), edges.end());
2165 std::cout <<
" finalEdges=" <<
toString(edges) <<
"\n";
2169 const int begDir = (edges.front()->getFromNode() ==
this ?
FORWARD :
BACKWARD);
2170 const int endDir = (edges.back()->getToNode() ==
this ?
FORWARD :
BACKWARD);
2171 if (edges.front()->getFirstNonPedestrianLaneIndex(begDir) < 0
2172 || edges.back()->getFirstNonPedestrianLaneIndex(endDir) < 0) {
2174 WRITE_WARNING(
"Discarding invalid crossing '" + c->id +
"' at junction '" +
getID() +
"' with edges '" +
toString(c->edges) +
"' (no vehicle lanes to cross).");
2177 NBEdge::Lane crossingBeg = edges.front()->getFirstNonPedestrianLane(begDir);
2178 NBEdge::Lane crossingEnd = edges.back()->getFirstNonPedestrianLane(endDir);
2185 c->shape.push_back(crossingBeg.
shape[begDir ==
FORWARD ? 0 : -1]);
2186 c->shape.push_back(crossingEnd.
shape[endDir ==
FORWARD ? -1 : 0]);
2195 #ifdef DEBUG_PED_STRUCTURES 2201 std::cout <<
"build walkingAreas for " <<
getID() <<
":\n";
2208 std::vector<std::pair<NBEdge*, NBEdge::Lane> > normalizedLanes;
2209 for (EdgeVector::const_iterator it = allEdges.begin(); it != allEdges.end(); ++it) {
2211 const std::vector<NBEdge::Lane>& lanes = edge->
getLanes();
2213 for (std::vector<NBEdge::Lane>::const_reverse_iterator it_l = lanes.rbegin(); it_l != lanes.rend(); ++it_l) {
2217 normalizedLanes.push_back(std::make_pair(edge, l));
2220 for (std::vector<NBEdge::Lane>::const_iterator it_l = lanes.begin(); it_l != lanes.end(); ++it_l) {
2225 normalizedLanes.push_back(std::make_pair(edge, l));
2231 std::vector<std::pair<int, int> > waIndices;
2233 NBEdge* prevEdge = normalizedLanes.back().first;
2234 for (
int i = 0; i < (int)normalizedLanes.size(); ++i) {
2235 NBEdge* edge = normalizedLanes[i].first;
2243 waIndices.push_back(std::make_pair(start, i - start));
2253 <<
" waI=" << waIndices.size() <<
" crossingBetween=" <<
crossingBetween(edge, prevEdge) <<
"\n";
2258 const int waNumLanes = (int)normalizedLanes.size() - start;
2259 if (waIndices.size() == 0) {
2260 waIndices.push_back(std::make_pair(start, waNumLanes));
2262 std::cout <<
" single wa, end at wrap-around\n";
2265 if (waIndices.front().first == 0) {
2266 NBEdge* edge = normalizedLanes.front().first;
2267 NBEdge* prevEdge = normalizedLanes.back().first;
2270 waIndices.push_back(std::make_pair(start, waNumLanes));
2272 std::cout <<
" do not wrap around, turn-around in between\n";
2276 waIndices.front().first = start;
2277 waIndices.front().second = waNumLanes + waIndices.front().second;
2279 std::cout <<
" wrapping around\n";
2284 waIndices.push_back(std::make_pair(start, waNumLanes));
2286 std::cout <<
" end at wrap-around\n";
2292 std::cout <<
" normalizedLanes=" << normalizedLanes.size() <<
" waIndices:\n";
2293 for (
int i = 0; i < (int)waIndices.size(); ++i) {
2294 std::cout <<
" " << waIndices[i].first <<
", " << waIndices[i].second <<
"\n";
2298 for (
int i = 0; i < (int)waIndices.size(); ++i) {
2299 const bool buildExtensions = waIndices[i].second != (int)normalizedLanes.size();
2300 const int start = waIndices[i].first;
2301 const int prev = start > 0 ? start - 1 : (int)normalizedLanes.size() - 1;
2302 const int count = waIndices[i].second;
2303 const int end = (start + count) % normalizedLanes.size();
2307 std::cout <<
"build walkingArea " << wa.
id <<
" start=" << start <<
" end=" << end <<
" count=" << count <<
" prev=" << prev <<
":\n";
2309 double endCrossingWidth = 0;
2310 double startCrossingWidth = 0;
2314 bool connectsCrossing =
false;
2315 std::vector<Position> connectedPoints;
2318 std::cout <<
" crossing=" << c->id <<
" sortedEdges=" <<
toString(c->edges) <<
"\n";
2320 if (c->edges.back() == normalizedLanes[end].first
2321 && (normalizedLanes[end].second.permissions &
SVC_PEDESTRIAN) == 0) {
2323 if (c->nextWalkingArea !=
"") {
2325 +
"'; crossing '" + c->id
2326 +
"' targets '" + c->nextWalkingArea
2327 +
"' and '" + wa.
id +
"'.");
2329 c->nextWalkingArea = wa.
id;
2330 endCrossingWidth = c->width;
2331 endCrossingShape = c->shape;
2333 connectsCrossing =
true;
2334 connectedPoints.push_back(c->shape[-1]);
2336 std::cout <<
" crossing " << c->id <<
" ends\n";
2339 if (c->edges.front() == normalizedLanes[prev].first
2340 && (normalizedLanes[prev].second.permissions &
SVC_PEDESTRIAN) == 0) {
2342 if (c->prevWalkingArea !=
"") {
2344 +
"'; crossing '" + c->id
2345 +
"' is targeted by '" + c->prevWalkingArea
2346 +
"' and '" + wa.
id +
"'.");
2348 c->prevWalkingArea = wa.
id;
2350 startCrossingWidth = c->width;
2351 startCrossingShape = c->shape;
2353 connectsCrossing =
true;
2354 connectedPoints.push_back(c->shape[0]);
2356 std::cout <<
" crossing " << c->id <<
" starts\n";
2359 if (
gDebugFlag1) std::cout <<
" check connections to crossing " << c->id
2360 <<
" cFront=" << c->edges.front()->getID() <<
" cBack=" << c->edges.back()->getID()
2361 <<
" wEnd=" << normalizedLanes[end].first->getID() <<
" wStart=" << normalizedLanes[start].first->getID()
2362 <<
" wStartPrev=" << normalizedLanes[prev].first->getID()
2365 if (count < 2 && !connectsCrossing) {
2368 std::cout <<
" not relevant for walking: count=" << count <<
" connectsCrossing=" << connectsCrossing <<
"\n";
2373 std::set<NBEdge*> connected;
2374 for (
int j = 0; j < count; ++j) {
2375 const int nlI = (start + j) % normalizedLanes.size();
2376 NBEdge* edge = normalizedLanes[nlI].first;
2379 if (connected.count(edge) == 0) {
2387 connected.insert(edge);
2394 if (buildExtensions) {
2396 if (startCrossingShape.size() > 0) {
2398 std::cout <<
" extension at startCrossing shape=" << startCrossingShape <<
"\n";
2400 startCrossingShape.
move2side(startCrossingWidth / 2);
2402 startCrossingShape.
move2side(-startCrossingWidth);
2406 if (endCrossingShape.size() > 0) {
2408 std::cout <<
" extension at endCrossing shape=" << endCrossingShape <<
"\n";
2410 endCrossingShape.
move2side(endCrossingWidth / 2);
2412 endCrossingShape.
move2side(-endCrossingWidth);
2417 && normalizedLanes.size() == 2) {
2419 NBEdge* e1 = *connected.begin();
2420 NBEdge* e2 = *(++connected.begin());
2423 std::cout <<
" not building a walkingarea since normal connections exist\n";
2429 if (cornerDetail > 0) {
2430 int smoothEnd = end;
2431 int smoothPrev = prev;
2433 if (endCrossingWidth > 0 && normalizedLanes[smoothEnd].second.permissions == 0) {
2434 smoothEnd = (smoothEnd + 1) % normalizedLanes.size();
2436 if (startCrossingWidth > 0 && normalizedLanes[smoothPrev].second.permissions == 0) {
2437 if (smoothPrev == 0) {
2438 smoothPrev = (int)normalizedLanes.size() - 1;
2443 PositionVector begShape = normalizedLanes[smoothEnd].second.shape;
2444 begShape = begShape.
reverse();
2446 begShape.
move2side(normalizedLanes[smoothEnd].second.width / 2);
2447 PositionVector endShape = normalizedLanes[smoothPrev].second.shape;
2448 endShape.
move2side(normalizedLanes[smoothPrev].second.width / 2);
2452 <<
" end=" << smoothEnd <<
" prev=" << smoothPrev
2453 <<
" endCrossingWidth=" << endCrossingWidth <<
" startCrossingWidth=" << startCrossingWidth
2454 <<
" begShape=" << begShape <<
" endShape=" << endShape <<
" smooth curve=" << curve <<
"\n";
2455 if (curve.size() > 2) {
2456 curve.erase(curve.begin());
2458 if (endCrossingWidth > 0) {
2459 wa.
shape.pop_back();
2461 if (startCrossingWidth > 0) {
2468 double lengthSum = 0;
2469 int combinations = 0;
2470 for (std::vector<Position>::const_iterator it1 = connectedPoints.begin(); it1 != connectedPoints.end(); ++it1) {
2471 for (std::vector<Position>::const_iterator it2 = connectedPoints.begin(); it2 != connectedPoints.end(); ++it2) {
2481 std::cout <<
" combinations=" << combinations <<
" connectedPoints=" << connectedPoints <<
"\n";
2484 if (combinations > 0) {
2490 std::vector<Crossing*> validCrossings =
getCrossings();
2491 for (std::vector<Crossing*>::iterator it = validCrossings.begin(); it != validCrossings.end(); ++it) {
2493 Crossing& next = (it != validCrossings.begin() ? **(it - 1) :** (validCrossings.end() - 1));
2495 std::cout <<
" checkIntermediate: prev=" << prev.
id <<
" next=" << next.
id <<
" prev.nextWA=" << prev.
nextWalkingArea <<
"\n";
2499 WRITE_WARNING(
"Invalid pedestrian topology: crossing '" + prev.
id +
"' has no target.");
2510 wa.
shape.push_back(tmp[-1]);
2512 wa.
shape.push_back(tmp[-1]);
2516 wa.
shape.push_back(tmp[0]);
2518 wa.
shape.push_back(tmp[0]);
2523 std::cout <<
" build wa=" << wa.
id <<
"\n";
2537 EdgeVector::const_iterator it1 = find(edges.begin(), edges.end(), e1);
2538 EdgeVector::const_iterator it2 = find(edges.begin(), edges.end(), e2);
2539 if (it1 != edges.end() && it2 != edges.end()) {
2555 while (it != it_end) {
2556 result.push_back(*it);
2577 if (
MAX2(angle0, angle1) <= 160) {
2607 EdgeSet edgeSet(edges.begin(), edges.end());
2609 EdgeSet edgeSet2((*it)->edges.begin(), (*it)->edges.end());
2610 if (edgeSet == edgeSet2) {
2627 throw ProcessError(
"Request for unknown crossing '" +
id +
"'");
2634 c->tlLinkNo = startIndex++;
2650 const std::vector<NBEdge::Connection>& elv = (*i)->getConnections();
2651 for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
2687 std::cout <<
" angles:\n";
2688 for (EdgeVector::const_iterator it = result.begin(); it != result.end(); ++it) {
2689 std::cout <<
" edge=" << (*it)->getID() <<
" edgeAngle=" << (*it)->getAngleAtNode(
this) <<
" angleToShape=" << (*it)->getAngleAtNodeToCenter(
this) <<
"\n";
2691 std::cout <<
" allEdges before: " <<
toString(result) <<
"\n";
2696 std::cout <<
" allEdges sorted: " <<
toString(result) <<
"\n";
2698 rotate(result.begin(), std::find(result.begin(), result.end(), *
myAllEdges.begin()), result.end());
2700 std::cout <<
" allEdges rotated: " <<
toString(result) <<
"\n";
2711 assert(
id[0] ==
':');
2712 std::string::size_type sep_index =
id.rfind(
'_');
2713 if (sep_index == std::string::npos) {
2714 WRITE_ERROR(
"Invalid lane id '" +
id +
"' (missing '_').");
2717 sep_index =
id.substr(0, sep_index).rfind(
'_');
2718 if (sep_index == std::string::npos) {
2719 WRITE_ERROR(
"Invalid lane id '" +
id +
"' (missing '_').");
2722 return id.substr(1, sep_index - 1);
2732 if (turnDest != 0) {
2753 if ((*i)->rightOnRedConflict(index, foeIndex)) {
2777 std::vector<NBEdge*>::iterator j;
2778 for (j = allEdges.begin(); j != allEdges.end() - 1 && j != allEdges.end(); ++j) {
2781 if (allEdges.size() > 1 && j != allEdges.end()) {
2785 NBEdge* firstOfAll = allEdges.front();
2786 NBEdge* firstOfIncoming = incoming.size() > 0 ? incoming.front() : 0;
2787 NBEdge* firstOfOutgoing = outgoing.size() > 0 ? outgoing.front() : 0;
2793 rotate(allEdges.begin(), std::find(allEdges.begin(), allEdges.end(), firstOfAll), allEdges.end());
2794 if (firstOfIncoming != 0) {
2795 rotate(incoming.begin(), std::find(incoming.begin(), incoming.end(), firstOfIncoming), incoming.end());
2797 if (firstOfOutgoing != 0) {
2798 rotate(outgoing.begin(), std::find(outgoing.begin(), outgoing.end(), firstOfOutgoing), outgoing.end());
2803 if (incoming.size() == outgoing.size() && incoming.front() == allEdges.front()) {
2804 std::vector<NBEdge*>::const_iterator in, out;
2805 std::vector<NBEdge*> allTmp;
2806 for (in = incoming.begin(), out = outgoing.begin(); in != incoming.end(); ++in, ++out) {
2807 if ((*in)->isTurningDirectionAt(*out)) {
2808 allTmp.push_back(*in);
2809 allTmp.push_back(*out);
2814 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
double getStartAngle() const
Returns the angle at the start of the edge (relative to the node shape center) The angle is computed ...
The link is a partial left direction.
double z() const
Returns the z-position.
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges (The edges which yield in this node)
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...
A structure which describes a connection between edges or lanes.
int numAvailableLanes() const
@ get number of avaliable lanes
int toLane
The lane the connections yields in.
void setRoundabout()
update the type of this node as a roundabout
Position getCenter() const
Returns a position that is guaranteed to lie within the node shape.
ApproachingDivider(EdgeVector *approaching, NBEdge *currentOutgoing)
Constructor.
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
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)
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
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.
bool isDistrict() const
check if node is a district
PositionVector myPoly
the (outer) shape of the junction
void execute(const int src, const int dest)
the bresenham-callback
NBEdge * getOppositeIncoming(NBEdge *e) const
returns the opposite incoming edge of certain edge
double getAngleAtNode(const NBNode *const node) const
Returns the angle of the edge's geometry at the given node.
A loaded (complete) traffic light logic.
double getEndAngle() const
Returns the angle at the end of the edge (relative to the node shape center) The angle is computed in...
static double normRelAngle(double angle1, double angle2)
ensure that reverse relAngles (>=179.999) always count as turnarounds (-180)
bool around(const Position &p, double offset=0) const
Returns the information whether the position vector describes a polygon lying around the given point...
SumoXMLNodeType myType
The type of the junction.
double getLoadedLength() const
Returns the length was set explicitly or the computed length if it wasn't set.
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
A container for traffic light definitions and built programs.
void reinit(const Position &position, SumoXMLNodeType type, bool updateEdgeGeometries=false)
Resets initial values.
int getConnectionIndex(const NBEdge *from, const NBEdge::Connection &con) const
return the index of the given connection
bool isTLControlled() const
Returns whether this node is controlled by any tls.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
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.
double x() const
Returns the x-position.
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
void addIncomingEdge(NBEdge *edge)
adds an incoming edge
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
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.
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
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.
The link is a 180 degree turn.
int numNormalConnections() const
return the number of lane-to-lane connections at this junction (excluding crossings) ...
static const double UNSPECIFIED_RADIUS
unspecified lane width
bool hasOutgoing(const NBEdge *const e) const
Returns whether the given edge starts at this node.
std::string getDescription(const NBEdge *parent) const
get string describing this connection
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
EdgeVector getIncomingEdges() const
Returns the list of incoming edges unsorted.
static bool isLongEnough(NBEdge *out, double minLength)
check if is long enough
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) ...
void buildBitfieldLogic()
PositionVector computeInternalLaneShape(NBEdge *fromE, const NBEdge::Connection &con, int numPoints, NBNode *recordError=0) const
Compute the shape for an internal lane.
void removeDoubleEdges()
remove duble edges
#define SUMO_MAX_CONNECTIONS
the maximum number of connections across an intersection
double getSpeed() const
Returns the speed allowed on this edge.
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)
build pedestrian walking areas and set connections from/to walkingAreas
bool isInnerEdge() const
Returns whether this edge was marked as being within an intersection.
This is an uncontrolled, right-before-left link.
static void nextCW(const EdgeVector &edges, EdgeVector::const_iterator &from)
bool isForbidden(SVCPermissions permissions)
Returns whether an edge with the given permission is a forbidden edge.
void remapConnections(const EdgeVector &incoming)
Remaps the connection in a way that allows the removal of it.
std::string id
the (edge)-id of this walkingArea
bool connectionsDone
Whether connection information for this lane is already completed.
EdgeVector getEdgesSortedByAngleAtNodeCenter() const
returns the list of all edges sorted clockwise by getAngleAtNodeToCenter
bool checkIsRemovable() const
check if node is removable
void mirrorX()
mirror coordinates along the x-axis
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission is a railway 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.
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.
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)
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)
bool isConnectedTo(const NBEdge *e) const
Returns the information whethe a connection to the given edge has been added (or computed) ...
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.
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
NBRequest * myRequest
Node requests.
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)...
CustomShapeMap myCustomLaneShapes
custom lane shapes
EdgeVector getConnectedEdges() const
Returns the list of outgoing edges unsorted.
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.
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges (The edges which start at this 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.
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.
void invalidateTLS(NBTrafficLightLogicCont &tlCont, bool removedConnections, bool addedConnections)
causes the traffic light to be computed anew
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 extrapolate2D(const double val, const bool onlyFirst=false)
extrapolate position vector in two dimensions (Z is ignored)
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)
double area() const
Returns the area (0 for non-closed)
const Position & getPosition() const
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.
double getLaneWidth() const
Returns the default width of lanes of this edge.
std::string prevWalkingArea
the lane-id of the previous walkingArea
NBEdge * getPossiblySplittedIncoming(const std::string &edgeid)
get possibly splitted incoming edge
bool hasConnectionTo(NBEdge *destEdge, int destLane, int fromLane=-1) const
Retrieves info about a connection to a certain lane of a certain edge.
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
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.
void setCrossingTLIndices(const std::string &tlID, int startIndex)
set tl indices of this nodes crossing starting at the given index
std::string getInternalLaneID() const
get ID of internal lane
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.
Crossing * getCrossing(const std::string &id) const
return the crossing with the given id
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.
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()
build crossings, and walkingareas. Also removes invalid loaded crossings if wished ...
static double getCWAngleDiff(double angle1, double angle2)
Returns the distance of second angle from first angle clockwise.
double y() const
Returns the y-position.
bool geometryLike() const
whether this is structurally similar to a geometry node
void invalidateOutgoingConnections()
invalidate outgoing connections
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)
returns a list of edges which are connected to the given outgoing edge
std::set< NBTrafficLightDefinition * > myTrafficLights
traffic lights of node
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
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
get link state
Position positionAtOffset2D(double pos, double lateralOffset=0) const
Returns the position at the given length.
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 discardAllCrossings(bool rejectAll)
discard all current (and optionally future) crossings
void replaceInConnectionProhibitions(NBEdge *which, NBEdge *by, int whichLaneOff, int byLaneOff)
replace incoming connections prohibitions
LinkDirection getDirection(const NBEdge *const incoming, const NBEdge *const outgoing, bool leftHand=false) const
Returns the representation of the described stream's direction.
PositionVector compute()
Computes the shape of the assigned junction.
bool checkIsRemovableReporting(std::string &reason) const
check if node is removable and return reason if not
const PositionVector & getShape() const
retrieve the junction shape
double myRadius
the turning radius (for all corners) at this node in m.
The link is a partial right direction.
NBEdge * getConnectionTo(NBNode *n) const
get connection to certain node
double width
This lane's width.
const std::vector< NBNode * > & getNodes() const
Returns the list of controlled nodes.
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.
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
get edges to join
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)
get possibly splitted outgoing edge
int internalLaneIndex
The lane index of this internal lane within the internal edge.
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
std::vector< Crossing * > myCrossings
Vector of crossings.
NBEdge * myCurrentOutgoing
The approached current 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
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
if node is near district
double width
This lane's width.
bool myHaveCustomPoly
whether this nodes shape was set by the user
std::vector< int > getConnectionLanes(NBEdge *currentOutgoing) const
Returns the list of lanes that may be used to reach the given edge.
Position myPosition
The position the node lies at.
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.
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...
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.
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.
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
void buildInnerEdges()
build internal lanes, pedestrian crossings and walking areas
static const int UNSPECIFIED_INTERNAL_LANE_INDEX
internal lane computation not yet done
A definition of a pedestrian walking area.
EdgeVector * myApproaching
The list of edges that approach the current edge.
A storage for options typed value containers)
void erase(NBDistrictCont &dc, NBEdge *edge)
Removes the given edge from the container (deleting it)
This is an uncontrolled, major link, may pass.
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...
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 isSimpleContinuation(bool checkLaneNumbers=true) const
check if node is a simple continuation
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 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
PositionVector getSubpart(double beginOffset, double endOffset) const
get subpart of a position vector
void addSortedLinkFoes(const NBConnection &mayDrive, const NBConnection &mustStop)
add shorted link FOES
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 writeLogic(OutputDevice &into, const bool checkLaneFoes) const
writes the XML-representation of the logic as a bitset-logic XML representation
void push_back_noDoublePos(const Position &p)
insert in back a non double position
#define SPLIT_CROSSING_WIDTH_THRESHOLD
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.
Position getPolygonCenter() const
Returns the arithmetic of all corner points.
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)
void add(double xoff, double yoff, double zoff)
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.
std::vector< Crossing * > getCrossings() const
return this junctions pedestrian crossings
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
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
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
bool valid
whether this crossing is valid (and can be written to the net.xml). This is needed for netedit becaus...
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 ""
double angleAt2D(int pos) const
get angle in certain position of position vector
static void nextCCW(const EdgeVector &edges, EdgeVector::const_iterator &from)
void reshiftPosition(double xoff, double yoff)
Applies an offset to the node.
double angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position ...
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
void replaceIncoming(const EdgeVector &which, NBEdge *const by)
Replaces incoming edges from the vector (sinks) by the given edge.
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)
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.
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.