61 #define DEBUG_COND(road) ((road)->id == "32")
62 #define DEBUG_COND2(edgeID) (StringUtils::startsWith((edgeID), "67"))
63 #define DEBUG_COND3(roadID) (roadID == "32")
186 bool customLaneShapes = oc.
getBool(
"opendrive.lane-shapes");
190 std::map<std::string, OpenDriveEdge*> edges;
193 std::vector<std::string> files = oc.
getStringVector(
"opendrive-files");
194 for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
196 WRITE_ERROR(
"Could not open opendrive file '" + *file +
"'.");
205 for (
auto& item : edges) {
207 if (signal.
type ==
"") {
221 std::map<std::string, OpenDriveEdge*> innerEdges, outerEdges;
222 for (std::map<std::string, OpenDriveEdge*>::iterator i = edges.begin(); i != edges.end(); ++i) {
223 if ((*i).second->isInner) {
224 innerEdges[(*i).first] = (*i).second;
226 outerEdges[(*i).first] = (*i).second;
241 std::map<std::string, Boundary> posMap;
242 std::map<std::string, std::string> edge2junction;
243 std::vector<NodeSet> joinedNodeIDs;
245 for (std::map<std::string, OpenDriveEdge*>::iterator i = innerEdges.begin(); i != innerEdges.end(); ++i) {
249 if (posMap.find(e->
junction) == posMap.end()) {
255 for (std::map<std::string, Boundary>::iterator i = posMap.begin(); i != posMap.end(); ++i) {
258 throw ProcessError(
"Could not add node '" + (*i).first +
"'.");
262 for (std::map<std::string, OpenDriveEdge*>::iterator i = outerEdges.begin(); i != outerEdges.end(); ++i) {
264 for (std::vector<OpenDriveLink>::iterator j = e->
links.begin(); j != e->
links.end(); ++j) {
272 throw ProcessError(
"Could not build node '" + nid +
"'.");
279 if (edge2junction.find(l.
elementID) != edge2junction.end()) {
291 for (std::map<std::string, OpenDriveEdge*>::iterator i = outerEdges.begin(); i != outerEdges.end(); ++i) {
293 for (std::vector<OpenDriveLink>::iterator j = e->
links.begin(); j != e->
links.end(); ++j) {
300 std::string id1 = e->
id;
305 std::string nid = id1 +
"." + id2;
310 throw ProcessError(
"Could not build node '" + nid +
"'.");
328 for (std::map<std::string, OpenDriveEdge*>::iterator i = outerEdges.begin(); i != outerEdges.end(); ++i) {
330 if (e->
to !=
nullptr && e->
from !=
nullptr) {
333 for (std::map<std::string, OpenDriveEdge*>::iterator j = innerEdges.begin(); j != innerEdges.end(); ++j) {
335 for (std::vector<OpenDriveLink>::iterator k = ie->
links.begin(); k != ie->
links.end(); ++k) {
341 std::string nid = edge2junction[ie->
id];
353 for (std::map<std::string, OpenDriveEdge*>::iterator i = outerEdges.begin(); i != outerEdges.end(); ++i) {
355 if ((e->
from ==
nullptr || e->
to ==
nullptr) && e->
geom.size() == 0) {
358 if (e->
from ==
nullptr) {
359 const std::string nid = e->
id +
".begin";
362 if (e->
to ==
nullptr) {
363 const std::string nid = e->
id +
".end";
368 std::map<NBNode*, NBNode*> joinedNodes;
369 for (
NodeSet& joined : joinedNodeIDs) {
371 for (
NBNode* j : joined) {
372 joinedPos = joinedPos + j->getPosition();
374 joinedPos = joinedPos * (1.0 / joined.size());
376 if (!nc.
insert(joinedID, joinedPos)) {
377 throw ProcessError(
"Could not add node '" + joinedID +
"'.");
380 for (
NBNode* j : joined) {
384 for (std::map<std::string, OpenDriveEdge*>::iterator i = outerEdges.begin(); i != outerEdges.end(); ++i) {
386 if (joinedNodes.count(e->
from) != 0) {
390 if (joinedNodes.count(e->
to) != 0) {
392 e->
to = joinedNodes[e->
to];
404 std::map<std::pair<NBEdge*, int>,
int> laneIndexMap;
406 for (std::map<std::string, OpenDriveEdge*>::iterator i = outerEdges.begin(); i != outerEdges.end(); ++i) {
408 if (e->
geom.size() < 2) {
412 bool lanesBuilt =
false;
437 if (
DEBUG_COND3(e->
id)) std::cout <<
" geomWithOffset=" << geomWithOffset <<
"\n";
439 const double length2D = geomWithOffset.
length2D();
440 double cF = length2D == 0 ? 1 : e->
length / length2D;
441 NBEdge* prevRight =
nullptr;
442 NBEdge* prevLeft =
nullptr;
450 WRITE_WARNING(
"Edge '" + e->
id +
"' has to be split as it connects same junctions.")
454 const double minDist = oc.
getFloat(
"opendrive.curve-resolution");
459 int sectionIndex = 0;
466 double nextS = (j + 1)->s;
467 const std::string nodeID = e->
id + (positionIDs ?
"." +
toString(nextS) :
"#" +
toString(sectionIndex + 1));
475 std::string
id = e->
id;
477 if (sFrom != e->
from || sTo != e->
to) {
483 id =
id +
"#" +
toString(sectionIndex++);
485 #ifdef DEBUG_VARIABLE_WIDTHS
487 std::cout <<
" id=" <<
id <<
" sB=" << sB <<
" sE=" << sE <<
" geom=" << geom <<
"\n";
492 NBEdge* currRight =
nullptr;
493 if ((*j).rightLaneNumber > 0) {
494 std::vector<double> offsets(geom.size(), 0);
495 bool useOffsets =
false;
500 rightGeom.
move2side((*j).discardedInnerWidthRight);
503 std::cout <<
" -" <<
id <<
"_geom=" << geom <<
" -" <<
id <<
"_rightGeom=" << rightGeom <<
"\n";
508 currRight =
new NBEdge(
"-" +
id, sFrom, sTo, (*j).rightType, defaultSpeed, (*j).rightLaneNumber, priorityR,
512 std::sort(lanes.begin(), lanes.end(),
LaneSorter());
513 for (std::vector<OpenDriveLane>::const_iterator k = lanes.begin(); k != lanes.end(); ++k) {
514 std::map<int, int>::const_iterator lp = (*j).laneMap.find((*k).id);
515 if (lp != (*j).laneMap.end()) {
516 int sumoLaneIndex = lp->second;
518 laneIndexMap[std::make_pair(currRight, sumoLaneIndex)] = (*k).id;
524 }
else if (customLaneShapes) {
527 if (customLaneShapes) {
538 if (prevRight !=
nullptr) {
540 for (std::map<int, int>::const_iterator k = connections.begin(); k != connections.end(); ++k) {
541 #ifdef DEBUG_CONNECTIONS
543 std::cout <<
"addCon1 from=" << prevRight->
getID() <<
"_" << (*k).first <<
" to=" << currRight->
getID() <<
"_" << (*k).second <<
"\n";
549 prevRight = currRight;
554 NBEdge* currLeft =
nullptr;
555 if ((*j).leftLaneNumber > 0) {
556 std::vector<double> offsets(geom.size(), 0);
557 bool useOffsets =
false;
559 leftGeom.
move2side(-(*j).discardedInnerWidthLeft);
562 if (
DEBUG_COND3(e->
id)) std::cout <<
" " <<
id <<
"_geom=" << geom <<
" " <<
id <<
"_leftGeom=" << leftGeom <<
"\n";
564 currLeft =
new NBEdge(
id, sTo, sFrom, (*j).leftType, defaultSpeed, (*j).leftLaneNumber, priorityL,
568 std::sort(lanes.begin(), lanes.end(),
LaneSorter());
569 for (std::vector<OpenDriveLane>::const_iterator k = lanes.begin(); k != lanes.end(); ++k) {
570 std::map<int, int>::const_iterator lp = (*j).laneMap.find((*k).id);
571 if (lp != (*j).laneMap.end()) {
572 int sumoLaneIndex = lp->second;
574 laneIndexMap[std::make_pair(currLeft, sumoLaneIndex)] = (*k).id;
580 }
else if (customLaneShapes) {
583 if (customLaneShapes) {
594 if (prevLeft !=
nullptr) {
595 std::map<int, int> connections = (*j).getInnerConnections(
OPENDRIVE_TAG_LEFT, *(j - 1));
596 for (std::map<int, int>::const_iterator k = connections.begin(); k != connections.end(); ++k) {
597 #ifdef DEBUG_CONNECTIONS
599 std::cout <<
"addCon2 from=" << currLeft->
getID() <<
"_" << (*k).first <<
" to=" << prevLeft->
getID() <<
"_" << (*k).second <<
"\n";
615 if (oc.
isSet(
"polygon-output")) {
634 centerLine.push_back(
Position(-o.length / 2, 0));
635 centerLine.push_back(
Position(o.length / 2, 0));
637 centerLine.
rotate2D(roadHdg + o.hdg);
668 for (std::map<std::string, OpenDriveEdge*>::iterator i = edges.begin(); i != edges.end(); ++i) {
672 std::vector<Connection> connections2;
673 for (std::map<std::string, OpenDriveEdge*>::iterator j = edges.begin(); j != edges.end(); ++j) {
674 const std::set<Connection>& conns = (*j).second->connections;
676 for (std::set<Connection>::const_iterator i = conns.begin(); i != conns.end(); ++i) {
677 if (innerEdges.find((*i).fromEdge) != innerEdges.end()) {
681 if (innerEdges.find((*i).toEdge) != innerEdges.end()) {
682 std::set<Connection> seen;
685 connections2.push_back(*i);
690 for (std::vector<Connection>::const_iterator i = connections2.begin(); i != connections2.end(); ++i) {
691 #ifdef DEBUG_CONNECTIONS
692 std::cout <<
"connections2 " << (*i).getDescription() <<
"\n";
694 std::string fromEdge = (*i).fromEdge;
695 if (edges.find(fromEdge) == edges.end()) {
696 WRITE_WARNING(
"While setting connections: from-edge '" + fromEdge +
"' is not known.");
700 int fromLane = (*i).fromLane;
704 std::string toEdge = (*i).toEdge;
705 if (edges.find(toEdge) == edges.end()) {
706 WRITE_WARNING(
"While setting connections: to-edge '" + toEdge +
"' is not known.");
711 int toLane = (*i).toLane;
731 if (from ==
nullptr) {
732 WRITE_WARNING(
"Could not find fromEdge representation of '" + fromEdge +
"' in connection '" + (*i).origID +
"'.");
735 WRITE_WARNING(
"Could not find fromEdge representation of '" + toEdge +
"' in connection '" + (*i).origID +
"'.");
737 if (from ==
nullptr || to ==
nullptr) {
741 #ifdef DEBUG_CONNECTIONS
743 std::cout <<
"addCon3 from=" << from->
getID() <<
"_" << fromLane <<
" to=" << to->
getID() <<
"_" << toLane <<
"\n";
754 if ((*i).origID !=
"" && saveOrigIDs) {
757 for (std::vector<NBEdge::Connection>::iterator k = cons.begin(); k != cons.end(); ++k) {
758 if ((*k).fromLane == fromLane && (*k).toEdge == to && (*k).toLane == toLane) {
770 std::map<std::string, std::string> tlsControlled;
771 for (std::map<std::string, OpenDriveEdge*>::iterator i = edges.begin(); i != edges.end(); ++i) {
774 if (signal.
type !=
"1000001") {
778 WRITE_WARNING(
"Edge '" + e->
id +
"' has signals but no lane sections.");
781 std::vector<OpenDriveLaneSection>::iterator k = e->
laneSections.begin();
784 if (signal.
s > (*k).s && signal.
s <= (*(k + 1)).s) {
791 std::string
id = (*k).sumoID;
796 std::string fromID, toID;
797 for (std::vector<OpenDriveLink>::const_iterator l = e->
links.begin(); l != e->
links.end(); ++l) {
806 fromID =
"-" + fromID;
811 fromID =
"-" + fromID;
829 if (from ==
nullptr) {
830 WRITE_WARNINGF(
"Could not find edge '%' for signal '%'.", fromID, signal.
id);
836 bool fromForward = from->
getID()[0] ==
'-';
837 bool lanesForward = signal.
maxLane < 0;
838 if (fromForward != lanesForward) {
839 std::swap(fromID, toID);
842 from = signalFromTo.first;
843 to = signalFromTo.second;
844 if (from ==
nullptr) {
845 WRITE_WARNINGF(
"Could not find edge '%' for signal '%'.", fromID, signal.
id);
851 if (c.toEdge == to) {
852 int odLane = laneIndexMap[std::make_pair(from, c.fromLane)];
855 c.setParameter(
"signalID", signal.
id);
863 WRITE_WARNINGF(
"Found a traffic light signal on an unknown edge (original edge id='%').", e->
id);
873 if (edge ==
nullptr) {
880 int odLane = laneIndexMap[std::make_pair(edge, c.fromLane)];
882 c.setParameter(
"signalID", signal.
id);
895 for (std::map<std::string, OpenDriveEdge*>::iterator i = edges.begin(); i != edges.end(); ++i) {
900 std::pair<NBEdge*, NBEdge*>
912 return std::make_pair(from, to);
950 if (sumoLane.
width >= 0 && widthResolution > 0) {
951 sumoLane.
width = floor(sumoLane.
width / widthResolution + 0.5) * widthResolution;
953 sumoLane.
width -= widthResolution;
954 if (sumoLane.
width <= 0) {
957 }
else if (sumoLane.
width == 0) {
959 sumoLane.
width = widthResolution;
965 if (forbiddenNarrow) {
973 const std::map<std::string, OpenDriveEdge*>& innerEdges,
974 const std::map<std::string, OpenDriveEdge*>& edges,
976 std::vector<Connection>& into, std::set<Connection>& seen) {
979 #ifdef DEBUG_CONNECTIONS
981 std::cout <<
" buildConnectionsToOuter " << c.
getDescription() <<
"\n";
982 std::cout <<
" dest=" << (dest ==
nullptr ?
"NULL" : dest->
id) <<
" seenlist=";
983 for (std::set<Connection>::const_iterator i = seen.begin(); i != seen.end(); ++i) {
984 std::cout <<
" " << (*i).fromEdge <<
"," << (*i).toEdge <<
" ";
989 if (dest ==
nullptr) {
995 auto innerEdgesIt = innerEdges.find(destCon.
toEdge);
996 #ifdef DEBUG_CONNECTIONS
998 std::cout <<
" toInner=" << (innerEdgesIt != innerEdges.end()) <<
" destCon " << (*i).getDescription() <<
"\n";
1001 if (innerEdgesIt != innerEdges.end()) {
1002 std::vector<Connection> t;
1003 if (seen.count(destCon) == 0) {
1005 for (std::vector<Connection>::const_iterator j = t.begin(); j != t.end(); ++j) {
1013 cn.shape = innerEdgesIt->second->geom + c.
shape;
1027 #ifdef DEBUG_CONNECTIONS
1029 std::cout <<
" laneSectionsConnected dest=" << dest->
id <<
" in=" << in <<
" out=" << out
1046 int referenceLane = 0;
1047 int offsetFactor = 1;
1051 for (
const auto& destLane : dest->
laneSections.front().lanesByDir[lanesDir]) {
1052 if (destLane.successor == c.
fromLane) {
1053 referenceLane = destLane.id;
1059 for (
const auto& destLane : dest->
laneSections.front().lanesByDir[lanesDir]) {
1060 if (destLane.predecessor == c.
fromLane) {
1061 referenceLane = destLane.id;
1070 std::vector<double> offsets(dest->
geom.size(), 0);
1074 #ifdef DEBUG_INTERNALSHAPES
1075 std::string destPred;
1079 for (
int laneSectionIndex = 0; laneSectionIndex < (int)dest->
laneSections.size(); laneSectionIndex++) {
1081 const double nextS = laneSectionIndex + 1 < (int)dest->
laneSections.size() ? dest->
laneSections[laneSectionIndex + 1].s : std::numeric_limits<double>::max();
1084 int finalI = iShape;
1087 double sectionS = 0;
1090 #ifdef DEBUG_INTERNALSHAPES
1091 destPred +=
" lane=" +
toString(destLane.id)
1092 +
" pred=" +
toString(destLane.predecessor)
1093 +
" succ=" +
toString(destLane.successor)
1094 +
" wStart=" + (destLane.widthData.empty() ?
"?" :
toString(destLane.widthData.front().computeAt(0)))
1095 +
" wEnd=" + (destLane.widthData.empty() ?
"?" :
toString(destLane.widthData.front().computeAt(
cn.shape.length2D())))
1096 +
" width=" +
toString(destLane.width) +
"\n";
1098 if (abs(destLane.id) <= abs(referenceLane)) {
1099 const double multiplier = offsetFactor * (destLane.id == referenceLane ? 0.5 : 1);
1100 #ifdef DEBUG_INTERNALSHAPES
1101 destPred +=
" multiplier=" +
toString(multiplier) +
"\n";
1103 int widthDataIndex = 0;
1104 while (s < nextS && i < (
int)
cn.shape.size()) {
1106 const double dist =
cn.shape[i - 1].distanceTo2D(
cn.shape[i]);
1111 while (widthDataIndex + 1 < (
int)destLane.widthData.size()
1112 && sectionS >= destLane.widthData[widthDataIndex + 1].s) {
1116 if (destLane.widthData.size() > 0) {
1117 width = destLane.widthData[widthDataIndex].computeAt(sectionS);
1119 #ifdef DEBUG_INTERNALSHAPES
1120 std::cout <<
" missing width data at inner edge " << dest->
id <<
" to=" <<
cn.toEdge <<
"_" <<
cn.toLane <<
" cp=" <<
cn.toCP <<
"\n";
1127 if (outerToLane.id ==
cn.toLane && outerToLane.width > 0) {
1128 #ifdef DEBUG_INTERNALSHAPES
1129 std::cout <<
" using toLane width " << width <<
"\n";
1135 offsets[i] += width * multiplier;
1143 }
else if (finalS == s) {
1145 while (s < nextS && i < (
int)
cn.shape.size()) {
1147 const double dist =
cn.shape[i - 1].distanceTo2D(
cn.shape[i]);
1163 cn.shape.move2sideCustom(offsets);
1168 #ifdef DEBUG_INTERNALSHAPES
1169 std::cout <<
"internalShape "
1171 <<
" dest=" << dest->
id
1172 <<
" refLane=" << referenceLane
1173 <<
" destPred\n" << destPred
1174 <<
" offsets=" << offsets
1175 <<
"\n shape=" << dest->
geom
1176 <<
"\n shape2=" <<
cn.shape
1180 cn.shape =
cn.shape.reverse();
1183 #ifdef DEBUG_CONNECTIONS
1185 std::cout <<
" added connection\n";
1205 if (lane.id == in) {
1206 in = lane.successor;
1213 if (lane.id == in) {
1214 in = lane.successor;
1227 for (std::vector<OpenDriveLink>::iterator i = e.
links.begin(); i != e.
links.end(); ++i) {
1234 std::string connectedEdge = l.
elementID;
1235 std::string edgeID = e.
id;
1238 const std::map<int, int>& laneMap = laneSection.
laneMap;
1239 #ifdef DEBUG_CONNECTIONS
1241 std::cout <<
"edge=" << e.
id <<
" eType=" << l.
elementType <<
" lType=" << l.
linkType <<
" connectedEdge=" << connectedEdge <<
" laneSection=" << laneSection.
s <<
" map:\n";
1247 for (std::vector<OpenDriveLane>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
1256 c.
toEdge = connectedEdge;
1264 if (edges.find(c.
fromEdge) == edges.end()) {
1265 WRITE_ERROR(
"While setting connections: incoming road '" + c.
fromEdge +
"' is not known.");
1269 #ifdef DEBUG_CONNECTIONS
1271 std::cout <<
"insertConRight from=" << src->
id <<
"_" << c.
fromLane <<
" to=" << c.
toEdge <<
"_" << c.
toLane <<
"\n";
1279 for (std::vector<OpenDriveLane>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
1296 if (edges.find(c.
fromEdge) == edges.end()) {
1297 WRITE_ERROR(
"While setting connections: incoming road '" + c.
fromEdge +
"' is not known.");
1301 #ifdef DEBUG_CONNECTIONS
1303 std::cout <<
"insertConLeft from=" << src->
id <<
"_" << c.
fromLane <<
" to=" << c.
toEdge <<
"_" << c.
toLane <<
"\n";
1315 return id.substr(1);
1326 if (!nc.
insert(
id, pos)) {
1328 throw ProcessError(
"Could not add node '" +
id +
"'.");
1340 throw ProcessError(
"Could not find node '" + nodeID +
"'.");
1342 NBNode* toJoin =
nullptr;
1344 if (e.
to !=
nullptr && e.
to != n) {
1349 if (e.
from !=
nullptr && e.
from != n) {
1354 if (toJoin !=
nullptr) {
1358 for (
NodeSet& joined : joinedNodeIDs) {
1359 if (joined.count(toJoin) != 0) {
1362 if (joined.count(n) != 0) {
1366 if (set1 ==
nullptr && set2 ==
nullptr) {
1367 joinedNodeIDs.push_back(
NodeSet());
1368 joinedNodeIDs.back().insert(n);
1369 joinedNodeIDs.back().insert(toJoin);
1370 }
else if (set1 ==
nullptr && set2 !=
nullptr) {
1371 set2->insert(toJoin);
1372 }
else if (set1 !=
nullptr && set2 ==
nullptr) {
1375 set1->insert(set2->begin(), set2->end());
1376 joinedNodeIDs.erase(std::find(joinedNodeIDs.begin(), joinedNodeIDs.end(), *set2));
1387 if (el.
c != 0 || el.
d != 0) {
1397 const double res = oc.
getFloat(
"opendrive.curve-resolution");
1398 for (std::map<std::string, OpenDriveEdge*>::iterator i = edges.begin(); i != edges.end(); ++i) {
1403 for (std::vector<OpenDriveGeometry>::iterator j = e.
geometries.begin(); j != e.
geometries.end(); ++j) {
1431 if (!e.
geom.back().almostSame(geom.front())) {
1432 const int index = (int)(j - e.
geometries.begin());
1438 for (PositionVector::iterator k = geom.begin(); k != geom.end(); ++k) {
1444 if (e.
geom.size() == 1 && e.
geom.front() != last) {
1446 e.
geom.push_back(last);
1451 if (oc.
exists(
"geometry.min-dist") && !oc.
isDefault(
"geometry.min-dist")) {
1454 if (e.
geom.size() > 4) {
1462 WRITE_ERROR(
"Unable to project coordinates for edge '" + e.
id +
"'.");
1469 for (std::vector<OpenDriveElevation>::iterator j = e.
elevations.begin(); j != e.
elevations.end(); ++j) {
1471 const double sNext = (j + 1) == e.
elevations.end() ? std::numeric_limits<double>::max() : (*(j + 1)).s;
1472 while (k < (
int)e.
geom.size() && pos < sNext) {
1477 if (k < (
int)e.
geom.size()) {
1480 pos += e.
geom[k - 1].distanceTo2D(e.
geom[k]);
1497 std::vector<double> laneOffsets;
1513 for (
auto j = offsets.begin(); j != offsets.end(); ++j) {
1515 const double sNext = (j + 1) == offsets.end() ? std::numeric_limits<double>::max() : (*(j + 1)).s;
1516 while (kk < (
int)geom.size() && ppos < sNext) {
1517 const double offset = el.
computeAt(ppos);
1518 laneOffsets.push_back(fabs(offset) > POSITION_EPS ? -offset : 0);
1520 if (kk < (
int)geom.size()) {
1523 ppos += geom[kk - 1].distanceTo2D(geom[kk]);
1543 double interpolatedOffset = 0;
1545 interpolatedOffset = result.front();
1546 }
else if (at == (
int)geom.size() - 1) {
1547 interpolatedOffset = result.back();
1549 interpolatedOffset = (result[at - 1] + result[at]) / 2;
1551 result.insert(result.begin() + at, interpolatedOffset);
1557 const int sign = left ? -1 : 1;
1558 for (
auto j = offsets.begin(); j != offsets.end(); ++j) {
1560 const double sNext = (j + 1) == offsets.end() ? std::numeric_limits<double>::max() : (*(j + 1)).s;
1561 while (kk < (
int)geom.size() && ppos < sNext) {
1562 const double offset = el.
computeAt(ppos);
1563 result[kk] += fabs(offset) > POSITION_EPS ? sign * offset : 0;
1565 if (kk < (
int)geom.size()) {
1568 ppos += geom[kk - 1].distanceTo2D(geom[kk]);
1577 for (std::map<std::string, OpenDriveEdge*>::iterator i = edges.begin(); i != edges.end(); ++i) {
1579 #ifdef DEBUG_VARIABLE_SPEED
1582 std::cout <<
"revisitLaneSections e=" << e.
id <<
"\n";
1585 std::vector<OpenDriveLaneSection>& laneSections = e.
laneSections;
1587 std::vector<OpenDriveLaneSection> newSections;
1588 for (std::vector<OpenDriveLaneSection>::iterator j = laneSections.begin(); j != laneSections.end(); ++j) {
1589 std::vector<OpenDriveLaneSection> splitSections;
1590 bool splitBySpeed = (*j).buildSpeedChanges(tc, splitSections);
1591 if (!splitBySpeed) {
1592 newSections.push_back(*j);
1594 std::copy(splitSections.begin(), splitSections.end(), back_inserter(newSections));
1603 for (std::vector<OpenDriveLaneSection>::const_iterator j = laneSections.begin(); j != laneSections.end() && sorted; ++j) {
1604 if ((*j).s <= lastS) {
1610 WRITE_WARNING(
"The sections of edge '" + e.
id +
"' are not sorted properly.");
1616 for (std::vector<OpenDriveLaneSection>::iterator j = laneSections.begin(); j != laneSections.end();) {
1617 bool simlarToLast = fabs((*j).s - lastS) < POSITION_EPS;
1621 if (simlarToLast && !e.
isInner) {
1622 WRITE_WARNING(
"Almost duplicate s-value '" +
toString(lastS) +
"' for lane sections occurred at edge '" + e.
id +
"'; second entry was removed.");
1623 j = laneSections.erase(j);
1628 #ifdef DEBUG_VARIABLE_SPEED
1641 if (resolution > 0 && g.
length > 0) {
1642 const int numPoints = (int)ceil(g.
length / resolution) + 1;
1643 double dx = (end.
x() - start.
x()) / (numPoints - 1);
1644 double dy = (end.
y() - start.
y()) / (numPoints - 1);
1645 for (
int i = 0; i < numPoints; i++) {
1646 ret.push_back(
Position(g.
x + i * dx, g.
y + i * dy));
1649 ret.push_back(start);
1660 double curveStart = g.
params[0];
1661 double curveEnd = g.
params[1];
1663 double cDot = (curveEnd - curveStart) / g.
length;
1664 if (cDot == 0 || g.
length == 0) {
1669 double sStart = curveStart / cDot;
1670 double sEnd = curveEnd / cDot;
1676 odrSpiral(sStart, cDot, &x, &y, &tStart);
1677 for (s = sStart; s <= sEnd; s += resolution) {
1688 assert(ret.size() >= 2);
1689 assert(ret[0] != ret[1]);
1692 ret.
add(ret.front() * -1);
1698 << std::setprecision(4)
1699 <<
"edge=" << e.
id <<
" s=" << g.
s
1700 <<
" cStart=" << curveStart
1701 <<
" cEnd=" << curveEnd
1703 <<
" sStart=" << sStart
1707 <<
"\n beforeShift=" << ret1
1708 <<
"\n beforeRot=" << ret2
1712 ret.
add(g.
x, g.
y, 0);
1713 }
catch (
const std::runtime_error&
error) {
1714 WRITE_WARNING(
"Could not compute spiral geometry for edge '" + e.
id +
"' (" +
error.what() +
").");
1725 double centerX = g.
x;
1726 double centerY = g.
y;
1728 double curvature = g.
params[0];
1729 double radius = 1. / curvature;
1734 double startX = g.
x;
1735 double startY = g.
y;
1736 double geo_posS = g.
s;
1737 double geo_posE = g.
s;
1740 geo_posE += resolution;
1741 if (geo_posE - g.
s > g.
length) {
1744 if (geo_posE - g.
s > g.
length) {
1747 calcPointOnCurve(&endX, &endY, centerX, centerY, radius, geo_posE - geo_posS);
1748 ret.push_back(
Position(startX, startY));
1752 geo_posS = geo_posE;
1754 if (geo_posE - (g.
s + g.
length) < 0.001 && geo_posE - (g.
s + g.
length) > -0.001) {
1758 ret.push_back(
Position(startX, startY));
1766 const double s = sin(g.
hdg);
1767 const double c = cos(g.
hdg);
1769 for (
double off = 0; off < g.
length + 2.; off += resolution) {
1772 double xnew = x * c - y * s;
1773 double ynew = x * s + y * c;
1774 ret.push_back(
Position(g.
x + xnew, g.
y + ynew));
1783 const double s = sin(g.
hdg);
1784 const double c = cos(g.
hdg);
1786 const double pStep = pMax / ceil(g.
length / resolution);
1788 for (
double p = 0; p <= pMax + pStep; p += pStep) {
1791 double xnew = x * c - y * s;
1792 double ynew = x * s + y * c;
1793 ret.push_back(
Position(g.
x + xnew, g.
y + ynew));
1801 double normx = 1.0f;
1802 double normy = 0.0f;
1803 double x2 = normx * cos(hdg) - normy * sin(hdg);
1804 double y2 = normx * sin(hdg) + normy * cos(hdg);
1805 normx = x2 * length;
1806 normy = y2 * length;
1807 return Position(start.
x() + normx, start.
y() + normy);
1817 if (ad_radius > 0) {
1824 normX = normX * cos(ad_hdg) + normY * sin(ad_hdg);
1825 normY = tmpX * sin(ad_hdg) + normY * cos(ad_hdg);
1828 normX = turn * normY;
1829 normY = -turn * tmpX;
1831 normX = fabs(ad_radius) * normX;
1832 normY = fabs(ad_radius) * normY;
1841 double ad_r,
double ad_length) {
1842 double rotAngle = ad_length / fabs(ad_r);
1843 double vx = *ad_x - ad_centerX;
1844 double vy = *ad_y - ad_centerY;
1854 vx = vx * cos(rotAngle) + turn * vy * sin(rotAngle);
1855 vy = -1 * turn * tmpx * sin(rotAngle) + vy * cos(rotAngle);
1856 *ad_x = vx + ad_centerX;
1857 *ad_y = vy + ad_centerY;
1873 discardedInnerWidthRight = 0;
1875 bool singleType =
true;
1876 std::vector<std::string> types;
1877 const std::vector<OpenDriveLane>& dirLanesR = lanesByDir.find(
OPENDRIVE_TAG_RIGHT)->second;
1878 for (std::vector<OpenDriveLane>::const_reverse_iterator i = dirLanesR.rbegin(); i != dirLanesR.rend(); ++i) {
1880 discardedInnerWidthRight = 0;
1881 laneMap[(*i).id] = sumoLane++;
1882 types.push_back((*i).type);
1883 if (types.front() != types.back()) {
1887 discardedInnerWidthRight += (*i).width;
1890 discardedInnerWidthLeft = 0;
1891 rightLaneNumber = sumoLane;
1892 rightType = sumoLane > 0 ? (singleType ? types.front() :
joinToString(types,
"|")) :
"";
1896 const std::vector<OpenDriveLane>& dirLanesL = lanesByDir.find(
OPENDRIVE_TAG_LEFT)->second;
1897 for (std::vector<OpenDriveLane>::const_iterator i = dirLanesL.begin(); i != dirLanesL.end(); ++i) {
1899 discardedInnerWidthLeft = 0;
1900 laneMap[(*i).id] = sumoLane++;
1901 types.push_back((*i).type);
1902 if (types.front() != types.back()) {
1906 discardedInnerWidthLeft += (*i).width;
1909 leftLaneNumber = sumoLane;
1910 leftType = sumoLane > 0 ? (singleType ? types.front() :
joinToString(types,
"|")) :
"";
1916 std::map<int, int> ret;
1917 const std::vector<OpenDriveLane>& dirLanes = lanesByDir.find(dir)->second;
1918 for (std::vector<OpenDriveLane>::const_reverse_iterator i = dirLanes.rbegin(); i != dirLanes.rend(); ++i) {
1919 std::map<int, int>::const_iterator toP = laneMap.find((*i).id);
1920 if (toP == laneMap.end()) {
1924 int to = (*toP).second;
1927 from = (*i).predecessor;
1930 std::map<int, int>::const_iterator fromP = prev.
laneMap.find(from);
1931 if (fromP != prev.
laneMap.end()) {
1932 from = (*fromP).second;
1938 if (ret.find(from) != ret.end()) {
1942 std::swap(from, to);
1961 if (i != l.
speeds.end()) {
1962 l.
speed = (*i).second;
1969 if (i != l.
speeds.end()) {
1970 l.
speed = (*i).second;
1979 std::set<double> speedChangePositions;
1982 for (std::vector<std::pair<double, double> >::const_iterator l = (*k).speeds.begin(); l != (*k).speeds.end(); ++l) {
1983 speedChangePositions.insert((*l).first);
1984 if ((*l).first == 0) {
1985 (*k).speed = (*l).second;
1990 for (std::vector<std::pair<double, double> >::const_iterator l = (*k).speeds.begin(); l != (*k).speeds.end(); ++l) {
1991 speedChangePositions.insert((*l).first);
1992 if ((*l).first == 0) {
1993 (*k).speed = (*l).second;
1998 if (speedChangePositions.size() == 0) {
2001 if (*speedChangePositions.begin() > 0) {
2002 speedChangePositions.insert(0);
2004 #ifdef DEBUG_VARIABLE_SPEED
2006 <<
" buildSpeedChanges sectionStart=" << s
2007 <<
" speedChangePositions=" <<
joinToString(speedChangePositions,
", ")
2010 for (std::set<double>::iterator i = speedChangePositions.begin(); i != speedChangePositions.end(); ++i) {
2011 if (i == speedChangePositions.begin()) {
2012 newSections.push_back(*
this);
2014 newSections.push_back(buildLaneSection(*i));
2018 for (
int i = 0; i != (int)newSections.size(); ++i) {
2019 for (
auto& k : newSections[i].lanesByDir) {
2020 for (
int j = 0; j != (int)k.second.size(); ++j) {
2026 l.
speed = newSections[i - 1].lanesByDir[k.first][j].speed;
2045 for (std::vector<OpenDriveSignal>::const_iterator i = signals.begin(); i != signals.end(); ++i) {
2047 if ((*i).type ==
"301" || (*i).type ==
"306") {
2050 if ((*i).type ==
"205" ) {
2164 std::vector<double> vals;
2170 std::vector<double> vals;
2177 std::vector<double> vals;
2183 std::vector<double> vals;
2192 std::vector<double> vals;
2202 if (pRange ==
"normalized") {
2203 vals.push_back(1.0);
2204 }
else if (pRange ==
"arcLength") {
2205 vals.push_back(-1.0);
2208 vals.push_back(1.0);
2256 int orientationCode = orientation ==
"-" ? -1 : orientation ==
"+" ? 1 : 0;
2267 int orientationCode = orientation ==
"-" ? -1 : orientation ==
"+" ? 1 : 0;
2304 WRITE_ERROR(
"In laneLink-element: incoming road '" + c.fromEdge +
"' is not known.");
2320 l.width =
MAX2(l.width, a);
2322 #ifdef DEBUG_VARIABLE_WIDTHS
2329 <<
" type=" << l.type
2330 <<
" width=" << l.width
2336 <<
" entries=" << l.widthData.size()
2350 if (!unit.empty()) {
2352 if (unit ==
"km/h") {
2355 if (unit ==
"mph") {
2356 speed *= 1.609344 / 3.6;
2388 const std::string baseID = o.
id;
2403 for (
double x = 0; x <= length + NUMERICAL_EPS; x += dist) {
2405 const double a = x / length;
2406 o.
width = wStart * (1 - a) + wEnd * a;
2407 o.
t = tStart * (1 - a) + tEnd * a;
2424 size_t i = cdata.find(
"+proj");
2425 if (i != std::string::npos) {
2426 const std::string proj = cdata.substr(i);
2438 WRITE_ERROR(
"Could not set projection. (" + std::string(e.what()) +
")");
2442 WRITE_WARNING(
"geoReference format '" + cdata +
"' currently not supported");
2486 const std::string& elementID,
2487 const std::string& contactPoint) {
2490 if (elementType ==
"road") {
2492 }
else if (elementType ==
"junction") {
2496 if (contactPoint ==
"start") {
2498 }
else if (contactPoint ==
"end") {
2538 #ifdef DEBUG_VARIABLE_WIDTHS
2541 std::cout <<
"sanitizeWidths e=" << e->
id <<
" sections=" << e->
laneSections.size() <<
"\n";
2559 if (l.widthData.size() > 0) {
2560 auto& wd = l.widthData;
2561 const double threshold = POSITION_EPS;
2562 double maxNoShort = -std::numeric_limits<double>::max();
2564 for (
int i = 0; i < (int)wd.size(); i++) {
2565 const double wdLength = i < (int)wd.size() - 1 ? wd[i + 1].s - wd[i].s : length - seen;
2567 if (wdLength > threshold) {
2568 maxNoShort =
MAX2(maxNoShort, wd[i].a);
2571 if (maxNoShort > 0) {
2572 l.width = maxNoShort;
2581 std::vector<OpenDriveLaneSection> newSections;
2582 #ifdef DEBUG_VARIABLE_WIDTHS
2585 std::cout <<
"splitMinWidths e=" << e->
id <<
" sections=" << e->
laneSections.size() <<
"\n";
2590 std::vector<double> splitPositions;
2591 const double sectionEnd = (j + 1) == e->
laneSections.end() ? e->
length : (*(j + 1)).s;
2592 const int section = (int)(j - e->
laneSections.begin());
2593 #ifdef DEBUG_VARIABLE_WIDTHS
2595 std::cout <<
" findWidthSplit section=" << section <<
" sectionStart=" << sec.
s <<
" sectionOrigStart=" << sec.
sOrig <<
" sectionEnd=" << sectionEnd <<
"\n";
2604 newSections.push_back(sec);
2605 std::sort(splitPositions.begin(), splitPositions.end());
2607 double prevSplit = sec.
s;
2608 for (std::vector<double>::iterator it = splitPositions.begin(); it != splitPositions.end();) {
2609 if ((*it) - prevSplit < minDist || sectionEnd - (*it) < minDist) {
2611 #ifdef DEBUG_VARIABLE_WIDTHS
2613 std::cout <<
" skip close split=" << (*it) <<
" prevSplit=" << prevSplit <<
"\n";
2616 it = splitPositions.erase(it);
2617 }
else if ((*it) < sec.
s) {
2619 #ifdef DEBUG_VARIABLE_WIDTHS
2621 std::cout <<
" skip early split=" << (*it) <<
" s=" << sec.
s <<
"\n";
2624 it = splitPositions.erase(it);
2631 if (splitPositions.size() > 0) {
2632 #ifdef DEBUG_VARIABLE_WIDTHS
2634 std::cout <<
" road=" << e->
id <<
" splitMinWidths section=" << section
2635 <<
" start=" << sec.
s
2636 <<
" origStart=" << sec.
sOrig
2637 <<
" end=" << sectionEnd <<
" minDist=" << minDist
2638 <<
" splitPositions=" <<
toString(splitPositions) <<
"\n";
2641 #ifdef DEBUG_VARIABLE_WIDTHS
2643 std::cout <<
"first section...\n";
2647 for (std::vector<double>::iterator it = splitPositions.begin(); it != splitPositions.end(); ++it) {
2650 #ifdef DEBUG_VARIABLE_WIDTHS
2652 std::cout <<
"splitAt " << secNew.
s <<
"\n";
2655 newSections.push_back(secNew);
2662 double end = (it + 1) == splitPositions.end() ? sectionEnd : *(it + 1);
2674 int section,
double sectionStart,
double sectionEnd,
2675 std::vector<double>& splitPositions) {
2677 for (std::vector<OpenDriveLane>::iterator k = lanes.begin(); k != lanes.end(); ++k) {
2682 double wPrev = l.
widthData.front().computeAt(sPrev);
2684 <<
"findWidthSplit section=" << section
2685 <<
" sectionStart=" << sectionStart
2686 <<
" sectionEnd=" << sectionEnd
2688 <<
" type=" << l.
type
2689 <<
" widthEntries=" << l.
widthData.size() <<
"\n"
2693 for (std::vector<OpenDriveWidth>::iterator it_w = l.
widthData.begin(); it_w != l.
widthData.end(); ++it_w) {
2694 double sEnd = (it_w + 1) != l.
widthData.end() ? (*(it_w + 1)).s : sectionEnd - sectionStart;
2695 double w = (*it_w).computeAt(sEnd);
2698 <<
" s=" << (*it_w).s
2699 <<
" a=" << (*it_w).a <<
" b=" << (*it_w).b <<
" c=" << (*it_w).c <<
" d=" << (*it_w).d
2702 const double changeDist = fabs(
myMinWidth - wPrev);
2705 double splitPos = sPrev + (sEnd - sPrev) / fabs(w - wPrev) * changeDist;
2706 double wSplit = (*it_w).computeAt(splitPos);
2708 std::cout <<
" candidate splitPos=" << splitPos <<
" w=" << wSplit <<
"\n";
2714 splitPos -= POSITION_EPS;
2715 if (splitPos < sPrev) {
2717 std::cout <<
" aborting search splitPos=" << splitPos <<
" wSplit=" << wSplit <<
" sPrev=" << sPrev <<
" wPrev=" << wPrev <<
"\n";
2724 splitPos += POSITION_EPS;
2725 if (splitPos > sEnd) {
2727 std::cout <<
" aborting search splitPos=" << splitPos <<
" wSplit=" << wSplit <<
" sEnd=" << sEnd <<
" w=" << w <<
"\n";
2733 wSplit = (*it_w).computeAt(splitPos);
2735 std::cout <<
" refined splitPos=" << splitPos <<
" w=" << wSplit <<
"\n";
2738 splitPositions.push_back(sectionStart + splitPos);
2756 for (std::vector<OpenDriveLane>::iterator k = lanes.begin(); k != lanes.end(); ++k) {
2757 (*k).predecessor = (*k).id;
2775 for (std::vector<OpenDriveLane>::iterator k = lanes.begin(); k != lanes.end(); ++k) {
2778 #ifdef DEBUG_VARIABLE_WIDTHS
2780 <<
"recomputeWidths lane=" << l.
id
2781 <<
" type=" << l.
type
2782 <<
" start=" << start
2784 <<
" sectionStart=" << sectionStart
2785 <<
" sectionEnd=" << sectionEnd
2786 <<
" widthEntries=" << l.
widthData.size() <<
"\n"
2791 double sPrevAbs = sPrev + sectionStart;
2792 for (std::vector<OpenDriveWidth>::iterator it_w = l.
widthData.begin(); it_w != l.
widthData.end(); ++it_w) {
2793 double sEnd = (it_w + 1) != l.
widthData.end() ? (*(it_w + 1)).s : sectionEnd - sectionStart;
2794 double sEndAbs = sEnd + sectionStart;
2795 #ifdef DEBUG_VARIABLE_WIDTHS
2797 <<
" sPrev=" << sPrev <<
" sPrevAbs=" << sPrevAbs
2798 <<
" sEnd=" << sEnd <<
" sEndAbs=" << sEndAbs
2799 <<
" widthData s=" << (*it_w).s
2800 <<
" a=" << (*it_w).a
2801 <<
" b=" << (*it_w).b
2802 <<
" c=" << (*it_w).c
2803 <<
" d=" << (*it_w).d
2806 if (sPrevAbs <= start && sEndAbs >= start) {
2807 #ifdef DEBUG_VARIABLE_WIDTHS
2809 std::cout <<
" atStart=" << start <<
" pos=" << start - sectionStart <<
" w=" << (*it_w).computeAt(start - sectionStart) <<
"\n";
2812 l.
width =
MAX2(l.
width, (*it_w).computeAt(start - sectionStart));
2814 if (sPrevAbs <= end && sEndAbs >= end) {
2815 #ifdef DEBUG_VARIABLE_WIDTHS
2817 std::cout <<
" atEnd=" << end <<
" pos=" << end - sectionStart <<
" w=" << (*it_w).computeAt(end - sectionStart) <<
"\n";
2822 if (start <= sPrevAbs && end >= sPrevAbs) {
2823 #ifdef DEBUG_VARIABLE_WIDTHS
2825 std::cout <<
" atSPrev=" << sPrev <<
" w=" << (*it_w).computeAt(sPrev) <<
"\n";
2830 if (start <= sEndAbs && end >= sEndAbs) {
2831 #ifdef DEBUG_VARIABLE_WIDTHS
2833 std::cout <<
" atSEnd=" << sEnd <<
" w=" << (*it_w).computeAt(sEnd) <<
"\n";
2838 #ifdef DEBUG_VARIABLE_WIDTHS
2840 std::cout <<
" sPrev=" << sPrev <<
" sEnd=" << sEnd <<
" l.width=" << l.
width <<
"\n";
#define WRITE_WARNINGF(...)
#define WRITE_WARNING(msg)
#define PROGRESS_DONE_MESSAGE()
#define PROGRESS_BEGIN_MESSAGE(msg)
std::set< NBNode *, ComparatorIdLess > NodeSet
#define DEBUG_COND3(roadID)
bool operator<(const NIImporter_OpenDrive::Connection &c1, const NIImporter_OpenDrive::Connection &c2)
#define DEBUG_COND2(edgeID)
@ SVC_PASSENGER
vehicle is a passenger car (a "normal" car)
@ SVC_BICYCLE
vehicle is a bicycle
@ SVC_EMERGENCY
public emergency vehicles
@ SVC_AUTHORITY
authorities vehicles
@ 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
int gPrecision
the precision for floating point outputs
bool gDebugFlag1
global utility flags for debugging
#define UNUSED_PARAMETER(x)
std::string joinNamedToString(const std::set< T *, C > &ns, const T_BETWEEN &between)
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
A class that stores a 2D geometrical boundary.
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
static bool isReadable(std::string path)
Checks whether the given file is readable.
A handler which converts occuring elements and attributes into enums.
void error(const XERCES_CPP_NAMESPACE::SAXParseException &exception)
Handler for XML-errors.
void setFileName(const std::string &name)
Sets the current file name.
static methods for processing the coordinates conversion for the current net
void cartesian2geo(Position &cartesian) const
Converts the given cartesian (shifted) position to its geo (lat/long) representation.
void moveConvertedBy(double x, double y)
Shifts the converted boundary by the given amounts.
static GeoConvHelper & getLoaded()
the coordinate transformation that was loaded fron an input file
static int getNumLoaded()
static void setLoaded(const GeoConvHelper &loaded)
sets the coordinate transformation loaded from a location element
bool usingGeoProjection() const
Returns whether a transformation from geo to metric coordinates will be performed.
static double naviDegree(const double angle)
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
bool wasIgnored(std::string id) const
Returns whether the edge with the id was ignored during parsing.
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
The representation of a single edge during network building.
const std::string & getID() const
NBNode * getToNode() const
Returns the destination node of the edge.
static const double UNSPECIFIED_LOADED_LENGTH
no length override given
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 permissions=SVC_UNSPECIFIED, const bool indirectLeft=false, const std::string &edgeType="", SVCPermissions changeLeft=SVC_UNSPECIFIED, SVCPermissions changeRight=SVC_UNSPECIFIED, bool postProcess=false)
Adds a connection between the specified this edge's lane and an approached one.
static const double UNSPECIFIED_CONTPOS
unspecified internal junction position
static const double UNSPECIFIED_VISIBILITY_DISTANCE
unspecified foe visibility for connections
static const double UNSPECIFIED_SPEED
unspecified lane speed
@ USER
The connection was given by the user.
@ VALIDATED
The connection was computed and validated.
static const double UNSPECIFIED_WIDTH
unspecified lane width
const std::vector< Connection > & getConnections() const
Returns the connections.
static const double UNSPECIFIED_OFFSET
unspecified lane offset
Lane & getLaneStruct(int lane)
NBNode * getFromNode() const
Returns the origin node of the edge.
Instance responsible for building networks.
static bool transformCoordinates(PositionVector &from, bool includeInBoundary=true, GeoConvHelper *from_srs=0)
NBTypeCont & getTypeCont()
Returns a reference to the type container.
NBEdgeCont & getEdgeCont()
NBNodeCont & getNodeCont()
Returns a reference to the node container.
NBTrafficLightLogicCont & getTLLogicCont()
Returns a reference to the traffic light logics container.
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.
bool extract(NBNode *node, bool remember=false)
Removes the given node but does not delete it.
Represents a single node (junction) during network building.
const std::set< NBTrafficLightDefinition * > & getControllingTLS() const
Returns the traffic lights that were assigned to this node (The set of tls that control this node)
void addTrafficLight(NBTrafficLightDefinition *tlDef)
Adds a traffic light to the list of traffic lights that control this node.
bool isTLControlled() const
Returns whether this node is controlled by any tls.
A traffic light logics which must be computed (only nodes/edges are given)
The base class for traffic light logic definitions.
bool insert(NBTrafficLightDefinition *logic, bool forceInsert=false)
Adds a logic definition to the dictionary.
A storage for available edgeTypes of edges.
double getEdgeTypeMaxWidth(const std::string &edgeType) const
Returns the maximum edge/lane widths of the given edgeType.
bool getEdgeTypeShallBeDiscarded(const std::string &edgeType) const
Returns the information whether edges of this edgeType shall be discarded.
double getEdgeTypeSpeed(const std::string &edgeType) const
Returns the maximal velocity for the given edgeType [m/s].
double getEdgeTypeWidth(const std::string &edgeType) const
Returns the lane width for the given edgeType [m].
SVCPermissions getEdgeTypePermissions(const std::string &edgeType) const
Returns allowed vehicle classes for the given edgeType.
double getEdgeTypeWidthResolution(const std::string &edgeType) const
Returns the resolution for interpreting edge/lane widths of the given edgeType.
bool knows(const std::string &edgeType) const
Returns whether the named edgeType is in the container.
A class for sorting lane sections by their s-value.
Importer for networks stored in openDrive format.
static void loadNetwork(const OptionsCont &oc, NBNetBuilder &nb)
Loads content of the optionally given SUMO file.
static void recomputeWidths(OpenDriveLaneSection &sec, double start, double end, double sectionStart, double sectionEnd)
static std::vector< double > discretizeOffsets(PositionVector &geom, const std::vector< OpenDriveLaneOffset > &offsets, const std::string &id)
transform Poly3 into a list of offsets, adding intermediate points to geom if needed
static void addOffsets(bool left, PositionVector &geom, const std::vector< OpenDriveLaneOffset > &offsets, const std::string &id, std::vector< double > &result)
std::map< std::string, OpenDriveSignal > & getSignals()
static std::pair< NBEdge *, NBEdge * > retrieveSignalEdges(NBNetBuilder &nb, const std::string &fromID, const std::string &toID, const std::string &junction)
static PositionVector geomFromParamPoly(const OpenDriveEdge &e, const OpenDriveGeometry &g, double resolution)
void myEndElement(int element)
Called when a closing tag occurs.
static void calcPointOnCurve(double *ad_x, double *ad_y, double ad_centerX, double ad_centerY, double ad_r, double ad_length)
static bool myImportInternalShapes
OpenDriveXMLTag
Numbers representing openDrive-XML - element names.
@ OPENDRIVE_TAG_ELEVATION
@ OPENDRIVE_TAG_PARAMPOLY3
@ OPENDRIVE_TAG_LANEOFFSET
@ OPENDRIVE_TAG_SIGNALREFERENCE
@ OPENDRIVE_TAG_GEOREFERENCE
@ OPENDRIVE_TAG_SUCCESSOR
@ OPENDRIVE_TAG_PREDECESSOR
@ OPENDRIVE_TAG_LANESECTION
@ OPENDRIVE_TAG_CONNECTION
void addGeometryShape(GeometryType type, const std::vector< double > &vals)
static bool myImportWidths
static void setStraightConnections(std::vector< OpenDriveLane > &lanes)
std::string myCurrentConnectingRoad
static void setLaneAttributes(const OpenDriveEdge *e, NBEdge::Lane &sumoLane, const OpenDriveLane &odLane, bool saveOrigIDs, const NBTypeCont &tc)
std::vector< int > myElementStack
~NIImporter_OpenDrive()
Destructor.
static void buildConnectionsToOuter(const Connection &c, const std::map< std::string, OpenDriveEdge * > &innerEdges, const std::map< std::string, OpenDriveEdge * > &edges, const NBTypeCont &tc, std::vector< Connection > &into, std::set< Connection > &seen)
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
static StringBijection< int >::Entry openDriveAttrs[]
The names of openDrive-XML attributes (for passing to GenericSAXHandler)
std::map< std::string, OpenDriveSignal > mySignals
static bool laneSectionsConnected(OpenDriveEdge *edge, int in, int out)
void addLink(LinkType lt, const std::string &elementType, const std::string &elementID, const std::string &contactPoint)
@ OPENDRIVE_ATTR_REVMAJOR
@ OPENDRIVE_ATTR_CURVSTART
@ OPENDRIVE_ATTR_CONTACTPOINT
@ OPENDRIVE_ATTR_REVMINOR
@ OPENDRIVE_ATTR_ORIENTATION
@ OPENDRIVE_ATTR_INCOMINGROAD
@ OPENDRIVE_ATTR_CURVATURE
@ OPENDRIVE_ATTR_ELEMENTTYPE
@ OPENDRIVE_ATTR_JUNCTION
@ OPENDRIVE_ATTR_CONNECTINGROAD
@ OPENDRIVE_ATTR_WIDTHEND
@ OPENDRIVE_ATTR_FROMLANE
@ OPENDRIVE_ATTR_DISTANCE
@ OPENDRIVE_ATTR_ELEMENTID
@ OPENDRIVE_ATTR_WIDTHSTART
static PositionVector geomFromSpiral(const OpenDriveEdge &e, const OpenDriveGeometry &g, double resolution)
static PositionVector geomFromLine(const OpenDriveEdge &e, const OpenDriveGeometry &g, double resolution)
static NBNode * getOrBuildNode(const std::string &id, const Position &pos, NBNodeCont &nc)
Builds a node or returns the already built.
const NBTypeCont & myTypeContainer
NIImporter_OpenDrive(const NBTypeCont &tc, std::map< std::string, OpenDriveEdge * > &edges)
Constructor.
static Position calculateStraightEndPoint(double hdg, double length, const Position &start)
OpenDriveXMLTag myCurrentLaneDirection
static PositionVector geomFromPoly(const OpenDriveEdge &e, const OpenDriveGeometry &g, double resolution)
static void revisitLaneSections(const NBTypeCont &tc, std::map< std::string, OpenDriveEdge * > &edges)
Rechecks lane sections of the given edges.
Poly3 OpenDriveLaneOffset
OpenDriveEdge myCurrentEdge
static void sanitizeWidths(OpenDriveEdge *e)
GeometryType
OpenDrive geometry type enumeration.
@ OPENDRIVE_GT_PARAMPOLY3
static void computeShapes(std::map< std::string, OpenDriveEdge * > &edges)
Computes a polygon representation of each edge's geometry.
static void calculateCurveCenter(double *ad_x, double *ad_y, double ad_radius, double ad_hdg)
static std::string revertID(const std::string &id)
std::string myCurrentJunctionID
static void setEdgeLinks2(OpenDriveEdge &e, const std::map< std::string, OpenDriveEdge * > &edges)
std::string myCurrentIncomingRoad
static void splitMinWidths(OpenDriveEdge *e, const NBTypeCont &tc, double minDist)
bool myConnectionWasEmpty
static bool myImportAllTypes
void myCharacters(int element, const std::string &chars)
Callback method for characters to implement by derived classes.
static NBTrafficLightDefinition * getTLSSecure(NBEdge *inEdge, NBNetBuilder &nb)
static StringBijection< int >::Entry openDriveTags[]
The names of openDrive-XML elements (for passing to GenericSAXHandler)
Poly3 OpenDriveElevation
LaneOffset has the same fields as Elevation.
ContactPoint myCurrentContactPoint
static void findWidthSplit(const NBTypeCont &tc, std::vector< OpenDriveLane > &lanes, int section, double sectionStart, double sectionEnd, std::vector< double > &splitPositions)
static PositionVector geomFromArc(const OpenDriveEdge &e, const OpenDriveGeometry &g, double resolution)
static void setNodeSecure(NBNodeCont &nc, OpenDriveEdge &e, const std::string &nodeID, NIImporter_OpenDrive::LinkType lt, std::vector< NodeSet > &joinedNodeIDs)
LinkType
OpenDrive link type enumeration.
@ OPENDRIVE_LT_PREDECESSOR
static bool hasNonLinearElevation(OpenDriveEdge &e)
std::map< std::string, OpenDriveEdge * > & myEdges
const std::string & getID() const
Returns the id.
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)
static OptionsCont & getOptions()
Retrieves the options.
bool isUsableFileList(const std::string &name) const
Checks whether the named option is usable as a file list (with at least a single file)
Static storage of an output device and its base (abstract) implementation.
bool writeXMLHeader(const std::string &rootElement, const std::string &schemaFile, std::map< SumoXMLAttr, std::string > attrs=std::map< SumoXMLAttr, std::string >(), bool includeConfig=true)
Writes an XML header with optional configuration.
static OutputDevice & getDevice(const std::string &name)
Returns the described OutputDevice.
virtual void setParameter(const std::string &key, const std::string &value)
Sets a parameter.
void writeXML(OutputDevice &out, const bool geo=false, const double zOffset=0., const std::string laneID="", const double pos=0., const bool friendlyPos=false, const double posLat=0.)
A point in 2D or 3D with translation and scaling methods.
void set(double x, double y)
set positions x and y
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
double x() const
Returns the x-position.
double y() const
Returns the y-position.
double length2D() const
Returns the length.
void append(const PositionVector &v, double sameThreshold=2.0)
void move2sideCustom(std::vector< double > amount, double maxExtension=100)
move position vector to side using a custom offset for each geometry point
void rotate2D(double angle)
double rotationAtOffset(double pos) const
Returns the rotation at the given length.
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
void add(double xoff, double yoff, double zoff)
int indexOfClosest(const Position &p, bool twoD=false) const
void move2side(double amount, double maxExtension=100)
move position vector to side using certain ammount
PositionVector getSubpart2D(double beginOffset, double endOffset) const
get subpart of a position vector in two dimensions (Z is ignored)
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
int insertAtClosest(const Position &p, bool interpolateZ)
inserts p between the two closest positions
void push_back_noDoublePos(const Position &p)
insert in back a non double position
void removeDoublePoints(double minDist=POSITION_EPS, bool assertLength=false, int beginOffset=0, int endOffset=0, bool resample=false)
Removes positions if too near.
PositionVector reverse() const
reverse position vector
Position positionAtOffset2D(double pos, double lateralOffset=0) const
Returns the position at the given length.
static const RGBColor YELLOW
void writeXML(OutputDevice &out, bool geo=false)
Encapsulated SAX-Attributes.
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue, bool report=true) const
Tries to read given attribute assuming it is an int.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list.
static StringBijection< TrafficLightType > TrafficLightTypes
traffic light types
T get(const std::string &str) const
static bool runParser(GenericSAXHandler &handler, const std::string &file, const bool isNet=false, const bool isRoute=false)
Runs the given handler on the given file; returns if everything's ok.
void odrSpiral(double s, double cDot, double *x, double *y, double *t)
A structure which describes a connection between edges or lanes.
An (internal) definition of a single lane of an edge.
double width
This lane's width.
PositionVector customShape
A custom shape for this lane set by the user.
std::string type
the type of this lane
double speed
The speed allowed on this lane.
SVCPermissions permissions
List of vehicle types that are allowed on this lane.
A connection between two roads.
std::string getDescription() const
Representation of an openDrive "link".
double length
The length of the edge.
std::vector< double > laneOffsets
std::string id
The id of the edge.
std::set< Connection > connections
std::string junction
The id of the junction the edge belongs to.
std::string streetName
The road name of the edge.
int getPriority(OpenDriveXMLTag dir) const
Returns the edge's priority, regarding the direction.
std::vector< OpenDriveLink > links
std::vector< OpenDriveSignal > signals
std::vector< OpenDriveLaneSection > laneSections
std::vector< OpenDriveLaneOffset > offsets
std::vector< OpenDriveObject > objects
std::vector< OpenDriveGeometry > geometries
std::vector< OpenDriveElevation > elevations
Representation of an OpenDrive geometry part.
std::vector< double > params
Representation of a lane.
std::vector< std::pair< double, double > > speeds
List of positions/speeds of speed changes.
std::vector< OpenDriveWidth > widthData
std::string type
The lane's type.
double speed
The lane's speed (set in post-processing)
Representation of a lane section.
double length
The length of this lane section.
std::map< OpenDriveXMLTag, std::vector< OpenDriveLane > > lanesByDir
The lanes, sorted by their direction.
std::map< int, int > laneMap
A mapping from OpenDrive to SUMO-index (the first is signed, the second unsigned)
OpenDriveLaneSection buildLaneSection(double startPos)
OpenDriveLaneSection(double sArg)
Constructor.
int rightLaneNumber
The number of lanes on the right and on the left side, respectively.
double sOrig
The original starting offset of this lane section (differs from s if the section had to be split)
void buildLaneMapping(const NBTypeCont &tc)
Build the mapping from OpenDrive to SUMO lanes.
std::map< int, int > getInnerConnections(OpenDriveXMLTag dir, const OpenDriveLaneSection &prev)
Returns the links from the previous to this lane section.
bool buildSpeedChanges(const NBTypeCont &tc, std::vector< OpenDriveLaneSection > &newSections)
double s
The starting offset of this lane section.
Representation of an OpenDrive link.
ContactPoint contactPoint
Representation of a signal.
int minLane
signal validity range
double computeAt(double pos) const