55 #define DEBUGCOND (getID() == DEBUGID)
58 #define DEBUGCOND2(obj) ((obj != 0 && (obj)->getID() == DEBUGID))
103 mayDefinitelyPass(false),
113 uncontrolled(false) {
118 double visibility_,
double speed_,
double length_,
bool haveVia_,
bool uncontrolled_,
const PositionVector& customShape_,
SVCPermissions permissions_) :
124 mayDefinitelyPass(mayDefinitelyPass_),
125 keepClear(keepClear_),
127 visibility(visibility_),
129 customLength(length_),
130 customShape(customShape_),
131 permissions(permissions_),
136 uncontrolled(uncontrolled_)
148 connectionsDone(false) {
161 assert((
int)myTransitions.size() > virtEdge);
163 NBEdge* succEdge = myTransitions[virtEdge];
164 std::vector<int> lanes;
168 std::map<NBEdge*, std::vector<int> >::iterator i =
myConnections.find(succEdge);
176 std::vector<int>::iterator j = std::find(lanes.begin(), lanes.end(), lane);
177 if (j == lanes.end()) {
179 lanes.push_back(lane);
192 const NBEdge* straight =
nullptr;
193 for (
const NBEdge*
const out : outgoing) {
195 for (
const int l : availableLanes) {
196 if ((parent->
myLanes[l].permissions & outPerms) != 0) {
197 if (straight ==
nullptr || sorter(out, straight)) {
204 if (straight ==
nullptr) {
207 myStraightest = (int)std::distance(outgoing.begin(), std::find(outgoing.begin(), outgoing.end(), straight));
210 assert(outgoing.size() > 0);
212 #ifdef DEBUG_CONNECTION_GUESSING
214 std::cout <<
" MainDirections edge=" << parent->
getID() <<
" straightest=" << straight->
getID() <<
" dir=" <<
toString(straightestDir) <<
"\n";
226 if (outgoing.back()->getJunctionPriority(to) == 1) {
230 if (outgoing.back()->getPriority() > straight->
getPriority() ||
231 outgoing.back()->getNumLanes() > straight->
getNumLanes()) {
248 return myDirs.empty();
254 return std::find(myDirs.begin(), myDirs.end(), d) != myDirs.end();
274 std::string type,
double speed,
int nolanes,
275 int priority,
double laneWidth,
double endOffset,
276 const std::string& streetName,
298 init(nolanes,
false,
"");
303 std::string type,
double speed,
int nolanes,
304 int priority,
double laneWidth,
double endOffset,
306 const std::string& streetName,
307 const std::string& origID,
312 myFrom(from), myTo(to),
313 myStartAngle(0), myEndAngle(0), myTotalAngle(0),
314 myPriority(priority), mySpeed(speed),
316 myTurnDestination(nullptr),
317 myPossibleTurnDestination(nullptr),
318 myFromJunctionPriority(-1), myToJunctionPriority(-1),
319 myGeom(geom), myLaneSpreadFunction(spread), myEndOffset(endOffset),
321 myLaneWidth(laneWidth),
322 myLoadedLength(UNSPECIFIED_LOADED_LENGTH),
323 myAmInTLS(false), myAmMacroscopicConnector(false),
324 myStreetName(streetName),
326 mySignalNode(nullptr),
329 init(nolanes, tryIgnoreNodePositions, origID);
336 myType(tpl->getTypeID()),
337 myFrom(from), myTo(to),
338 myStartAngle(0), myEndAngle(0), myTotalAngle(0),
339 myPriority(tpl->getPriority()), mySpeed(tpl->getSpeed()),
341 myTurnDestination(nullptr),
342 myPossibleTurnDestination(nullptr),
343 myFromJunctionPriority(-1), myToJunctionPriority(-1),
345 myLaneSpreadFunction(tpl->getLaneSpreadFunction()),
346 myEndOffset(tpl->getEndOffset()),
347 myStopOffsets(tpl->getStopOffsets()),
348 myLaneWidth(tpl->getLaneWidth()),
349 myLoadedLength(UNSPECIFIED_LOADED_LENGTH),
351 myAmMacroscopicConnector(false),
352 myStreetName(tpl->getStreetName()),
353 mySignalPosition(to == tpl->myTo ? tpl->mySignalPosition :
Position::
INVALID),
354 mySignalNode(to == tpl->myTo ? tpl->mySignalNode : nullptr) {
361 myLanes[i].updateParameters(tpl->
myLanes[tplIndex].getParametersMap());
362 if (to == tpl->
myTo) {
381 double speed,
int nolanes,
int priority,
383 const std::string& streetName,
385 bool tryIgnoreNodePositions) {
407 const std::vector<Lane> oldLanes =
myLanes;
408 init(nolanes, tryIgnoreNodePositions, oldLanes.empty() ?
"" : oldLanes[0].getParameter(
SUMO_PARAM_ORIGID));
409 for (
int i = 0; i < (int)nolanes; ++i) {
411 myLanes[i] = oldLanes[
MIN2(i, (
int)oldLanes.size() - 1)];
430 if (from ==
nullptr || to ==
nullptr) {
431 throw ProcessError(
"At least one of edge's '" +
myID +
"' nodes is not known.");
454 NBEdge::init(
int noLanes,
bool tryIgnoreNodePositions,
const std::string& origID) {
459 throw ProcessError(
"At least one of edge's '" +
myID +
"' nodes is not known.");
468 if (!tryIgnoreNodePositions ||
myGeom.size() < 2) {
492 assert(
myGeom.size() >= 2);
493 if ((
int)
myLanes.size() > noLanes) {
495 for (
int lane = noLanes; lane < (int)
myLanes.size(); ++lane) {
500 for (EdgeVector::const_iterator i = incoming.begin(); i != incoming.end(); i++) {
501 for (
int lane = noLanes; lane < (int)
myLanes.size(); ++lane) {
502 (*i)->removeFromConnections(
this, -1, lane);
507 for (
int i = 0; i < noLanes; i++) {
513 #ifdef DEBUG_CONNECTION_GUESSING
515 std::cout <<
"init edge=" <<
getID() <<
"\n";
517 std::cout <<
" conn " << c.getDescription(
this) <<
"\n";
520 std::cout <<
" connToDelete " << c.getDescription(
this) <<
"\n";
535 lane.customShape.add(xoff, yoff, 0);
539 (*i).customShape.add(xoff, yoff, 0);
554 for (
int i = 0; i < (int)
myLanes.size(); i++) {
556 myLanes[i].customShape.mirrorX();
560 c.viaShape.mirrorX();
561 c.customShape.mirrorX();
593 assert(node ==
myTo);
628 assert(node ==
myTo);
657 if (rectangularCut) {
658 const double extend = 100;
662 border.push_back(p2);
664 if (border.size() == 2) {
665 double edgeWidth = 0;
666 for (
int i = 0; i < (int)
myLanes.size(); i++) {
673 assert(node ==
myTo);
677 #ifdef DEBUG_NODE_BORDER
680 <<
" rect=" << rectangularCut
681 <<
" p=" << p <<
" p2=" << p2
682 <<
" border=" << border
695 assert(node ==
myTo);
706 assert(node ==
myTo);
742 if (shape.size() < 2) {
744 const double oldLength = old.
length();
745 shape = old.
getSubpart(oldLength - 2 * POSITION_EPS, oldLength);
749 if (shape.
length() < POSITION_EPS) {
750 if (old.
length() < 2 * POSITION_EPS) {
753 const double midpoint = old.
length() / 2;
755 shape = old.
getSubpart(midpoint - POSITION_EPS, midpoint + POSITION_EPS);
756 assert(shape.size() >= 2);
757 assert(shape.
length() > 0);
765 tmp.push_back(shape[0]);
766 tmp.push_back(shape[-1]);
768 if (tmp.
length() < POSITION_EPS) {
770 if (old.
length() < 2 * POSITION_EPS) {
773 const double midpoint = old.
length() / 2;
775 shape = old.
getSubpart(midpoint - POSITION_EPS, midpoint + POSITION_EPS);
776 assert(shape.size() >= 2);
777 assert(shape.
length() > 0);
780 const double midpoint = shape.
length() / 2;
782 shape = shape.
getSubpart(midpoint - POSITION_EPS, midpoint + POSITION_EPS);
783 if (shape.
length() < POSITION_EPS) {
790 const double z = (shape[0].z() + shape[1].z()) / 2;
806 const double d = cut[0].distanceTo2D(cut[1]);
807 const double dZ = fabs(cut[0].z() - cut[1].z());
808 if (dZ / smoothElevationThreshold > d) {
814 const double d = cut[-1].distanceTo2D(cut[-2]);
815 const double dZ = fabs(cut[-1].z() - cut[-2].z());
816 if (dZ / smoothElevationThreshold > d) {
827 for (
int i = 0; i < (int)
myLanes.size(); i++) {
831 double avgLength = 0;
832 for (
int i = 0; i < (int)
myLanes.size(); i++) {
833 avgLength +=
myLanes[i].shape.length();
842 if (nodeShape.size() == 0) {
851 assert(pbv.size() > 0);
859 const double delta = ns[0].z() - laneShape[0].z();
861 if (fabs(delta) > 2 * POSITION_EPS && (!startNode->
geometryLike() || pb < 1)) {
866 assert(ns.size() >= 2);
871 assert(pbv.size() > 0);
876 const double delta = np.
z() - laneShape[0].z();
878 if (fabs(delta) > 2 * POSITION_EPS && !startNode->
geometryLike()) {
932 lane.customShape.removeDoublePoints(minDist,
true);
944 std::vector<double> angles;
946 for (
int i = 0; i < (int)
myGeom.size() - 1; ++i) {
951 for (
int i = 0; i < (int)angles.size() - 1; ++i) {
954 if (maxAngle > 0 && relAngle > maxAngle && !silent) {
960 if (i == 0 || i == (
int)angles.size() - 2) {
961 const bool start = i == 0;
963 const double r = tan(0.5 * (
M_PI - relAngle)) * dist;
965 if (minRadius > 0 && r < minRadius) {
968 (start ?
"start" :
"end") +
" of edge '" +
getID() +
"'.");
972 }
else if (!silent) {
974 toString(start ?
"start" :
"end") +
" of edge '%'.", r,
getID());
992 if (dest !=
nullptr &&
myTo != dest->
myFrom) {
995 if (dest ==
nullptr) {
1001 if (overrideRemoval) {
1004 if (it->toEdge == dest) {
1021 bool mayUseSameDestination,
1022 bool mayDefinitelyPass,
1044 return setConnection(from, dest, toLane, type, mayUseSameDestination, mayDefinitelyPass, keepClear, contPos, visibility, speed, length, customShape, uncontrolled, permissions, postProcess);
1050 NBEdge* dest,
int toLane,
1052 bool invalidatePrevious,
1053 bool mayDefinitelyPass) {
1054 if (invalidatePrevious) {
1058 for (
int i = 0; i < no && ok; i++) {
1068 bool mayUseSameDestination,
1069 bool mayDefinitelyPass,
1103 if ((*i).toEdge == destEdge && ((*i).fromLane == -1 || (*i).toLane == -1)) {
1110 if (mayDefinitelyPass) {
1138 if ((it->fromLane < 0 || it->fromLane == lane)
1139 && (it->toEdge ==
nullptr || it->toEdge == destEdge)
1140 && (it->toLane < 0 || it->toLane == destLane)) {
1151 std::vector<NBEdge::Connection>
1153 std::vector<NBEdge::Connection> ret;
1155 if ((lane < 0 || c.fromLane == lane)
1156 && (to ==
nullptr || to == c.toEdge)
1157 && (toLane < 0 || toLane == c.toLane)) {
1169 (*i).fromLane == fromLane
1170 && (*i).toEdge == to
1171 && (*i).toLane == toLane) {
1176 +
" to " + to->
getID() +
"_" +
toString(toLane) +
" not found");
1183 (*i).fromLane == fromLane
1184 && (*i).toEdge == to
1185 && (*i).toLane == toLane) {
1190 +
" to " + to->
getID() +
"_" +
toString(toLane) +
" not found");
1221 if (find(outgoing.begin(), outgoing.end(), (*i).toEdge) == outgoing.end()) {
1222 outgoing.push_back((*i).toEdge);
1227 if (it->fromLane < 0 && it->toLane < 0) {
1229 EdgeVector::iterator forbidden = std::find(outgoing.begin(), outgoing.end(), it->toEdge);
1230 if (forbidden != outgoing.end()) {
1231 outgoing.erase(forbidden);
1236 int size = (int) outgoing.size();
1238 edges->reserve(size);
1239 for (EdgeVector::const_iterator i = outgoing.begin(); i != outgoing.end(); i++) {
1242 edges->push_back(outedge);
1254 if (find(ret.begin(), ret.end(), (*i).toEdge) == ret.end()) {
1255 ret.push_back((*i).toEdge);
1266 for (EdgeVector::const_iterator i = candidates.begin(); i != candidates.end(); i++) {
1267 if ((*i)->isConnectedTo(
this)) {
1277 std::vector<int> ret;
1281 ret.push_back(c.fromLane);
1304 for (EdgeVector::const_iterator i = incoming.begin(); i != incoming.end(); i++) {
1309 for (EdgeVector::iterator j = connected.begin(); j != connected.end(); j++) {
1319 const bool keepPossibleTurns) {
1321 const int fromLaneRemoved = adaptToLaneRemoval && fromLane >= 0 ? fromLane : -1;
1322 const int toLaneRemoved = adaptToLaneRemoval && toLane >= 0 ? toLane : -1;
1325 if ((toEdge ==
nullptr || c.
toEdge == toEdge)
1326 && (fromLane < 0 || c.
fromLane == fromLane)
1327 && (toLane < 0 || c.
toLane == toLane)) {
1330 for (std::set<NBTrafficLightDefinition*>::iterator it = tldefs.begin(); it != tldefs.end(); it++) {
1337 if (fromLaneRemoved >= 0 && c.
fromLane > fromLaneRemoved) {
1340 for (std::set<NBTrafficLightDefinition*>::iterator it = tldefs.begin(); it != tldefs.end(); it++) {
1341 for (NBConnectionVector::iterator tlcon = (*it)->getControlledLinks().begin(); tlcon != (*it)->getControlledLinks().end(); ++tlcon) {
1352 if (toLaneRemoved >= 0 && c.
toLane > toLaneRemoved && (toEdge ==
nullptr || c.
toEdge == toEdge)) {
1368 #ifdef DEBUG_CONNECTION_GUESSING
1370 std::cout <<
"removeFromConnections " <<
getID() <<
"_" << fromLane <<
"->" << toEdge->
getID() <<
"_" << toLane <<
"\n";
1372 std::cout <<
" conn " << c.getDescription(
this) <<
"\n";
1375 std::cout <<
" connToDelete " << c.getDescription(
this) <<
"\n";
1387 if ((i->toEdge == connectionToRemove.
toEdge) && (i->fromLane == connectionToRemove.
fromLane) && (i->toLane == connectionToRemove.
toLane)) {
1402 if (reallowSetting) {
1414 if ((*i).toEdge == which) {
1416 (*i).toLane += laneOff;
1427 std::map<int, int> laneMap;
1431 bool wasConnected =
false;
1433 if ((*i).toEdge != which) {
1436 wasConnected =
true;
1437 if ((*i).fromLane != -1) {
1438 int fromLane = (*i).fromLane;
1439 laneMap[(*i).toLane] = fromLane;
1440 if (minLane == -1 || minLane > fromLane) {
1443 if (maxLane == -1 || maxLane < fromLane) {
1448 if (!wasConnected) {
1452 std::vector<NBEdge::Connection> conns = origConns;
1454 for (std::vector<NBEdge::Connection>::iterator i = conns.begin(); i != conns.end(); ++i) {
1455 if ((*i).toEdge == which || (*i).toEdge ==
this
1457 || std::find(origTargets.begin(), origTargets.end(), (*i).toEdge) != origTargets.end()) {
1458 #ifdef DEBUG_REPLACECONNECTION
1460 std::cout <<
" replaceInConnections edge=" <<
getID() <<
" which=" << which->
getID()
1461 <<
" origTargets=" <<
toString(origTargets) <<
" newTarget=" << i->toEdge->getID() <<
" skipped\n";
1471 int fromLane = (*i).fromLane;
1473 if (laneMap.find(fromLane) == laneMap.end()) {
1474 if (fromLane >= 0 && fromLane <= minLane) {
1477 for (
auto& item : laneMap) {
1478 if (item.first < fromLane) {
1479 item.second =
MIN2(item.second, minLane);
1483 if (fromLane >= 0 && fromLane >= maxLane) {
1486 for (
auto& item : laneMap) {
1487 if (item.first > fromLane) {
1488 item.second =
MAX2(item.second, maxLane);
1493 toUse = laneMap[fromLane];
1498 #ifdef DEBUG_REPLACECONNECTION
1500 std::cout <<
" replaceInConnections edge=" <<
getID() <<
" which=" << which->
getID() <<
" origTargets=" <<
toString(origTargets)
1501 <<
" origFrom=" << fromLane <<
" laneMap=" <<
joinToString(laneMap,
":",
",") <<
" minLane=" << minLane <<
" maxLane=" << maxLane
1502 <<
" newTarget=" << i->toEdge->getID() <<
" fromLane=" << toUse <<
" toLane=" << i->toLane <<
"\n";
1506 i->contPos, i->visibility, i->speed, i->customLength, i->customShape, i->uncontrolled);
1537 std::vector<Connection>::iterator i =
myConnections.begin() + index;
1567 std::string innerID =
":" + n.
getID();
1568 NBEdge* toEdge =
nullptr;
1569 int edgeIndex = linkIndex;
1570 int internalLaneIndex = 0;
1572 double lengthSum = 0;
1573 int avoidedIntersectingLeftOriginLane = std::numeric_limits<int>::max();
1577 if (con.
toEdge ==
nullptr) {
1585 if (con.
toEdge != toEdge || (isTurn && !joinTurns)) {
1588 edgeIndex = linkIndex;
1589 toEdge = (*i).toEdge;
1590 internalLaneIndex = 0;
1598 std::vector<int> foeInternalLinks;
1605 std::pair<double, std::vector<int> > crossingPositions(-1, std::vector<int>());
1606 std::set<std::string> tmpFoeIncomingLanes;
1614 std::vector<PositionVector> otherShapes;
1616 for (
const Connection& k2 : i2->getConnections()) {
1617 if (k2.toEdge ==
nullptr) {
1622 double width2 = k2.toEdge->getLaneWidth(k2.toLane);
1623 if (k2.toEdge->getPermissions(k2.toLane) !=
SVC_BICYCLE) {
1626 const bool foes = n.
foes(
this, con.
toEdge, i2, k2.toEdge);
1628 const bool avoidIntersectCandidate = !foes &&
bothLeftTurns(n, dir, i2, k2);
1629 bool oppositeLeftIntersect = avoidIntersectCandidate &&
haveIntersection(n, shape, i2, k2, numPoints, width2);
1634 && k2.customShape.size() == 0
1635 && (oppositeLeftIntersect || (avoidedIntersectingLeftOriginLane < con.
fromLane && avoidIntersectCandidate))
1636 && ((i2->getPermissions(k2.fromLane) & warn) != 0
1637 && (k2.toEdge->getPermissions(k2.toLane) & warn) != 0)) {
1643 oppositeLeftIntersect =
haveIntersection(n, shape, i2, k2, numPoints, width2, shapeFlag);
1644 if (oppositeLeftIntersect
1649 if (avoidedIntersectingLeftOriginLane == std::numeric_limits<int>::max()
1650 || avoidedIntersectingLeftOriginLane < con.
fromLane) {
1653 "Could not compute intersection of conflicting internal lanes at node '" +
myTo->
getID() +
"'");
1654 if (minDV < shape.
length() - POSITION_EPS && minDV > POSITION_EPS) {
1656 if (crossingPositions.first < 0 || crossingPositions.first > minDV) {
1657 crossingPositions.first = minDV;
1663 avoidedIntersectingLeftOriginLane = con.
fromLane;
1669 if (needsCont || (bothPrio && oppositeLeftIntersect)) {
1670 crossingPositions.second.push_back(index);
1672 otherShapes.push_back(otherShape);
1674 "Could not compute intersection of conflicting internal lanes at node '" +
myTo->
getID() +
"'");
1675 if (minDV < shape.
length() - POSITION_EPS && minDV > POSITION_EPS) {
1677 if (crossingPositions.first < 0 || crossingPositions.first > minDV) {
1678 crossingPositions.first = minDV;
1686 if (foes || rightTurnConflict || oppositeLeftIntersect || mergeConflict) {
1687 foeInternalLinks.push_back(index);
1690 if (oppositeLeftIntersect &&
getID() > i2->getID()
1693 && (i2->getPermissions(k2.fromLane) & warn) != 0
1694 && (k2.toEdge->getPermissions(k2.toLane) & warn) != 0
1698 WRITE_WARNINGF(
"Intersecting left turns at junction '%' from lane '%' and lane '%' (increase junction radius to avoid this).",
1704 tmpFoeIncomingLanes.insert(i2->getID() +
"_" +
toString(k2.fromLane));
1706 if (bothPrio && oppositeLeftIntersect &&
getID() < i2->getID()) {
1709 tmpFoeIncomingLanes.insert(innerID +
"_" +
toString(index) +
"_0");
1715 std::vector<NBNode::Crossing*> crossings = n.
getCrossings();
1716 for (
auto c : crossings) {
1718 for (EdgeVector::const_iterator it_e = crossing.
edges.begin(); it_e != crossing.
edges.end(); ++it_e) {
1719 const NBEdge* edge = *it_e;
1721 if (
this == edge || con.
toEdge == edge) {
1722 foeInternalLinks.push_back(index);
1723 if (con.
toEdge == edge &&
1729 if (minDV < shape.
length() - POSITION_EPS && minDV > POSITION_EPS) {
1731 if (crossingPositions.first < 0 || crossingPositions.first > minDV) {
1732 crossingPositions.first = minDV;
1741 if (dir ==
LinkDirection::TURN && crossingPositions.first < 0 && crossingPositions.second.size() != 0 && shape.
length() > 2. * POSITION_EPS) {
1755 crossingPositions.first = -1;
1758 crossingPositions.first = con.
contPos;
1773 if (limitTurnSpeed > 0) {
1778 const double angle =
MAX2(0.0, angleRaw - (fromRail ? limitTurnSpeedMinAngleRail : limitTurnSpeedMinAngle));
1779 const double length = shape.
length2D();
1782 if (angle > 0 && length > 1) {
1785 const double limit = sqrt(limitTurnSpeed * radius);
1786 const double reduction = con.
vmax - limit;
1794 dirType =
"roundabout";
1796 WRITE_WARNINGF(
"Speed of % connection '%' reduced by % due to turning radius of % (length=%, angle=%).",
1803 assert(con.
vmax > 0);
1815 assert(shape.size() >= 2);
1817 con.
id = innerID +
"_" +
toString(edgeIndex);
1818 if (crossingPositions.first >= 0 && crossingPositions.first < shape.
length()) {
1819 std::pair<PositionVector, PositionVector>
split = shape.
splitAt(crossingPositions.first);
1821 con.
foeIncomingLanes = std::vector<std::string>(tmpFoeIncomingLanes.begin(), tmpFoeIncomingLanes.end());
1823 con.
viaID = innerID +
"_" +
toString(splitIndex + noInternalNoSplits);
1831 ++internalLaneIndex;
1850 for (
int prevIndex = 1; prevIndex <= numLanes; prevIndex++) {
1854 c.
length =
MAX2(minLength, lengthSum / numLanes);
1860 const double a = firstLength / (firstLength + c.
viaLength);
1870 double intersect = std::numeric_limits<double>::max();
1871 if (v2.
length() < POSITION_EPS) {
1883 intersect =
MIN2(intersect, cand);
1886 intersect =
MIN2(intersect, cand);
1902 if (otherFrom ==
this) {
1914 return minDV < shape.
length() - POSITION_EPS && minDV > POSITION_EPS;
1933 #ifdef DEBUG_JUNCTIONPRIO
1938 #ifdef DEBUG_JUNCTIONPRIO
1951 assert(atNode ==
myTo);
1966 assert(atNode ==
myTo);
1974 if (!onlyPossible) {
1998 std::vector<double> offsets(
myLanes.size(), 0.);
2000 for (
int i = (
int)
myLanes.size() - 2; i >= 0; --i) {
2002 offsets[i] = offset;
2006 for (
int i = 0; i < (int)
myLanes.size(); ++i) {
2024 for (
int i = 0; i < (int)
myLanes.size(); ++i) {
2025 offsets[i] += offset;
2029 for (
int i = 0; i < (int)
myLanes.size(); ++i) {
2030 if (
myLanes[i].customShape.size() != 0) {
2066 if ((hasFromShape || hasToShape) &&
getNumLanes() > 0) {
2099 if (suspiciousFromShape) {
2100 std::cout <<
" len=" << shape.
length() <<
" startA=" <<
myStartAngle <<
" startA2=" << myStartAngle2 <<
" startA3=" << myStartAngle3
2102 <<
" fromCenter=" << fromCenter
2104 <<
" refStart=" << referencePosStart
2107 if (suspiciousToShape) {
2108 std::cout <<
" len=" << shape.
length() <<
" endA=" <<
myEndAngle <<
" endA2=" << myEndAngle2 <<
" endA3=" << myEndAngle3
2110 <<
" toCenter=" << toCenter
2112 <<
" refEnd=" << referencePosEnd
2118 if (suspiciousFromShape && shape.
length() > 1) {
2129 if (suspiciousToShape && shape.
length() > 1) {
2143 <<
" fromCenter=" << fromCenter <<
" toCenter=" << toCenter
2144 <<
" refStart=" << referencePosStart <<
" refEnd=" << referencePosEnd <<
" shape=" << shape
2145 <<
" hasFromShape=" << hasFromShape
2146 <<
" hasToShape=" << hasToShape
2172 for (std::vector<Lane>::const_iterator i =
myLanes.begin(); i !=
myLanes.end(); ++i) {
2173 if ((*i).permissions !=
SVCAll) {
2183 std::vector<Lane>::const_iterator i =
myLanes.begin();
2186 for (; i !=
myLanes.end(); ++i) {
2187 if (i->permissions != firstLanePermissions) {
2197 for (std::vector<Lane>::const_iterator i =
myLanes.begin(); i !=
myLanes.end(); ++i) {
2208 for (std::vector<Lane>::const_iterator i =
myLanes.begin(); i !=
myLanes.end(); ++i) {
2209 if (i->width !=
myLanes.begin()->width) {
2219 for (std::vector<Lane>::const_iterator i =
myLanes.begin(); i !=
myLanes.end(); ++i) {
2220 if (i->type !=
myLanes.begin()->type) {
2230 for (std::vector<Lane>::const_iterator i =
myLanes.begin(); i !=
myLanes.end(); ++i) {
2231 if (i->endOffset !=
myLanes.begin()->endOffset) {
2241 for (std::vector<Lane>::const_iterator i =
myLanes.begin(); i !=
myLanes.end(); ++i) {
2242 if (!i->stopOffsets.empty()) {
2243 const std::pair<const int, double>& offsets = *(i->stopOffsets.begin());
2255 for (std::vector<Lane>::const_iterator i =
myLanes.begin(); i !=
myLanes.end(); ++i) {
2266 for (std::vector<Lane>::const_iterator i =
myLanes.begin(); i !=
myLanes.end(); ++i) {
2267 if (i->customShape.size() > 0) {
2277 for (std::vector<Lane>::const_iterator i =
myLanes.begin(); i !=
myLanes.end(); ++i) {
2278 if (i->getParametersMap().size() > 0) {
2303 #ifdef DEBUG_CONNECTION_GUESSING
2305 std::cout <<
"computeEdge2Edges edge=" <<
getID() <<
" step=" << (int)
myStep <<
"\n";
2307 std::cout <<
" conn " << c.getDescription(
this) <<
"\n";
2310 std::cout <<
" connToDelete " << c.getDescription(
this) <<
"\n";
2321 for (EdgeVector::const_iterator i = o.begin(); i != o.end(); ++i) {
2326 if (fromRail &&
isRailway((*i)->getPermissions()) &&
2339 #ifdef DEBUG_CONNECTION_GUESSING
2341 std::cout <<
"computeLanes2Edges edge=" <<
getID() <<
" step=" << (int)
myStep <<
"\n";
2343 std::cout <<
" conn " << c.getDescription(
this) <<
"\n";
2346 std::cout <<
" connToDelete " << c.getDescription(
this) <<
"\n";
2374 #ifdef DEBUG_CONNECTION_GUESSING
2376 std::cout <<
"recheckLanes (initial) edge=" <<
getID() <<
"\n";
2378 std::cout <<
" conn " << c.getDescription(
this) <<
"\n";
2381 std::cout <<
" connToDelete " << c.getDescription(
this) <<
"\n";
2389 std::vector<int> connNumbersPerLane(
myLanes.size(), 0);
2391 if ((*i).toEdge ==
nullptr || (*i).fromLane < 0 || (*i).toLane < 0) {
2394 if ((*i).fromLane >= 0) {
2395 ++connNumbersPerLane[(*i).fromLane];
2406 for (
int i = 0; i < (int)
myLanes.size(); i++) {
2409 bool hasDeadEnd =
true;
2411 for (
int i2 = i - 1; hasDeadEnd && i2 >= 0; i2--) {
2415 if (connNumbersPerLane[i2] > 1) {
2416 connNumbersPerLane[i2]--;
2417 for (
int i3 = i2; i3 != i; i3++) {
2427 for (
int i2 = i + 1; hasDeadEnd && i2 <
getNumLanes(); i2++) {
2431 if (connNumbersPerLane[i2] > 1) {
2432 connNumbersPerLane[i2]--;
2433 for (
int i3 = i2; i3 != i; i3--) {
2451 }
else if (common == 0) {
2454 const int origToLane = c.
toLane;
2456 int toLane = origToLane;
2469 int toLane = origToLane;
2500 if (incoming.size() > 1) {
2501 for (
int i = 0; i < (int)
myLanes.size(); i++) {
2503 bool connected =
false;
2504 for (std::vector<NBEdge*>::const_iterator in = incoming.begin(); in != incoming.end(); ++in) {
2505 if ((*in)->hasConnectionTo(
this, i)) {
2517 #ifdef ADDITIONAL_WARNINGS
2524 bool hasAlternative =
false;
2526 if (c.fromLane == c2.fromLane && c.toEdge == c2.toEdge
2527 && (c.toEdge->getPermissions(c2.toLane) &
SVC_PASSENGER) != 0) {
2528 hasAlternative =
true;
2531 if (!hasAlternative) {
2532 WRITE_WARNING(
"Road lane ends on bikeLane for connection " + c.getDescription(
this));
2537 int passengerLanes = 0;
2538 int passengerTargetLanes = 0;
2546 for (
const Lane& lane : out->getLanes()) {
2548 passengerTargetLanes++;
2553 if (passengerLanes <= passengerTargetLanes) {
2555 connNumbersPerLane = std::vector<int>(
myLanes.size(), 0);
2557 connNumbersPerLane[c.fromLane]++;
2559 for (
int i = 0; i < (int)
myLanes.size(); i++) {
2568 #ifdef DEBUG_CONNECTION_GUESSING
2570 std::cout <<
"recheckLanes (final) edge=" <<
getID() <<
"\n";
2572 std::cout <<
" conn " << c.getDescription(
this) <<
"\n";
2582 if (outgoing->size() == 0) {
2588 #ifdef DEBUG_CONNECTION_GUESSING
2590 std::cout <<
" divideOnEdges " <<
getID() <<
" outgoing=" <<
toString(*outgoing) <<
"\n";
2595 std::vector<int> availableLanes;
2596 for (
int i = 0; i < (int)
myLanes.size(); ++i) {
2598 availableLanes.push_back(i);
2601 if (availableLanes.size() > 0) {
2605 availableLanes.clear();
2606 for (
int i = 0; i < (int)
myLanes.size(); ++i) {
2611 availableLanes.push_back(i);
2613 if (availableLanes.size() > 0) {
2617 availableLanes.clear();
2618 for (
int i = 0; i < (int)
myLanes.size(); ++i) {
2623 availableLanes.push_back(i);
2625 if (availableLanes.size() > 0) {
2629 availableLanes.clear();
2630 for (
int i = 0; i < (int)
myLanes.size(); ++i) {
2635 availableLanes.push_back(i);
2637 if (availableLanes.size() > 0) {
2642 if ((*i).fromLane == -1) {
2655 if (priorities.empty()) {
2658 #ifdef DEBUG_CONNECTION_GUESSING
2660 std::cout <<
"divideSelectedLanesOnEdges " <<
getID() <<
" out=" <<
toString(*outgoing) <<
" prios=" <<
toString(priorities) <<
" avail=" <<
toString(availableLanes) <<
"\n";
2664 const int numOutgoing = (int)outgoing->size();
2665 std::vector<int> resultingLanesFactor;
2666 resultingLanesFactor.reserve(numOutgoing);
2667 int minResulting = std::numeric_limits<int>::max();
2668 for (
int i = 0; i < numOutgoing; i++) {
2670 const int res = priorities[i] * (int)availableLanes.size();
2671 resultingLanesFactor.push_back(res);
2672 if (minResulting > res && res > 0) {
2684 transition.reserve(numOutgoing);
2685 for (
int i = 0; i < numOutgoing; i++) {
2687 assert(i < (
int)resultingLanesFactor.size());
2688 const int tmpNum = (resultingLanesFactor[i] + minResulting - 1) / minResulting;
2689 numVirtual += tmpNum;
2690 for (
int j = 0; j < tmpNum; j++) {
2691 transition.push_back((*outgoing)[i]);
2694 #ifdef DEBUG_CONNECTION_GUESSING
2696 std::cout <<
" minResulting=" << minResulting <<
" numVirtual=" << numVirtual <<
" availLanes=" <<
toString(availableLanes) <<
" resLanes=" <<
toString(resultingLanesFactor) <<
" transition=" <<
toString(transition) <<
"\n";
2705 for (
NBEdge*
const target : *outgoing) {
2706 assert(l2eConns.find(target) != l2eConns.end());
2707 for (
const int j : l2eConns.find(target)->second) {
2708 const int fromIndex = availableLanes[j];
2709 if ((
getPermissions(fromIndex) & target->getPermissions()) == 0) {
2723 int targetLanes = target->getNumLanes();
2727 if (numConsToTarget >= targetLanes) {
2730 if (
myLanes[fromIndex].connectionsDone) {
2733 #ifdef DEBUG_CONNECTION_GUESSING
2735 std::cout <<
" connectionsDone from " <<
getID() <<
"_" << fromIndex <<
": ";
2737 std::cout << c.getDescription(
this) <<
", ";
2745 #ifdef DEBUG_CONNECTION_GUESSING
2747 std::cout <<
" request connection from " <<
getID() <<
"_" << fromIndex <<
" to " << target->getID() <<
"\n";
2760 const int numOutgoing = (int) outgoing->size();
2761 NBEdge* target =
nullptr;
2762 NBEdge* rightOfTarget =
nullptr;
2763 NBEdge* leftOfTarget =
nullptr;
2765 for (
int i = 0; i < numOutgoing; i++) {
2766 if (maxPrio < priorities[i]) {
2769 maxPrio = priorities[i];
2770 target = (*outgoing)[i];
2771 rightOfTarget = i == 0 ? outgoing->back() : (*outgoing)[i - 1];
2772 leftOfTarget = i + 1 == numOutgoing ? outgoing->front() : (*outgoing)[i + 1];
2776 if (target ==
nullptr) {
2784 const int numDesiredConsToTarget =
MIN2(targetLanes, (
int)availableLanes.size());
2785 #ifdef DEBUG_CONNECTION_GUESSING
2787 std::cout <<
" checking extra lanes for target=" << target->
getID() <<
" cons=" << numConsToTarget <<
" desired=" << numDesiredConsToTarget <<
"\n";
2790 std::vector<int>::const_iterator it_avail = availableLanes.begin();
2791 while (numConsToTarget < numDesiredConsToTarget && it_avail != availableLanes.end()) {
2792 const int fromIndex = *it_avail;
2801 && !
myLanes[fromIndex].connectionsDone
2803 #ifdef DEBUG_CONNECTION_GUESSING
2805 std::cout <<
" candidate from " <<
getID() <<
"_" << fromIndex <<
" to " << target->
getID() <<
"\n";
2814 #ifdef DEBUG_CONNECTION_GUESSING
2816 std::cout <<
" request additional connection from " <<
getID() <<
"_" << fromIndex <<
" to " << target->
getID() <<
"\n";
2822 #ifdef DEBUG_CONNECTION_GUESSING
2827 <<
" rightOfTarget=" << rightOfTarget->
getID()
2828 <<
" leftOfTarget=" << leftOfTarget->
getID()
2839 const std::vector<int>
2841 std::vector<int> priorities;
2848 priorities.reserve(outgoing->size());
2849 for (
const NBEdge*
const out : *outgoing) {
2851 assert((prio + 1) * 2 > 0);
2852 prio = (prio + 1) * 2;
2853 priorities.push_back(prio);
2858 #ifdef DEBUG_CONNECTION_GUESSING
2860 <<
" outgoing=" <<
toString(*outgoing)
2861 <<
" priorities1=" <<
toString(priorities)
2866 assert(priorities.size() > 0);
2868 #ifdef DEBUG_CONNECTION_GUESSING
2870 std::cout <<
" priorities2=" <<
toString(priorities) <<
"\n";
2877 if (mainDirections.
empty()) {
2878 assert(dist < (
int)priorities.size());
2879 priorities[dist] *= 2;
2880 #ifdef DEBUG_CONNECTION_GUESSING
2882 std::cout <<
" priorities3=" <<
toString(priorities) <<
"\n";
2887 priorities[dist] += 1;
2892 priorities[(int)priorities.size() - 1] /= 2;
2893 #ifdef DEBUG_CONNECTION_GUESSING
2895 std::cout <<
" priorities6=" <<
toString(priorities) <<
"\n";
2899 && outgoing->size() > 2
2900 && availableLanes.size() == 2
2901 && (*outgoing)[dist]->getPriority() == (*outgoing)[0]->getPriority()) {
2903 priorities.back() /= 2;
2904 #ifdef DEBUG_CONNECTION_GUESSING
2906 std::cout <<
" priorities7=" <<
toString(priorities) <<
"\n";
2913 priorities[dist] *= 2;
2914 #ifdef DEBUG_CONNECTION_GUESSING
2916 std::cout <<
" priorities4=" <<
toString(priorities) <<
"\n";
2920 priorities[dist] *= 3;
2921 #ifdef DEBUG_CONNECTION_GUESSING
2923 std::cout <<
" priorities5=" <<
toString(priorities) <<
"\n";
2933 NBEdge::appendTurnaround(
bool noTLSControlled,
bool noFringe,
bool onlyDeadends,
bool onlyTurnlane,
bool noGeometryLike,
bool checkPermissions) {
2946 bool isDeadEnd =
true;
2948 if ((c.toEdge->getPermissions(c.toLane)
2956 if (onlyDeadends && !isDeadEnd) {
2959 const int fromLane = (int)
myLanes.size() - 1;
2969 if (checkPermissions) {
2996 if (turnIncoming.size() > 1) {
3021 if (pos < tolerance) {
3035 for (
int i = 0; i < lanes; i++) {
3037 for (std::vector<NBEdge::Connection>::iterator j = elv.begin(); j != elv.end(); j++) {
3039 assert(el.
tlID ==
"");
3061 if (c.fromLane == fromLane && c.toEdge == toEdge && c.toLane == toLane && c.uncontrolled) {
3081 assert(fromLane < 0 || fromLane < (
int)
myLanes.size());
3083 if (fromLane >= 0 && toLane >= 0) {
3085 std::vector<Connection>::iterator i =
3093 connection.
tlID = tlID;
3102 bool hadError =
false;
3104 if ((*i).toEdge != toEdge) {
3107 if (fromLane >= 0 && fromLane != (*i).fromLane) {
3110 if (toLane >= 0 && toLane != (*i).toLane) {
3113 if ((*i).tlID ==
"") {
3115 (*i).tlLinkIndex = tlIndex;
3116 (*i).tlLinkIndex2 = tlIndex2;
3119 if ((*i).tlID != tlID && (*i).tlLinkIndex == tlIndex) {
3120 WRITE_WARNINGF(
"The lane '%' on edge '%' already had a traffic light signal.", i->fromLane,
getID());
3125 if (hadError && no == 0) {
3126 WRITE_WARNINGF(
"Could not set any signal of the tlLogic '%' (unknown group).", tlID);
3152 ret =
myLanes[lane].shape.reverse();
3172 ret =
myLanes[lane].shape.reverse();
3184 reason =
"laneNumber";
3194 reason =
"bidi-rail";
3208 if (find(conn.begin(), conn.end(), possContinuation) == conn.end()) {
3209 reason =
"disconnected";
3220 reason =
"disconnected";
3226 if (conns.size() <
myLanes.size() - offset) {
3227 reason =
"some lanes disconnected";
3241 reason =
"priority";
3251 reason =
"spreadType";
3255 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3257 reason =
"lane " +
toString(i) +
" speed";
3259 }
else if (
myLanes[i].permissions != possContinuation->
myLanes[i].permissions) {
3260 reason =
"lane " +
toString(i) +
" permissions";
3262 }
else if (
myLanes[i].width != possContinuation->
myLanes[i].width &&
3264 reason =
"lane " +
toString(i) +
" width";
3281 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3287 if (origID != origID2) {
3296 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3327 if ((*i).toEdge == e && (*i).tlID !=
"") {
3353 assert(distances.size() > 0);
3359 NBEdge::addLane(
int index,
bool recomputeShape,
bool recomputeConnections,
bool shiftIndices) {
3360 assert(index <= (
int)
myLanes.size());
3364 int templateIndex = index > 0 ? index - 1 : index + 1;
3373 if (recomputeShape) {
3376 if (recomputeConnections) {
3377 for (EdgeVector::const_iterator i = incs.begin(); i != incs.end(); ++i) {
3378 (*i)->invalidateConnections(
true);
3381 }
else if (shiftIndices) {
3384 if (c.fromLane >= index) {
3403 int newLaneNo = (int)
myLanes.size() + by;
3404 while ((
int)
myLanes.size() < newLaneNo) {
3414 assert(index < (
int)
myLanes.size());
3419 for (EdgeVector::const_iterator i = incs.begin(); i != incs.end(); ++i) {
3420 (*i)->invalidateConnections(
true);
3423 }
else if (shiftIndices) {
3426 inc->removeFromConnections(
this, -1, index,
false,
true);
3434 int newLaneNo = (int)
myLanes.size() - by;
3435 assert(newLaneNo > 0);
3436 while ((
int)
myLanes.size() > newLaneNo) {
3454 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3458 assert(lane < (
int)
myLanes.size());
3459 myLanes[lane].permissions |= vclass;
3467 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3471 assert(lane < (
int)
myLanes.size());
3472 myLanes[lane].permissions &= ~vclass;
3480 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3484 assert(lane < (
int)
myLanes.size());
3485 myLanes[lane].preferred |= vclass;
3495 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3501 assert(lane < (
int)
myLanes.size());
3508 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3514 assert(lane < (
int)
myLanes.size());
3530 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3542 const std::map<SVCPermissions, double>&
3547 return myLanes[lane].stopOffsets;
3556 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3562 assert(lane < (
int)
myLanes.size());
3563 myLanes[lane].endOffset = offset;
3574 if (offsets.size() != 0 && 0 > offsets.begin()->second) {
3582 assert(lane < (
int)
myLanes.size());
3583 if (
myLanes[lane].stopOffsets.size() == 0 || overwrite) {
3584 if (offsets.size() != 0 && 0 > offsets.begin()->second) {
3588 myLanes[lane].stopOffsets = offsets;
3601 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3607 assert(lane < (
int)
myLanes.size());
3614 assert(lane < (
int)
myLanes.size());
3615 myLanes[lane].accelRamp = accelRamp;
3621 assert(lane < (
int)
myLanes.size());
3622 myLanes[lane].customShape = shape;
3629 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3634 assert(lane < (
int)
myLanes.size());
3635 myLanes[lane].permissions = permissions;
3643 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3648 assert(lane < (
int)
myLanes.size());
3649 myLanes[lane].preferred = permissions;
3658 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3663 assert(lane < (
int)
myLanes.size());
3664 return myLanes[lane].permissions;
3682 for (std::vector<Lane>::iterator i =
myLanes.begin(); i !=
myLanes.end(); ++i) {
3683 (*i).permissions =
SVCAll;
3717 for (
int i = start; i != end; i += direction) {
3730 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3731 if (
myLanes[i].permissions == permissions) {
3743 for (
int i = start; i != end; i += direction) {
3744 if (
myLanes[i].permissions != 0) {
3748 return end - direction;
3752 std::set<SVCPermissions>
3754 std::set<SVCPermissions> result;
3758 for (
int i = iStart; i < iEnd; ++i) {
3768 if ((lane.permissions & permissions) == permissions) {
3785 std::cout <<
getID() <<
" angle=" <<
getAngleAtNode(node) <<
" convAngle=" << angle <<
"\n";
3803 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3808 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3842 if (lane.permissions == vclass) {
3864 myLanes[0].permissions = vclass;
3865 myLanes[0].width = fabs(width);
3875 for (EdgeVector::const_iterator it = incoming.begin(); it != incoming.end(); ++it) {
3876 (*it)->shiftToLanesToEdge(
this, 1);
3887 if (
myLanes[0].permissions != vclass) {
3897 for (EdgeVector::const_iterator it = incoming.begin(); it != incoming.end(); ++it) {
3898 (*it)->shiftToLanesToEdge(
this, 0);
3911 if ((*it).toEdge == to && (*it).toLane >= 0) {
3912 (*it).toLane += laneOff;
3921 const int i = (node ==
myTo ? -1 : 0);
3922 const int i2 = (node ==
myTo ? 0 : -1);
3928 if (dist < neededOffset && dist2 < neededOffset2) {
3963 double avgEndOffset = 0;
3965 avgEndOffset += lane.endOffset;
3970 avgEndOffset /=
myLanes.size();
3971 return MAX2(result - avgEndOffset, POSITION_EPS);
3977 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3982 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3995 if (con.fromLane >= 0 && con.toLane >= 0 && con.toEdge !=
nullptr &&
3997 & con.toEdge->getPermissions(con.toLane) & vClass) != 0)
4012 std::pair<const NBEdge*, const Connection*> pair(con.toEdge,
nullptr);
4016 }
else if (con.fromLane >= 0 && con.toLane >= 0 &&
4017 con.toEdge !=
nullptr &&
4018 (
getPermissions(con.fromLane) & con.toEdge->getPermissions(con.toLane) & vClass) != 0) {
4020 if (con.getLength() > 0) {
4034 std::cout <<
" " <<
getID() <<
"_" << c.fromLane <<
"->" << c.toEdge->getID() <<
"_" << c.toLane <<
"\n";
4056 bool haveJoined =
false;
4061 const std::string newType =
myLanes[i].type +
"|" +
myLanes[i + 1].type;
4077 for (
NBEdge* edge : edges) {
4078 if ((edge->getPermissions() & permissions) != 0) {
4079 result.push_back(edge);
4088 if (cands.size() == 0) {
4092 NBEdge* best = cands.front();
4103 if (cands.size() == 0) {
4107 NBEdge* best = cands.front();
std::vector< std::string > & split(const std::string &s, char delim, std::vector< std::string > &elems)
#define WRITE_WARNINGF(...)
#define WRITE_MESSAGE(msg)
#define WRITE_WARNING(msg)
std::vector< std::pair< const NBRouterEdge *, const NBRouterEdge * > > ConstRouterEdgePairVector
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
KeepClear
keepClear status of connections
const SVCPermissions SVCAll
all VClasses are allowed
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission is a railway edge.
const SVCPermissions SVC_UNSPECIFIED
permissions not specified
bool isForbidden(SVCPermissions permissions)
Returns whether an edge with the given permission is a forbidden edge.
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_IGNORING
vehicles ignoring classes
@ SVC_RAIL_CLASSES
classes which drive on tracks
@ SVC_PASSENGER
vehicle is a passenger car (a "normal" car)
@ SVC_BICYCLE
vehicle is a bicycle
@ SVC_DELIVERY
vehicle is a small delivery vehicle
@ SVC_BUS
vehicle is a bus
@ SVC_PEDESTRIAN
pedestrian
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
const std::string SUMO_PARAM_ORIGID
LaneSpreadFunction
Numbers representing special SUMO-XML-attribute values Information how the edge's lateral offset shal...
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)....
@ PARTLEFT
The link is a partial left direction.
@ RIGHT
The link is a (hard) right direction.
@ TURN
The link is a 180 degree turn.
@ LEFT
The link is a (hard) left direction.
@ STRAIGHT
The link is a straight direction.
@ PARTRIGHT
The link is a partial right direction.
int gPrecision
the precision for floating point outputs
bool gDebugFlag1
global utility flags for debugging
const double SUMO_const_laneWidth
const double SUMO_const_laneWidthAndOffset
const double SUMO_const_laneOffset
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
static void compute(BresenhamCallBack *callBack, const int val1, const int val2)
static const double INVALID_OFFSET
a value to signify offsets outside the range of [0, Line.length()]
static double legacyDegree(const double angle, const bool positive=false)
static double angleDiff(const double angle1, const double angle2)
Returns the difference of the second angle to the first angle in radiants.
int getFromLane() const
returns the from-lane
int getTLIndex() const
returns the index within the controlling tls or InvalidTLIndex if this link is unontrolled
void shiftLaneIndex(NBEdge *edge, int offset, int threshold=-1)
patches lane indices refering to the given edge and above the threshold by the given offset
int getToLane() const
returns the to-lane
NBEdge * getTo() const
returns the to-edge (end of the connection)
Holds (- relative to the edge it is build from -!!!) the list of main directions a vehicle that drive...
bool empty() const
returns the information whether no following street has a higher priority
bool includes(Direction d) const
returns the information whether the street in the given direction has a higher priority
int getStraightest() const
returns the index of the straightmost among the given outgoing edges
MainDirections(const EdgeVector &outgoing, NBEdge *parent, NBNode *to, const std::vector< int > &availableLanes)
constructor
std::vector< Direction > myDirs
list of the main direction within the following junction relative to the edge
~MainDirections()
destructor
int myStraightest
the index of the straightmost among the given outgoing edges
Direction
enum of possible directions
A class that being a bresenham-callback assigns the incoming lanes to the edges.
void execute(const int lane, const int virtEdge)
executes a bresenham - step
const std::map< NBEdge *, std::vector< int > > & getBuiltConnections() const
get built connections
Class to sort edges by their angle.
int operator()(const Connection &c1, const Connection &c2) const
comparing operation
The representation of a single edge during network building.
void addGeometryPoint(int index, const Position &p)
Adds a further geometry point.
void mirrorX()
mirror coordinates along the x-axis
void setPreferredVehicleClass(SVCPermissions permissions, int lane=-1)
set preferred Vehicle Class
double getLaneSpeed(int lane) const
get lane speed
std::map< int, double > myStopOffsets
A vClass specific stop offset - assumed of length 0 (unspecified) or 1. For the latter case the int i...
bool addEdge2EdgeConnection(NBEdge *dest, bool overrideRemoval=false)
Adds a connection to another edge.
double getLength() const
Returns the computed length of the edge.
double myLaneWidth
This width of this edge's lanes.
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
void buildInnerEdges(const NBNode &n, int noInternalNoSplits, int &linkIndex, int &splitIndex)
std::vector< Connection > myConnectionsToDelete
List of connections marked for delayed removal.
const EdgeVector * getConnectedSorted()
Returns the list of outgoing edges without the turnaround sorted in clockwise direction.
double myEndOffset
This edges's offset to the intersection begin (will be applied to all lanes)
int myToJunctionPriority
The priority normalised for the node the edge is incoming in.
void setPermissions(SVCPermissions permissions, int lane=-1)
set allowed/disallowed classes for the given lane or for all lanes if -1 is given
double getLoadedLength() const
Returns the length was set explicitly or the computed length if it wasn't set.
double getCrossingAngle(NBNode *node)
return the angle for computing pedestrian crossings at the given node
void addBikeLane(double width)
add a bicycle lane of the given width and shift existing connctions
bool expandableBy(NBEdge *possContinuation, std::string &reason) const
Check if Node is expandable.
void init(int noLanes, bool tryIgnoreNodePositions, const std::string &origID)
Initialization routines common to all constructors.
void setSpeed(int lane, double speed)
set lane specific speed (negative lane implies set for all lanes)
void reinitNodes(NBNode *from, NBNode *to)
Resets nodes but keeps all other values the same (used when joining)
double mySpeed
The maximal speed.
double getLaneWidth() const
Returns the default width of lanes of this edge.
PositionVector getCWBoundaryLine(const NBNode &n) const
get the outer boundary of this edge when going clock-wise around the given node
std::vector< Connection > myConnections
List of connections to following edges.
Connection & getConnectionRef(int fromLane, const NBEdge *to, int toLane)
Returns reference to the specified connection This method goes through "myConnections" and returns th...
NBEdge()
constructor for dummy edge
void divideOnEdges(const EdgeVector *outgoing)
divides the lanes on the outgoing edges
ConstRouterEdgePairVector myViaSuccessors
PositionVector getCCWBoundaryLine(const NBNode &n) const
get the outer boundary of this edge when going counter-clock-wise around the given node
void setOrigID(const std::string origID)
set origID for all lanes
void incLaneNo(int by)
increment lane
static EdgeVector filterByPermissions(const EdgeVector &edges, SVCPermissions permissions)
return only those edges that permit at least one of the give permissions
const std::string & getStreetName() const
Returns the street name of this edge.
void addLane(int index, bool recomputeShape, bool recomputeConnections, bool shiftIndices)
add lane
bool hasLaneSpecificSpeed() const
whether lanes differ in speed
void setAverageLengthWithOpposite(double val)
patch average lane length in regard to the opposite edge
void disallowVehicleClass(int lane, SUMOVehicleClass vclass)
set disallowed class for the given lane or for all lanes if -1 is given
double getShapeStartAngle() const
Returns the angle at the start of the edge.
static const int UNSPECIFIED_INTERNAL_LANE_INDEX
internal lane computation not yet done
void appendTurnaround(bool noTLSControlled, bool noFringe, bool onlyDeadends, bool onlyTurnlane, bool noGeometryLike, bool checkPermissions)
Add a connection to the previously computed turnaround, if wished and a turning direction exists (myT...
static bool connections_sorter(const Connection &c1, const Connection &c2)
connections_sorter sort by fromLane, toEdge and toLane
std::string myType
The type of the edge.
bool hasPermissions() const
whether at least one lane has restrictions
LaneSpreadFunction getLaneSpreadFunction() const
Returns how this edge's lanes' lateral offset is computed.
bool hasDefaultGeometryEndpoints() const
Returns whether the geometry is terminated by the node positions This default may be violated by init...
bool isBidiRail(bool ignoreSpread=false) const
whether this edge is part of a bidirectional railway
static const bool UNSPECIFIED_CONNECTION_UNCONTROLLED
TLS-controlled despite its node controlled not specified.
const EdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges for the given vClass.
void dismissVehicleClassInformation()
dimiss vehicle class information
bool computeEdge2Edges(bool noLeftMovers)
computes the edge (step1: computation of approached edges)
EdgeBuildingStep getStep() const
The building step of this edge.
LaneSpreadFunction myLaneSpreadFunction
The information about how to spread the lanes.
void moveConnectionToLeft(int lane)
void restoreBikelane(std::vector< NBEdge::Lane > oldLanes, PositionVector oldGeometry, std::vector< NBEdge::Connection > oldConnections)
restore an previously added BikeLane
Position getEndpointAtNode(const NBNode *node) const
NBEdge * getStraightContinuation(SVCPermissions permissions) const
return the straightest follower edge for the given permissions or nullptr (never returns turn-arounds...
void preferVehicleClass(int lane, SUMOVehicleClass vclass)
prefer certain vehicle class
bool hasLoadedLength() const
Returns whether a length was set explicitly.
void restoreSidewalk(std::vector< NBEdge::Lane > oldLanes, PositionVector oldGeometry, std::vector< NBEdge::Connection > oldConnections)
restore an previously added sidewalk
void divideSelectedLanesOnEdges(const EdgeVector *outgoing, const std::vector< int > &availableLanes)
divide selected lanes on edges
bool hasLaneSpecificStopOffsets() const
whether lanes differ in stopOffsets
void setNodeBorder(const NBNode *node, const Position &p, const Position &p2, bool rectangularCut)
Set Node border.
int getFirstNonPedestrianLaneIndex(int direction, bool exclusive=false) const
return the first lane with permissions other than SVC_PEDESTRIAN and 0
const std::string & getID() const
const std::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
void shiftToLanesToEdge(NBEdge *to, int laneOff)
modifify the toLane for all connections to the given edge
void checkGeometry(const double maxAngle, const double minRadius, bool fix, bool silent)
Check the angles of successive geometry segments.
static double myDefaultConnectionLength
bool bothLeftTurns(const NBNode &n, LinkDirection dir, const NBEdge *otherFrom, const NBEdge::Connection &otherCon) const
determine conflict between opposite left turns
bool isNearEnough2BeJoined2(NBEdge *e, double threshold) const
Check if edge is near enought to be joined to another edge.
EdgeBuildingStep myStep
The building step.
NBNode * getToNode() const
Returns the destination node of the edge.
void setLaneType(int lane, const std::string &type)
set lane specific type (negative lane implies set for all lanes)
bool computeLanes2Edges()
computes the edge, step2: computation of which lanes approach the edges)
EdgeBuildingStep
Current state of the edge within the building process.
@ INIT_REJECT_CONNECTIONS
The edge has been loaded and connections shall not be added.
@ EDGE2EDGES
The relationships between edges are computed/loaded.
@ LANES2LANES_RECHECK
Lanes to lanes - relationships are computed; should be recheked.
@ LANES2LANES_DONE
Lanes to lanes - relationships are computed; no recheck is necessary/wished.
@ LANES2EDGES
Lanes to edges - relationships are computed/loaded.
@ LANES2LANES_USER
Lanes to lanes - relationships are loaded; no recheck is necessary/wished.
@ INIT
The edge has been loaded, nothing is computed yet.
NBEdge * getStraightPredecessor(SVCPermissions permissions) const
return the straightest predecessor edge for the given permissions or nullptr (never returns turn-arou...
void remapConnections(const EdgeVector &incoming)
Remaps the connection in a way that allows the removal of it.
double getSpeed() const
Returns the speed allowed on this edge.
int getFirstAllowedLaneIndex(int direction) const
return the first lane that permits at least 1 vClass or the last lane if search direction of there is...
static const double UNSPECIFIED_LOADED_LENGTH
no length override given
void setLaneWidth(int lane, double width)
set lane specific width (negative lane implies set for all lanes)
void resetLaneShapes()
reset lane shapes to what they would be before cutting with the junction shapes
bool setControllingTLInformation(const NBConnection &c, const std::string &tlID)
Returns if the link could be set as to be controlled.
void setAcceleration(int lane, bool accelRamp)
marks one lane as acceleration lane
NBNode * tryGetNodeAtPosition(double pos, double tolerance=5.0) const
Returns the node at the given edges length (using an epsilon)
void setLaneSpreadFunction(LaneSpreadFunction spread)
(Re)sets how the lanes lateral offset shall be computed
void clearControllingTLInformation()
clears tlID for all connections
bool isTurningDirectionAt(const NBEdge *const edge) const
Returns whether the given edge is the opposite direction to this edge.
void addStraightConnections(const EdgeVector *outgoing, const std::vector< int > &availableLanes, const std::vector< int > &priorities)
add some straight connections
bool hasLaneSpecificPermissions() const
whether lanes differ in allowed vehicle classes
bool needsLaneSpecificOutput() const
whether at least one lane has values differing from the edges values
void computeAngle()
computes the angle of this edge and stores it in myAngle
std::vector< Connection > getConnectionsFromLane(int lane, NBEdge *to=nullptr, int toLane=-1) const
Returns connections from a given lane.
static const double UNSPECIFIED_SIGNAL_OFFSET
unspecified signal offset
void addSidewalk(double width)
add a pedestrian sidewalk of the given width and shift existing connctions
void reinit(NBNode *from, NBNode *to, const std::string &type, double speed, int nolanes, int priority, PositionVector geom, double width, double endOffset, const std::string &streetName, LaneSpreadFunction spread=LaneSpreadFunction::RIGHT, bool tryIgnoreNodePositions=false)
Resets initial values.
bool setStopOffsets(int lane, std::map< int, double > offsets, bool overwrite=false)
set lane and vehicle class specific stopOffset (negative lane implies set for all lanes)
bool hasSignalisedConnectionTo(const NBEdge *const e) const
Check if edge has signalised connections.
std::vector< Lane > myLanes
Lane information.
int getNumLanes() const
Returns the number of lanes.
const PositionVector & getGeometry() const
Returns the geometry of the edge.
bool hasAccelLane() const
whether one of the lanes is an acceleration lane
PositionVector myToBorder
void extendGeometryAtNode(const NBNode *node, double maxExtent)
linearly extend the geometry at the given node
static const double UNSPECIFIED_CONTPOS
unspecified internal junction position
static const double ANGLE_LOOKAHEAD
the distance at which to take the default angle
void reduceGeometry(const double minDist)
Removes points with a distance lesser than the given.
static NBEdge DummyEdge
Dummy edge to use when a reference must be supplied in the no-arguments constructor (FOX technicality...
bool joinLanes(SVCPermissions perms)
join adjacent lanes with the given permissions
void resetNodeBorder(const NBNode *node)
void markAsInLane2LaneState()
mark edge as in lane to state lane
bool mayBeTLSControlled(int fromLane, NBEdge *toEdge, int toLane) const
return true if certain connection must be controlled by TLS
void addRestrictedLane(double width, SUMOVehicleClass vclass)
add a lane of the given width, restricted to the given class and shift existing connections
void removeFromConnections(NBEdge *toEdge, int fromLane=-1, int toLane=-1, bool tryLater=false, const bool adaptToLaneRemoval=false, const bool keepPossibleTurns=false)
Removes the specified connection(s)
double myLength
The length of the edge.
NBEdge::Lane getFirstNonPedestrianLane(int direction) const
@brif get first non-pedestrian lane
void invalidateConnections(bool reallowSetting=false)
invalidate current connections of edge
const std::vector< int > prepareEdgePriorities(const EdgeVector *outgoing, const std::vector< int > &availableLanes)
recomputes the edge priorities and manipulates them for a distribution of lanes on edges which is mor...
int myIndex
the index of the edge in the list of all edges. Set by NBEdgeCont and requires re-set whenever the li...
double getTotalWidth() const
Returns the combined width of all lanes of this edge.
PositionVector cutAtIntersection(const PositionVector &old) const
cut shape at the intersection shapes
Position geometryPositionAtOffset(double offset) const
return position taking into account loaded length
static const double UNSPECIFIED_VISIBILITY_DISTANCE
unspecified foe visibility for connections
bool canMoveConnection(const Connection &con, int newFromLane) const
whether the connection can originate on newFromLane
void allowVehicleClass(int lane, SUMOVehicleClass vclass)
set allowed class for the given lane or for all lanes if -1 is given
bool isConnectedTo(const NBEdge *e, const bool ignoreTurnaround=false) const
Returns the information whethe a connection to the given edge has been added (or computed)
bool haveIntersection(const NBNode &n, const PositionVector &shape, const NBEdge *otherFrom, const NBEdge::Connection &otherCon, int numPoints, double width2, int shapeFlag=0) const
double getMaxLaneOffset()
get max lane offset
void deleteLane(int index, bool recompute, bool shiftIndices)
delete lane
const std::map< int, double > & getStopOffsets() const
Returns the stopOffset to the end of the edge.
NBEdge * myPossibleTurnDestination
The edge that would be the turn destination if there was one.
const PositionVector & getNodeBorder(const NBNode *node) const
int getNumLanesThatAllow(SVCPermissions permissions) const
get lane indices that allow the given permissions
const NBNode * mySignalNode
bool hasLaneSpecificWidth() const
whether lanes differ in width
void moveConnectionToRight(int lane)
std::set< SVCPermissions > getPermissionVariants(int iStart, int iEnd) const
return all permission variants within the specified lane range [iStart, iEnd[
void reshiftPosition(double xoff, double yoff)
Applies an offset to the edge.
void moveOutgoingConnectionsFrom(NBEdge *e, int laneOff)
move outgoing connection
std::string getLaneID(int lane) const
get lane ID
bool myIsOffRamp
whether this edge is an Off-Ramp or leads to one
bool setConnection(int lane, NBEdge *destEdge, int destLane, Lane2LaneInfoType type, bool mayUseSameDestination=false, bool mayDefinitelyPass=false, KeepClear keepClear=KEEPCLEAR_UNSPECIFIED, double contPos=UNSPECIFIED_CONTPOS, double visibility=UNSPECIFIED_VISIBILITY_DISTANCE, double speed=UNSPECIFIED_SPEED, double length=myDefaultConnectionLength, const PositionVector &customShape=PositionVector::EMPTY, const bool uncontrolled=UNSPECIFIED_CONNECTION_UNCONTROLLED, SVCPermissions permissions=SVC_UNSPECIFIED, bool postProcess=false)
Adds a connection to a certain lane of a certain edge.
static const double UNSPECIFIED_SPEED
unspecified lane speed
Lane2LaneInfoType
Modes of setting connections between lanes.
@ USER
The connection was given by the user.
@ VALIDATED
The connection was computed and validated.
@ COMPUTED
The connection was computed.
static PositionVector startShapeAt(const PositionVector &laneShape, const NBNode *startNode, PositionVector nodeShape)
std::string getSidewalkID()
get the lane id for the canonical sidewalk lane
std::vector< int > getConnectionLanes(NBEdge *currentOutgoing, bool withBikes=true) const
Returns the list of lanes that may be used to reach the given edge.
void computeLaneShapes()
compute lane shapes
double getAngleAtNodeToCenter(const NBNode *const node) const
Returns the angle of from the node shape center to where the edge meets the node shape.
int getSpecialLane(SVCPermissions permissions) const
return index of the first lane that allows the given permissions
bool hasLaneSpecificEndOffset() const
whether lanes differ in offset
int getJunctionPriority(const NBNode *const node) const
Returns the junction priority (normalised for the node currently build)
double myDistance
The mileage/kilometrage at the start of this edge in a linear coordination system.
void assignInternalLaneLength(std::vector< Connection >::iterator i, int numLanes, double lengthSum)
assign length to all lanes of an internal edge
bool myAmMacroscopicConnector
Information whether this edge is a (macroscopic) connector.
EdgeVector getConnectedEdges() const
Returns the list of outgoing edges unsorted.
const ConstRouterEdgePairVector & getViaSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges for the given vClass.
void setLaneShape(int lane, const PositionVector &shape)
sets a custom lane shape
double myLoadedLength
An optional length to use (-1 if not valid)
void sortOutgoingConnectionsByAngle()
sorts the outgoing connections by their angle relative to their junction
double myStartAngle
The angles of the edge.
NBEdge * getTurnDestination(bool possibleDestination=false) const
void shiftPositionAtNode(NBNode *node, NBEdge *opposite)
shift geometry at the given node to avoid overlap
double getAngleAtNode(const NBNode *const node) const
Returns the angle of the edge's geometry at the given node.
bool hasLaneSpecificType() const
whether lanes differ in type
PositionVector myFromBorder
intersection borders (because the node shape might be invalid)
double getSignalOffset() const
Returns the offset of a traffic signal from the end of this edge.
bool hasDefaultGeometry() const
Returns whether the geometry consists only of the node positions.
bool myAmInTLS
Information whether this is lies within a joined tls.
void setTurningDestination(NBEdge *e, bool onlyPossible=false)
Sets the turing destination at the given edge.
bool hasDefaultGeometryEndpointAtNode(const NBNode *node) const
Returns whether the geometry is terminated by the node positions This default may be violated by init...
NBEdge * myTurnDestination
The turn destination edge (if a connection exists)
int getPriority() const
Returns the priority of the edge.
void computeEdgeShape(double smoothElevationThreshold=-1)
Recomputeds the lane shapes to terminate at the node shape For every lane the intersection with the f...
static const double UNSPECIFIED_WIDTH
unspecified lane width
bool hasRestrictedLane(SUMOVehicleClass vclass) const
returns whether any lane already allows the given vclass exclusively
void copyConnectionsFrom(NBEdge *src)
copy connections from antoher edge
void debugPrintConnections(bool outgoing=true, bool incoming=false) const
debugging helper to print all connections
Position mySignalPosition
the position of a traffic light signal on this edge
void replaceInConnections(NBEdge *which, NBEdge *by, int laneOff)
replace in current connections of edge
bool hasConnectionTo(NBEdge *destEdge, int destLane, int fromLane=-1) const
Retrieves info about a connection to a certain lane of a certain edge.
bool lanesWereAssigned() const
Check if lanes were assigned.
void restoreRestrictedLane(SUMOVehicleClass vclass, std::vector< NBEdge::Lane > oldLanes, PositionVector oldGeometry, std::vector< NBEdge::Connection > oldConnections)
restore a restricted lane
double getEndOffset() const
Returns the offset to the destination node.
bool isRailDeadEnd() const
whether this edge is a railway edge that does not continue
void setEndOffset(int lane, double offset)
set lane specific end-offset (negative lane implies set for all lanes)
static const double UNSPECIFIED_OFFSET
unspecified lane offset
void sortOutgoingConnectionsByIndex()
sorts the outgoing connections by their from-lane-index and their to-lane-index
bool recheckLanes()
recheck whether all lanes within the edge are all right and optimises the connections once again
int myFromJunctionPriority
The priority normalised for the node the edge is outgoing of.
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.
PositionVector computeLaneShape(int lane, double offset) const
Computes the shape for the given lane.
static int getLaneIndexFromLaneID(const std::string laneID)
bool addLane2LaneConnection(int fromLane, NBEdge *dest, int toLane, Lane2LaneInfoType type, bool mayUseSameDestination=false, bool mayDefinitelyPass=false, KeepClear keepClear=KEEPCLEAR_UNSPECIFIED, double contPos=UNSPECIFIED_CONTPOS, double visibility=UNSPECIFIED_VISIBILITY_DISTANCE, double speed=UNSPECIFIED_SPEED, double length=myDefaultConnectionLength, const PositionVector &customShape=PositionVector::EMPTY, const bool uncontrolled=UNSPECIFIED_CONNECTION_UNCONTROLLED, SVCPermissions=SVC_UNSPECIFIED, bool postProcess=false)
Adds a connection between the specified this edge's lane and an approached one.
bool hasCustomLaneShape() const
whether one of the lanes has a custom shape
bool hasLaneParams() const
whether one of the lanes has parameters set
const PositionVector & getLaneShape(int i) const
Returns the shape of the nth lane.
double getShapeEndAngle() const
Returns the angle at the end of the edge.
void setLoadedLength(double val)
set loaded length
PositionVector myGeom
The geometry for the edge.
const PositionVector getInnerGeometry() const
Returns the geometry of the edge without the endpoints.
void decLaneNo(int by)
decrement lane
Connection getConnection(int fromLane, const NBEdge *to, int toLane) const
Returns the specified connection This method goes through "myConnections" and returns the specified o...
NBNode * myFrom
The source and the destination node.
void append(NBEdge *continuation)
append another edge
void setJunctionPriority(const NBNode *const node, int prio)
Sets the junction priority of the edge.
double getFinalLength() const
get length that will be assigned to the lanes in the final network
void shortenGeometryAtNode(const NBNode *node, double reduction)
linearly extend the geometry at the given node
void setGeometry(const PositionVector &g, bool inner=false)
(Re)sets the edge's geometry
int myPriority
The priority of the edge.
std::string myStreetName
The street name (or whatever arbitrary string you wish to attach)
NBNode * getFromNode() const
Returns the origin node of the edge.
EdgeVector getIncomingEdges() const
Returns the list of incoming edges unsorted.
static double firstIntersection(const PositionVector &v1, const PositionVector &v2, double width2, const std::string &error="")
compute the first intersection point between the given lane geometries considering their rspective wi...
static double normRelAngle(double angle1, double angle2)
ensure that reverse relAngles (>=179.999) always count as turnarounds (-180)
A definition of a pedestrian crossing.
PositionVector shape
The crossing's shape.
EdgeVector edges
The edges being crossed.
double width
This crossing's width.
Represents a single node (junction) during network building.
void addIncomingEdge(NBEdge *edge)
adds an incoming 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 const int AVOID_INTERSECTING_LEFT_TURNS
void removeEdge(NBEdge *edge, bool removeFromConnections=true)
Removes edge from this node and optionally removes connections as well.
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
FringeType getFringeType() const
Returns fringe type.
static const int BACKWARD
SumoXMLNodeType getType() const
Returns the type of this node.
static bool isTrafficLight(SumoXMLNodeType type)
return whether the given type is a traffic light
static bool rightTurnConflict(const NBEdge *from, const NBEdge *to, int fromLane, const NBEdge *prohibitorFrom, const NBEdge *prohibitorTo, int prohibitorFromLane)
return whether the given laneToLane connection is a right turn which must yield to a bicycle crossing...
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.
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges (The edges which start at this node)
bool isLeftMover(const NBEdge *const from, const NBEdge *const to) const
Computes whether the given connection is a left mover across the junction.
bool mergeConflict(const NBEdge *from, const NBEdge::Connection &con, const NBEdge *prohibitorFrom, const NBEdge::Connection &prohibitorCon, bool foes) const
whether multple connections from the same edge target the same lane
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges (The edges which yield in this node)
std::vector< Crossing * > getCrossings() const
return this junctions pedestrian crossings
void addOutgoingEdge(NBEdge *edge)
adds an outgoing edge
const std::set< NBTrafficLightDefinition * > & getControllingTLS() const
Returns the traffic lights that were assigned to this node (The set of tls that control this node)
const PositionVector & getShape() const
retrieve the junction shape
const Position & getPosition() const
static const int FORWARD
edge directions (for pedestrian related stuff)
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 computeInternalLaneShape(const NBEdge *fromE, const NBEdge::Connection &con, int numPoints, NBNode *recordError=0, int shapeFlag=0) const
Compute the shape for an internal lane.
void shiftTLConnectionLaneIndex(NBEdge *edge, int offset, int threshold=-1)
patches loaded signal plans by modifying lane indices above threshold by the given offset
bool geometryLike() const
whether this is structurally similar to a geometry node
bool isTLControlled() const
Returns whether this node is controlled by any tls.
static const int SCURVE_IGNORE
Base class for objects which have an id.
std::string myID
The name of the object.
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
const std::string & getID() const
Returns the id.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
int getInt(const std::string &name) const
Returns the int-value of the named option (only for Option_Integer)
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
static OptionsCont & getOptions()
Retrieves the options.
const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
virtual void setParameter(const std::string &key, const std::string &value)
Sets a parameter.
void updateParameters(const std::map< std::string, std::string > &mapArg)
Adds or updates all given parameters from the map.
const std::map< std::string, std::string > & getParametersMap() const
Returns the inner key/value map.
bool knowsParameter(const std::string &key) const
Returns whether the parameter is known.
A point in 2D or 3D with translation and scaling methods.
static const Position INVALID
used to indicate that a position is valid
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimension
void add(const Position &pos)
Adds the given position to this one.
void setz(double z)
set position z
double z() const
Returns the z-position.
double angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position
double length2D() const
Returns the length.
void append(const PositionVector &v, double sameThreshold=2.0)
double beginEndAngle() const
returns the angle in radians of the line connecting the first and the last position
double length() const
Returns the length.
void push_front_noDoublePos(const Position &p)
insert in front a non double position
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
void add(double xoff, double yoff, double zoff)
void closePolygon()
ensures that the last position equals the first
std::vector< double > intersectsAtLengths2D(const PositionVector &other) const
For all intersections between this vector and other, return the 2D-length of the subvector from this ...
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)
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
std::vector< double > distances(const PositionVector &s, bool perpendicular=false) const
distances of all my points to s and all of s points to myself
PositionVector getOrthogonal(const Position &p, double extend, bool before, double length=1.0, double deg=90) const
return orthogonal through p (extending this vector if necessary)
std::pair< PositionVector, PositionVector > splitAt(double where, bool use2D=false) const
Returns the two lists made when this list vector is splitted at the given point.
void move2side(double amount, double maxExtension=100)
move position vector to side using certain ammount
PositionVector getSubpart2D(double beginOffset, double endOffset) const
get subpart of a position vector in two dimensions (Z is ignored)
PositionVector smoothedZFront(double dist=std::numeric_limits< double >::max()) const
returned vector that is smoothed at the front (within dist)
double angleAt2D(int pos) const
get angle in certain position of position vector
void removeDoublePoints(double minDist=POSITION_EPS, bool assertLength=false)
Removes positions if too near.
bool hasElevation() const
return whether two positions differ in z-coordinate
void extrapolate(const double val, const bool onlyFirst=false, const bool onlyLast=false)
extrapolate position vector
Position getCentroid() const
Returns the centroid (closes the polygon if unclosed)
void extrapolate2D(const double val, const bool onlyFirst=false)
extrapolate position vector in two dimensions (Z is ignored)
void push_back_noDoublePos(const Position &p)
insert in back a non double position
bool intersects(const Position &p1, const Position &p2) const
Returns the information whether this list of points interesects the given line.
PositionVector reverse() const
reverse position vector
PositionVector getSubpartByIndex(int beginIndex, int count) const
get subpart of a position vector using index and a cout
Position positionAtOffset2D(double pos, double lateralOffset=0) const
Returns the position at the given length.
PositionVector getSubpart(double beginOffset, double endOffset) const
get subpart of a position vector
bool around(const Position &p, double offset=0) const
Returns the information whether the position vector describes a polygon lying around the given point.
static bool isValidNetID(const std::string &value)
whether the given string is a valid id for a network element
Some static methods for string processing.
static std::string convertUmlaute(std::string str)
Converts german "Umlaute" to their latin-version.
static int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter,...
static T maxValue(const std::vector< T > &v)
A structure which describes a connection between edges or lanes.
int fromLane
The lane the connections starts at.
std::string viaID
if Connection have a via, ID of it
int toLane
The lane the connections yields in.
std::vector< int > foeInternalLinks
FOE Internal links.
double speed
custom speed for connection
NBEdge * toEdge
The edge the connections yields in.
Connection(int fromLane_, NBEdge *toEdge_, int toLane_)
Constructor.
double customLength
custom length for connection
double vmax
maximum velocity
PositionVector customShape
custom shape for connection
PositionVector viaShape
shape of via
std::string getDescription(const NBEdge *parent) const
get string describing this connection
double contPos
custom position for internal junction on this connection
std::string getInternalLaneID() const
get ID of internal lane
int internalLaneIndex
The lane index of this internal lane within the internal edge.
std::string tlID
The id of the traffic light that controls this connection.
int tlLinkIndex2
The index of the internal junction within the controlling traffic light (optional)
double length
computed length (average of all internal lane shape lengths that share an internal edge)
PositionVector shape
shape of Connection
std::string id
id of Connection
std::vector< std::string > foeIncomingLanes
FOE Incomings lanes.
bool haveVia
check if Connection have a Via
int tlLinkIndex
The index of this connection within the controlling traffic light.
double viaLength
the length of the via shape (maybe customized)
static ConstRouterEdgePairVector myViaSuccessors
An (internal) definition of a single lane of an edge.
Lane(NBEdge *e, const std::string &_origID)
constructor