53 #define JOIN_TRAM_MAX_ANGLE 10
54 #define JOIN_TRAM_MIN_LENGTH 3
58 #define DEBUG_EDGE_ID "301241681#2"
66 myVehicleClasses2Keep(0),
67 myVehicleClasses2Remove(0),
68 myNeedGeoTransformedPruningBoundary(false) {
83 if (oc.
isSet(
"keep-edges.input-file")) {
86 if (oc.
isSet(
"remove-edges.input-file")) {
89 if (oc.
isSet(
"keep-edges.explicit")) {
90 const std::vector<std::string> edges = oc.
getStringVector(
"keep-edges.explicit");
93 if (oc.
isSet(
"remove-edges.explicit")) {
94 const std::vector<std::string> edges = oc.
getStringVector(
"remove-edges.explicit");
97 if (oc.
exists(
"keep-edges.by-vclass") && oc.
isSet(
"keep-edges.by-vclass")) {
100 if (oc.
exists(
"remove-edges.by-vclass") && oc.
isSet(
"remove-edges.by-vclass")) {
103 if (oc.
exists(
"keep-edges.by-type") && oc.
isSet(
"keep-edges.by-type")) {
104 const std::vector<std::string> types = oc.
getStringVector(
"keep-edges.by-type");
107 if (oc.
exists(
"remove-edges.by-type") && oc.
isSet(
"remove-edges.by-type")) {
108 const std::vector<std::string> types = oc.
getStringVector(
"remove-edges.by-type");
112 if (oc.
isSet(
"keep-edges.in-boundary") || oc.
isSet(
"keep-edges.in-geo-boundary")) {
115 "keep-edges.in-boundary" :
"keep-edges.in-geo-boundary");
120 if (boundaryShape.size() < 2) {
121 throw ProcessError(
"Invalid boundary: need at least 2 coordinates");
122 }
else if (boundaryShape.size() == 2) {
134 "keep-edges.in-boundary" :
"keep-edges.in-geo-boundary");
135 std::vector<double> poly;
136 for (std::vector<std::string>::iterator i = polyS.begin(); i != polyS.end(); ++i) {
139 if (poly.size() < 4) {
140 throw ProcessError(
"Invalid boundary: need at least 2 coordinates");
141 }
else if (poly.size() % 2 != 0) {
142 throw ProcessError(
"Invalid boundary: malformed coordinate");
143 }
else if (poly.size() == 4) {
150 for (std::vector<double>::iterator j = poly.begin(); j != poly.end();) {
164 for (EdgeCont::iterator i =
myEdges.begin(); i !=
myEdges.end(); i++) {
165 delete ((*i).second);
169 delete ((*i).second);
189 if (oc.
exists(
"dismiss-vclasses") && oc.
getBool(
"dismiss-vclasses")) {
255 WRITE_ERROR(
"Cannot prune edges using a geo-boundary because no projection has been loaded");
276 EdgeCont::const_iterator i =
myEdges.find(
id);
278 if (retrieveExtracted) {
313 if (edge !=
nullptr) {
317 if ((
retrieve(
id +
"[0]") !=
nullptr) && (
retrieve(
id +
"[1]") !=
nullptr)) {
319 if (downstream ==
true) {
333 if (edge !=
nullptr) {
340 if (hintedge ==
nullptr) {
343 hints.push_back(hintedge);
346 for (EdgeVector::iterator i = hints.begin(); i != hints.end(); i++) {
348 for (EdgeVector::iterator j = candidates.begin(); j != candidates.end(); j++) {
349 NBEdge* poss_searched = (*j);
351 ? poss_searched->
myTo : poss_searched->
myFrom;
354 if (find(cont.begin(), cont.end(), hintedge) != cont.end()) {
355 return poss_searched;
367 if (edge !=
nullptr) {
371 std::string tid =
id +
"[";
372 for (EdgeCont::const_iterator i =
myEdges.begin(); i !=
myEdges.end(); ++i) {
373 if ((*i).first.find(tid) == 0) {
374 maxLength =
MAX2(maxLength, (
int)(*i).first.length());
379 std::vector<std::string> names;
380 names.push_back(
id +
"[1]");
381 names.push_back(
id +
"[0]");
382 while (names.size() > 0) {
384 std::string cid = names.back();
389 if (edge ==
nullptr) {
390 if ((
int)cid.length() + 3 < maxLength) {
391 names.push_back(cid +
"[1]");
392 names.push_back(cid +
"[0]");
429 if (
myEdges.count(newID) != 0) {
430 throw ProcessError(
"Attempt to rename edge using existing id '" + newID +
"'");
443 if (splits.size() == 0) {
446 const std::string origID = e->
getID();
447 std::vector<Split>::iterator i;
451 for (i = splits.begin(); i != splits.end(); ++i) {
452 sort((*i).lanes.begin(), (*i).lanes.end());
453 noLanesMax =
MAX2(noLanesMax, (
int)(*i).lanes.size());
456 std::vector<int> currLanes;
458 currLanes.push_back(l);
460 if (e->
getNumLanes() != (
int)splits.back().lanes.size()) {
468 std::string firstID =
"";
470 for (i = splits.begin(); i != splits.end(); ++i) {
471 const Split& exp = *i;
472 assert(exp.
lanes.size() != 0);
485 WRITE_WARNING(
"Error on parsing a split (edge '" + origID +
"').");
488 std::vector<int> newLanes = exp.
lanes;
494 int rightMostP = currLanes[0];
495 int rightMostN = newLanes[0];
496 for (
int l = 0; l < (int) rightMostP - (
int) rightMostN; ++l) {
500 int leftMostP = currLanes.back();
501 int leftMostN = newLanes.back();
502 for (
int l = 0; l < (int) leftMostN - (
int) leftMostP; ++l) {
506 for (
int l = 0; l < noLanesMax; ++l) {
507 if (find(currLanes.begin(), currLanes.end(), l) == currLanes.end()) {
510 if (find(newLanes.begin(), newLanes.end(), l) == newLanes.end()) {
521 in->invalidateConnections(
true);
526 currLanes = newLanes;
527 }
else if (exp.
pos == 0) {
529 if (laneCountDiff < 0) {
534 currLanes = exp.
lanes;
544 if (splits.front().pos != 0) {
548 for (
int lane = 0; lane < (int)e->
getNumLanes(); ++lane) {
549 start.
lanes.push_back(lane);
551 start.
offset = splits.front().offset;
553 splits.insert(splits.begin(), start);
557 for (; i != splits.end(); ++i) {
558 int maxLeft = (*i).lanes.back();
559 double offset = (*i).offset;
560 if (maxLeft < noLanesMax) {
567 int maxRight = (*i).lanes.front();
594 const std::string& firstEdgeName,
595 const std::string& secondEdgeName,
596 int noLanesFirstEdge,
int noLanesSecondEdge,
598 const int changedLeft) {
609 return splitAt(dc, edge, pos, node, firstEdgeName, secondEdgeName,
610 noLanesFirstEdge, noLanesSecondEdge, speed, changedLeft);
617 const std::string& firstEdgeName,
618 const std::string& secondEdgeName,
619 int noLanesFirstEdge,
int noLanesSecondEdge,
621 const int changedLeft
624 assert(changedLeft > -((
int)noLanesFirstEdge));
625 assert(changedLeft < (
int)noLanesSecondEdge);
628 std::pair<PositionVector, PositionVector> geoms =
631 NBEdge* one =
new NBEdge(firstEdgeName, edge->
myFrom, node, edge, geoms.first, noLanesFirstEdge);
632 NBEdge* two =
new NBEdge(secondEdgeName, node, edge->
myTo, edge, geoms.second, noLanesSecondEdge);
635 if (firstEdgeName != origID) {
638 if (secondEdgeName != origID) {
651 for (std::set<NBTrafficLightDefinition*>::iterator i = fromTLS.begin(); i != fromTLS.end(); ++i) {
652 (*i)->replaceRemoved(edge, -1, one, -1,
false);
655 for (std::set<NBTrafficLightDefinition*>::iterator i = toTLS.begin(); i != toTLS.end(); ++i) {
656 (*i)->replaceRemoved(edge, -1, two, -1,
true);
667 for (
int i2 = 0; i2 < (int)two->
getNumLanes(); i2++) {
686 const std::string oldID = edge->
getID();
689 WRITE_ERROR(
"Could not insert edge '" + one->
getID() +
"' before split of edge '" + oldID +
"'");
692 WRITE_ERROR(
"Could not insert edge '" + two->
getID() +
"' after split of edge '" + oldID +
"'");
701 std::set<EdgeSet> addLater;
702 for (std::set<EdgeSet>::iterator it = roundabouts.begin(); it != roundabouts.end(); ++it) {
704 if (roundaboutSet.count(orig) > 0) {
705 roundaboutSet.erase(orig);
706 roundaboutSet.insert(part1);
707 roundaboutSet.insert(part2);
709 addLater.insert(roundaboutSet);
712 roundabouts.insert(addLater.begin(), addLater.end());
717 std::vector<std::string>
719 std::vector<std::string> ret;
720 for (EdgeCont::const_iterator i =
myEdges.begin(); i !=
myEdges.end(); ++i) {
721 ret.push_back((*i).first);
731 for (EdgeCont::iterator i =
myEdges.begin(); i !=
myEdges.end(); ++i) {
732 NBEdge* edge = (*i).second;
736 toRemove.push_back(edge);
739 for (EdgeVector::iterator j = toRemove.begin(); j != toRemove.end(); ++j) {
749 for (
auto& item : edges) {
750 NBEdge* edge = item.second;
755 const std::string
id = edge->
getID();
757 for (
int i = 1; i < (int)geom.size() - 1; i++) {
758 offset += geom[i - 1].distanceTo(geom[i]);
759 std::string nodeID =
id +
"." +
toString((
int)offset);
760 if (!nc.
insert(nodeID, geom[i])) {
774 for (EdgeCont::iterator i =
myEdges.begin(); i !=
myEdges.end(); ++i) {
775 (*i).second->reduceGeometry(minDist);
782 if (maxAngle > 0 || minRadius > 0) {
787 item.second->checkGeometry(maxAngle, minRadius, fix || (fixRailways &&
isRailway(item.second->getPermissions())), silent);
796 for (EdgeCont::const_iterator i =
myEdges.begin(); i !=
myEdges.end(); i++) {
797 (*i).second->clearControllingTLInformation();
804 for (EdgeCont::iterator i =
myEdges.begin(); i !=
myEdges.end(); i++) {
805 (*i).second->sortOutgoingConnectionsByAngle();
812 for (EdgeCont::iterator i =
myEdges.begin(); i !=
myEdges.end(); i++) {
813 (*i).second->computeEdge2Edges(noLeftMovers);
820 for (EdgeCont::iterator i =
myEdges.begin(); i !=
myEdges.end(); i++) {
821 (*i).second->computeLanes2Edges();
829 for (EdgeCont::iterator i =
myEdges.begin(); i !=
myEdges.end(); i++) {
836 for (
int i = 0; i < leftmostLane; i++) {
837 const std::string& oppositeID = edge->
getLanes()[i].oppositeID;
838 NBEdge* oppEdge =
retrieve(oppositeID.substr(0, oppositeID.rfind(
"_")));
839 if (oppositeID !=
"" && oppositeID !=
"-") {
840 if (edge->
getLanes().back().oppositeID ==
"" && oppEdge !=
nullptr) {
842 WRITE_WARNING(
"Moving opposite lane '" + oppositeID +
"' from invalid lane '" + edge->
getLaneID(i) +
"' to lane " +
toString(leftmostLane) +
".");
844 WRITE_WARNING(
"Removing opposite lane '" + oppositeID +
"' for invalid lane '" + edge->
getLaneID(i) +
"'.");
849 const std::string& oppositeID = edge->
getLanes().back().oppositeID;
850 if (oppositeID !=
"" && oppositeID !=
"-") {
851 NBEdge* oppEdge =
retrieve(oppositeID.substr(0, oppositeID.rfind(
"_")));
852 if (oppEdge ==
nullptr) {
853 WRITE_WARNING(
"Removing unknown opposite lane '" + oppositeID +
"' for edge '" + edge->
getID() +
"'.");
858 WRITE_WARNING(
"Adapting invalid opposite lane '" + oppositeID +
"' for edge '" + edge->
getID() +
"' to '" + oppEdgeLeftmost +
"'");
862 if (fixOppositeLengths) {
876 WRITE_ERROR(
"Opposite lane '" + oppositeID +
"' does not connect the same nodes as edge '" + edge->
getID() +
"'!");
887 for (EdgeCont::iterator i =
myEdges.begin(); i !=
myEdges.end(); i++) {
888 (*i).second->appendTurnaround(noTLSControlled, noFringe, onlyDeadends, onlyTurnlane, noGeometryLike,
true);
895 for (std::set<std::string>::const_iterator it = ids.begin(); it != ids.end(); it++) {
896 myEdges[*it]->appendTurnaround(noTLSControlled,
false,
false,
false,
false,
false);
903 std::set<std::string> stopEdgeIDs;
904 for (
auto& stopItem : sc.
getStops()) {
905 stopEdgeIDs.insert(stopItem.second->getEdgeId());
908 NBEdge* edge = item.second;
910 && (stopEdgeIDs.count(item.first) > 0 ||
925 for (EdgeCont::iterator i =
myEdges.begin(); i !=
myEdges.end(); i++) {
926 (*i).second->computeEdgeShape(smoothElevationThreshold);
929 for (EdgeCont::iterator i =
myEdges.begin(); i !=
myEdges.end(); i++) {
931 const std::string& oppositeID = edge->
getLanes().back().oppositeID;
932 if (oppositeID !=
"" && oppositeID !=
"-") {
933 NBEdge* oppEdge =
retrieve(oppositeID.substr(0, oppositeID.rfind(
"_")));
949 for (EdgeCont::iterator i =
myEdges.begin(); i !=
myEdges.end(); ++i) {
950 (*i).second->computeLaneShapes();
968 bool joinEdges =
true;
972 NBEdge* tpledge = *(edges.begin());
975 EdgeVector::const_iterator i;
976 int myPriority = (*edges.begin())->getPriority();
977 for (i = edges.begin(); i != edges.end(); i++) {
979 assert((*i)->getFromNode() == from);
980 assert((*i)->getToNode() == to);
982 nolanes += (*i)->getNumLanes();
984 if (i != edges.begin()) {
989 speed += (*i)->getSpeed();
992 if (myPriority == (*i)->getPriority()) {
993 priority = myPriority;
1000 speed /= edges.size();
1002 NBEdge* newEdge =
new NBEdge(
id, from, to,
"", speed, nolanes, priority,
1007 for (i = edges.begin(); i != edges.end(); ++i) {
1008 const std::vector<NBEdge::Lane>& lanes = (*i)->getLanes();
1009 for (
int j = 0; j < (int)lanes.size(); ++j) {
1023 for (i = edges.begin(); i != edges.end(); i++) {
1025 for (EdgeVector::iterator j = ev.begin(); j != ev.end(); j++) {
1031 for (i = edges.begin(); i != edges.end(); i++) {
1033 currLane += (*i)->getNumLanes();
1037 for (i = edges.begin(); i != edges.end(); i++) {
1038 int noLanes = (*i)->getNumLanes();
1039 for (
int j = 0; j < noLanes; j++, currLane++) {
1046 for (i = edges.begin(); i != edges.end(); i++) {
1056 const double distanceThreshold = 7;
1057 for (EdgeCont::iterator i =
myEdges.begin(); i !=
myEdges.end(); ++i) {
1058 NBEdge* edge = i->second;
1063 NBEdge* opposite =
nullptr;
1066 if ((*j)->getToNode() == edge->
getFromNode() && !(*j)->getLanes().empty()) {
1068 if (distance < distanceThreshold) {
1074 if (opposite !=
nullptr) {
1085 for (EdgeCont::iterator i =
myEdges.begin(); i !=
myEdges.end(); ++i) {
1087 if (opposite !=
nullptr) {
1099 const std::string oppositeID = edgeID[0] ==
'-' ? edgeID.substr(1) :
"-" + edgeID;
1100 EdgeCont::const_iterator it =
myEdges.find(oppositeID);
1106 EdgeCont::const_iterator it =
myEdges.find(edgeID);
1113 KeepClear keepClear,
double contPos,
double visibility,
double speed,
double length,
1116 speed, length, customShape, uncontrolled, warnOnly, permissions));
1141 for (std::vector<PostProcessConnection>::const_iterator i = item.second.begin(); i != item.second.end(); ++i) {
1144 if (from ==
nullptr || to ==
nullptr ||
1146 (*i).keepClear, (*i).contPos, (*i).visibility, (*i).speed, (*i).customLength, (*i).customShape,
1149 const std::string msg =
"Could not insert connection between '" + (*i).from +
"' and '" + (*i).to +
"' after build.";
1150 if (warnOnly || (*i).warnOnly) {
1160 for (EdgeCont::iterator it =
myEdges.begin(); it !=
myEdges.end(); ++it) {
1161 NBEdge* edge = it->second;
1164 std::vector<NBEdge::Connection> connections = edge->
getConnections();
1165 for (std::vector<NBEdge::Connection>::iterator it_con = connections.begin(); it_con != connections.end(); ++it_con) {
1169 "' to edge '" + c.
toEdge->
getID() +
"' via junction '" + to->
getID() +
"'.");
1179 int len = (int)
id.length();
1181 for (EdgeCont::const_iterator i =
myEdges.begin(); i !=
myEdges.end(); ++i) {
1182 std::string curr = (*i).first;
1185 if ((
int)curr.length() <= len) {
1190 if (curr.substr(0, len) ==
id && curr[len] ==
'[') {
1191 ret.push_back((*i).second);
1195 std::string::size_type pos = curr.find(
id);
1197 if (pos == std::string::npos) {
1202 if (curr[pos - 1] !=
']' && curr[pos - 1] !=
'+') {
1207 if (pos +
id.length() < curr.length()) {
1208 if (curr[pos +
id.length()] !=
'[' && curr[pos +
id.length()] !=
'+') {
1213 ret.push_back((*i).second);
1222 std::set<NBEdge*> loadedRoundaboutEdges;
1224 loadedRoundaboutEdges.insert(it->begin(), it->end());
1228 std::set<NBEdge*> candidates;
1230 for (EdgeCont::const_iterator i =
myEdges.begin(); i !=
myEdges.end(); ++i) {
1235 && loadedRoundaboutEdges.count(e) == 0
1237 candidates.insert(e);
1242 std::set<NBEdge*> visited;
1243 for (std::set<NBEdge*>::const_iterator i = candidates.begin(); i != candidates.end(); ++i) {
1250 if (visited.count(e) > 0) {
1254 loopEdges.push_back(e);
1256 #ifdef DEBUG_GUESS_ROUNDABOUT
1260 #ifdef DEBUG_GUESS_ROUNDABOUT
1262 std::cout <<
" e=" << e->
getID() <<
" loopEdges=" <<
toString(loopEdges) <<
"\n";
1270 #ifdef DEBUG_GUESS_ROUNDABOUT
1272 std::cout <<
" rbl\n";
1278 if (edges.size() < 2) {
1280 #ifdef DEBUG_GUESS_ROUNDABOUT
1282 std::cout <<
" deadend\n";
1291 #ifdef DEBUG_GUESS_ROUNDABOUT
1293 std::cout <<
" turn\n";
1299 EdgeVector::const_iterator me = std::find(edges.begin(), edges.end(), e);
1309 #ifdef DEBUG_GUESS_ROUNDABOUT
1311 std::cout <<
" noContinuation\n";
1321 #ifdef DEBUG_GUESS_ROUNDABOUT
1323 std::cout <<
" angle=" << angle <<
" nextAngle=" << nextAngle <<
"\n";
1337 #ifdef DEBUG_GUESS_ROUNDABOUT
1339 std::cout <<
" angle=" << angle <<
"\n";
1345 EdgeVector::const_iterator loopClosed = std::find(loopEdges.begin(), loopEdges.end(), left);
1346 const int loopSize = (int)(loopEdges.end() - loopClosed);
1351 }
else if (loopSize < (
int)loopEdges.size()) {
1353 EdgeVector(loopEdges.begin() + (loopEdges.size() - loopSize), loopEdges.end()).swap(loopEdges);
1356 int attachments = 0;
1357 for (EdgeVector::const_iterator j = loopEdges.begin(); j != loopEdges.end(); ++j) {
1358 if ((*j)->getToNode()->getEdges().size() > 2) {
1362 if (attachments < 3) {
1364 #ifdef DEBUG_GUESS_ROUNDABOUT
1366 std::cout <<
" attachments=" << attachments <<
"\n";
1373 if (visited.count(left) > 0) {
1377 loopEdges.push_back(left);
1381 #ifdef DEBUG_GUESS_ROUNDABOUT
1399 for (EdgeVector::const_iterator it = loopEdges.begin(); it != loopEdges.end(); ++it) {
1400 points.
append((*it)->getGeometry());
1402 double circumference = points.
length2D();
1403 return 4 *
M_PI * points.
area() / (circumference * circumference);
1407 const std::set<EdgeSet>
1417 if (roundabout.size() > 0) {
1430 if (e->getToNode() == node) {
1442 for (
NBEdge*
const edge : roundaboutSet) {
1444 NBNode*
const node = edge->getToNode();
1446 if (roundaboutSet.count(inEdge) > 0) {
1452 if (inEdge->getTurnDestination() !=
nullptr) {
1453 inEdge->removeFromConnections(inEdge->getTurnDestination(), -1);
1457 edge->setJunctionPriority(node, NBEdge::JunctionPriority::ROUNDABOUT);
1458 edge->setJunctionPriority(edge->getFromNode(), NBEdge::JunctionPriority::ROUNDABOUT);
1467 for (EdgeCont::iterator i =
myEdges.begin(); i !=
myEdges.end(); ++i) {
1507 int lanesCreated = 0;
1508 std::vector<std::string> edges;
1509 if (excludeOpt !=
"") {
1512 std::set<std::string> exclude(edges.begin(), edges.end());
1513 for (EdgeCont::iterator it =
myEdges.begin(); it !=
myEdges.end(); it++) {
1514 NBEdge* edge = it->second;
1516 exclude.count(edge->
getID()) == 0
1523 || (!fromPermissions && edge->
getSpeed() > minSpeed && edge->
getSpeed() <= maxSpeed)
1529 return lanesCreated;
1536 std::vector<std::string> avoid;
1542 std::set<std::string> reserve;
1545 avoid.insert(avoid.end(), reserve.begin(), reserve.end());
1548 std::set<NBEdge*, ComparatorIdLess> toChange;
1549 for (EdgeCont::iterator it =
myEdges.begin(); it !=
myEdges.end(); it++) {
1551 toChange.insert(it->second);
1558 toChange.insert(it->second);
1561 if (reservedIDs && reserve.count(it->first) > 0) {
1562 toChange.insert(it->second);
1566 std::map<std::string, std::vector<NBPTStop*> > stopsOnEdge;
1567 for (
const auto& item : sc.
getStops()) {
1568 stopsOnEdge[item.second->getEdgeId()].push_back(item.second);
1572 for (
NBEdge* edge : toChange) {
1575 for (
NBEdge* edge : toChange) {
1576 const std::string origID = edge->getID();
1578 edge->setOrigID(origID);
1580 edge->setID(idSupplier.
getNext());
1581 myEdges[edge->getID()] = edge;
1582 for (
NBPTStop* stop : stopsOnEdge[origID]) {
1583 stop->setEdgeId(prefix + edge->getID(), *
this);
1586 if (prefix.empty()) {
1587 return (
int)toChange.size();
1592 for (
auto item : oldEdges) {
1594 rename(item.second, prefix + item.first);
1605 for (EdgeCont::const_iterator it =
myEdges.begin(); it !=
myEdges.end(); it++) {
1606 const NBEdge* e1 = it->second;
1612 for (EdgeCont::const_iterator it2 = it; it2 !=
myEdges.end(); it2++) {
1613 const NBEdge* e2 = it2->second;
1622 const double overlap = outline1.
getOverlapWith(outline2, zThreshold);
1623 if (overlap > threshold) {
1634 for (EdgeCont::const_iterator it =
myEdges.begin(); it !=
myEdges.end(); it++) {
1635 const NBEdge* edge = it->second;
1636 for (
int i = 0; i < (int)edge->
getNumLanes(); i++) {
1639 if (maxJump > 0.01) {
1641 }
else if (grade > threshold) {
1646 const std::vector<NBEdge::Connection>& connections = edge->
getConnections();
1647 for (std::vector<NBEdge::Connection>::const_iterator it_con = connections.begin(); it_con != connections.end(); ++it_con) {
1651 if (maxJump > 0.01) {
1653 }
else if (grade > threshold) {
1663 int affectedEdges = 0;
1665 if (item.second->joinLanes(perms)) {
1669 return affectedEdges;
1677 std::set<NBEdge*> tramEdges;
1678 std::set<NBEdge*> targetEdges;
1682 if (item.second->getNumLanes() == 1) {
1683 tramEdges.insert(item.second);
1685 WRITE_WARNINGF(
"Not joining tram edge '%s' with % lanes", item.second->getID(), item.second->getNumLanes());
1688 targetEdges.insert(item.second);
1691 if (tramEdges.size() == 0 || targetEdges.size() == 0) {
1696 for (
NBEdge* edge : tramEdges) {
1697 const Boundary& bound = edge->getGeometry().getBoxBoundary();
1698 float min[2] = {
static_cast<float>(bound.
xmin()),
static_cast<float>(bound.
ymin()) };
1699 float max[2] = {
static_cast<float>(bound.
xmax()),
static_cast<float>(bound.
ymax()) };
1700 tramTree.
Insert(min, max, edge);
1703 std::map<std::pair<NBEdge*, int>,
NBEdge*> matches;
1705 for (
NBEdge* edge : targetEdges) {
1706 Boundary bound = edge->getGeometry().getBoxBoundary();
1707 bound.
grow(maxDist + edge->getTotalWidth());
1708 float min[2] = {
static_cast<float>(bound.
xmin()),
static_cast<float>(bound.
ymin()) };
1709 float max[2] = {
static_cast<float>(bound.
xmax()),
static_cast<float>(bound.
ymax()) };
1710 std::set<const Named*> nearby;
1712 tramTree.
Search(min, max, visitor);
1713 for (
const Named* namedEdge : nearby) {
1718 double minEdgeDist = maxDist + 1;
1722 for (
int i = 0; i < edge->getNumLanes(); i++) {
1723 double maxLaneDist = -1;
1727 const double dist = tramShape.
distance2D(pos,
false);
1728 #ifdef DEBUG_JOIN_TRAM
1737 maxLaneDist =
MAX2(maxLaneDist, dist);
1739 if (maxLaneDist >= 0 && maxLaneDist < minEdgeDist) {
1740 minEdgeDist = maxLaneDist;
1754 if (angleOK && offset2 > offset1) {
1755 std::pair<NBEdge*, int> key = std::make_pair(edge, minLane);
1756 if (matches.count(key) == 0) {
1757 matches[key] = tramEdge;
1759 WRITE_WARNINGF(
"Ambiguous tram edges '%' and '%' for lane '%'", matches[key]->getID(), tramEdge->
getID(), edge->getLaneID(minLane));
1761 #ifdef DEBUG_JOIN_TRAM
1762 std::cout << edge->getLaneID(minLane) <<
" is close to tramEdge " << tramEdge->
getID() <<
" maxLaneDist=" << minEdgeDist <<
" tramLength=" << tramEdge->
getLength() <<
" edgeLength=" << edge->getLength() <<
" tramAngle=" << tramAngle <<
" edgeAngle=" << edge->getTotalAngle() <<
"\n";
1768 if (matches.size() == 0) {
1772 for (
NBEdge* tramEdge : tramEdges) {
1773 std::vector<std::pair<double, std::pair<NBEdge*, int> > > roads;
1774 for (
auto item : matches) {
1775 if (item.second == tramEdge) {
1776 NBEdge* road = item.first.first;
1777 int laneIndex = item.first.second;
1780 roads.push_back(std::make_pair(tramPos, item.first));
1783 if (roads.size() != 0) {
1785 sort(roads.begin(), roads.end());
1786 #ifdef DEBUG_JOIN_TRAM
1787 std::cout <<
" tramEdge=" << tramEdge->getID() <<
" roads=";
1788 for (
auto item : roads) {
1789 std::cout << item.second.first->getLaneID(item.second.second) <<
",";
1791 std::cout <<
" offsets=";
1792 for (
auto item : roads) {
1793 std::cout << item.first <<
",";
1801 std::string tramEdgeID = tramEdge->getID();
1802 NBNode* tramFrom = tramEdge->getFromNode();
1804 const double tramLength = tramShape.
length();
1806 bool erasedLast =
false;
1807 for (
auto item : roads) {
1808 const double gap = item.first - pos;
1809 NBEdge* road = item.second.first;
1810 int laneIndex = item.second.second;
1812 #ifdef DEBUG_JOIN_TRAM
1813 std::cout <<
" splitting tramEdge=" << tramEdge->
getID() <<
" at " << item.first <<
" (gap=" << gap <<
")\n";
1815 const std::string firstPartID = tramEdgeID +
"#" +
toString(tramPart++);
1821 incoming.push_back(firstPart);
1822 replacement.push_back(firstPart);
1826 replacement.push_back(road);
1829 tramEdge->reinitNodes(road->
getToNode(), tramEdge->getToNode());
1832 #ifdef DEBUG_JOIN_TRAM
1833 std::cout <<
" shorted tramEdge=" << tramEdge->getID() <<
" (joined with roadEdge=" << road->
getID() <<
"\n";
1836 #ifdef DEBUG_JOIN_TRAM
1837 std::cout <<
" erased tramEdge=" << tramEdge->getID() <<
"\n";
1843 for (
NBEdge* in : incoming) {
1844 if (in->getPermissions() ==
SVC_TRAM && !in->isConnectedTo(road)) {
1846 in->reinitNodes(in->getFromNode(), road->
getFromNode());
1849 #ifdef DEBUG_JOIN_TRAM
1850 std::cout <<
" erased incoming tramEdge=" << in->getID() <<
"\n";
1857 NBEdge* lastRoad = roads.back().second.first;
1861 if (lastRoad->
getToNode() != out->getToNode()) {
1865 #ifdef DEBUG_JOIN_TRAM
1866 std::cout <<
" erased outgoing tramEdge=" << out->getID() <<
"\n";
1873 replacement.push_back(tramEdge);
1888 item.second->setNumericalID((
int)result.size());
1889 result.push_back(item.second);
1903 for (
const auto& item :
myEdges) {
#define WRITE_WARNINGF(...)
#define WRITE_WARNING(msg)
std::set< NBEdge * > EdgeSet
container for unique edges
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
KeepClear
keepClear status of connections
std::vector< NBRouterEdge * > RouterEdgeVector
#define JOIN_TRAM_MIN_LENGTH
#define JOIN_TRAM_MAX_ANGLE
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.
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
bool isSidewalk(SVCPermissions permissions)
Returns whether an edge with the given permission is a sidewalk.
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_PASSENGER
vehicle is a passenger car (a "normal" car)
@ SVC_TRAM
vehicle is a light rail
@ 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
SumoXMLNodeType
Numbers representing special SUMO-XML-attribute values for representing node- (junction-) types used ...
bool gDebugFlag1
global utility flags for debugging
const double SUMO_const_laneWidthAndOffset
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
const double SUMO_const_halfLaneAndOffset
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
A class that stores a 2D geometrical boundary.
double ymin() const
Returns minimum y-coordinate.
double xmin() const
Returns minimum x-coordinate.
Boundary & grow(double by)
extends the boundary by the given amount
bool overlapsWith(const AbstractPoly &poly, double offset=0) const
Returns whether the boundary overlaps with the given polygon.
double ymax() const
Returns maximum y-coordinate.
double xmax() const
Returns maximum x-coordinate.
static GeoConvHelper & getProcessing()
the coordinate transformation to use for input conversion and processing
static GeoConvHelper & getLoaded()
the coordinate transformation that was loaded fron an input file
bool x2cartesian_const(Position &from) const
Converts the given coordinate into a cartesian using the previous initialisation.
static PositionVector parseShapeReporting(const std::string &shpdef, const std::string &objecttype, const char *objectid, bool &ok, bool allowEmpty, bool report=true)
Builds a PositionVector from a string representation, reporting occurred errors.
static const double INVALID_OFFSET
a value to signify offsets outside the range of [0, Line.length()]
static double nearest_offset_on_line_to_point2D(const Position &lineStart, const Position &lineEnd, const Position &p, bool perpendicular=true)
static double legacyDegree(const double angle, const bool positive=false)
static double getMinAngleDiff(double angle1, double angle2)
Returns the minimum distance (clockwise/counter-clockwise) between both angles.
std::string getNext()
Returns the next id.
static void nextCW(const EdgeVector &edges, EdgeVector::const_iterator &from)
A container for districts.
void removeFromSinksAndSources(NBEdge *const e)
Removes the given edge from the lists of sources and sinks in all stored districts.
Sorts splits by their position (increasing)
void patchRoundabouts(NBEdge *orig, NBEdge *part1, NBEdge *part2, std::set< EdgeSet > &roundabouts)
fix roundabout information after splitting an edge
void computeEdgeShapes(double smoothElevationThreshold=-1)
Computes the shapes of all edges stored in the container.
void removeUnwishedEdges(NBDistrictCont &dc)
Removes unwished edges (not in keep-edges)
NBEdge * getByID(const std::string &edgeID) const
Returns the edge with id if it exists.
const std::set< EdgeSet > getRoundabouts() const
Returns the determined roundabouts.
void computeEdge2Edges(bool noLeftMovers)
Computes for each edge the approached edges.
int guessRoundabouts()
Determines which edges belong to roundabouts and increases their priority.
bool myNeedGeoTransformedPruningBoundary
whether a geo transform has been applied to the pruning boundary
void sortOutgoingLanesConnections()
Sorts all lanes of all edges within the container by their direction.
void addRoundabout(const EdgeSet &roundabout)
add user specified roundabout
std::set< EdgeSet > myRoundabouts
Edges marked as belonging to a roundabout by the user (each EdgeVector is a roundabout)
void appendRailwayTurnarounds(const NBPTStopCont &sc)
Appends turnarounds to all bidiRail edges with stops.
std::set< std::string > myEdges2Remove
Set of ids of edges which shall explicitly be removed.
std::set< std::string > myIgnoredEdges
The ids of ignored edges.
double myEdgesMinSpeed
The minimum speed an edge may have in order to be kept (default: -1)
int myEdgesSplit
the number of splits of edges during the building
void recheckPostProcessConnections()
Try to set any stored connections.
void checkGeometries(const double maxAngle, const double minRadius, bool fix, bool fixRailways, bool silent=false)
void extract(NBDistrictCont &dc, NBEdge *edge, bool remember=false)
Removes the given edge from the container like erase but does not delete it.
void processSplits(NBEdge *e, std::vector< Split > splits, NBNodeCont &nc, NBDistrictCont &dc, NBTrafficLightLogicCont &tlc)
EdgeVector getAllEdges() const
return all edges
void erase(NBDistrictCont &dc, NBEdge *edge)
Removes the given edge from the container (deleting it)
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
std::set< std::string > myTypes2Keep
Set of edges types which shall be kept.
void recheckLanes()
Rechecks whether all lanes have a successor for each of the stored edges.
NBEdge * getOppositeByID(const std::string &edgeID) const
Returns the edge with negated id if it exists.
EdgeCont myExtractedEdges
The extracted nodes which are kept for reference.
void reduceGeometries(const double minDist)
void recheckLaneSpread()
Rechecks whether the lane spread is proper.
bool ignoreFilterMatch(NBEdge *edge)
Returns true if this edge matches one of the removal criteria.
void removeRoundabout(const NBNode *node)
remove roundabout that contains the given node
void splitGeometry(NBDistrictCont &dc, NBNodeCont &nc)
Splits edges into multiple if they have a complex geometry.
void computeLanes2Edges()
Computes for each edge which lanes approach the next edges.
NBEdge * retrievePossiblySplit(const std::string &id, bool downstream) const
Tries to retrieve an edge, even if it is splitted.
RouterEdgeVector getAllRouterEdges() const
void rename(NBEdge *edge, const std::string &newID)
Renames the edge. Throws exception if newID already exists.
bool hasPostProcessConnection(const std::string &from, const std::string &to="")
EdgeCont myEdges
The instance of the dictionary (id->edge)
std::set< std::string > myEdges2Keep
Set of ids of edges which shall explicitly be kept.
NBTypeCont & myTypeCont
The network builder; used to obtain type information.
void generateStreetSigns()
assigns street signs to edges based on toNode types
void clearControllingTLInformation() const
Clears information about controlling traffic lights for all connenections of all edges.
std::set< EdgeSet > myGuessedRoundabouts
Edges marked as belonging to a roundabout after guessing.
void clear()
Deletes all edges.
void guessOpposites()
Sets opposite lane information for geometrically close edges.
void markRoundabouts()
mark edge priorities and prohibit turn-arounds for all roundabout edges
std::set< std::string > myTypes2Remove
Set of edges types which shall be removed.
void applyOptions(OptionsCont &oc)
Initialises the storage by applying given options.
PositionVector myPruningBoundary
Boundary within which an edge must be located in order to be kept.
int joinLanes(SVCPermissions perms)
join adjacent lanes with the given permissions
void checkOverlap(double threshold, double zThreshold) const
check whether edges overlap
SVCPermissions myVehicleClasses2Remove
Set of vehicle types which need not be supported (edges which allow ONLY these are removed)
EdgeVector getGeneratedFrom(const std::string &id) const
Returns the edges which have been built by splitting the edge of the given id.
void appendTurnarounds(bool noTLSControlled, bool noFringe, bool onlyDeadends, bool onlyTurnlane, bool noGeometryLike)
Appends turnarounds to all edges stored in the container.
SVCPermissions myVehicleClasses2Keep
Set of vehicle types which must be allowed on edges in order to keep them.
void computeLaneShapes()
Computes the shapes of all lanes of all edges stored in the container.
void joinSameNodeConnectingEdges(NBDistrictCont &dc, NBTrafficLightLogicCont &tlc, EdgeVector edges)
Joins the given edges because they connect the same nodes.
bool myRemoveEdgesAfterJoining
Whether edges shall be joined first, then removed.
std::map< std::string, NBEdge * > EdgeCont
The type of the dictionary where an edge may be found by its id.
void addPostProcessConnection(const std::string &from, int fromLane, const std::string &to, int toLane, bool mayDefinitelyPass, KeepClear keepClear, double contPos, double visibility, double speed, double length, const PositionVector &customShape, bool uncontrolled, bool warnOnly, SVCPermissions permissions=SVC_UNSPECIFIED)
Adds a connection which could not be set during loading.
std::map< std::string, std::vector< PostProcessConnection > > myConnections
The list of connections to recheck.
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
NBEdgeCont(NBTypeCont &tc)
Constructor.
int joinTramEdges(NBDistrictCont &dc, NBPTLineCont &lc, double maxDist)
join tram edges into adjacent lanes
int guessSpecialLanes(SUMOVehicleClass svc, double width, double minSpeed, double maxSpeed, bool fromPermissions, const std::string &excludeOpt)
add sidwalks to edges within the given limits or permissions and return the number of edges affected
int remapIDs(bool numericaIDs, bool reservedIDs, const std::string &prefix, NBPTStopCont &sc)
remap node IDs accoring to options –numerical-ids and –reserved-ids
bool checkConsistency(const NBNodeCont &nc)
ensure that all edges have valid nodes
static double formFactor(const EdgeVector &loopEdges)
compute the form factor for a loop of edges
bool splitAt(NBDistrictCont &dc, NBEdge *edge, NBNode *node)
Splits the edge at the position nearest to the given node.
std::vector< std::string > getAllNames() const
Returns all ids of known edges.
void checkGrade(double threshold) const
check whether edges are to steep
The representation of a single edge during network building.
bool addEdge2EdgeConnection(NBEdge *dest, bool overrideRemoval=false)
Adds a connection to another edge.
double getLength() const
Returns the computed length of the edge.
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
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.
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)
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
const std::string & getStreetName() const
Returns the street name of this edge.
void setAverageLengthWithOpposite(double val)
patch average lane length in regard to the opposite edge
LaneSpreadFunction getLaneSpreadFunction() const
Returns how this edge's lanes' lateral offset is computed.
bool isBidiRail(bool ignoreSpread=false) const
whether this edge is part of a bidirectional railway
void dismissVehicleClassInformation()
dimiss vehicle class information
LaneSpreadFunction myLaneSpreadFunction
The information about how to spread the lanes.
const std::string & getID() const
const std::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
NBNode * getToNode() const
Returns the destination node of the edge.
@ LANES2LANES_USER
Lanes to lanes - relationships are loaded; no recheck is necessary/wished.
double getSpeed() const
Returns the speed allowed on this edge.
void setLaneWidth(int lane, double width)
set lane specific width (negative lane implies set for all lanes)
void setLaneSpreadFunction(LaneSpreadFunction spread)
(Re)sets how the lanes lateral offset shall be computed
std::vector< Lane > myLanes
Lane information.
int getNumLanes() const
Returns the number of lanes.
const PositionVector & getGeometry() const
Returns the geometry of the edge.
static const double UNSPECIFIED_CONTPOS
unspecified internal junction position
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)
void invalidateConnections(bool reallowSetting=false)
invalidate current connections of edge
double getTotalWidth() const
Returns the combined width of all lanes of this edge.
static const double UNSPECIFIED_VISIBILITY_DISTANCE
unspecified foe visibility for connections
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)
void addSign(NBSign sign)
add Sign
void moveOutgoingConnectionsFrom(NBEdge *e, int laneOff)
move outgoing connection
std::string getLaneID(int lane) const
get lane ID
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.
@ USER
The connection was given by the user.
@ VALIDATED
The connection was computed and validated.
@ COMPUTED
The connection was computed.
int getJunctionPriority(const NBNode *const node) const
Returns the junction priority (normalised for the node currently build)
NBEdge * getTurnDestination(bool possibleDestination=false) const
double getAngleAtNode(const NBNode *const node) const
Returns the angle of the edge's geometry at the given node.
static const double UNSPECIFIED_WIDTH
unspecified lane width
bool hasRestrictedLane(SUMOVehicleClass vclass) const
returns whether any lane already allows the given vclass exclusively
const std::vector< Connection > & getConnections() const
Returns the connections.
void copyConnectionsFrom(NBEdge *src)
copy connections from antoher edge
const std::string & getTypeID() const
get ID of type
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
bool recheckLanes()
recheck whether all lanes within the edge are all right and optimises the connections once again
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.
const PositionVector & getLaneShape(int i) const
Returns the shape of the nth lane.
Lane & getLaneStruct(int lane)
void setLoadedLength(double val)
set loaded length
void decLaneNo(int by)
decrement lane
NBNode * myFrom
The source and the destination node.
double getFinalLength() const
get length that will be assigned to the lanes in the final network
void setGeometry(const PositionVector &g, bool inner=false)
(Re)sets the edge's geometry
NBNode * getFromNode() const
Returns the origin node of the edge.
static void loadPrefixedIDsFomFile(const std::string &file, const std::string prefix, std::set< std::string > &into)
Add prefixed ids defined in file.
static double relAngle(double angle1, double angle2)
computes the relative angle between the two angles
static void loadEdgesFromFile(const std::string &file, std::set< std::string > &into)
Add edge ids defined in file (either ID or edge:ID per line) into the given set.
static bool transformCoordinates(PositionVector &from, bool includeInBoundary=true, GeoConvHelper *from_srs=0)
Container for nodes during the netbuilding process.
bool insert(const std::string &id, const Position &position, NBDistrict *district=0)
Inserts a node into the map.
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
void markAsSplit(const NBNode *node)
mark a node as being created form a split
Represents a single node (junction) during network building.
void removeEdge(NBEdge *edge, bool removeFromConnections=true)
Removes edge from this node and optionally removes connections as well.
bool isSimpleContinuation(bool checkLaneNumbers=true, bool checkWidth=false) const
check if node is a simple continuation
SumoXMLNodeType getType() const
Returns the type of this node.
void replaceOutgoing(NBEdge *which, NBEdge *by, int laneOff)
Replaces occurences of the first edge within the list of outgoing by the second Connections are remap...
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges (The edges which start at this node)
const EdgeVector & getEdges() const
Returns all edges which participate in this node (Edges that start or end at this node)
void setRoundabout()
update the type of this node as a roundabout
void invalidateTLS(NBTrafficLightLogicCont &tlCont, bool removedConnections, bool addedConnections)
causes the traffic light to be computed anew
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges (The edges which yield in this node)
void replaceIncoming(NBEdge *which, NBEdge *by, int laneOff)
Replaces occurences of the first edge within the list of incoming by the second Connections are remap...
const std::set< NBTrafficLightDefinition * > & getControllingTLS() const
Returns the traffic lights that were assigned to this node (The set of tls that control this node)
bool typeWasGuessed() const
return whether a priority road turns at this node
const Position & getPosition() const
void removeDoubleEdges()
remove duble edges
NBEdge * getConnectionTo(NBNode *n) const
get connection to certain node
void replaceEdge(const std::string &edgeID, const EdgeVector &replacement)
replace the edge with the given edge list in all lines
const std::map< std::string, NBPTStop * > & getStops() const
The representation of a single pt stop.
A class representing a single street sign.
@ SIGN_TYPE_RIGHT_BEFORE_LEFT
A container for traffic light definitions and built programs.
void replaceRemoved(NBEdge *removed, int removedLane, NBEdge *by, int byLane, bool incoming)
Replaces occurences of the removed edge/lane in all definitions by the given edge.
A storage for available edgeTypes of edges.
bool getEdgeTypeShallBeDiscarded(const std::string &edgeType) const
Returns the information whether edges of this edgeType shall be discarded.
bool knows(const std::string &edgeType) const
Returns whether the named edgeType is in the container.
Allows to store the object; used as context while traveling the rtree in TraCI.
Base class for objects which have an id.
virtual void setID(const std::string &newID)
resets the id
const std::string & getID() const
Returns the id.
A RT-tree for efficient storing of SUMO's Named objects.
void Insert(const float a_min[2], const float a_max[2], Named *const &a_data)
Insert entry.
int Search(const float a_min[2], const float a_max[2], const Named::StoringVisitor &c) const
Find all within search rectangle.
A storage for options typed value containers)
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
bool isDefault(const std::string &name) const
Returns the information whether the named option has still the default value.
bool exists(const std::string &name) const
Returns the information whether the named option is known.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
const StringVector & getStringVector(const std::string &name) const
Returns the list of string-value of the named option (only for Option_StringVector)
std::string getValueString(const std::string &name) const
Returns the string-value of the named option (all options)
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.
A point in 2D or 3D with translation and scaling methods.
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 length() const
Returns the length.
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
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
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
double getOverlapWith(const PositionVector &poly, double zThreshold) const
Returns the maximum overlaps between this and the given polygon (when not separated by at least zThre...
bool partialWithin(const AbstractPoly &poly, double offset=0) const
Returns the information whether this polygon lies partially within the given polygon.
double getMaxGrade(double &maxJump) const
double area() const
Returns the area (0 for non-closed)
bool intersects(const Position &p1, const Position &p2) const
Returns the information whether this list of points interesects the given line.
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
static long long int toLong(const std::string &sData)
converts a string into the long value described by it by calling the char-type converter,...
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
static bool startsWith(const std::string &str, const std::string prefix)
Checks whether a given string starts with the prefix.
static T maxValue(const std::vector< T > &v)
A structure which describes a connection between edges or lanes.
NBEdge * toEdge
The edge the connections yields in.
PositionVector viaShape
shape of via
std::string getDescription(const NBEdge *parent) const
get string describing this connection
PositionVector shape
shape of Connection
An (internal) definition of a single lane of an edge.
std::string oppositeID
An opposite lane ID, if given.
PositionVector shape
The lane's shape.
A structure representing a connection between two lanes.
A structure which describes changes of lane number or speed along the road.
int offsetFactor
direction in which to apply the offset (used by netgenerate for lefthand networks)
double speed
The speed after this change.
double offset
lateral offset to edge geometry
std::string nameID
the default node id
std::string idBefore
The id for the edge before the split.
double pos
The position of this change.
std::vector< int > lanes
The lanes after this change.
std::string idAfter
The id for the edge after the split.
NBNode * node
The new node that is created for this split.