109 double visibility_,
double speed_,
bool haveVia_,
bool uncontrolled_,
const PositionVector& customShape_) :
136 connectionsDone(false) {
149 assert((
int)myTransitions.size() > virtEdge);
151 NBEdge* succEdge = myTransitions[virtEdge];
152 std::vector<int> lanes;
156 std::map<NBEdge*, std::vector<int> >::iterator i =
myConnections.find(succEdge);
164 std::vector<int>::iterator j = find(lanes.begin(), lanes.end(), lane);
165 if (j == lanes.end()) {
167 lanes.push_back(lane);
180 if (outgoing.size() == 0) {
184 assert(outgoing.size() > 0);
186 #ifdef DEBUG_CONNECTION_GUESSING 188 std::cout <<
" MainDirections edge=" << parent->
getID() <<
" straightest=" << outgoing[indexOfStraightest]->getID() <<
" dir=" <<
toString(straightestDir) <<
"\n";
200 if (outgoing.back()->getJunctionPriority(to) == 1) {
206 if (outgoing.back()->getPriority() > tmp[0]->getPriority()) {
209 if (outgoing.back()->getNumLanes() > tmp[0]->getNumLanes()) {
218 NBEdge* edge = *(tmp.begin());
231 return myDirs.empty();
237 return find(myDirs.begin(), myDirs.end(), d) != myDirs.end();
257 std::string type,
double speed,
int nolanes,
258 int priority,
double laneWidth,
double endOffset,
259 const std::string& streetName,
278 init(nolanes,
false,
"");
283 std::string type,
double speed,
int nolanes,
284 int priority,
double laneWidth,
double endOffset,
286 const std::string& streetName,
287 const std::string& origID,
306 init(nolanes, tryIgnoreNodePositions, origID);
336 myLanes[i].updateParameter(tpl->
myLanes[tplIndex].getParametersMap());
337 if (to == tpl->
myTo) {
352 double speed,
int nolanes,
int priority,
354 const std::string& streetName,
356 bool tryIgnoreNodePositions) {
378 const std::vector<Lane> oldLanes =
myLanes;
379 init(nolanes, tryIgnoreNodePositions, oldLanes.empty() ?
"" : oldLanes[0].getParameter(
SUMO_PARAM_ORIGID));
380 for (
int i = 0; i < (int)nolanes; ++i) {
382 myLanes[i] = oldLanes[
MIN2(i, (
int)oldLanes.size() - 1)];
401 if (from ==
nullptr || to ==
nullptr) {
402 throw ProcessError(
"At least one of edge's '" +
myID +
"' nodes is not known.");
425 NBEdge::init(
int noLanes,
bool tryIgnoreNodePositions,
const std::string& origID) {
430 throw ProcessError(
"At least one of edge's '" +
myID +
"' nodes is not known.");
439 if (!tryIgnoreNodePositions ||
myGeom.size() < 2) {
454 WRITE_WARNING(
"Edge's '" +
myID +
"' from- and to-node are at the same position.");
462 assert(
myGeom.size() >= 2);
463 if ((
int)
myLanes.size() > noLanes) {
465 for (
int lane = noLanes; lane < (int)
myLanes.size(); ++lane) {
470 for (EdgeVector::const_iterator i = incoming.begin(); i != incoming.end(); i++) {
471 for (
int lane = noLanes; lane < (int)
myLanes.size(); ++lane) {
472 (*i)->removeFromConnections(
this, -1, lane);
477 for (
int i = 0; i < noLanes; i++) {
483 #ifdef DEBUG_CONNECTION_GUESSING 485 std::cout <<
"init edge=" <<
getID() <<
"\n";
487 std::cout <<
" conn " <<
getID() <<
"_" << (*i).fromLane <<
" to " <<
Named::getIDSecure((*i).toEdge) <<
"_" << (*i).toLane <<
"\n";
488 (*i).shape.mirrorX();
489 (*i).viaShape.mirrorX();
503 for (
int i = 0; i < (int)
myLanes.size(); i++) {
504 myLanes[i].shape.add(xoff, yoff, 0);
507 (*i).customShape.add(xoff, yoff, 0);
516 for (
int i = 0; i < (int)
myLanes.size(); i++) {
520 (*i).shape.mirrorX();
521 (*i).viaShape.mirrorX();
553 assert(node ==
myTo);
583 assert(node ==
myTo);
612 if (rectangularCut) {
613 const double extend = 100;
617 border.push_back(p2);
619 if (border.size() == 2) {
620 double edgeWidth = 0;
621 for (
int i = 0; i < (int)
myLanes.size(); i++) {
628 assert(node ==
myTo);
632 #ifdef DEBUG_NODE_BORDER 635 <<
" rect=" << rectangularCut
636 <<
" p=" << p <<
" p2=" << p2
637 <<
" border=" << border
650 assert(node ==
myTo);
661 assert(node ==
myTo);
697 if (shape.size() < 2) {
699 const double oldLength = old.
length();
708 const double midpoint = old.
length() / 2;
711 assert(shape.size() >= 2);
712 assert(shape.
length() > 0);
720 tmp.push_back(shape[0]);
721 tmp.push_back(shape[-1]);
737 const double midpoint = old.
length() / 2;
740 assert(shape.size() >= 2);
741 assert(shape.
length() > 0);
744 const double midpoint = shape.
length() / 2;
766 const double d = cut[0].distanceTo2D(cut[1]);
767 const double dZ = fabs(cut[0].z() - cut[1].z());
768 if (dZ / smoothElevationThreshold > d) {
774 const double d = cut[-1].distanceTo2D(cut[-2]);
775 const double dZ = fabs(cut[-1].z() - cut[-2].z());
776 if (dZ / smoothElevationThreshold > d) {
787 for (
int i = 0; i < (int)
myLanes.size(); i++) {
791 double avgLength = 0;
792 for (
int i = 0; i < (int)
myLanes.size(); i++) {
793 avgLength +=
myLanes[i].shape.length();
802 if (nodeShape.size() == 0) {
811 assert(pbv.size() > 0);
823 assert(ns.size() >= 2);
828 assert(pbv.size() > 0);
886 NBEdge* currentEdge =
this;
887 for (
int i = 1; i < (int)
myGeom.size() - 1; i++) {
889 if (i != (
int)
myGeom.size() - 2) {
890 std::string nodename =
myID +
"_in_between#" +
toString(i);
892 throw ProcessError(
"Error on adding in-between node '" + nodename +
"'.");
900 currentEdge->
myTo = newTo;
903 std::string edgename =
myID +
"[" +
toString(i - 1) +
"]";
907 if (!ec.
insert(currentEdge,
true)) {
908 throw ProcessError(
"Error on adding splitted edge '" + edgename +
"'.");
933 std::vector<double> angles;
935 for (
int i = 0; i < (int)
myGeom.size() - 1; ++i) {
940 for (
int i = 0; i < (int)angles.size() - 1; ++i) {
943 if (maxAngle > 0 && relAngle > maxAngle) {
949 if (i == 0 || i == (
int)angles.size() - 2) {
950 const bool start = i == 0;
952 const double r = tan(0.5 * (
M_PI - relAngle)) * dist;
954 if (minRadius > 0 && r < minRadius) {
957 (start ?
"start" :
"end") +
" of edge '" +
getID() +
"'.");
963 (start ?
"start" :
"end") +
" of edge '" +
getID() +
"'.");
981 if (dest !=
nullptr &&
myTo != dest->
myFrom) {
984 if (dest ==
nullptr) {
1000 bool mayUseSameDestination,
1001 bool mayDefinitelyPass,
1007 bool uncontrolled) {
1020 return setConnection(from, dest, toLane, type, mayUseSameDestination, mayDefinitelyPass, keepClear, contPos, visibility, speed, customShape, uncontrolled);
1026 NBEdge* dest,
int toLane,
1028 bool invalidatePrevious,
1029 bool mayDefinitelyPass) {
1030 if (invalidatePrevious) {
1034 for (
int i = 0; i < no && ok; i++) {
1044 bool mayUseSameDestination,
1045 bool mayDefinitelyPass,
1051 bool uncontrolled) {
1076 if ((*i).toEdge == destEdge && ((*i).fromLane == -1 || (*i).toLane == -1)) {
1083 if (mayDefinitelyPass) {
1116 std::vector<NBEdge::Connection>
1118 std::vector<NBEdge::Connection> ret;
1120 if ((*i).fromLane == lane) {
1132 (*i).fromLane == fromLane
1133 && (*i).toEdge == to
1134 && (*i).toLane == toLane) {
1139 +
" to " + to->
getID() +
"_" +
toString(toLane) +
" not found");
1146 (*i).fromLane == fromLane
1147 && (*i).toEdge == to
1148 && (*i).toLane == toLane) {
1153 +
" to " + to->
getID() +
"_" +
toString(toLane) +
" not found");
1184 if (find(outgoing.begin(), outgoing.end(), (*i).toEdge) == outgoing.end()) {
1185 outgoing.push_back((*i).toEdge);
1190 if (it->fromLane < 0 && it->toLane < 0) {
1192 EdgeVector::iterator forbidden = find(outgoing.begin(), outgoing.end(), it->toEdge);
1193 if (forbidden != outgoing.end()) {
1194 outgoing.erase(forbidden);
1199 int size = (int) outgoing.size();
1201 edges->reserve(size);
1202 for (EdgeVector::const_iterator i = outgoing.begin(); i != outgoing.end(); i++) {
1205 edges->push_back(outedge);
1217 if (find(ret.begin(), ret.end(), (*i).toEdge) == ret.end()) {
1218 ret.push_back((*i).toEdge);
1229 for (EdgeVector::const_iterator i = candidates.begin(); i != candidates.end(); i++) {
1230 if ((*i)->isConnectedTo(
this)) {
1240 std::vector<int> ret;
1243 if ((*i).toEdge == currentOutgoing) {
1244 ret.push_back((*i).fromLane);
1267 for (EdgeVector::const_iterator i = incoming.begin(); i != incoming.end(); i++) {
1272 for (EdgeVector::iterator j = connected.begin(); j != connected.end(); j++) {
1283 const int fromLaneRemoved = adaptToLaneRemoval && fromLane >= 0 ? fromLane : -1;
1284 const int toLaneRemoved = adaptToLaneRemoval && toLane >= 0 ? toLane : -1;
1287 if ((toEdge ==
nullptr || c.
toEdge == toEdge)
1288 && (fromLane < 0 || c.
fromLane == fromLane)
1289 && (toLane < 0 || c.
toLane == toLane)) {
1292 for (std::set<NBTrafficLightDefinition*>::iterator it = tldefs.begin(); it != tldefs.end(); it++) {
1299 if (fromLaneRemoved >= 0 && c.
fromLane > fromLaneRemoved) {
1302 for (std::set<NBTrafficLightDefinition*>::iterator it = tldefs.begin(); it != tldefs.end(); it++) {
1303 for (NBConnectionVector::iterator tlcon = (*it)->getControlledLinks().begin(); tlcon != (*it)->getControlledLinks().end(); ++tlcon) {
1313 if (toLaneRemoved >= 0 && c.
toLane > toLaneRemoved) {
1336 if (((*i).toEdge == connectionToRemove.
toEdge) && ((*i).fromLane == connectionToRemove.
fromLane) && ((*i).toLane == connectionToRemove.
toLane)) {
1351 if (reallowSetting) {
1363 if ((*i).toEdge == which) {
1365 (*i).toLane += laneOff;
1376 std::map<int, int> laneMap;
1380 bool wasConnected =
false;
1382 if ((*i).toEdge != which) {
1385 wasConnected =
true;
1386 if ((*i).fromLane != -1) {
1387 int fromLane = (*i).fromLane;
1388 laneMap[(*i).toLane] = fromLane;
1389 if (minLane == -1 || minLane > fromLane) {
1392 if (maxLane == -1 || maxLane < fromLane) {
1397 if (!wasConnected) {
1401 std::vector<NBEdge::Connection> conns = origConns;
1402 for (std::vector<NBEdge::Connection>::iterator i = conns.begin(); i != conns.end(); ++i) {
1403 if ((*i).toEdge == which || (*i).toEdge ==
this) {
1411 int fromLane = (*i).fromLane;
1413 if (laneMap.find(fromLane) == laneMap.end()) {
1414 if (fromLane >= 0 && fromLane <= minLane) {
1417 if (fromLane >= 0 && fromLane >= maxLane) {
1421 toUse = laneMap[fromLane];
1427 i->contPos, i->visibility, i->speed, i->customShape, i->uncontrolled);
1458 std::vector<Connection>::iterator i =
myConnections.begin() + index;
1488 std::string innerID =
":" + n.
getID();
1489 NBEdge* toEdge =
nullptr;
1490 int edgeIndex = linkIndex;
1491 int internalLaneIndex = 0;
1493 double lengthSum = 0;
1497 if (con.
toEdge ==
nullptr) {
1505 if (con.
toEdge != toEdge || (isTurn && !joinTurns)) {
1508 edgeIndex = linkIndex;
1509 toEdge = (*i).toEdge;
1510 internalLaneIndex = 0;
1516 std::vector<int> foeInternalLinks;
1523 std::pair<double, std::vector<int> > crossingPositions(-1, std::vector<int>());
1524 std::set<std::string> tmpFoeIncomingLanes;
1533 for (EdgeVector::const_iterator i2 = incoming.begin(); i2 != incoming.end(); ++i2) {
1534 const std::vector<Connection>& elv = (*i2)->getConnections();
1535 for (std::vector<NBEdge::Connection>::const_iterator k2 = elv.begin(); k2 != elv.end(); k2++) {
1536 if ((*k2).toEdge ==
nullptr) {
1541 double width2 = (*k2).toEdge->getLaneWidth((*k2).toLane);
1542 if ((*k2).toEdge->getPermissions((*k2).toLane) !=
SVC_BICYCLE) {
1545 const bool foes = n.
foes(
this, con.
toEdge, *i2, (*k2).toEdge);
1546 bool needsCont = n.
needsCont(
this, *i2, con, *k2);
1547 const bool oppositeLeftIntersect = !foes &&
bothLeftIntersect(n, shape, dir, *i2, *k2, numPoints, width2);
1551 if (needsCont || (bothPrio && oppositeLeftIntersect)) {
1552 crossingPositions.second.push_back(index);
1557 if (crossingPositions.first < 0 || crossingPositions.first > minDV) {
1558 crossingPositions.first = minDV;
1563 this, con.
toEdge, con.
fromLane, (*i2), (*k2).toEdge, (*k2).fromLane);
1565 if (foes || rightTurnConflict || oppositeLeftIntersect) {
1566 foeInternalLinks.push_back(index);
1571 if (oppositeLeftIntersect &&
getID() > (*i2)->getID()
1574 && ((*i2)->getPermissions((*k2).fromLane) & warn) != 0
1575 && ((*k2).toEdge->getPermissions((*k2).toLane) & warn) != 0
1579 WRITE_WARNING(
"Intersecting left turns at junction '" + n.
getID() +
"' from lane '" +
getLaneID(con.
fromLane) +
"' and lane '" + (*i2)->getLaneID((*k2).fromLane) +
"'. (increase junction radius to avoid this)");
1583 if ((n.
forbids(*i2, (*k2).toEdge,
this, con.
toEdge, signalised) || rightTurnConflict) && (needsCont || dir ==
LINKDIR_TURN)) {
1584 tmpFoeIncomingLanes.insert((*i2)->getID() +
"_" +
toString((*k2).fromLane));
1586 if (bothPrio && oppositeLeftIntersect &&
getID() < (*i2)->getID()) {
1589 tmpFoeIncomingLanes.insert(innerID +
"_" +
toString(index) +
"_0");
1595 std::vector<NBNode::Crossing*> crossings = n.
getCrossings();
1596 for (
auto c : crossings) {
1598 for (EdgeVector::const_iterator it_e = crossing.
edges.begin(); it_e != crossing.
edges.end(); ++it_e) {
1599 const NBEdge* edge = *it_e;
1601 if (
this == edge || con.
toEdge == edge) {
1602 foeInternalLinks.push_back(index);
1603 if (con.
toEdge == edge &&
1611 if (crossingPositions.first < 0 || crossingPositions.first > minDV) {
1612 crossingPositions.first = minDV;
1635 crossingPositions.first = -1;
1638 crossingPositions.first = con.
contPos;
1653 if (limitTurnSpeed > 0) {
1658 const double angle =
MAX2(0.0, angleRaw - (fromRail ? limitTurnSpeedMinAngleRail : limitTurnSpeedMinAngle));
1659 const double length = shape.
length2D();
1662 if (angle > 0 && length > 1) {
1665 const double limit = sqrt(limitTurnSpeed * radius);
1666 const double reduction = con.
vmax - limit;
1671 || (dir2 !=
LINKDIR_TURN && reduction > limitTurnSpeedWarnTurn)) {
1672 std::string dirType = std::string(dir ==
LINKDIR_STRAIGHT ?
"straight" :
"turning");
1674 dirType =
"roundabout";
1677 +
"' reduced by " +
toString(reduction) +
" due to turning radius of " +
toString(radius)
1684 assert(con.
vmax > 0);
1694 assert(shape.size() >= 2);
1696 con.
id = innerID +
"_" +
toString(edgeIndex);
1697 if (crossingPositions.first >= 0) {
1698 std::pair<PositionVector, PositionVector>
split = shape.
splitAt(crossingPositions.first);
1699 con.
shape = split.first;
1700 con.
foeIncomingLanes = std::vector<std::string>(tmpFoeIncomingLanes.begin(), tmpFoeIncomingLanes.end());
1702 con.
viaID = innerID +
"_" +
toString(splitIndex + noInternalNoSplits);
1710 ++internalLaneIndex;
1725 for (
int prevIndex = 1; prevIndex <= numLanes; prevIndex++) {
1727 (*(i - prevIndex)).length = lengthSum / numLanes;
1733 double intersect = std::numeric_limits<double>::max();
1745 intersect =
MIN2(intersect, cand);
1748 intersect =
MIN2(intersect, cand);
1759 if (otherFrom ==
this) {
1806 assert(atNode ==
myTo);
1821 assert(atNode ==
myTo);
1829 if (!onlyPossible) {
1849 std::vector<double> offsets(
myLanes.size(), 0.);
1851 for (
int i = (
int)
myLanes.size() - 2; i >= 0; --i) {
1853 offsets[i] = offset;
1860 for (
int i = 0; i < (int)
myLanes.size(); ++i) {
1866 for (
int i = 0; i < (int)
myLanes.size(); ++i) {
1867 offsets[i] += offset;
1871 for (
int i = 0; i < (int)
myLanes.size(); ++i) {
1872 if (
myLanes[i].customShape.size() != 0) {
1879 WRITE_WARNING(
"In edge '" +
getID() +
"': lane shape could not be determined (" + e.what() +
").");
1908 if ((hasFromShape || hasToShape) &&
getNumLanes() > 0) {
1939 if (
DEBUGCOND) std::cout <<
"computeAngle edge=" <<
getID() <<
" fromCenter=" << fromCenter <<
" toCenter=" << toCenter
1940 <<
" refStart=" << referencePosStart <<
" refEnd=" << referencePosEnd <<
" shape=" << shape
1941 <<
" hasFromShape=" << hasFromShape
1942 <<
" hasToShape=" << hasToShape
1968 for (std::vector<Lane>::const_iterator i =
myLanes.begin(); i !=
myLanes.end(); ++i) {
1969 if ((*i).permissions !=
SVCAll) {
1979 std::vector<Lane>::const_iterator i =
myLanes.begin();
1982 for (; i !=
myLanes.end(); ++i) {
1983 if (i->permissions != firstLanePermissions) {
1993 for (std::vector<Lane>::const_iterator i =
myLanes.begin(); i !=
myLanes.end(); ++i) {
2004 for (std::vector<Lane>::const_iterator i =
myLanes.begin(); i !=
myLanes.end(); ++i) {
2005 if (i->width !=
myLanes.begin()->width) {
2015 for (std::vector<Lane>::const_iterator i =
myLanes.begin(); i !=
myLanes.end(); ++i) {
2016 if (i->endOffset !=
myLanes.begin()->endOffset) {
2026 for (std::vector<Lane>::const_iterator i =
myLanes.begin(); i !=
myLanes.end(); ++i) {
2027 if (!i->stopOffsets.empty()) {
2028 const std::pair<const int, double>& offsets = *(i->stopOffsets.begin());
2040 for (std::vector<Lane>::const_iterator i =
myLanes.begin(); i !=
myLanes.end(); ++i) {
2051 for (std::vector<Lane>::const_iterator i =
myLanes.begin(); i !=
myLanes.end(); ++i) {
2052 if (i->customShape.size() > 0) {
2062 for (std::vector<Lane>::const_iterator i =
myLanes.begin(); i !=
myLanes.end(); ++i) {
2063 if (i->getParametersMap().size() > 0) {
2094 for (EdgeVector::const_iterator i = o.begin(); i != o.end(); ++i) {
2099 if (fromRail &&
isRailway((*i)->getPermissions()) &&
2136 #ifdef DEBUG_CONNECTION_GUESSING 2138 std::cout <<
"recheckLanes (initial) edge=" <<
getID() <<
"\n";
2140 std::cout <<
" conn " <<
getID() <<
"_" << (*i).fromLane <<
" to " <<
Named::getIDSecure((*i).toEdge) <<
"_" << (*i).toLane <<
"\n";
2141 (*i).shape.mirrorX();
2142 (*i).viaShape.mirrorX();
2146 std::vector<int> connNumbersPerLane(
myLanes.size(), 0);
2148 if ((*i).toEdge ==
nullptr || (*i).fromLane < 0 || (*i).toLane < 0) {
2151 if ((*i).fromLane >= 0) {
2152 ++connNumbersPerLane[(*i).fromLane];
2163 for (
int i = 0; i < (int)
myLanes.size(); i++) {
2179 }
else if (common == 0) {
2182 const int origToLane = c.
toLane;
2184 int toLane = origToLane;
2197 int toLane = origToLane;
2232 if (incoming.size() > 1) {
2233 for (
int i = 0; i < (int)
myLanes.size(); i++) {
2235 bool connected =
false;
2236 for (std::vector<NBEdge*>::const_iterator in = incoming.begin(); in != incoming.end(); ++in) {
2237 if ((*in)->hasConnectionTo(
this, i)) {
2249 #ifdef DEBUG_CONNECTION_GUESSING 2251 std::cout <<
"recheckLanes (final) edge=" <<
getID() <<
"\n";
2253 std::cout <<
" conn " <<
getID() <<
"_" << (*i).fromLane <<
" to " <<
Named::getIDSecure((*i).toEdge) <<
"_" << (*i).toLane <<
"\n";
2254 (*i).shape.mirrorX();
2255 (*i).viaShape.mirrorX();
2265 if (outgoing->size() == 0) {
2277 #ifdef DEBUG_CONNECTION_GUESSING 2279 std::cout <<
" divideOnEdges " <<
getID() <<
" outgoing=" <<
toString(*outgoing) <<
" prios=" <<
toString(*priorities) <<
"\n";
2284 std::vector<int> availableLanes;
2285 for (
int i = 0; i < (int)
myLanes.size(); ++i) {
2287 availableLanes.push_back(i);
2290 if (availableLanes.size() > 0) {
2294 availableLanes.clear();
2295 for (
int i = 0; i < (int)
myLanes.size(); ++i) {
2300 availableLanes.push_back(i);
2302 if (availableLanes.size() > 0) {
2306 availableLanes.clear();
2307 for (
int i = 0; i < (int)
myLanes.size(); ++i) {
2312 availableLanes.push_back(i);
2314 if (availableLanes.size() > 0) {
2318 availableLanes.clear();
2319 for (
int i = 0; i < (int)
myLanes.size(); ++i) {
2324 availableLanes.push_back(i);
2326 if (availableLanes.size() > 0) {
2331 if ((*i).fromLane == -1) {
2350 const int numOutgoing = (int) outgoing->size();
2351 std::vector<double> resultingLanes;
2352 resultingLanes.reserve(numOutgoing);
2353 double sumResulting = 0.;
2354 double minResulting = 10000.;
2355 for (
int i = 0; i < numOutgoing; i++) {
2359 (double)(*priorities)[i] *
2360 (double) availableLanes.size() / (double) prioSum;
2362 if (res > availableLanes.size()) {
2363 res = (double) availableLanes.size();
2366 resultingLanes.push_back(res);
2367 sumResulting += res;
2368 if (minResulting > res && res > 0) {
2380 transition.reserve(numOutgoing);
2381 for (
int i = 0; i < numOutgoing; i++) {
2384 assert(i < (
int)resultingLanes.size());
2385 const int tmpNum = (int)std::ceil(resultingLanes[i] / minResulting);
2386 numVirtual += tmpNum;
2387 for (
double j = 0; j < tmpNum; j++) {
2388 transition.push_back((*outgoing)[i]);
2391 #ifdef DEBUG_CONNECTION_GUESSING 2393 std::cout <<
" prioSum=" << prioSum <<
" sumResulting=" << sumResulting <<
" minResulting=" << minResulting <<
" numVirtual=" << numVirtual <<
" availLanes=" <<
toString(availableLanes) <<
" resLanes=" <<
toString(resultingLanes) <<
" transition=" <<
toString(transition) <<
"\n";
2402 for (EdgeVector::const_iterator i = outgoing->begin(); i != outgoing->end(); ++i) {
2404 assert(l2eConns.find(target) != l2eConns.end());
2405 const std::vector<int> lanes = (l2eConns.find(target))->second;
2406 for (std::vector<int>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
2407 const int fromIndex = availableLanes[*j];
2426 if (numConsToTarget >= targetLanes) {
2431 for (
int ii = 0; ii < (int)
myLanes.size(); ++ii) {
2439 if (
myLanes[fromIndex].connectionsDone) {
2445 #ifdef DEBUG_CONNECTION_GUESSING 2447 std::cout <<
" request connection from " <<
getID() <<
"_" << fromIndex <<
" to " << target->
getID() <<
"\n";
2460 const int numOutgoing = (int) outgoing->size();
2461 NBEdge* target =
nullptr;
2462 NBEdge* rightOfTarget =
nullptr;
2463 NBEdge* leftOfTarget =
nullptr;
2465 for (
int i = 0; i < numOutgoing; i++) {
2466 if (maxPrio < (*priorities)[i]) {
2469 maxPrio = (*priorities)[i];
2470 target = (*outgoing)[i];
2471 rightOfTarget = i == 0 ? outgoing->back() : (*outgoing)[i - 1];
2472 leftOfTarget = i + 1 == numOutgoing ? outgoing->front() : (*outgoing)[i + 1];
2476 if (target ==
nullptr) {
2484 const int numDesiredConsToTarget =
MIN2(targetLanes, (
int)availableLanes.size());
2485 #ifdef DEBUG_CONNECTION_GUESSING 2487 std::cout <<
" checking extra lanes for target=" << target->
getID() <<
" cons=" << numConsToTarget <<
" desired=" << numDesiredConsToTarget <<
"\n";
2490 std::vector<int>::const_iterator it_avail = availableLanes.begin();
2491 while (numConsToTarget < numDesiredConsToTarget && it_avail != availableLanes.end()) {
2492 const int fromIndex = *it_avail;
2501 && !
myLanes[fromIndex].connectionsDone
2503 #ifdef DEBUG_CONNECTION_GUESSING 2505 std::cout <<
" candidate from " <<
getID() <<
"_" << fromIndex <<
" to " << target->
getID() <<
"\n";
2514 #ifdef DEBUG_CONNECTION_GUESSING 2516 std::cout <<
" request additional connection from " <<
getID() <<
"_" << fromIndex <<
" to " << target->
getID() <<
"\n";
2522 #ifdef DEBUG_CONNECTION_GUESSING 2527 <<
" rightOfTarget=" << rightOfTarget->
getID()
2528 <<
" leftOfTarget=" << leftOfTarget->
getID()
2542 std::vector<int>* priorities =
new std::vector<int>();
2543 if (outgoing->size() == 0) {
2546 priorities->reserve(outgoing->size());
2547 EdgeVector::const_iterator i;
2548 for (i = outgoing->begin(); i != outgoing->end(); i++) {
2551 assert((prio + 1) * 2 > 0);
2552 prio = (prio + 1) * 2;
2553 priorities->push_back(prio);
2560 i = find(outgoing->begin(), outgoing->end(), *(tmp.begin()));
2561 int dist = (int) distance(outgoing->begin(), i);
2563 #ifdef DEBUG_CONNECTION_GUESSING 2565 <<
" outgoing=" <<
toString(*outgoing)
2566 <<
" priorities1=" <<
toString(*priorities)
2573 assert(priorities->size() > 0);
2574 (*priorities)[0] /= 2;
2575 #ifdef DEBUG_CONNECTION_GUESSING 2577 std::cout <<
" priorities2=" <<
toString(*priorities) <<
"\n";
2584 if (mainDirections.
empty()) {
2585 assert(dist < (
int)priorities->size());
2586 (*priorities)[dist] *= 2;
2587 #ifdef DEBUG_CONNECTION_GUESSING 2589 std::cout <<
" priorities3=" <<
toString(*priorities) <<
"\n";
2594 (*priorities)[dist] += 1;
2598 (*priorities)[0] /= 4;
2599 (*priorities)[(int)priorities->size() - 1] /= 2;
2600 #ifdef DEBUG_CONNECTION_GUESSING 2602 std::cout <<
" priorities6=" <<
toString(*priorities) <<
"\n";
2609 (*priorities)[dist] *= 2;
2610 #ifdef DEBUG_CONNECTION_GUESSING 2612 std::cout <<
" priorities4=" <<
toString(*priorities) <<
"\n";
2616 (*priorities)[dist] *= 3;
2617 #ifdef DEBUG_CONNECTION_GUESSING 2619 std::cout <<
" priorities5=" <<
toString(*priorities) <<
"\n";
2632 for (std::vector<int>::const_iterator i = priorities.begin(); i != priorities.end(); i++) {
2653 const int fromLane = (int)
myLanes.size() - 1;
2655 if (checkPermissions) {
2699 if (pos < tolerance) {
2713 for (
int i = 0; i < lanes; i++) {
2715 for (std::vector<NBEdge::Connection>::iterator j = elv.begin(); j != elv.end(); j++) {
2717 assert(el.
tlID ==
"");
2763 assert(fromLane < 0 || fromLane < (
int)
myLanes.size());
2765 if (fromLane >= 0 && toLane >= 0) {
2767 std::vector<Connection>::iterator i =
2775 connection.
tlID = tlID;
2783 bool hadError =
false;
2785 if ((*i).toEdge != toEdge) {
2788 if (fromLane >= 0 && fromLane != (*i).fromLane) {
2791 if (toLane >= 0 && toLane != (*i).toLane) {
2794 if ((*i).tlID ==
"") {
2796 (*i).tlLinkIndex = tlIndex;
2799 if ((*i).tlID != tlID && (*i).tlLinkIndex == tlIndex) {
2800 WRITE_WARNING(
"The lane '" + toString<int>((*i).fromLane) +
"' on edge '" +
getID() +
"' already had a traffic light signal.");
2805 if (hadError && no == 0) {
2806 WRITE_WARNING(
"Could not set any signal of the tlLogic '" + tlID +
"' (unknown group)");
2842 ret =
myLanes[lane].shape.reverse();
2862 ret =
myLanes[lane].shape.reverse();
2874 reason =
"laneNumber";
2879 reason =
"priority";
2889 reason =
"spreadType";
2898 for (
int i = 0; i < (int)
myLanes.size(); i++) {
2900 reason =
"lane " +
toString(i) +
" speed";
2902 }
else if (
myLanes[i].permissions != possContinuation->
myLanes[i].permissions) {
2903 reason =
"lane " +
toString(i) +
" permissions";
2905 }
else if (
myLanes[i].width != possContinuation->
myLanes[i].width) {
2906 reason =
"lane " +
toString(i) +
" width";
2912 reason =
"bidi-rail";
2935 if (find(conn.begin(), conn.end(), possContinuation) == conn.end()) {
2936 reason =
"disconnected";
2947 reason =
"disconnected";
2953 if (conns.size() !=
myLanes.size() - offset) {
2954 reason =
"some lanes disconnected";
2970 for (
int i = 0; i < (int)
myLanes.size(); i++) {
2976 if (origID != origID2) {
3004 if ((*i).toEdge == e && (*i).tlID !=
"") {
3036 assert(distances.size() > 0);
3042 NBEdge::addLane(
int index,
bool recomputeShape,
bool recomputeConnections,
bool shiftIndices) {
3043 assert(index <= (
int)
myLanes.size());
3047 int templateIndex = index > 0 ? index - 1 : index + 1;
3056 if (recomputeShape) {
3059 if (recomputeConnections) {
3060 for (EdgeVector::const_iterator i = incs.begin(); i != incs.end(); ++i) {
3061 (*i)->invalidateConnections(
true);
3064 }
else if (shiftIndices) {
3067 if (c.fromLane >= index) {
3086 int newLaneNo = (int)
myLanes.size() + by;
3087 while ((
int)
myLanes.size() < newLaneNo) {
3097 assert(index < (
int)
myLanes.size());
3102 for (EdgeVector::const_iterator i = incs.begin(); i != incs.end(); ++i) {
3103 (*i)->invalidateConnections(
true);
3106 }
else if (shiftIndices) {
3109 inc->removeFromConnections(
this, -1, index,
false,
true);
3117 int newLaneNo = (int)
myLanes.size() - by;
3118 assert(newLaneNo > 0);
3119 while ((
int)
myLanes.size() > newLaneNo) {
3137 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3141 assert(lane < (
int)
myLanes.size());
3142 myLanes[lane].permissions |= vclass;
3150 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3154 assert(lane < (
int)
myLanes.size());
3155 myLanes[lane].permissions &= ~vclass;
3163 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3167 assert(lane < (
int)
myLanes.size());
3168 myLanes[lane].preferred |= vclass;
3178 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3184 assert(lane < (
int)
myLanes.size());
3200 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3212 const std::map<SVCPermissions, double>&
3217 return myLanes[lane].stopOffsets;
3226 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3232 assert(lane < (
int)
myLanes.size());
3233 myLanes[lane].endOffset = offset;
3244 if (offsets.size() != 0 && 0 > offsets.begin()->second) {
3246 std::stringstream ss;
3247 ss <<
"Ignoring invalid stopOffset for edge " <<
getID() <<
" (negative offset).";
3254 assert(lane < (
int)
myLanes.size());
3255 if (
myLanes[lane].stopOffsets.size() == 0 || overwrite) {
3256 if (offsets.size() != 0 && 0 > offsets.begin()->second) {
3258 std::stringstream ss;
3259 ss <<
"Ignoring invalid stopOffset for lane " << lane <<
" on edge " <<
getID() <<
" (negative offset).";
3263 myLanes[lane].stopOffsets = offsets;
3276 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3282 assert(lane < (
int)
myLanes.size());
3289 assert(lane < (
int)
myLanes.size());
3290 myLanes[lane].accelRamp = accelRamp;
3297 assert(lane < (
int)
myLanes.size());
3298 myLanes[lane].customShape = shape;
3305 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3310 assert(lane < (
int)
myLanes.size());
3311 myLanes[lane].permissions = permissions;
3319 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3324 assert(lane < (
int)
myLanes.size());
3325 myLanes[lane].preferred = permissions;
3334 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3339 assert(lane < (
int)
myLanes.size());
3340 return myLanes[lane].permissions;
3353 for (std::vector<Lane>::iterator i =
myLanes.begin(); i !=
myLanes.end(); ++i) {
3354 (*i).permissions =
SVCAll;
3377 for (
int i = start; i != end; i += direction) {
3394 for (
int i = start; i != end; i += direction) {
3395 if (
myLanes[i].permissions != 0) {
3399 return end - direction;
3403 std::set<SVCPermissions>
3405 std::set<SVCPermissions> result;
3409 for (
int i = iStart; i < iEnd; ++i) {
3426 std::cout <<
getID() <<
" angle=" <<
getAngleAtNode(node) <<
" convAngle=" << angle <<
"\n";
3444 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3449 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3483 if (
myLanes[0].permissions == vclass) {
3495 myLanes[0].permissions = vclass;
3506 for (EdgeVector::const_iterator it = incoming.begin(); it != incoming.end(); ++it) {
3507 (*it)->shiftToLanesToEdge(
this, 1);
3518 if (
myLanes[0].permissions != vclass) {
3528 for (EdgeVector::const_iterator it = incoming.begin(); it != incoming.end(); ++it) {
3529 (*it)->shiftToLanesToEdge(
this, 0);
3542 if ((*it).toEdge == to && (*it).toLane >= 0) {
3543 (*it).toLane += laneOff;
3552 const int i = (node ==
myTo ? -1 : 0);
3553 const int i2 = (node ==
myTo ? 0 : -1);
3559 if (dist < neededOffset && dist2 < neededOffset2) {
3567 WRITE_WARNING(
"Could not avoid overlapping shape at node '" + node->
getID() +
"' for edge '" +
getID() +
"'");
3590 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3595 for (
int i = 0; i < (int)
myLanes.size(); i++) {
3608 if (con.fromLane >= 0 && con.toLane >= 0 && con.toEdge !=
nullptr &&
3610 & con.toEdge->getPermissions(con.toLane) & vClass) != 0
3625 std::pair<const NBEdge*, const NBEdge*> pair(con.toEdge,
nullptr);
3626 if (con.fromLane >= 0 && con.toLane >= 0 && con.toEdge !=
nullptr &&
3628 & con.toEdge->getPermissions(con.toLane) & vClass) != 0
3641 std::cout <<
" " <<
getID() <<
"_" << c.fromLane <<
"->" << c.toEdge->getID() <<
"_" << c.toLane <<
"\n";
bool mayBeTLSControlled(int fromLane, NBEdge *toEdge, int toLane) const
return true if certain connection must be controlled by TLS
LaneSpreadFunction getLaneSpreadFunction() const
Returns how this edge's lanes' lateral offset is computed.
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::string id
id of Connection
void moveConnectionToRight(int lane)
void invalidateConnections(bool reallowSetting=false)
invalidate current connections of edge
bool bothLeftIntersect(const NBNode &n, const PositionVector &shape, LinkDirection dir, NBEdge *otherFrom, const NBEdge::Connection &otherCon, int numPoints, double width2) const
determine conflict between opposite left turns
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.
The link is a partial left direction.
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
void appendTurnaround(bool noTLSControlled, bool onlyDeadends, bool checkPermissions)
Add a connection to the previously computed turnaround, if wished.
static const bool UNSPECIFIED_CONNECTION_UNCONTROLLED
TLS-controlled despite its node controlled not specified.
std::vector< Lane > myLanes
Lane information.
double vmax
maximum velocity
double getLength() const
Returns the computed length of the edge.
double getAngleAtNodeToCenter(const NBNode *const node) const
Returns the angle of from the node shape center to where the edge meets the node shape.
bool setControllingTLInformation(const NBConnection &c, const std::string &tlID)
Returns if the link could be set as to be controlled.
double length2D() const
Returns the length.
void divideOnEdges(const EdgeVector *outgoing)
divides the lanes on the outgoing edges
A structure which describes a connection between edges or lanes.
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...
int toLane
The lane the connections yields in.
bool foes(const NBEdge *const from1, const NBEdge *const to1, const NBEdge *const from2, const NBEdge *const to2) const
Returns the information whether the given flows cross.
void debugPrintConnections(bool outgoing=true, bool incoming=false) const
debugging helper to print all connections
int getInt(const std::string &name) const
Returns the int-value of the named option (only for Option_Integer)
static const double UNSPECIFIED_LOADED_LENGTH
no length override given
std::vector< TLSDisabledConnection > myTLSDisabledConnections
vector with the disabled connections
const std::map< int, double > & getStopOffsets() const
Returns the stopOffset to the end of the edge.
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)
LaneSpreadFunction myLaneSpreadFunction
The information about how to spread the lanes.
double z() const
Returns the z-position.
void sortOutgoingConnectionsByAngle()
sorts the outgoing connections by their angle relative to their junction
std::string viaID
if Connection have a via, ID of it
double distance2D(const Position &p, bool perpendicular=false) const
closest 2D-distance to point p (or -1 if perpendicular is true and the point is beyond this vector) ...
NBEdge * toEdge
The edge the connections yields in.
EdgeVector getIncomingEdges() const
Returns the list of incoming edges unsorted.
void mirrorX()
mirror coordinates along the x-axis
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types...
static PositionVector startShapeAt(const PositionVector &laneShape, const NBNode *startNode, PositionVector nodeShape)
static NBEdge DummyEdge
Dummy edge to use when a reference must be supplied in the no-arguments constructor (FOX technicality...
static const double UNSPECIFIED_VISIBILITY_DISTANCE
unspecified foe visibility for connections
void setEndOffset(int lane, double offset)
set lane specific end-offset (negative lane implies set for all lanes)
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.
The relationships between edges are computed/loaded.
double getLaneSpeed(int lane) const
get lane speed
void computeEdgeShape(double smoothElevationThreshold=-1)
Recomputeds the lane shapes to terminate at the node shape For every lane the intersection with the f...
bool hasPermissions() const
whether at least one lane has restrictions
bool isConnectedTo(const NBEdge *e) const
Returns the information whethe a connection to the given edge has been added (or computed) ...
void reduceGeometry(const double minDist)
Removes points with a distance lesser than the given.
bool hasSignalisedConnectionTo(const NBEdge *const e) const
Check if edge has signalised connections.
std::vector< std::pair< const NBEdge *, const NBEdge * > > NBConstEdgePairVector
static double normRelAngle(double angle1, double angle2)
ensure that reverse relAngles (>=179.999) always count as turnarounds (-180)
double myLaneWidth
This width of this edge's lanes.
std::map< int, double > myStopOffsets
A vClass specific stop offset - assumed of length 0 (unspecified) or 1. For the latter case the int i...
double myEndOffset
This edges's offset to the intersection begin (will be applied to all lanes)
void addLane(int index, bool recomputeShape, bool recomputeConnections, bool shiftIndices)
add lane
void setSpeed(int lane, double speed)
set lane specific speed (negative lane implies set for all lanes)
Holds (- relative to the edge it is build from -!!!) the list of main directions a vehicle that drive...
PositionVector computeInternalLaneShape(NBEdge *fromE, const NBEdge::Connection &con, int numPoints, NBNode *recordError=0) const
Compute the shape for an internal lane.
Position positionAtOffset2D(double pos, double lateralOffset=0) const
Returns the position at the given length.
double getSignalOffset() const
Returns the offset of a traffic signal from the end of this edge.
Some static methods for string processing.
static const double ANGLE_LOOKAHEAD
the distance at which to take the default angle
int getJunctionPriority(const NBNode *const node) const
Returns the junction priority (normalised for the node currently build)
void moveConnectionToLeft(int lane)
std::vector< Crossing * > getCrossings() const
return this junctions pedestrian crossings
int getPriority() const
Returns the priority of the edge.
void removeEdge(NBEdge *edge, bool removeFromConnections=true)
Removes edge from this node and optionally removes connections as well.
const std::string & getTypeID() const
get ID of type
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.
const double SUMO_const_laneWidth
bool empty() const
returns the information whether no following street has a higher priority
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.
void reinitNodes(NBNode *from, NBNode *to)
Resets nodes but keeps all other values the same (used when joining)
void clearControllingTLInformation()
clears tlID for all connections
vehicle is a small delivery vehicle
void setNodeBorder(const NBNode *node, const Position &p, const Position &p2, bool rectangularCut)
Set Node border.
Lane2LaneInfoType
Modes of setting connections between lanes.
std::vector< int > * prepareEdgePriorities(const EdgeVector *outgoing)
recomputes the edge priorities and manipulates them for a distribution of lanes on edges which is mor...
Lane(NBEdge *e, const std::string &_origID)
constructor
const double SUMO_const_laneWidthAndOffset
The link is a 180 degree turn.
bool hasLaneSpecificSpeed() const
whether lanes differ in speed
static const double UNSPECIFIED_SIGNAL_OFFSET
unspecified signal offset
bool isBidiRail(bool ignoreSpread=false) const
whether this edge is part of a bidirectional railway
std::vector< Direction > myDirs
list of the main direction within the following junction relative to the edge
void markAsInLane2LaneState()
mark edge as in lane to state lane
static const double UNSPECIFIED_OFFSET
unspecified lane offset
void removeFromConnections(NBEdge *toEdge, int fromLane=-1, int toLane=-1, bool tryLater=false, const bool adaptToLaneRemoval=false)
Removes the specified connection(s)
double getMaxLaneOffset()
get max lane offset
TLS Disabled Connections.
double angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position ...
Lanes to lanes - relationships are computed; should be recheked.
Position getCentroid() const
Returns the centroid (closes the polygon if unclosed)
bool hasLoadedLength() const
Returns whether a length was set explicitly.
NBEdge * getTurnDestination(bool possibleDestination=false) const
void setPermissions(SVCPermissions permissions, int lane=-1)
set allowed/disallowed classes for the given lane or for all lanes if -1 is given ...
PositionVector shape
The crossing's shape.
int myFromJunctionPriority
The priority normalised for the node the edge is outgoing of.
void setLoadedLength(double val)
set loaded lenght
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::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
void computeLaneShapes()
compute lane shapes
bool mayDefinitelyPass
Information about being definitely free to drive (on-ramps)
PositionVector reverse() const
reverse position vector
double endOffset
This lane's offset to the intersection begin.
PositionVector myGeom
The geometry for the edge.
double visibility
custom foe visiblity for connection
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.
const double SUMO_const_laneOffset
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 insert_noDoublePos(const std::vector< Position >::iterator &at, const Position &p)
insert in front a non double position
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission is a railway edge.
const SVCPermissions SVCAll
all VClasses are allowed
std::vector< int > getConnectionLanes(NBEdge *currentOutgoing) const
Returns the list of lanes that may be used to reach the given edge.
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 myFromBorder
intersection borders (because the node shape might be invalid)
void restoreBikelane(std::vector< NBEdge::Lane > oldLanes, PositionVector oldGeometry, std::vector< NBEdge::Connection > oldConnections)
restore an previously added BikeLane
bool isRailDeadEnd() const
whether this edge is a railway edge that does not continue
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) ...
void addSidewalk(double width)
add a pedestrian sidewalk of the given width and shift existing connctions
void addOutgoingEdge(NBEdge *edge)
adds an outgoing edge
bool hasElevation() const
return whether two positions differ in z-coordinate
void setGeometry(const PositionVector &g, bool inner=false)
(Re)sets the edge's geometry
std::string getDescription(const NBEdge *parent) const
get string describing this connection
bool hasLaneSpecificStopOffsets() const
whether lanes differ in stopOffsets
bool includes(Direction d) const
returns the information whether the street in the given direction has a higher priority ...
double getShapeStartAngle() const
Returns the angle at the start of the edge.
static const double UNSPECIFIED_WIDTH
unspecified lane width
The link is a (hard) left direction.
void assignInternalLaneLength(std::vector< Connection >::iterator i, int numLanes, double lengthSum)
assign length to all lanes of an internal edge
PositionVector customShape
custom shape for connection
#define WRITE_WARNING(msg)
The connection was computed and validated.
bool hasDefaultGeometryEndpoints() const
Returns whether the geometry is terminated by the node positions This default may be violated by init...
static OptionsCont & getOptions()
Retrieves the options.
void shortenGeometryAtNode(const NBNode *node, double reduction)
linearly extend the geometry at the given node
void setLaneShape(int lane, const PositionVector &shape)
sets a custom lane shape
void setAcceleration(int lane, bool accelRamp)
marks one lane as acceleration lane
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...
static double legacyDegree(const double angle, const bool positive=false)
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges (The edges which start at this node)
PositionVector cutAtIntersection(const PositionVector &old) const
cut shape at the intersection shapes
The edge has been loaded, nothing is computed yet.
NBNode * tryGetNodeAtPosition(double pos, double tolerance=5.0) const
Returns the node at the given edges length (using an epsilon)
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)...
int myToJunctionPriority
The priority normalised for the node the edge is incoming in.
The link is a straight direction.
PositionVector shape
shape of Connection
static const double UNSPECIFIED_SPEED
unspecified lane speed
void restoreSidewalk(std::vector< NBEdge::Lane > oldLanes, PositionVector oldGeometry, std::vector< NBEdge::Connection > oldConnections)
restore an previously added sidewalk
bool addLane2LaneConnection(int fromLane, NBEdge *dest, int toLane, 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 between the specified this edge's lane and an approached one.
bool keepClear
whether the junction must be kept clear when using this connection
void addRestrictedLane(double width, SUMOVehicleClass vclass)
add a lane of the given width, restricted to the given class and shift existing connections ...
std::vector< Connection > getConnectionsFromLane(int lane) const
Returns connections from a given lane.
An (internal) definition of a single lane of an edge.
bool addEdge2EdgeConnection(NBEdge *dest)
Adds a connection to another edge.
void extrapolate2D(const double val, const bool onlyFirst=false)
extrapolate position vector in two dimensions (Z is ignored)
void incLaneNo(int by)
increment lane
bool isTLControlled() const
Returns whether this node is controlled by any tls.
bool myAmMacroscopicConnector
Information whether this edge is a (macroscopic) connector.
void push_front_noDoublePos(const Position &p)
insert in front a non double position
void removeDoublePoints(double minDist=POSITION_EPS, bool assertLength=false)
Removes positions if too near.
bool computeLanes2Edges()
computes the edge, step2: computation of which lanes approach the edges)
NBEdge * myTurnDestination
The turn destination edge (if a connection exists)
double myStartAngle
The angles of the edge.
bool hasLaneSpecificWidth() const
whether lanes differ in width
double speed
custom speed for connection
Lanes to lanes - relationships are loaded; no recheck is necessary/wished.
bool knowsParameter(const std::string &key) const
Returns whether the parameter is known.
bool hasLaneSpecificEndOffset() const
whether lanes differ in offset
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
static const int FORWARD
edge directions (for pedestrian related stuff)
bool hasDefaultGeometryEndpointAtNode(const NBNode *node) const
Returns whether the geometry is terminated by the node positions This default may be violated by init...
void decLaneNo(int by)
decrement lane
std::string tlID
The id of the traffic light that controls this connection.
double beginEndAngle() const
returns the angle in radians of the line connecting the first and the last position ...
std::string getLaneID(int lane) const
get Lane ID (Secure)
int getNumLanes() const
Returns the number of lanes.
int fromLane
The lane the connections starts at.
A point in 2D or 3D with translation and scaling methods.
NBEdge()
constructor for dummy edge
int operator()(const Connection &c1, const Connection &c2) const
comparing operation
bool addLane2LaneConnections(int fromLane, NBEdge *dest, int toLane, int no, Lane2LaneInfoType type, bool invalidatePrevious=false, bool mayDefinitelyPass=false)
Builds no connections starting at the given lanes.
void setOrigID(const std::string origID)
set origID for all lanes
const PositionVector getInnerGeometry() const
Returns the geometry of the edge without the endpoints.
void moveOutgoingConnectionsFrom(NBEdge *e, int laneOff)
move outgoing connection
static int computePrioritySum(const std::vector< int > &priorities)
computes the sum of the given list's entries (sic!)
static bool connections_sorter(const Connection &c1, const Connection &c2)
connections_sorter sort by fromLane, toEdge and toLane
void resetNodeBorder(const NBNode *node)
static const double UNSPECIFIED_CONTPOS
unspecified internal junction position
bool needsLaneSpecificOutput() const
whether at least one lane has values differing from the edges values
void deleteLane(int index, bool recompute, bool shiftIndices)
delete lane
bool hasConnectionTo(NBEdge *destEdge, int destLane, int fromLane=-1) const
Retrieves info about a connection to a certain lane of a certain edge.
NBEdge * myPossibleTurnDestination
The edge that would be the turn destination if there was one.
bool hasDefaultGeometry() const
Returns whether the geometry consists only of the node positions.
static int getLaneIndexFromLaneID(const std::string laneID)
int myPriority
The priority of the edge.
static double firstIntersection(const PositionVector &v1, const PositionVector &v2, double width2)
compute the first intersection point between the given lane geometries considering their rspective wi...
bool geometryLike() const
whether this is structurally similar to a geometry node
NBConstEdgePairVector myViaSuccessors
Storage for edges, including some functionality operating on multiple edges.
std::vector< std::string > & split(const std::string &s, char delim, std::vector< std::string > &elems)
The link is a (hard) right direction.
Connection(int fromLane_, NBEdge *toEdge_, int toLane_)
Constructor.
std::string getSidewalkID()
get the lane id for the canonical sidewalk lane
EdgeBuildingStep myStep
The building step.
EdgeBuildingStep getStep() const
The building step of this edge.
const std::string & getStreetName() const
Returns the street name of this edge.
double getAngleAtNode(const NBNode *const node) const
Returns the angle of the edge's geometry at the given node.
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 ...
void setParameter(const std::string &key, const std::string &value)
Sets a parameter.
Class to sort edges by their angle.
void buildInnerEdges(const NBNode &n, int noInternalNoSplits, int &linkIndex, int &splitIndex)
PositionVector getCWBoundaryLine(const NBNode &n) const
get the outer boundary of this edge when going clock-wise around the given node
PositionVector getSubpart(double beginOffset, double endOffset) const
get subpart of a position vector
double getEndOffset() const
Returns the offset to the destination node.
static int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter...
PositionVector smoothedZFront(double dist=std::numeric_limits< double >::max()) const
returned vector that is smoothed at the front (within dist)
static const double INVALID_OFFSET
a value to signify offsets outside the range of [0, Line.length()]
std::vector< Connection > myConnections
List of connections to following edges.
std::string getLaneIDInsecure(int lane) const
get Lane ID (Insecure)
void execute(const int lane, const int virtEdge)
executes a bresenham - step
PositionVector getSubpartByIndex(int beginIndex, int count) const
get subpart of a position vector using index and a cout
The connection was given by the user.
The link is a partial right direction.
double speed
The speed allowed on this lane.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
std::set< SVCPermissions > getPermissionVariants(int iStart, int iEnd) const
return all permission variants within the specified lane range [iStart, iEnd[
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
bool lanesWereAssigned() const
Check if lanes were assigned.
double getFinalLength() const
get length that will be assigned to the lanes in the final network
void move2side(double amount)
move position vector to side using certain ammount
vehicle is a passenger car (a "normal" car)
bool myAmInnerEdge
Information whether this is a junction-inner edge.
int myIndex
the index of the edge in the list of all edges. Set by NBEdgeCont and requires re-set whenever the li...
int tlLinkIndex
The index of this connection within the controlling traffic light.
bool hasLaneSpecificPermissions() const
whether lanes differ in allowed vehicle classes
Base class for objects which have an id.
bool recheckLanes()
recheck whether all lanes within the edge are all right and optimises the connections once again ...
bool hasLaneParams() const
whether one of the lanes has parameters set
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=LANESPREAD_RIGHT, bool tryIgnoreNodePositions=false)
Resets initial values.
double mySpeed
The maximal speed.
static std::string convertUmlaute(std::string str)
Converts german "Umlaute" to their latin-version.
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.
int getToLane() const
returns the to-lane
NBEdge * getTo() const
returns the to-edge (end of the connection)
int internalLaneIndex
The lane index of this internal lane within the internal edge.
const PositionVector & getGeometry() const
Returns the geometry of the edge.
void extendGeometryAtNode(const NBNode *node, double maxExtent)
linearly extend the geometry at the given node
PositionVector getSubpart2D(double beginOffset, double endOffset) const
get subpart of a position vector in two dimensions (Z is ignored)
Connection getConnection(int fromLane, const NBEdge *to, int toLane) const
Returns the specified connection This method goes through "myConnections" and returns the specified o...
double getLaneWidth() const
Returns the default width of lanes of this edge.
void setTurningDestination(NBEdge *e, bool onlyPossible=false)
Sets the turing destination at the given edge.
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
double width
This crossing's width.
double length() const
Returns the length.
void addStraightConnections(const EdgeVector *outgoing, const std::vector< int > &availableLanes, const std::vector< int > *priorities)
add some straight connections
void disableConnection4TLS(int fromLane, NBEdge *toEdge, int toLane)
disable connections for TLS
PositionVector viaShape
shape of via
void shiftTLConnectionLaneIndex(NBEdge *edge, int offset, int threshold=-1)
patches loaded signal plans by modifying lane indices above threshold by the given offset ...
bool hasAccelLane() const
whether one of the lanes is an acceleration lane
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)
PositionVector myToBorder
double getCrossingAngle(NBNode *node)
return the angle for computing pedestrian crossings at the given node
const std::set< NBTrafficLightDefinition * > & getControllingTLS() const
Returns the traffic lights that were assigned to this node (The set of tls that control this node) ...
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.
double getTotalWidth() const
Returns the combined width of all lanes of this edge.
static const int UNSPECIFIED_INTERNAL_LANE_INDEX
internal lane computation not yet done
void setPreferredVehicleClass(SVCPermissions permissions, int lane=-1)
set preferred Vehicle Class
const PositionVector & getNodeBorder(const NBNode *node)
double mySignalOffset
the offset of a traffic light signal from the end of this edge (-1 for None)
The edge has been loaded and connections shall not be added.
bool hasCustomLaneShape() const
whether one of the lanes has a custom shape
std::vector< Connection > myConnectionsToDelete
List of connections marked for delayed removal.
double contPos
custom position for internal junction on this connection
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 ...
std::vector< std::string > foeIncomingLanes
FOE Incomings lanes.
bool uncontrolled
check if Connection is uncontrolled
void setJunctionPriority(const NBNode *const node, int prio)
Sets the junction priority of the edge.
SumoXMLNodeType getType() const
Returns the type of this node.
const std::string getParameter(const std::string &key, const std::string &defaultValue="") const
Returns the value for a given key.
double angleAt2D(int pos) const
get angle in certain position of position vector
void addBikeLane(double width)
add a bicycle lane of the given width and shift existing connctions
bool insert(const std::string &id, const Position &position, NBDistrict *district=0)
Inserts a node into the map.
const EdgeVector * getConnectedSorted()
Returns the list of outgoing edges without the turnaround sorted in clockwise direction.
void restoreRestrictedLane(SUMOVehicleClass vclass, std::vector< NBEdge::Lane > oldLanes, PositionVector oldGeometry, std::vector< NBEdge::Connection > oldConnections)
restore a restricted lane
void sortOutgoingConnectionsByIndex()
sorts the outgoing connections by their from-lane-index and their to-lane-index
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
const std::string SUMO_PARAM_ORIGID
std::string myType
The type of the edge.
LaneSpreadFunction
Numbers representing special SUMO-XML-attribute values Information how the edge's lateral offset shal...
void append(NBEdge *continuation)
append another edge
bool isTurningDirectionAt(const NBEdge *const edge) const
Returns whether the given edge is the opposite direction to this edge.
The connection was computed.
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
const Position & getPosition() const
EdgeVector edges
The edges being crossed.
int getFromLane() const
returns the from-lane
Represents a single node (junction) during network building.
const std::map< std::string, std::string > & getParametersMap() const
Returns the inner key/value map.
MainDirections(const EdgeVector &outgoing, NBEdge *parent, NBNode *to, int indexOfStraightest)
constructor
void dismissVehicleClassInformation()
dimiss vehicle class information
Lanes to lanes - relationships are computed; no recheck is necessary/wished.
A definition of a pedestrian crossing.
const NBConstEdgePairVector & getViaSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges for the given vClass.
void replaceInConnections(NBEdge *which, NBEdge *by, int laneOff)
replace in current connections of edge
EdgeVector getConnectedEdges() const
Returns the list of outgoing edges unsorted.
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimension
static void compute(BresenhamCallBack *callBack, const int val1, const int val2)
Direction
enum of possible directions
const EdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges for the given vClass.
void preferVehicleClass(int lane, SUMOVehicleClass vclass)
prefer certain vehicle class
void checkGeometry(const double maxAngle, const double minRadius, bool fix)
Check the angles of successive geometry segments.
void push_back_noDoublePos(const Position &p)
insert in back a non double position
bool isLeftMover(const NBEdge *const from, const NBEdge *const to) const
Computes whether the given connection is a left mover across the junction.
void allowVehicleClass(int lane, SUMOVehicleClass vclass)
set allowed class for the given lane or for all lanes if -1 is given
int getTLIndex() const
returns the index within the controlling tls or InvalidTLIndex if this link is unontrolled ...
void insertConnection(NBEdge::Connection connection)
insert a previously created NBEdge::connection
void addGeometryPoint(int index, const Position &p)
Adds a further geometry point.
void shiftToLanesToEdge(NBEdge *to, int laneOff)
modifify the toLane for all connections to the given edge
void computeAngle()
computes the angle of this edge and stores it in myAngle
NBNode * getFromNode() const
Returns the origin node of the edge.
Container for nodes during the netbuilding process.
bool computeEdge2Edges(bool noLeftMovers)
computes the edge (step1: computation of approached edges)
std::string getInternalLaneID() const
get ID of internal lane
PositionVector getCCWBoundaryLine(const NBNode &n) const
get the outer boundary of this edge when going counter-clock-wise around the given node ...
static T maxValue(const std::vector< T > &v)
static double angleDiff(const double angle1, const double angle2)
Returns the difference of the second angle to the first angle in radiants.
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)
void setLaneSpreadFunction(LaneSpreadFunction spread)
(Re)sets how the lanes lateral offset shall be computed
double myLength
The length of the edge.
#define WRITE_MESSAGE(msg)
void divideSelectedLanesOnEdges(const EdgeVector *outgoing, const std::vector< int > &availableLanes, const std::vector< int > *priorities)
divide selected lanes on edges
PositionVector computeLaneShape(int lane, double offset) const
Computes the shape for the given lane.
double getShapeEndAngle() const
Returns the angle at the end of the edge.
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
double myLoadedLength
An optional length to use (-1 if not valid)
void closePolygon()
ensures that the last position equals the first
Lanes to edges - relationships are computed/loaded.
std::string myStreetName
The street name (or whatever arbitrary string you wish to attach)
NBNode * myFrom
The source and the destination node.
bool canMoveConnection(const Connection &con, int newFromLane) const
whether the connection can originate on newFromLane
Connection & getConnectionRef(int fromLane, const NBEdge *to, int toLane)
Returns reference to the specified connection This method goes through "myConnections" and returns th...
bool isNearEnough2BeJoined2(NBEdge *e, double threshold) const
Check if edge is near enought to be joined to another edge.
NBNode * getToNode() const
Returns the destination node of the edge.
std::vector< int > foeInternalLinks
FOE Internal links.
~MainDirections()
destructor
static bool isTrafficLight(SumoXMLNodeType type)
return whether the given type is a traffic light
void shiftPositionAtNode(NBNode *node, NBEdge *opposite)
shift geometry at the given node to avoid overlap
bool intersects(const Position &p1, const Position &p2) const
Returns the information whether this list of points interesects the given line.
void disallowVehicleClass(int lane, SUMOVehicleClass vclass)
set disallowed class for the given lane or for all lanes if -1 is given
void copyConnectionsFrom(NBEdge *src)
copy connections from antoher edge
A class that being a bresenham-callback assigns the incoming lanes to the edges.
void setLaneWidth(int lane, double width)
set lane specific width (negative lane implies set for all lanes)
void reshiftPosition(double xoff, double yoff)
Applies an offset to the edge.
const std::map< NBEdge *, std::vector< int > > & getBuiltConnections() const
get built connections
void setz(double z)
set position z
NBEdge::Lane getFirstNonPedestrianLane(int direction) const
get first non-pedestrian lane
bool splitGeometry(NBEdgeCont &ec, NBNodeCont &nc)
Splits this edge at geometry points.