62 #define EXTEND_CROSSING_ANGLE_THRESHOLD 35.0 // degrees 64 #define SPLIT_CROSSING_WIDTH_THRESHOLD 1.5 // meters 65 #define SPLIT_CROSSING_ANGLE_THRESHOLD 5 // degrees 68 #define MIN_WEAVE_LENGTH 20.0 75 #define DEBUG_NODE_ID "F" 76 #define DEBUGCOND (getID() == DEBUG_NODE_ID) 77 #define DEBUGCOND2(obj) ((obj != 0 && (obj)->getID() == DEBUG_NODE_ID)) 99 myApproaching(approaching),
100 myCurrentOutgoing(currentOutgoing),
101 myIsBikeEdge(currentOutgoing->getPermissions() ==
SVC_BICYCLE) {
103 std::set<int> approachedLanes;
107 approachedLanes.insert(con.toLane);
115 for (
int i = 0; i < currentOutgoing->
getNumLanes(); ++i) {
121 && approachedLanes.count(i) == 0) {
144 if (approachingLanes.size() == 0) {
147 #ifdef DEBUG_CONNECTION_GUESSING 149 std::cout <<
"Bre:ex src=" << src <<
" dest=" << dest <<
" in=" << incomingEdge->getID() <<
" apLanes=" <<
toString(approachingLanes) <<
"\n";
153 std::deque<int>* approachedLanes =
spread(approachingLanes, dest);
156 for (
int i = 0; i < (int)approachedLanes->size(); i++) {
157 assert((
int)approachingLanes.size() > i);
161 delete approachedLanes;
167 std::deque<int>* ret =
new std::deque<int>();
168 const int numLanes = (int)approachingLanes.size();
172 ret->push_back(dest);
178 ret->push_back(dest);
182 while (noSet < numLanes) {
188 if (numOutgoingLanes == noSet) {
197 if (dest + loffset >= numOutgoingLanes) {
200 for (
int i = 0; i < (int)ret->size(); i++) {
201 (*ret)[i] = (*ret)[i] - 1;
206 ret->push_back(dest + loffset);
211 if (numOutgoingLanes == noSet) {
216 if (noSet < numLanes) {
219 if (dest < roffset) {
222 for (
int i = 0; i < (int)ret->size(); i++) {
223 (*ret)[i] = (*ret)[i] + 1;
226 ret->push_front(dest - roffset);
242 customShape(_customShape),
243 tlLinkIndex(_customTLIndex),
244 tlLinkIndex2(_customTLIndex2),
245 customTLIndex(_customTLIndex),
246 customTLIndex2(_customTLIndex2),
305 bool updateEdgeGeometries) {
312 if (updateEdgeGeometries) {
316 (*i)->setGeometry(geom);
321 (*i)->setGeometry(geom);
334 wacs.shape.add(xoff, yoff, 0);
345 c->customShape.mirrorX();
352 wacs.shape.mirrorX();
378 for (std::set<NBTrafficLightDefinition*>::const_iterator i = trafficLights.begin(); i != trafficLights.end(); ++i) {
388 for (std::set<NBTrafficLightDefinition*>::iterator it = oldDefs.begin(); it != oldDefs.end(); ++it) {
390 if (dynamic_cast<NBLoadedSUMOTLDef*>(orig) !=
nullptr) {
391 dynamic_cast<NBLoadedSUMOTLDef*
>(orig)->registerModifications(removedConnections, addedConnections);
392 }
else if (dynamic_cast<NBOwnTLDef*>(orig) ==
nullptr) {
394 const std::vector<NBNode*>& nodes = orig->
getNodes();
395 while (!nodes.empty()) {
396 newDef->
addNode(nodes.front());
397 nodes.front()->removeTrafficLight(orig);
410 (*it)->shiftTLConnectionLaneIndex(edge, offset, threshold);
437 remapRemoved(tc, dummy, incomingConnected, outgoingConnected);
489 if (checkLaneNumbers && in->
getNumLanes() != (*opposite)->getNumLanes()) {
492 if (checkWidth && in->
getTotalWidth() != (*opposite)->getTotalWidth()) {
508 double extrapolateBeg,
509 double extrapolateEnd,
511 int shapeFlag)
const {
515 #ifdef DEBUG_SMOOTH_GEOM 517 std::cout <<
"computeSmoothShape node " <<
getID() <<
" init=" << init <<
"\n";
520 if (init.size() == 0) {
522 ret.push_back(begShape.back());
523 ret.push_back(endShape.front());
535 double extrapolateBeg,
536 double extrapolateEnd,
539 double straightThresh,
542 const Position beg = begShape.back();
543 const Position end = endShape.front();
547 #ifdef DEBUG_SMOOTH_GEOM 548 if (
DEBUGCOND2(recordError)) std::cout <<
" bezierControlPoints failed beg=" << beg <<
" end=" << end
564 center.
sub(beg.
y() - end.
y(), end.
x() - beg.
x());
565 init.push_back(center);
570 endShapeBegLine.extrapolate2D(100,
true);
572 if (fabs(angle) <
M_PI / 4.) {
575 const double bendDeg =
RAD2DEG(fabs(displacementAngle - angle));
576 const double halfDistance = dist / 2;
577 if (fabs(displacementAngle) <= straightThresh && fabs(angle) <= straightThresh) {
578 #ifdef DEBUG_SMOOTH_GEOM 579 if (
DEBUGCOND2(recordError)) std::cout <<
" bezierControlPoints identified straight line beg=" << beg <<
" end=" << end
580 <<
" angle=" <<
RAD2DEG(angle) <<
" displacementAngle=" <<
RAD2DEG(displacementAngle) <<
"\n";
583 }
else if (bendDeg > 22.5 && pow(bendDeg / 45, 2) / dist > 0.13) {
586 #ifdef DEBUG_SMOOTH_GEOM 587 if (
DEBUGCOND2(recordError)) std::cout <<
" bezierControlPoints found extreme s-curve, falling back to straight line beg=" << beg <<
" end=" << end
588 <<
" angle=" <<
RAD2DEG(angle) <<
" displacementAngle=" <<
RAD2DEG(displacementAngle)
589 <<
" dist=" << dist <<
" bendDeg=" << bendDeg <<
" bd2=" << pow(bendDeg / 45, 2)
590 <<
" displacementError=" << sin(displacementAngle) * dist
591 <<
" begShape=" << begShape <<
" endShape=" << endShape <<
"\n";
594 if (recordError !=
nullptr && (shapeFlag &
SCURVE_IGNORE) == 0) {
599 const double endLength = begShape[-2].distanceTo2D(begShape[-1]);
600 const double off1 = endLength +
MIN2(extrapolateBeg, halfDistance);
602 const double off2 = 100. -
MIN2(extrapolateEnd, halfDistance);
604 #ifdef DEBUG_SMOOTH_GEOM 605 if (
DEBUGCOND2(recordError)) std::cout <<
" bezierControlPoints found s-curve beg=" << beg <<
" end=" << end
606 <<
" angle=" <<
RAD2DEG(angle) <<
" displacementAngle=" <<
RAD2DEG(displacementAngle)
607 <<
" halfDistance=" << halfDistance <<
"\n";
616 Position intersect = endShapeBegLine.intersectionPosition2D(begShapeEndLineRev);
618 #ifdef DEBUG_SMOOTH_GEOM 620 std::cout <<
" bezierControlPoints failed beg=" << beg <<
" end=" << end <<
" intersect=" << intersect
621 <<
" endShapeBegLine=" << endShapeBegLine
622 <<
" begShapeEndLineRev=" << begShapeEndLineRev
627 if (recordError !=
nullptr && (shapeFlag &
SCURVE_IGNORE) == 0) {
633 const double minControlLength =
MIN2((
double)1.0, dist / 2);
636 const bool lengthenBeg = distBeg <= minControlLength;
637 const bool lengthenEnd = distEnd <= minControlLength;
638 if (lengthenBeg && lengthenEnd) {
639 #ifdef DEBUG_SMOOTH_GEOM 640 if (
DEBUGCOND2(recordError)) std::cout <<
" bezierControlPoints failed beg=" << beg <<
" end=" << end <<
" intersect=" << intersect
641 <<
" distBeg=" << distBeg <<
" distEnd=" << distEnd <<
"\n";
643 if (recordError !=
nullptr && (shapeFlag &
SCURVE_IGNORE) == 0) {
651 init.push_back(endShapeBegLine.positionAtOffset2D(100 - extrapolateEnd));
652 }
else if (lengthenBeg || lengthenEnd) {
654 init.push_back(endShapeBegLine.positionAtOffset2D(100 - minControlLength));
661 || (angle >
DEG2RAD(95) && (distBeg > 20 || distEnd > 20)))) {
664 :
MIN2(0.6, 16 / dist));
665 init.push_back(begShapeEndLineRev.
positionAtOffset2D(100 -
MIN2(distBeg * factor / 1.2, dist * factor / 1.8)));
666 init.push_back(endShapeBegLine.positionAtOffset2D(100 -
MIN2(distEnd * factor / 1.2, dist * factor / 1.8)));
670 init.push_back(endShapeBegLine.positionAtOffset2D(100 -
MIN2(distEnd / 1.4, dist / 2)));
674 const double z2 = endShapeBegLine.positionAtOffset2D(endShapeBegLine.nearest_offset_to_point2D(intersect)).z();
675 const double z3 = 0.5 * (beg.
z() + end.
z());
679 if ((z1 <= z3 && z2 <= z3) || (z1 >= z3 && z2 >= z3)) {
684 intersect.
set(intersect.
x(), intersect.
y(), z);
685 init.push_back(intersect);
707 if (useCustomShape) {
710 if (startBorder.size() == 0) {
711 startBorder = fromShape.
getOrthogonal(fromShape.back(), 1,
true);
714 if (tmp.size() < 2) {
716 useCustomShape =
false;
720 tmp[0] = fromShape.back();
721 }
else if (recordError !=
nullptr) {
722 const double offset = tmp[0].distanceTo2D(fromShape.back());
728 if (endBorder.size() == 0) {
729 endBorder = toShape.
getOrthogonal(toShape.front(), 1,
false);
732 if (ret.size() < 2) {
734 useCustomShape =
false;
737 ret[-1] = toShape.front();
738 }
else if (recordError !=
nullptr) {
739 const double offset = ret[-1].distanceTo2D(toShape.front());
746 if (!useCustomShape) {
754 #ifdef DEBUG_SMOOTH_GEOM 756 std::cout <<
"computeInternalLaneShape node " <<
getID() <<
" fromE=" << fromE->
getID() <<
" toE=" << con.
toEdge->
getID() <<
"\n";
761 extrapolateBeg, extrapolateEnd, recordError, shapeFlag);
764 if (lane.endOffset > 0) {
793 for (
int i = 0; i < con.
toLane; ++i) {
797 for (
int i = 0; i < con.
fromLane; ++i) {
807 fromShape.
move2side(inCenter - outCenter);
847 if (thisRight && !rightTurnConflict) {
850 if (!(
foes(otherFromE, otherToE, fromE, toE) ||
myRequest ==
nullptr || rightTurnConflict)) {
860 const bool bothLeft = thisLeft && otherLeft;
861 if (fromE == otherFromE && !thisRight) {
868 if (c.
tlID !=
"" && !bothLeft) {
871 if ((*it)->needsCont(fromE, toE, otherFromE, otherToE)) {
896 for (std::set<NBTrafficLightDefinition*>::const_iterator i = trafficLights.begin(); i != trafficLights.end(); ++i) {
898 if ((*i)->getNodes().size() > 1) {
900 (*i)->removeNode(
this);
901 (*i)->setParticipantsInformation();
902 (*i)->setTLControllingInformation();
940 }
else if (numConnections == 0) {
1014 if (mismatchThreshold >= 0
1041 #ifdef DEBUG_CONNECTION_GUESSING 1043 std::cout <<
"l2l node=" <<
getID() <<
" specialCase a\n";
1052 for (
int i = inOffset; i < in->
getNumLanes(); ++i) {
1080 #ifdef DEBUG_CONNECTION_GUESSING 1082 std::cout <<
"l2l node=" <<
getID() <<
" specialCase b\n";
1091 std::swap(in1, in2);
1092 std::swap(in1Offset, in2Offset);
1119 #ifdef DEBUG_CONNECTION_GUESSING 1121 std::cout <<
"l2l node=" <<
getID() <<
" specialCase c\n";
1126 std::swap(out1, out2);
1127 std::swap(out1Offset, out2Offset);
1144 #ifdef DEBUG_CONNECTION_GUESSING 1146 std::cout <<
"l2l node=" <<
getID() <<
" specialCase d\n";
1155 for (
int i = inOffset; i < in->
getNumLanes(); ++i) {
1171 #ifdef DEBUG_CONNECTION_GUESSING 1173 std::cout <<
"l2l node=" <<
getID() <<
" specialCase f\n";
1184 inOffset += reduction;
1185 for (
int i = outOffset; i < out->
getNumLanes(); ++i) {
1201 const int numApproaching = (int)approaching.size();
1202 if (numApproaching != 0) {
1206 #ifdef DEBUG_CONNECTION_GUESSING 1208 std::cout <<
"l2l node=" <<
getID() <<
" bresenham:\n";
1210 const std::vector<NBEdge::Connection>& elv = e->getConnections();
1211 for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
1212 std::cout <<
" " << e->getID() <<
"_" << (*k).fromLane <<
" -> " << (*k).toEdge->getID() <<
"_" << (*k).toLane <<
"\n";
1217 int bikeLaneTarget = currentOutgoing->getSpecialLane(
SVC_BICYCLE);
1226 const std::vector<NBEdge::Connection>& elv = incoming->getConnections();
1227 for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
1232 unsatisfied &= ~satisfied;
1235 if (unsatisfied != 0) {
1236 #ifdef DEBUG_CONNECTION_GUESSING 1238 std::cout <<
" unsatisfied modes from edge=" << incoming->
getID() <<
" toEdge=" << currentOutgoing->getID() <<
" deadModes=" <<
getVehicleClassNames(unsatisfied) <<
"\n";
1242 while (unsatisfied != 0 && fromLane < incoming->getNumLanes()) {
1243 if ((incoming->getPermissions(fromLane) & unsatisfied) != 0) {
1244 for (
int toLane = 0; toLane < currentOutgoing->getNumLanes(); ++toLane) {
1245 const SVCPermissions satisfied = incoming->getPermissions(fromLane) & currentOutgoing->getPermissions(toLane) & unsatisfied;
1246 if (satisfied != 0 && !incoming->getLaneStruct(fromLane).connectionsDone) {
1248 #ifdef DEBUG_CONNECTION_GUESSING 1250 std::cout <<
" new connection from=" << fromLane <<
" to=" << currentOutgoing->getID() <<
"_" << toLane <<
" satisfies=" <<
getVehicleClassNames(satisfied) <<
"\n";
1253 unsatisfied &= ~satisfied;
1259 #ifdef DEBUG_CONNECTION_GUESSING 1261 if (unsatisfied != 0) {
1262 std::cout <<
" still unsatisfied modes from edge=" << incoming->getID() <<
" toEdge=" << currentOutgoing->getID() <<
" deadModes=" <<
getVehicleClassNames(unsatisfied) <<
"\n";
1275 bool builtConnection =
false;
1276 for (
int i = 0; i < (int)incoming->getNumLanes(); i++) {
1278 && incoming->getConnectionsFromLane(i, currentOutgoing).size() == 0) {
1280 if (bikeLaneTarget >= 0) {
1282 builtConnection =
true;
1285 for (
int i2 = 0; i2 < (int)currentOutgoing->getNumLanes(); i2++) {
1286 if ((currentOutgoing->getPermissions(i2) &
SVC_BICYCLE) != 0) {
1290 builtConnection =
true;
1297 if (!builtConnection && bikeLaneTarget >= 0
1298 && incoming->getConnectionsFromLane(-1, currentOutgoing, bikeLaneTarget).size() == 0) {
1301 int end = (int)incoming->getNumLanes();
1304 std::swap(start, end);
1307 for (
int i = start; i < end; i += inc) {
1308 if ((incoming->getPermissions(i) &
SVC_BICYCLE) != 0) {
1321 const std::vector<NBEdge::Connection> cons = (*i)->getConnections();
1322 for (std::vector<NBEdge::Connection>::const_iterator k = cons.begin(); k != cons.end(); ++k) {
1324 (*i)->removeFromConnections((*k).toEdge);
1333 if (myOutgoingEdges.size() == 0) {
1335 incoming->markAsInLane2LaneState();
1339 #ifdef DEBUG_CONNECTION_GUESSING 1341 std::cout <<
"final connections at " <<
getID() <<
"\n";
1343 const std::vector<NBEdge::Connection>& elv = e->getConnections();
1344 for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
1345 std::cout <<
" " << e->getID() <<
"_" << (*k).fromLane <<
" -> " << (*k).toEdge->getID() <<
"_" << (*k).toLane <<
"\n";
1355 while (seen < minLength) {
1372 EdgeVector::const_iterator i = std::find(
myAllEdges.begin(),
1377 approaching.clear();
1378 for (; *i != currentOutgoing;) {
1380 if ((*i)->getToNode() ==
this && (*i)->getTurnDestination() != currentOutgoing) {
1381 std::vector<int> connLanes = (*i)->getConnectionLanes(currentOutgoing);
1382 if (connLanes.size() != 0) {
1383 approaching.push_back(*i);
1413 for (EdgeVector::const_iterator i = which.begin(); i != which.end(); i++) {
1415 laneOff += (*i)->getNumLanes();
1445 for (EdgeVector::const_iterator i = which.begin(); i != which.end(); i++) {
1447 laneOff += (*i)->getNumLanes();
1462 int whichLaneOff,
int byLaneOff) {
1466 bool changed =
false;
1468 if (c.
replaceFrom(which, whichLaneOff, by, byLaneOff)) {
1471 if (c.
replaceTo(which, whichLaneOff, by, byLaneOff)) {
1485 for (NBConnectionVector::iterator k = prohibiting.begin(); k != prohibiting.end(); k++) {
1487 sprohibiting.
replaceFrom(which, whichLaneOff, by, byLaneOff);
1488 sprohibiting.
replaceTo(which, whichLaneOff, by, byLaneOff);
1548 if (find(edges.begin(), edges.end(), e) != edges.end()) {
1549 edges.erase(find(edges.begin(), edges.end(), e));
1551 if (edges.size() == 0) {
1566 if (mayDrive.
getFrom() ==
nullptr ||
1567 mayDrive.
getTo() ==
nullptr ||
1568 mustStop.
getFrom() ==
nullptr ||
1569 mustStop.
getTo() ==
nullptr) {
1571 WRITE_WARNING(
"Something went wrong during the building of a connection...");
1575 conn.push_back(mayDrive);
1582 int size = (int) edgeid.length();
1584 std::string
id = (*i)->
getID();
1585 if (
id.substr(0, size) == edgeid) {
1595 int size = (int) edgeid.length();
1597 std::string
id = (*i)->
getID();
1598 if (
id.substr(0, size) == edgeid) {
1623 if (removeFromConnections) {
1625 (*i)->removeFromConnections(edge);
1630 (*i)->replaceRemoved(edge, -1,
nullptr, -1);
1639 EdgeVector::const_iterator i;
1641 NBNode* conn = (*i)->getFromNode();
1644 toAdd.
mul((
double) 1.0 / sqrt(toAdd.
x()*toAdd.
x() + toAdd.
y()*toAdd.
y()));
1648 NBNode* conn = (*i)->getToNode();
1651 toAdd.
mul((
double) 1.0 / sqrt(toAdd.
x()*toAdd.
x() + toAdd.
y()*toAdd.
y()));
1655 if (pos.
x() == 0 && pos.
y() == 0) {
1667 (*i)->invalidateConnections();
1675 (*i)->invalidateConnections();
1687 if (to ==
nullptr) {
1702 const NBEdge* prohibitorFrom,
const NBEdge* prohibitorTo,
int prohibitorFromLane,
1704 if (from != prohibitorFrom) {
1728 lefthand = !lefthand;
1735 if ((!lefthand && fromLane <= prohibitorFromLane) ||
1736 (lefthand && fromLane >= prohibitorFromLane)) {
1739 const double toAngleAtNode = fmod(to->
getStartAngle() + 180, (double)360.0);
1740 const double prohibitorToAngleAtNode = fmod(prohibitorTo->
getStartAngle() + 180, (double)360.0);
1750 bool lefthand)
const {
1752 if (from != from2 || to == to2 || fromLane == fromLane2) {
1760 bool result =
false;
1762 if (fromLane < fromLane2) {
1764 while (*it != to2) {
1772 while (*it != to2) {
1804 std::vector<NBEdge*>::const_iterator i = std::find(
myAllEdges.begin(),
myAllEdges.end(), from);
1814 const NBEdge*
const possProhibitedFrom,
const NBEdge*
const possProhibitedTo,
1815 bool regardNonSignalisedLowerPriority)
const {
1817 possProhibitedFrom, possProhibitedTo,
1818 regardNonSignalisedLowerPriority);
1824 const NBEdge*
const from2,
const NBEdge*
const to2)
const {
1833 assert(find(incoming.begin(), incoming.end(), removed) == incoming.end());
1834 bool changed =
true;
1840 for (NBConnectionProhibits::iterator i = blockedConnectionsTmp.begin(); i != blockedConnectionsTmp.end(); i++) {
1845 bool blockedChanged =
false;
1847 NBConnectionVector::const_iterator j;
1848 for (j = blocked.begin(); j != blocked.end(); j++) {
1850 if (sblocked.
getFrom() == removed || sblocked.
getTo() == removed) {
1851 blockedChanged =
true;
1855 for (j = blocked.begin(); blockedChanged && j != blocked.end(); j++) {
1857 if (sblocked.
getFrom() == removed && sblocked.
getTo() == removed) {
1861 }
else if (sblocked.
getFrom() == removed) {
1862 assert(sblocked.
getTo() != removed);
1863 for (EdgeVector::const_iterator k = incoming.begin(); k != incoming.end(); k++) {
1866 }
else if (sblocked.
getTo() == removed) {
1867 assert(sblocked.
getFrom() != removed);
1868 for (EdgeVector::const_iterator k = outgoing.begin(); k != outgoing.end(); k++) {
1875 if (blockedChanged) {
1876 blockedConnectionsNew[blocker] = newBlocked;
1881 if (blocker.
getFrom() == removed && blocker.
getTo() == removed) {
1886 }
else if (blocker.
getFrom() == removed) {
1887 assert(blocker.
getTo() != removed);
1889 for (EdgeVector::const_iterator k = incoming.begin(); k != incoming.end(); k++) {
1892 }
else if (blocker.
getTo() == removed) {
1893 assert(blocker.
getFrom() != removed);
1895 for (EdgeVector::const_iterator k = outgoing.begin(); k != outgoing.end(); k++) {
1899 blockedConnectionsNew[blocker] = blocked;
1912 EdgeVector::const_iterator i = itOut;
1913 while (*i != incoming) {
1919 if ((*i)->getFromNode() !=
this) {
1927 if ((vehPerm & (*i)->getPermissions()) != 0 || vehPerm == 0) {
1938 if (outgoing ==
nullptr) {
1956 if (abs((
int) angle) + 1 < 45) {
1959 if (outCW !=
nullptr) {
1961 if (fabs(angle2) < fabs(angle)) {
1962 if (fabs(angle2 - angle) > 5) {
1963 if (angle2 > angle) {
1972 if (outCCW !=
nullptr) {
1974 if (fabs(angle2) < fabs(angle)) {
1975 if (fabs(angle2 - angle) > 5) {
1976 if (angle2 > angle) {
1993 if (outCW !=
nullptr) {
2004 if (outCCW !=
nullptr) {
2015 bool mayDefinitelyPass,
const std::string& tlID)
const {
2022 if (outgoing ==
nullptr) {
2034 if (!mayDefinitelyPass
2035 &&
mustBrake(incoming, outgoing, fromlane, toLane,
true)
2060 reason =
"rail_signal";
2064 reason =
"crossing";
2067 EdgeVector::const_iterator i;
2072 reason =
"edges incompatible: " + reason;
2076 reason =
"turnaround";
2084 std::set<NBNode*> origSet;
2086 origSet.insert((*i)->getFromNode());
2088 if (origSet.size() < 2) {
2096 if (opposite !=
nullptr) {
2100 if (!(*i)->expandableBy(continuation, reason)) {
2101 reason =
"edges incompatible: " + reason;
2107 reason =
"not opposites";
2114 reason =
"intersection";
2119 std::vector<std::pair<NBEdge*, NBEdge*> >
2122 std::vector<std::pair<NBEdge*, NBEdge*> > ret;
2126 std::pair<NBEdge*, NBEdge*>(
2134 assert(opposite != 0);
2136 ret.push_back(std::pair<NBEdge*, NBEdge*>(*i, continuation));
2154 (*i)->resetNodeBorder(
this);
2163 if ((*i)->getToNode() == n) {
2178 back_inserter(edges));
2180 back_inserter(edges));
2181 for (EdgeVector::const_iterator j = edges.begin(); j != edges.end(); ++j) {
2192 for (EdgeVector::const_iterator k = edges2.begin(); k != edges2.end(); ++k) {
2193 if ((*k)->getFromNode()->isDistrict() || (*k)->getToNode()->isDistrict()) {
2210 #ifdef DEBUG_PED_STRUCTURES 2219 std::cout <<
"guess crossings for " <<
getID() <<
"\n";
2223 std::vector<std::pair<NBEdge*, bool> > normalizedLanes;
2224 for (EdgeVector::const_iterator it = allEdges.begin(); it != allEdges.end(); ++it) {
2226 const std::vector<NBEdge::Lane>& lanes = edge->
getLanes();
2228 for (std::vector<NBEdge::Lane>::const_reverse_iterator it_l = lanes.rbegin(); it_l != lanes.rend(); ++it_l) {
2229 normalizedLanes.push_back(std::make_pair(edge, ((*it_l).permissions &
SVC_PEDESTRIAN) != 0));
2232 for (std::vector<NBEdge::Lane>::const_iterator it_l = lanes.begin(); it_l != lanes.end(); ++it_l) {
2233 normalizedLanes.push_back(std::make_pair(edge, ((*it_l).permissions &
SVC_PEDESTRIAN) != 0));
2238 int firstSidewalk = -1;
2239 for (
int i = 0; i < (int)normalizedLanes.size(); ++i) {
2240 if (normalizedLanes[i].second) {
2245 int hadCandidates = 0;
2246 std::vector<int> connectedCandidates;
2247 if (firstSidewalk != -1) {
2249 std::vector<std::pair<NBEdge*, bool> > tmp;
2250 copy(normalizedLanes.begin() + firstSidewalk, normalizedLanes.end(), std::back_inserter(tmp));
2251 copy(normalizedLanes.begin(), normalizedLanes.begin() + firstSidewalk, std::back_inserter(tmp));
2252 normalizedLanes = tmp;
2255 for (
int i = 0; i < (int)normalizedLanes.size(); ++i) {
2256 NBEdge* edge = normalizedLanes[i].first;
2257 const bool allowsPed = normalizedLanes[i].second;
2259 std::cout <<
" cands=" <<
toString(candidates) <<
" edge=" << edge->
getID() <<
" allowsPed=" << allowsPed <<
"\n";
2261 if (!allowsPed && (candidates.size() == 0 || candidates.back() != edge)) {
2262 candidates.push_back(edge);
2263 }
else if (allowsPed) {
2264 if (candidates.size() > 0) {
2270 connectedCandidates.push_back(n);
2277 if (hadCandidates > 0 && candidates.size() > 0) {
2283 connectedCandidates.push_back(n);
2289 std::cout <<
" hadCandidates=" << hadCandidates <<
" connectedCandidates=" <<
toString(connectedCandidates) <<
"\n";
2291 if (hadCandidates == 2 && connectedCandidates.size() == 2) {
2293 if (connectedCandidates.back() <= connectedCandidates.front()) {
2294 numGuessed -= connectedCandidates.back();
2297 numGuessed -= connectedCandidates.front();
2303 std::cout <<
"guessedCrossings:\n";
2305 std::cout <<
" edges=" <<
toString(crossing->edges) <<
"\n";
2315 std::cout <<
"checkCrossing candidates=" <<
toString(candidates) <<
"\n";
2317 if (candidates.size() == 0) {
2319 std::cout <<
"no crossing added (numCandidates=" << candidates.size() <<
")\n";
2324 double prevAngle = -100000;
2325 for (
int i = 0; i < (int)candidates.size(); ++i) {
2326 NBEdge* edge = candidates[i];
2331 std::cout <<
"no crossing added (found angle difference of " << fabs(
NBHelpers::relAngle(angle, prevAngle)) <<
" at i=" << i <<
"\n";
2337 std::cout <<
"no crossing added (uncontrolled, edge with speed > " << edge->
getSpeed() <<
")\n";
2346 std::cout <<
"adding crossing: " <<
toString(candidates) <<
"\n";
2351 double prevAngle = -100000;
2352 for (EdgeVector::iterator it = candidates.begin(); it != candidates.end(); ++it) {
2353 double angle = (*it)->getCrossingAngle(
this);
2354 if (it != candidates.begin()) {
2355 NBEdge* prev = *(it - 1);
2360 double intermediateWidth = 0;
2363 prevPos = prev->
getLanes()[laneI].shape[-1];
2366 prevPos = prev->
getLanes()[laneI].shape[0];
2371 currPos = curr->
getLanes()[laneI].shape[0];
2374 currPos = curr->
getLanes()[laneI].shape[-1];
2380 <<
" prevAngle=" << prevAngle
2381 <<
" angle=" << angle
2382 <<
" intermediateWidth=" << intermediateWidth
2395 std::cout <<
"adding crossing: " <<
toString(candidates) <<
"\n";
2406 std::sort(edges.begin(), edges.end());
2410 EdgeVector edgesOfCrossing = crossing->edges;
2411 std::sort(edgesOfCrossing.begin(), edgesOfCrossing.end());
2412 if (edgesOfCrossing == edges) {
2422 for (
int i = startIndex; i < (int)normalizedLanes.size(); ++i) {
2423 if (!normalizedLanes[i].second) {
2437 if (crossing->prevWalkingArea ==
"" || crossing->nextWalkingArea ==
"" || !crossing->valid) {
2438 if (crossing->valid) {
2439 WRITE_WARNING(
"Discarding invalid crossing '" + crossing->id +
"' at junction '" +
getID() +
"' with edges '" +
toString(crossing->edges) +
"' (no walkingarea found).");
2442 std::vector<std::string>::iterator it_nc = std::find(wa.nextCrossings.begin(), wa.nextCrossings.end(), crossing->id);
2443 if (it_nc != wa.nextCrossings.end()) {
2444 wa.nextCrossings.erase(it_nc);
2447 crossing->valid =
false;
2448 crossing->prevWalkingArea =
"";
2449 crossing->nextWalkingArea =
"";
2454 std::vector<NBNode::Crossing*>
2456 std::vector<Crossing*> result;
2459 result.push_back(c);
2477 myCrossings.clear();
2496 int noInternalNoSplits = 0;
2498 const std::vector<NBEdge::Connection>& elv = (*i)->getConnections();
2499 for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
2500 if ((*k).toEdge ==
nullptr) {
2503 noInternalNoSplits++;
2509 (*i)->buildInnerEdges(*
this, noInternalNoSplits, lno, splitNo);
2516 #ifdef DEBUG_PED_STRUCTURES 2520 std::cout <<
"build crossings for " <<
getID() <<
":\n";
2536 c->nextWalkingArea =
"";
2537 c->prevWalkingArea =
"";
2540 std::cout <<
" crossing=" << c->id <<
" edges=" <<
toString(edges);
2546 std::cout <<
" sortedEdges=" <<
toString(edges) <<
"\n";
2549 double maxAngleDiff = 0;
2550 int maxAngleDiffIndex = 0;
2551 for (
int i = 0; i < (int) edges.size(); i++) {
2553 edges[(i + 1) % edges.size()]->getAngleAtNodeToCenter(
this));
2558 std::cout <<
" i=" << i <<
" a1=" << edges[i]->getAngleAtNodeToCenter(
this) <<
" a2=" << edges[(i + 1) % edges.size()]->getAngleAtNodeToCenter(
this) <<
" diff=" << diff <<
"\n";
2560 if (diff > maxAngleDiff) {
2561 maxAngleDiff = diff;
2562 maxAngleDiffIndex = i;
2565 if (maxAngleDiff > 2 && maxAngleDiff < 360 - 2) {
2567 std::rotate(edges.begin(), edges.begin() + (maxAngleDiffIndex + 1) % edges.size(), edges.end());
2569 std::cout <<
" rotatedEdges=" <<
toString(edges);
2573 std::reverse(edges.begin(), edges.end());
2575 std::cout <<
" finalEdges=" <<
toString(edges) <<
"\n";
2579 const int begDir = (edges.front()->getFromNode() ==
this ?
FORWARD :
BACKWARD);
2580 const int endDir = (edges.back()->getToNode() ==
this ?
FORWARD :
BACKWARD);
2581 if (edges.front()->getFirstNonPedestrianLaneIndex(begDir) < 0
2582 || edges.back()->getFirstNonPedestrianLaneIndex(endDir) < 0) {
2584 WRITE_WARNING(
"Discarding invalid crossing '" + c->id +
"' at junction '" +
getID() +
"' with edges '" +
toString(c->edges) +
"' (no vehicle lanes to cross).");
2586 }
else if (c->customShape.size() != 0) {
2587 c->shape = c->customShape;
2589 NBEdge::Lane crossingBeg = edges.front()->getFirstNonPedestrianLane(begDir);
2590 NBEdge::Lane crossingEnd = edges.back()->getFirstNonPedestrianLane(endDir);
2599 WRITE_WARNING(
"Discarding invalid crossing '" + c->id +
"' at junction '" +
getID() +
"' with edges '" +
toString(c->edges) +
"' (Invalid shape).");
2602 c->shape.push_back(crossingBeg.
shape[begDir ==
FORWARD ? 0 : -1]);
2603 c->shape.push_back(crossingEnd.
shape[endDir ==
FORWARD ? -1 : 0]);
2613 #ifdef DEBUG_PED_STRUCTURES 2619 std::cout <<
"build walkingAreas for " <<
getID() <<
":\n";
2626 std::vector<std::pair<NBEdge*, NBEdge::Lane> > normalizedLanes;
2627 for (EdgeVector::const_iterator it = allEdges.begin(); it != allEdges.end(); ++it) {
2629 const std::vector<NBEdge::Lane>& lanes = edge->
getLanes();
2631 for (std::vector<NBEdge::Lane>::const_reverse_iterator it_l = lanes.rbegin(); it_l != lanes.rend(); ++it_l) {
2635 normalizedLanes.push_back(std::make_pair(edge, l));
2638 for (std::vector<NBEdge::Lane>::const_iterator it_l = lanes.begin(); it_l != lanes.end(); ++it_l) {
2643 normalizedLanes.push_back(std::make_pair(edge, l));
2649 std::vector<std::pair<int, int> > waIndices;
2651 NBEdge* prevEdge = normalizedLanes.back().first;
2652 for (
int i = 0; i < (int)normalizedLanes.size(); ++i) {
2653 NBEdge* edge = normalizedLanes[i].first;
2661 waIndices.push_back(std::make_pair(start, i - start));
2671 <<
" waI=" << waIndices.size() <<
" crossingBetween=" <<
crossingBetween(edge, prevEdge) <<
"\n";
2676 const int waNumLanes = (int)normalizedLanes.size() - start;
2677 if (waIndices.size() == 0) {
2678 waIndices.push_back(std::make_pair(start, waNumLanes));
2680 std::cout <<
" single wa, end at wrap-around\n";
2683 if (waIndices.front().first == 0) {
2684 NBEdge* edge = normalizedLanes.front().first;
2685 NBEdge* prevEdge = normalizedLanes.back().first;
2688 waIndices.push_back(std::make_pair(start, waNumLanes));
2690 std::cout <<
" do not wrap around, turn-around in between\n";
2694 waIndices.front().first = start;
2695 waIndices.front().second = waNumLanes + waIndices.front().second;
2697 std::cout <<
" wrapping around\n";
2702 waIndices.push_back(std::make_pair(start, waNumLanes));
2704 std::cout <<
" end at wrap-around\n";
2710 std::cout <<
" normalizedLanes=" << normalizedLanes.size() <<
" waIndices:\n";
2711 for (
int i = 0; i < (int)waIndices.size(); ++i) {
2712 std::cout <<
" " << waIndices[i].first <<
", " << waIndices[i].second <<
"\n";
2716 for (
int i = 0; i < (int)waIndices.size(); ++i) {
2717 const bool buildExtensions = waIndices[i].second != (int)normalizedLanes.size();
2718 const int start = waIndices[i].first;
2719 const int prev = start > 0 ? start - 1 : (int)normalizedLanes.size() - 1;
2720 const int count = waIndices[i].second;
2721 const int end = (start + count) % normalizedLanes.size();
2725 std::cout <<
"build walkingArea " << wa.
id <<
" start=" << start <<
" end=" << end <<
" count=" << count <<
" prev=" << prev <<
":\n";
2727 double endCrossingWidth = 0;
2728 double startCrossingWidth = 0;
2732 bool connectsCrossing =
false;
2733 std::vector<Position> connectedPoints;
2736 std::cout <<
" crossing=" << c->id <<
" sortedEdges=" <<
toString(c->edges) <<
"\n";
2738 if (c->edges.back() == normalizedLanes[end].first
2739 && (normalizedLanes[end].second.permissions &
SVC_PEDESTRIAN) == 0) {
2741 if (c->nextWalkingArea !=
"") {
2743 +
"'; crossing '" + c->id
2744 +
"' targets '" + c->nextWalkingArea
2745 +
"' and '" + wa.
id +
"'.");
2748 c->nextWalkingArea = wa.
id;
2751 endCrossingWidth = c->width;
2752 endCrossingShape = c->shape;
2754 connectsCrossing =
true;
2755 connectedPoints.push_back(c->shape[-1]);
2759 std::cout <<
" crossing " << c->id <<
" ends\n";
2762 if (c->edges.front() == normalizedLanes[prev].first
2763 && (normalizedLanes[prev].second.permissions &
SVC_PEDESTRIAN) == 0) {
2765 if (c->prevWalkingArea !=
"") {
2767 +
"'; crossing '" + c->id
2768 +
"' is targeted by '" + c->prevWalkingArea
2769 +
"' and '" + wa.
id +
"'.");
2772 c->prevWalkingArea = wa.
id;
2776 startCrossingWidth = c->width;
2777 startCrossingShape = c->shape;
2779 connectsCrossing =
true;
2780 connectedPoints.push_back(c->shape[0]);
2784 std::cout <<
" crossing " << c->id <<
" starts\n";
2787 if (
gDebugFlag1) std::cout <<
" check connections to crossing " << c->id
2788 <<
" cFront=" << c->edges.front()->getID() <<
" cBack=" << c->edges.back()->getID()
2789 <<
" wEnd=" << normalizedLanes[end].first->getID() <<
" wStart=" << normalizedLanes[start].first->getID()
2790 <<
" wStartPrev=" << normalizedLanes[prev].first->getID()
2793 if (count < 2 && !connectsCrossing) {
2796 std::cout <<
" not relevant for walking: count=" << count <<
" connectsCrossing=" << connectsCrossing <<
"\n";
2801 std::set<NBEdge*, ComparatorIdLess> connected;
2802 for (
int j = 0; j < count; ++j) {
2803 const int nlI = (start + j) % normalizedLanes.size();
2804 NBEdge* edge = normalizedLanes[nlI].first;
2807 if (connected.count(edge) == 0) {
2815 connected.insert(edge);
2822 if (buildExtensions) {
2824 if (startCrossingShape.size() > 0) {
2826 std::cout <<
" extension at startCrossing shape=" << startCrossingShape <<
"\n";
2828 startCrossingShape.
move2side(startCrossingWidth / 2);
2830 startCrossingShape.
move2side(-startCrossingWidth);
2834 if (endCrossingShape.size() > 0) {
2836 std::cout <<
" extension at endCrossing shape=" << endCrossingShape <<
"\n";
2838 endCrossingShape.
move2side(endCrossingWidth / 2);
2840 endCrossingShape.
move2side(-endCrossingWidth);
2845 && normalizedLanes.size() == 2) {
2847 NBEdge* e1 = *connected.begin();
2848 NBEdge* e2 = *(++connected.begin());
2851 std::cout <<
" not building a walkingarea since normal connections exist\n";
2857 if (cornerDetail > 0) {
2858 int smoothEnd = end;
2859 int smoothPrev = prev;
2861 if (endCrossingWidth > 0 && normalizedLanes[smoothEnd].second.permissions == 0) {
2862 smoothEnd = (smoothEnd + 1) % normalizedLanes.size();
2864 if (startCrossingWidth > 0 && normalizedLanes[smoothPrev].second.permissions == 0) {
2865 if (smoothPrev == 0) {
2866 smoothPrev = (int)normalizedLanes.size() - 1;
2871 PositionVector begShape = normalizedLanes[smoothEnd].second.shape;
2872 begShape = begShape.
reverse();
2874 begShape.
move2side(normalizedLanes[smoothEnd].second.width / 2);
2875 PositionVector endShape = normalizedLanes[smoothPrev].second.shape;
2876 endShape.
move2side(normalizedLanes[smoothPrev].second.width / 2);
2879 if ((normalizedLanes[smoothEnd].first->getPermissions() & normalizedLanes[smoothPrev].first->getPermissions() &
2883 const double extend =
MIN2(10.0, begShape.back().distanceTo2D(endShape.front()) / 2);
2887 <<
" end=" << smoothEnd <<
" prev=" << smoothPrev
2888 <<
" endCrossingWidth=" << endCrossingWidth <<
" startCrossingWidth=" << startCrossingWidth
2889 <<
" begShape=" << begShape <<
" endShape=" << endShape <<
" smooth curve=" << curve <<
"\n";
2890 if (curve.size() > 2) {
2891 curve.erase(curve.begin());
2893 if (endCrossingWidth > 0) {
2894 wa.
shape.pop_back();
2896 if (startCrossingWidth > 0) {
2906 if (wacs.shape.size() != 0 &&
includes(connected, wacs.edges)) {
2907 wa.
shape = wacs.shape;
2913 double lengthSum = 0;
2914 int combinations = 0;
2915 for (std::vector<Position>::const_iterator it1 = connectedPoints.begin(); it1 != connectedPoints.end(); ++it1) {
2916 for (std::vector<Position>::const_iterator it2 = connectedPoints.begin(); it2 != connectedPoints.end(); ++it2) {
2926 std::cout <<
" combinations=" << combinations <<
" connectedPoints=" << connectedPoints <<
"\n";
2929 if (combinations > 0) {
2935 std::vector<Crossing*> validCrossings =
getCrossings();
2936 for (std::vector<Crossing*>::iterator it = validCrossings.begin(); it != validCrossings.end(); ++it) {
2938 Crossing& next = (it != validCrossings.begin() ? **(it - 1) :** (validCrossings.end() - 1));
2940 std::cout <<
" checkIntermediate: prev=" << prev.
id <<
" next=" << next.
id <<
" prev.nextWA=" << prev.
nextWalkingArea <<
"\n";
2955 wa.
shape.push_back(tmp[-1]);
2957 wa.
shape.push_back(tmp[-1]);
2961 wa.
shape.push_back(tmp[0]);
2963 wa.
shape.push_back(tmp[0]);
2966 std::set<NBEdge*, ComparatorIdLess> crossed(prev.
edges.begin(), prev.
edges.end());
2967 crossed.insert(next.
edges.begin(), next.
edges.end());
2970 if (wacs.shape.size() != 0 && wacs.edges.size() > 1 &&
includes(crossed, wacs.edges)) {
2971 wa.
shape = wacs.shape;
2980 std::cout <<
" build wa=" << wa.
id <<
"\n";
2988 const std::set<const NBEdge*, ComparatorIdLess>& sub) {
2990 for (
const NBEdge* e : sub) {
2991 if (super.count(const_cast<NBEdge*>(e)) == 0) {
3010 EdgeVector::const_iterator it1 = std::find(edges.begin(), edges.end(), e1);
3011 EdgeVector::const_iterator it2 = std::find(edges.begin(), edges.end(), e2);
3012 if (it1 != edges.end() && it2 != edges.end()) {
3028 while (it != it_end) {
3029 result.push_back(*it);
3039 wacs.
edges.insert(edges.begin(), edges.end());
3052 if (incoming.size() == 1 && outgoing.size() == 1) {
3055 if (incoming.size() == 2 && outgoing.size() == 2) {
3058 NBEdge* in0 = incoming[0];
3059 NBEdge* in1 = incoming[1];
3060 NBEdge* out0 = outgoing[0];
3061 NBEdge* out1 = outgoing[1];
3066 for (EdgeVector::const_iterator it = incoming.begin(); it != incoming.end(); ++it) {
3070 if (
MAX2(angle0, angle1) <= 160) {
3091 Crossing* c =
new Crossing(
this, edges, width, priority, tlIndex, tlIndex2, customShape);
3102 EdgeSet edgeSet(edges.begin(), edges.end());
3104 EdgeSet edgeSet2((*it)->edges.begin(), (*it)->edges.end());
3105 if (edgeSet == edgeSet2) {
3122 throw ProcessError(
"Request for unknown crossing '" +
id +
"'");
3128 EdgeSet edgeSet(edges.begin(), edges.end());
3130 EdgeSet edgeSet2(it->edges.begin(), it->edges.end());
3131 if (edgeSet == edgeSet2) {
3138 throw ProcessError(
"Request for unknown crossing for the given Edges");
3145 bool usedCustom =
false;
3147 c->tlLinkIndex = startIndex++;
3149 if (c->customTLIndex != -1) {
3150 usedCustom |= (c->tlLinkIndex != c->customTLIndex);
3151 c->tlLinkIndex = c->customTLIndex;
3153 c->tlLinkIndex2 = c->customTLIndex2;
3165 result += (int)edge->getConnections().size();
3178 const std::vector<NBEdge::Connection>& elv = (*i)->getConnections();
3179 for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
3215 std::cout <<
" angles:\n";
3216 for (EdgeVector::const_iterator it = result.begin(); it != result.end(); ++it) {
3217 std::cout <<
" edge=" << (*it)->getID() <<
" edgeAngle=" << (*it)->getAngleAtNode(
this) <<
" angleToShape=" << (*it)->getAngleAtNodeToCenter(
this) <<
"\n";
3219 std::cout <<
" allEdges before: " <<
toString(result) <<
"\n";
3224 std::cout <<
" allEdges sorted: " <<
toString(result) <<
"\n";
3226 rotate(result.begin(), std::find(result.begin(), result.end(), *
myAllEdges.begin()), result.end());
3228 std::cout <<
" allEdges rotated: " <<
toString(result) <<
"\n";
3239 assert(
id[0] ==
':');
3240 std::string::size_type sep_index =
id.rfind(
'_');
3241 if (sep_index == std::string::npos) {
3242 WRITE_ERROR(
"Invalid lane id '" +
id +
"' (missing '_').");
3245 sep_index =
id.substr(0, sep_index).rfind(
'_');
3246 if (sep_index == std::string::npos) {
3247 WRITE_ERROR(
"Invalid lane id '" +
id +
"' (missing '_').");
3250 return id.substr(1, sep_index - 1);
3260 if (turnDest !=
nullptr) {
3281 if ((*i)->rightOnRedConflict(index, foeIndex)) {
3304 std::vector<NBEdge*>::iterator j;
3305 for (j = allEdges.begin(); j != allEdges.end() - 1 && j != allEdges.end(); ++j) {
3308 if (allEdges.size() > 1 && j != allEdges.end()) {
3313 NBEdge* firstOfAll = allEdges.front();
3314 NBEdge* firstOfIncoming = incoming.size() > 0 ? incoming.front() : 0;
3315 NBEdge* firstOfOutgoing = outgoing.size() > 0 ? outgoing.front() : 0;
3321 rotate(allEdges.begin(), std::find(allEdges.begin(), allEdges.end(), firstOfAll), allEdges.end());
3322 if (firstOfIncoming !=
nullptr) {
3323 rotate(incoming.begin(), std::find(incoming.begin(), incoming.end(), firstOfIncoming), incoming.end());
3325 if (firstOfOutgoing !=
nullptr) {
3326 rotate(outgoing.begin(), std::find(outgoing.begin(), outgoing.end(), firstOfOutgoing), outgoing.end());
3328 #ifdef DEBUG_EDGE_SORTING 3330 std::cout <<
"sortedEdges:\n";
3331 for (
NBEdge* e : allEdges) {
3332 std::cout <<
" " << e->
getID()
3333 <<
" angleToCenter=" << e->getAngleAtNodeToCenter(
this)
3334 <<
" junctionAngle=" << e->getAngleAtNode(
this) <<
"\n";
3341 if (incoming.size() == outgoing.size() && incoming.front() == allEdges.front()) {
3342 std::vector<NBEdge*>::const_iterator in, out;
3343 std::vector<NBEdge*> allTmp;
3344 for (in = incoming.begin(), out = outgoing.begin(); in != incoming.end(); ++in, ++out) {
3345 if ((*in)->isTurningDirectionAt(*out)) {
3346 allTmp.push_back(*in);
3347 allTmp.push_back(*out);
3352 if (allTmp.size() == allEdges.size()) {
3365 if (useNodeShape &&
myAllEdges != allEdgesOriginal) {
3369 e->computeEdgeShape();
3374 std::vector<std::pair<Position, std::string> >
3377 std::vector<std::pair<Position, std::string> >result;
3379 Position pos =
this == e->getFromNode() ? e->getGeometry().front() : e->getGeometry().back();
3380 const std::string origID = e->getParameter(
this == e->getFromNode() ?
"origFrom" :
"origTo");
3382 for (
const auto& pair : result) {
3383 if (pos.
almostSame(pair.first) || (origID !=
"" && pair.second == origID)) {
3389 result.push_back(std::make_pair(pos, origID));
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.
int getSpecialLane(SVCPermissions permissions) const
return index of the first lane that allows the given permissions
bool almostSame(const Position &p2, double maxDiv=POSITION_EPS) const
check if two position is almost the sme as other
bool isSimpleContinuation(bool checkLaneNumbers=true, bool checkWidth=false) const
check if node is a simple continuation
double length2D() const
Returns the length.
A structure which describes a connection between edges or lanes.
std::vector< WalkingAreaCustomShape > myWalkingAreaCustomShapes
Vector of custom walking areas shapes.
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) ...
void getEdgesThatApproach(NBEdge *currentOutgoing, EdgeVector &approaching)
returns a list of edges which are connected to the given outgoing edge
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.
PositionVector shape
The lane's shape.
double getRadius() const
get computed radius for node
virtual void addNode(NBNode *node)
Adds a node to the traffic light logic.
int buildCrossings()
build pedestrian crossings
void writeLogic(OutputDevice &into) const
const std::string & getID() const
void append(const PositionVector &v, double sameThreshold=2.0)
PositionVector getOrthogonal(const Position &p, double extend, bool before, double length=1.0) const
return orthogonal through p (extending this vector if necessary)
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.
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.
void computeLogic2(bool checkLaneFoes)
compute right-of-way logic for all lane-to-lane connections
RightOfWay myRightOfWay
how to compute right of way for this node
#define EXTEND_CROSSING_ANGLE_THRESHOLD
Sorts crossings by minimum clockwise clockwise edge angle. Use the ordering found in myAllEdges of th...
EdgeVector getIncomingEdges() const
Returns the list of incoming edges unsorted.
static PositionVector startShapeAt(const PositionVector &laneShape, const NBNode *startNode, PositionVector nodeShape)
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 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, double speed=UNSPECIFIED_SPEED, const PositionVector &customShape=PositionVector::EMPTY, const bool uncontrolled=UNSPECIFIED_CONNECTION_UNCONTROLLED)
Adds a connection to a certain lane of a certain edge.
bool isInsideTLS() const
Returns whether this edge was marked as being within an intersection.
bool isConnectedTo(const NBEdge *e) const
Returns the information whethe a connection to the given edge has been added (or computed) ...
A loaded (complete) traffic light logic.
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.
int minPrevCrossingEdges
minimum number of edges crossed by incoming crossings
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.
std::vector< Crossing * > getCrossings() const
return this junctions pedestrian crossings
This is an uncontrolled, minor link, has to stop.
int getPriority() const
Returns the priority of the edge.
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
void displaceShapeAtWidthChange(const NBEdge *from, const NBEdge::Connection &con, PositionVector &fromShape, PositionVector &toShape) const
displace lane shapes to account for change in lane width at this node
The link is a 180 degree turn.
static const double UNSPECIFIED_RADIUS
unspecified lane width
std::vector< std::pair< Position, std::string > > getEndPoints() const
return list of unique endpoint coordinates of all edges at this node
double x() const
Returns the x-position.
bool isBidiRail(bool ignoreSpread=false) const
whether this edge is part of a bidirectional railway
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()
builds the bitset-representation of the logic
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 ...
bool hasCustomShape
whether this walkingArea has a custom shape
#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
Crossing * getCrossing(const std::string &id) const
return the crossing with the given id
PositionVector shape
The crossing's shape.
#define SPLIT_CROSSING_ANGLE_THRESHOLD
const std::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
const EdgeVector & myApproaching
The list of edges that approach the current edge.
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)
const std::string & getID() const
Returns the id.
void mirrorX()
mirror coordinates along the x-axis
PositionVector computeInternalLaneShape(NBEdge *fromE, const NBEdge::Connection &con, int numPoints, NBNode *recordError=0, int shapeFlag=0) const
Compute the shape for an internal lane.
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.
const std::string & getFoes(int linkIndex) const
This is an uncontrolled, all-way stop link.
void addOutgoingEdge(NBEdge *edge)
adds an outgoing edge
std::string getDescription(const NBEdge *parent) const
get string describing this connection
#define UNUSED_PARAMETER(x)
Crossing(const NBNode *_node, const EdgeVector &_edges, double _width, bool _priority, int _customTLIndex, int _customTLIndex2, const PositionVector &_customShape)
constructor
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.
PositionVector customShape
custom shape for connection
#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.
static const int AVOID_WIDE_RIGHT_TURN
flags for controlling shape generation
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)...
The link is a straight direction.
SUMOTime getOffset()
Returns the offset.
void computeLogic(const bool checkLaneFoes)
writes the XML-representation of the logic as a bitset-logic XML representation
NBDistrict * myDistrict
The district the node is the centre of.
A class representing a single district.
PositionVector bezier(int numPoints)
return a bezier interpolation
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
bool tlsContConflict(const NBEdge *from, const NBEdge::Connection &c, const NBEdge *foeFrom, const NBEdge::Connection &foe) const
whether the connection must yield if the foe remains on the intersection after its phase ends ...
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.
bool myTypeWasGuessed
whether the node type was guessed rather than loaded
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
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.
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)
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.
This is an uncontrolled, minor link, has to brake.
bool writeLogic(OutputDevice &into) const
writes the XML-representation of the logic as a bitset-logic XML representation
int getNumLanes() const
Returns the number of lanes.
int fromLane
The lane the connections starts at.
int minNextCrossingEdges
minimum number of edges crossed by nextCrossings
A point in 2D or 3D with translation and scaling methods.
classes which drive on tracks
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.
bool turnFoes(const NBEdge *from, const NBEdge *to, int fromLane, const NBEdge *from2, const NBEdge *to2, int fromLane2, bool lefthand=false) const
return whether the given laneToLane connection originate from the same edge and are in conflict due t...
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.
Position getPolygonCenter() const
Returns the arithmetic of all corner points.
void move2side(double amount, double maxExtension=100)
move position vector to side using certain ammount
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
bool isConstantWidthTransition() const
detects whether a given junction splits or merges lanes while keeping constant road width ...
void removeJoinedTrafficLights()
remove all traffic light definitions that are part of a joined tls
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.
const std::string & getID() const
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.
std::set< const NBEdge *, ComparatorIdLess > edges
static const int AVOID_INTERSECTING_LEFT_TURNS
The link is a (hard) right direction.
std::string getSidewalkID()
get the lane id for the canonical sidewalk lane
EdgeBuildingStep getStep() const
The building step of this edge.
const std::string & getResponse(int linkIndex) const
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.
static PositionVector bezierControlPoints(const PositionVector &begShape, const PositionVector &endShape, bool isTurnaround, double extrapolateBeg, double extrapolateEnd, bool &ok, NBNode *recordError=0, double straightThresh=DEG2RAD(5), int shapeFlag=0)
get bezier control points
bool myDiscardAllCrossings
whether to discard all pedestrian crossings
PositionVector getSubpart(double beginOffset, double endOffset) const
get subpart of a position vector
static const int SCURVE_IGNORE
double getEndOffset() const
Returns the offset to the destination node.
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
PositionVector smoothedZFront(double dist=std::numeric_limits< double >::max()) const
returned vector that is smoothed at the front (within dist)
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.
class for maintaining associations between enums and xml-strings
An upper class for objects with additional parameters.
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)
bool myIsBikeEdge
whether the outgoing edge is exclusively used by bikes
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.
virtual void removeNode(NBNode *node)
Removes the given node from the list of controlled nodes.
EdgeVector myIncomingEdges
Vector of incoming edges.
int tlLinkIndex
The index of this connection within the controlling traffic light.
bool checkIsRemovableReporting(std::string &reason) const
check if node is removable and return reason if not
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.
bool setCrossingTLIndices(const std::string &tlID, int startIndex)
void avoidOverlap()
fix overlap
FringeType myFringeType
fringe type of this node
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.
static bool isValidNetID(const std::string &value)
whether the given string is a valid id for a network element
const PositionVector & getShape() const
retrieve the junction shape
double getSpeed() const
Returns the speed allowed on this edge.
NBNode::Crossing * addCrossing(EdgeVector edges, double width, bool priority, int tlIndex=-1, int tlIndex2=-1, const PositionVector &customShape=PositionVector::EMPTY, bool fromSumoNet=false)
add a pedestrian crossing to this node
NBEdge * getTo() const
returns the to-edge (end of the connection)
EdgeVector myOutgoingEdges
Vector of outgoing edges.
std::vector< Crossing * > myCrossings
Vector of crossings.
void addWalkingAreaShape(EdgeVector edges, const PositionVector &shape)
add custom shape for walkingArea
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 crossing'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 there 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.
void shiftTLConnectionLaneIndex(NBEdge *edge, int offset, int threshold=-1)
patches loaded signal plans by modifying lane indices above threshold by the given offset ...
~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)
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...
const std::string & getVehicleClassNames(SVCPermissions permissions, bool expand)
Returns the ids of the given classes, divided using a ' '.
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
double getTotalWidth() const
Returns the combined width of all lanes of this edge.
const PositionVector & getNodeBorder(const NBNode *node)
static const int FOUR_CONTROL_POINTS
A definition of a pedestrian walking area.
const std::vector< NBNode * > & getNodes() const
Returns the list of controlled nodes.
A storage for options typed value containers)
const std::string getFoes(int linkIndex) const
SumoXMLNodeType getType() const
Returns the type of this node.
bool isNAN() const
check if PositionVector is NAN
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
EdgeVector edges
The edges being crossed.
Represents a single node (junction) during network building.
bool removeFully(const std::string id)
Removes a logic definition (and all programs) from the dictionary.
ApproachingDivider(const EdgeVector &approaching, NBEdge *currentOutgoing)
Constructor.
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.
const std::string getResponse(int linkIndex) const
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
static bool isRailwayNode(const NBNode *n)
whether the given node only has rail edges
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
std::vector< std::string > nextCrossings
the lane-id of the next crossing(s)
void push_back_noDoublePos(const Position &p)
insert in back a non double position
static bool includes(const std::set< NBEdge *, ComparatorIdLess > &super, const std::set< const NBEdge *, ComparatorIdLess > &sub)
returns whether sub is a subset of super
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.
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)
bool haveVia
check if Connection have a Via
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)
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
PositionVector computeSmoothShape(const PositionVector &begShape, const PositionVector &endShape, int numPoints, bool isTurnaround, double extrapolateBeg, double extrapolateEnd, NBNode *recordError=0, int shapeFlag=0) const
Compute a smooth curve between the given geometries.
void discardWalkingareas()
discard previously built walkingareas (required for repeated computation by netedit) ...
NBEdge * getNextCompatibleOutgoing(const NBEdge *incoming, SVCPermissions vehPerm, EdgeVector::const_iterator start, bool clockwise) const
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
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 ""
static void nextCCW(const EdgeVector &edges, EdgeVector::const_iterator &from)
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
static const int AVOID_WIDE_LEFT_TURN
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 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