174 std::map<std::string, OpenDriveEdge*> edges;
177 std::vector<std::string> files = oc.
getStringVector(
"opendrive-files");
178 for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
180 WRITE_ERROR(
"Could not open opendrive file '" + *file +
"'.");
183 handler.setFileName(*file);
189 std::map<std::string, OpenDriveEdge*> innerEdges, outerEdges;
190 for (std::map<std::string, OpenDriveEdge*>::iterator i = edges.begin(); i != edges.end(); ++i) {
191 if ((*i).second->isInner) {
192 innerEdges[(*i).first] = (*i).second;
194 outerEdges[(*i).first] = (*i).second;
209 std::map<std::string, Boundary> posMap;
210 std::map<std::string, std::string> edge2junction;
212 for (std::map<std::string, OpenDriveEdge*>::iterator i = innerEdges.begin(); i != innerEdges.end(); ++i) {
216 if (posMap.find(e->
junction) == posMap.end()) {
222 for (std::map<std::string, Boundary>::iterator i = posMap.begin(); i != posMap.end(); ++i) {
225 throw ProcessError(
"Could not add node '" + (*i).first +
"'.");
229 for (std::map<std::string, OpenDriveEdge*>::iterator i = outerEdges.begin(); i != outerEdges.end(); ++i) {
231 for (std::vector<OpenDriveLink>::iterator j = e->
links.begin(); j != e->
links.end(); ++j) {
239 throw ProcessError(
"Could not build node '" + nid +
"'.");
246 if (edge2junction.find(l.
elementID) != edge2junction.end()) {
258 for (std::map<std::string, OpenDriveEdge*>::iterator i = outerEdges.begin(); i != outerEdges.end(); ++i) {
260 for (std::vector<OpenDriveLink>::iterator j = e->
links.begin(); j != e->
links.end(); ++j) {
267 std::string id1 = e->
id;
272 std::string nid = id1 +
"." + id2;
277 throw ProcessError(
"Could not build node '" + nid +
"'.");
295 for (std::map<std::string, OpenDriveEdge*>::iterator i = outerEdges.begin(); i != outerEdges.end(); ++i) {
297 if (e->
to != 0 && e->
from != 0) {
300 for (std::map<std::string, OpenDriveEdge*>::iterator j = innerEdges.begin(); j != innerEdges.end(); ++j) {
302 for (std::vector<OpenDriveLink>::iterator k = ie->
links.begin(); k != ie->
links.end(); ++k) {
308 std::string nid = edge2junction[ie->
id];
320 for (std::map<std::string, OpenDriveEdge*>::iterator i = outerEdges.begin(); i != outerEdges.end(); ++i) {
322 if ((e->
from == 0 || e->
to == 0) && e->
geom.size() == 0) {
326 const std::string nid = e->
id +
".begin";
330 const std::string nid = e->
id +
".end";
339 double defaultSpeed = tc.
getSpeed(
"");
341 for (std::map<std::string, OpenDriveEdge*>::iterator i = outerEdges.begin(); i != outerEdges.end(); ++i) {
343 if (e->
geom.size() == 0) {
347 bool lanesBuilt =
false;
363 double cF = length2D == 0 ? 1 : e->
length / length2D;
373 WRITE_WARNING(
"Edge '" + e->
id +
"' has to be split as it connects same junctions.")
376 const double minDist = oc.
getFloat(
"opendrive.curve-resolution");
387 double nextS = (j + 1)->s;
395 std::string
id = e->
id;
396 if (sFrom != e->
from || sTo != e->
to) {
401 #ifdef DEBUG_VARIABLE_WIDTHS 403 std::cout <<
" id=" <<
id <<
" sB=" << sB <<
" sE=" << sE <<
" geom=" << geom <<
"\n";
409 if ((*j).rightLaneNumber > 0) {
410 currRight =
new NBEdge(
"-" +
id, sFrom, sTo, (*j).rightType, defaultSpeed, (*j).rightLaneNumber, priorityR,
414 for (std::vector<OpenDriveLane>::const_iterator k = lanes.begin(); k != lanes.end(); ++k) {
415 std::map<int, int>::const_iterator lp = (*j).laneMap.find((*k).id);
416 if (lp != (*j).laneMap.end()) {
417 int sumoLaneIndex = lp->second;
440 if (prevRight != 0) {
442 for (std::map<int, int>::const_iterator k = connections.begin(); k != connections.end(); ++k) {
443 #ifdef DEBUG_CONNECTIONS 445 std::cout <<
"addCon1 from=" << prevRight->
getID() <<
"_" << (*k).first <<
" to=" << currRight->
getID() <<
"_" << (*k).second <<
"\n";
451 prevRight = currRight;
457 if ((*j).leftLaneNumber > 0) {
458 currLeft =
new NBEdge(
id, sTo, sFrom, (*j).leftType, defaultSpeed, (*j).leftLaneNumber, priorityL,
462 for (std::vector<OpenDriveLane>::const_iterator k = lanes.begin(); k != lanes.end(); ++k) {
463 std::map<int, int>::const_iterator lp = (*j).laneMap.find((*k).id);
464 if (lp != (*j).laneMap.end()) {
465 int sumoLaneIndex = lp->second;
489 std::map<int, int> connections = (*j).getInnerConnections(
OPENDRIVE_TAG_LEFT, *(j - 1));
490 for (std::map<int, int>::const_iterator k = connections.begin(); k != connections.end(); ++k) {
491 #ifdef DEBUG_CONNECTIONS 493 std::cout <<
"addCon2 from=" << currLeft->
getID() <<
"_" << (*k).first <<
" to=" << prevLeft->
getID() <<
"_" << (*k).second <<
"\n";
517 for (std::map<std::string, OpenDriveEdge*>::iterator i = edges.begin(); i != edges.end(); ++i) {
521 std::vector<Connection> connections2;
522 for (std::map<std::string, OpenDriveEdge*>::iterator j = edges.begin(); j != edges.end(); ++j) {
523 const std::set<Connection>& conns = (*j).second->connections;
525 for (std::set<Connection>::const_iterator i = conns.begin(); i != conns.end(); ++i) {
526 if (innerEdges.find((*i).fromEdge) != innerEdges.end()) {
530 if (innerEdges.find((*i).toEdge) != innerEdges.end()) {
531 std::set<Connection> seen;
534 connections2.push_back(*i);
539 for (std::vector<Connection>::const_iterator i = connections2.begin(); i != connections2.end(); ++i) {
540 std::string fromEdge = (*i).fromEdge;
541 if (edges.find(fromEdge) == edges.end()) {
542 WRITE_WARNING(
"While setting connections: from-edge '" + fromEdge +
"' is not known.");
546 int fromLane = (*i).fromLane;
547 bool fromLast = ((*i).fromCP ==
OPENDRIVE_CP_END) ^ ((*i).fromLane > 0 && !(*i).all);
550 std::string toEdge = (*i).toEdge;
551 if (edges.find(toEdge) == edges.end()) {
552 WRITE_WARNING(
"While setting connections: to-edge '" + toEdge +
"' is not known.");
557 int toLane = (*i).toLane;
578 WRITE_WARNING(
"Could not find fromEdge representation of '" + fromEdge +
"' in connection '" + (*i).origID +
"'.");
581 WRITE_WARNING(
"Could not find fromEdge representation of '" + toEdge +
"' in connection '" + (*i).origID +
"'.");
583 if (from == 0 || to == 0) {
587 #ifdef DEBUG_CONNECTIONS 589 std::cout <<
"addCon3 from=" << from->
getID() <<
"_" << fromLane <<
" to=" << to->
getID() <<
"_" << toLane <<
"\n";
594 if ((*i).origID !=
"") {
597 for (std::vector<NBEdge::Connection>::iterator k = cons.begin(); k != cons.end(); ++k) {
598 if ((*k).fromLane == fromLane && (*k).toEdge == to && (*k).toLane == toLane) {
599 (*k).origID = (*i).origID +
"_" +
toString((*i).origLane);
610 std::map<std::string, std::string> tlsControlled;
611 for (std::map<std::string, OpenDriveEdge*>::iterator i = edges.begin(); i != edges.end(); ++i) {
613 for (std::vector<OpenDriveSignal>::const_iterator j = e->
signals.begin(); j != e->
signals.end(); ++j) {
614 if ((*j).type !=
"1000001") {
617 std::vector<OpenDriveLaneSection>::iterator k = e->
laneSections.begin();
620 if ((*j).s > (*k).s && (*j).s <= (*(k + 1)).s) {
630 std::string
id = (*k).sumoID;
634 std::string fromID, toID;
635 for (std::vector<OpenDriveLink>::const_iterator l = e->
links.begin(); l != e->
links.end(); ++l) {
643 if ((*j).orientation < 0) {
644 fromID =
"-" + fromID;
648 if ((*j).orientation > 0) {
649 fromID =
"-" + fromID;
661 id = fromID +
"->" + toID;
663 WRITE_WARNING(
"Found a traffic light signal on an unknown edge (original edge id='" + e->
id +
"').");
667 if ((*j).orientation > 0) {
671 tlsControlled[id] = (*j).name;
675 for (std::map<std::string, std::string>::iterator i = tlsControlled.begin(); i != tlsControlled.end(); ++i) {
676 std::string
id = (*i).first;
677 if (
id.find(
"->") != std::string::npos) {
678 id =
id.substr(0,
id.find(
"->"));
682 WRITE_WARNING(
"Could not find edge '" +
id +
"' while building its traffic light.");
704 for (std::map<std::string, OpenDriveEdge*>::iterator i = edges.begin(); i != edges.end(); ++i) {
735 const std::set<Connection>& conts = dest->
connections;
736 for (std::set<Connection>::const_iterator i = conts.begin(); i != conts.end(); ++i) {
737 if (innerEdges.find((*i).toEdge) != innerEdges.end()) {
738 std::vector<Connection> t;
739 if (seen.count(*i) == 0) {
741 for (std::vector<Connection>::const_iterator j = t.begin(); j != t.end(); ++j) {
754 if ((*i).fromLane == c.
toLane) {
771 for (std::vector<OpenDriveLink>::iterator i = e.
links.begin(); i != e.
links.end(); ++i) {
779 std::string edgeID = e.
id;
782 const std::map<int, int>& laneMap = laneSection.
laneMap;
783 #ifdef DEBUG_CONNECTIONS 785 std::cout <<
"edge=" << e.
id <<
" eType=" << l.
elementType <<
" lType=" << l.
linkType <<
" connectedEdge=" << connectedEdge <<
" laneSection=" << laneSection.
s <<
" map:\n";
791 for (std::vector<OpenDriveLane>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
808 if (edges.find(c.
fromEdge) == edges.end()) {
809 WRITE_ERROR(
"While setting connections: incoming road '" + c.
fromEdge +
"' is not known.");
813 #ifdef DEBUG_CONNECTIONS 821 for (std::vector<OpenDriveLane>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
838 if (edges.find(c.
fromEdge) == edges.end()) {
839 WRITE_ERROR(
"While setting connections: incoming road '" + c.
fromEdge +
"' is not known.");
843 #ifdef DEBUG_CONNECTIONS 845 std::cout <<
"insertConLeft from=" << src->
id <<
"_" << c.
fromLane <<
" to=" << c.
toEdge <<
"_" << c.
toLane <<
"\n";
868 if (!nc.
insert(
id, pos)) {
882 throw ProcessError(
"Could not find node '" + nodeID +
"'.");
885 if (e.
to != 0 && e.
to != n) {
901 const double res = oc.
getFloat(
"opendrive.curve-resolution");
902 for (std::map<std::string, OpenDriveEdge*>::iterator i = edges.begin(); i != edges.end(); ++i) {
905 for (std::vector<OpenDriveGeometry>::iterator j = e.
geometries.begin(); j != e.
geometries.end(); ++j) {
933 if (!e.
geom.back().almostSame(geom.front())) {
934 const int index = (int)(j - e.
geometries.begin());
940 for (PositionVector::iterator k = geom.begin(); k != geom.end(); ++k) {
945 if (oc.
exists(
"geometry.min-dist") && !oc.
isDefault(
"geometry.min-dist")) {
949 WRITE_ERROR(
"Unable to project coordinates for edge '" + e.
id +
"'.");
954 for (std::vector<OpenDriveElevation>::iterator j = e.
elevations.begin(); j != e.
elevations.end(); ++j) {
957 while (k < (
int)e.
geom.size() && pos < sNext) {
962 if (k < (
int)e.
geom.size()) {
965 pos += e.
geom[k - 1].distanceTo2D(e.
geom[k]);
972 for (std::vector<OpenDriveLaneOffset>::iterator j = e.
offsets.begin(); j != e.
offsets.end(); ++j) {
988 for (std::vector<OpenDriveLaneOffset>::iterator j = e.
offsets.begin(); j != e.
offsets.end(); ++j) {
991 while (k < (
int)e.
geom.size() && pos < sNext) {
1000 geom2.push_back(tmp[k]);
1002 geom2.push_back(e.
geom[k]);
1005 geom2.push_back(e.
geom[k]);
1008 if (k < (
int)e.
geom.size()) {
1011 pos += e.
geom[k - 1].distanceTo2D(e.
geom[k]);
1015 assert(e.
geom.size() == geom2.size());
1025 for (std::map<std::string, OpenDriveEdge*>::iterator i = edges.begin(); i != edges.end(); ++i) {
1027 #ifdef DEBUG_VARIABLE_SPEED 1030 std::cout <<
"revisitLaneSections e=" << e.
id <<
"\n";
1033 std::vector<OpenDriveLaneSection>& laneSections = e.
laneSections;
1035 std::vector<OpenDriveLaneSection> newSections;
1036 for (std::vector<OpenDriveLaneSection>::iterator j = laneSections.begin(); j != laneSections.end(); ++j) {
1037 std::vector<OpenDriveLaneSection> splitSections;
1038 bool splitBySpeed = (*j).buildSpeedChanges(tc, splitSections);
1039 if (!splitBySpeed) {
1040 newSections.push_back(*j);
1042 std::copy(splitSections.begin(), splitSections.end(), back_inserter(newSections));
1051 for (std::vector<OpenDriveLaneSection>::const_iterator j = laneSections.begin(); j != laneSections.end() && sorted; ++j) {
1052 if ((*j).s <= lastS) {
1058 WRITE_WARNING(
"The sections of edge '" + e.
id +
"' are not sorted properly.");
1064 for (std::vector<OpenDriveLaneSection>::iterator j = laneSections.begin(); j != laneSections.end();) {
1065 bool simlarToLast = fabs((*j).s - lastS) <
POSITION_EPS;
1068 WRITE_WARNING(
"Almost duplicate s-value '" +
toString(lastS) +
"' for lane sections occured at edge '" + e.
id +
"'; second entry was removed.");
1069 j = laneSections.erase(j);
1074 #ifdef DEBUG_VARIABLE_SPEED 1095 double curveStart = g.
params[0];
1096 double curveEnd = g.
params[1];
1098 double cDot = (curveEnd - curveStart) / g.
length;
1099 if (cDot == 0 || g.
length == 0) {
1103 double sStart = curveStart / cDot;
1104 double sEnd = curveEnd / cDot;
1110 odrSpiral(sStart, cDot, &x, &y, &tStart);
1111 for (s = sStart; s <= sEnd; s += resolution) {
1122 assert(ret.size() >= 2);
1123 assert(ret[0] != ret[1]);
1126 ret.
add(ret.front() * -1);
1132 << std::setprecision(4)
1133 <<
"edge=" << e.
id <<
" s=" << g.
s 1134 <<
" cStart=" << curveStart
1135 <<
" cEnd=" << curveEnd
1137 <<
" sStart=" << sStart
1141 <<
"\n beforeShift=" << ret1
1142 <<
"\n beforeRot=" << ret2
1146 ret.
add(g.
x, g.
y, 0);
1147 }
catch (
const std::runtime_error&
error) {
1148 WRITE_WARNING(
"Could not compute spiral geometry for edge '" + e.
id +
"' (" + error.what() +
").");
1160 double centerX = g.
x;
1161 double centerY = g.
y;
1163 double curvature = g.
params[0];
1164 double radius = 1. / curvature;
1169 double startX = g.
x;
1170 double startY = g.
y;
1171 double geo_posS = g.
s;
1172 double geo_posE = g.
s;
1175 geo_posE += resolution;
1176 if (geo_posE - g.
s > g.
length) {
1179 if (geo_posE - g.
s > g.
length) {
1182 calcPointOnCurve(&endX, &endY, centerX, centerY, radius, geo_posE - geo_posS);
1184 dist += (geo_posE - geo_posS);
1186 ret.push_back(
Position(startX, startY));
1190 geo_posS = geo_posE;
1192 if (geo_posE - (g.
s + g.
length) < 0.001 && geo_posE - (g.
s + g.
length) > -0.001) {
1203 const double s = sin(g.
hdg);
1204 const double c = cos(g.
hdg);
1206 for (
double off = 0; off < g.
length + 2.; off += resolution) {
1209 double xnew = x * c - y * s;
1210 double ynew = x * s + y * c;
1211 ret.push_back(
Position(g.
x + xnew, g.
y + ynew));
1220 const double s = sin(g.
hdg);
1221 const double c = cos(g.
hdg);
1223 const double pStep = pMax / ceil(g.
length / resolution);
1225 for (
double p = 0; p <= pMax + pStep; p += pStep) {
1228 double xnew = x * c - y * s;
1229 double ynew = x * s + y * c;
1230 ret.push_back(
Position(g.
x + xnew, g.
y + ynew));
1238 double normx = 1.0f;
1239 double normy = 0.0f;
1240 double x2 = normx * cos(hdg) - normy * sin(hdg);
1241 double y2 = normx * sin(hdg) + normy * cos(hdg);
1242 normx = x2 * length;
1243 normy = y2 * length;
1244 return Position(start.
x() + normx, start.
y() + normy);
1254 if (ad_radius > 0) {
1261 normX = normX * cos(ad_hdg) + normY * sin(ad_hdg);
1262 normY = tmpX * sin(ad_hdg) + normY * cos(ad_hdg);
1265 normX = turn * normY;
1266 normY = -turn * tmpX;
1268 normX = fabs(ad_radius) * normX;
1269 normY = fabs(ad_radius) * normY;
1278 double ad_r,
double ad_length) {
1279 double rotAngle = ad_length / fabs(ad_r);
1280 double vx = *ad_x - ad_centerX;
1281 double vy = *ad_y - ad_centerY;
1291 vx = vx * cos(rotAngle) + turn * vy * sin(rotAngle);
1292 vy = -1 * turn * tmpx * sin(rotAngle) + vy * cos(rotAngle);
1293 *ad_x = vx + ad_centerX;
1294 *ad_y = vy + ad_centerY;
1311 bool singleType =
true;
1312 std::vector<std::string> types;
1314 for (std::vector<OpenDriveLane>::const_reverse_iterator i = dirLanesR.rbegin(); i != dirLanesR.rend(); ++i) {
1316 laneMap[(*i).id] = sumoLane++;
1317 types.push_back((*i).type);
1318 if (types.front() != types.back()) {
1329 for (std::vector<OpenDriveLane>::const_iterator i = dirLanesL.begin(); i != dirLanesL.end(); ++i) {
1331 laneMap[(*i).id] = sumoLane++;
1332 types.push_back((*i).type);
1333 if (types.front() != types.back()) {
1345 std::map<int, int> ret;
1346 const std::vector<OpenDriveLane>& dirLanes =
lanesByDir.find(dir)->second;
1347 for (std::vector<OpenDriveLane>::const_reverse_iterator i = dirLanes.rbegin(); i != dirLanes.rend(); ++i) {
1348 std::map<int, int>::const_iterator toP =
laneMap.find((*i).id);
1353 int to = (*toP).second;
1356 from = (*i).predecessor;
1359 std::map<int, int>::const_iterator fromP = prev.
laneMap.find(from);
1360 if (fromP != prev.
laneMap.end()) {
1361 from = (*fromP).second;
1367 if (ret.find(from) != ret.end()) {
1371 std::swap(from, to);
1390 if (i != l.
speeds.end()) {
1391 l.
speed = (*i).second;
1398 if (i != l.
speeds.end()) {
1399 l.
speed = (*i).second;
1408 std::set<double> speedChangePositions;
1411 for (std::vector<std::pair<double, double> >::const_iterator l = (*k).speeds.begin(); l != (*k).speeds.end(); ++l) {
1412 speedChangePositions.insert((*l).first);
1413 if ((*l).first == 0) {
1414 (*k).speed = (*l).second;
1419 for (std::vector<std::pair<double, double> >::const_iterator l = (*k).speeds.begin(); l != (*k).speeds.end(); ++l) {
1420 speedChangePositions.insert((*l).first);
1421 if ((*l).first == 0) {
1422 (*k).speed = (*l).second;
1427 if (speedChangePositions.size() == 0) {
1430 if (*speedChangePositions.begin() > 0) {
1431 speedChangePositions.insert(0);
1433 #ifdef DEBUG_VARIABLE_SPEED 1435 <<
" buildSpeedChanges sectionStart=" <<
s 1436 <<
" speedChangePositions=" <<
joinToString(speedChangePositions,
", ")
1439 for (std::set<double>::iterator i = speedChangePositions.begin(); i != speedChangePositions.end(); ++i) {
1440 if (i == speedChangePositions.begin()) {
1441 newSections.push_back(*
this);
1447 for (
int i = 0; i != (int)newSections.size(); ++i) {
1450 for (std::map<
OpenDriveXMLTag, std::vector<OpenDriveLane> >::iterator k = lanesByDir.begin(); k != lanesByDir.end(); ++k) {
1451 std::vector<OpenDriveLane>& lanes = (*k).second;
1452 for (
int j = 0; j != (int)lanes.size(); ++j) {
1458 l.
speed = newSections[i - 1].lanesByDir[(*k).first][j].speed;
1477 for (std::vector<OpenDriveSignal>::const_iterator i = signals.begin(); i != signals.end(); ++i) {
1479 if ((*i).type ==
"301" || (*i).type ==
"306") {
1482 if ((*i).type ==
"205" ) {
1519 if (majorVersion != 1 || minorVersion != 2) {
1585 std::vector<double> vals;
1591 std::vector<double> vals;
1598 std::vector<double> vals;
1604 std::vector<double> vals;
1613 std::vector<double> vals;
1623 if (pRange ==
"normalized") {
1624 vals.push_back(1.0);
1625 }
else if (pRange ==
"arcLength") {
1626 vals.push_back(-1.0);
1629 vals.push_back(1.0);
1701 WRITE_ERROR(
"In laneLink-element: incoming road '" + c.fromEdge +
"' is not known.");
1717 l.width =
MAX2(l.width, a);
1719 #ifdef DEBUG_VARIABLE_WIDTHS 1726 <<
" type=" << l.type
1727 <<
" width=" << l.width
1733 <<
" entries=" << l.widthData.size()
1747 if (!unit.empty()) {
1749 if (unit ==
"km/h") {
1752 if (unit ==
"mph") {
1753 speed *= 1.609344 / 3.6;
1806 const std::string& elementID,
1807 const std::string& contactPoint) {
1810 if (elementType ==
"road") {
1812 }
else if (elementType ==
"junction") {
1816 if (contactPoint ==
"start") {
1818 }
else if (contactPoint ==
"end") {
1859 std::vector<OpenDriveLaneSection> newSections;
1860 #ifdef DEBUG_VARIABLE_WIDTHS 1863 std::cout <<
"splitMinWidths e=" << e->
id <<
" sections=" << e->
laneSections.size() <<
"\n";
1868 std::vector<double> splitPositions;
1869 const double sectionEnd = (j + 1) == e->
laneSections.end() ? e->
length : (*(j + 1)).s;
1870 const int section = (int)(j - e->
laneSections.begin());
1871 #ifdef DEBUG_VARIABLE_WIDTHS 1873 std::cout <<
" findWidthSplit section=" << section <<
" sectionStart=" << sec.
s <<
" sectionOrigStart=" << sec.
sOrig <<
" sectionEnd=" << sectionEnd <<
"\n";
1882 newSections.push_back(sec);
1883 std::sort(splitPositions.begin(), splitPositions.end());
1885 double prevSplit = sec.
s;
1886 for (std::vector<double>::iterator it = splitPositions.begin(); it != splitPositions.end();) {
1887 if ((*it) - prevSplit < minDist || sectionEnd - (*it) < minDist) {
1889 #ifdef DEBUG_VARIABLE_WIDTHS 1891 std::cout <<
" skip close split=" << (*it) <<
" prevSplit=" << prevSplit <<
"\n";
1894 it = splitPositions.erase(it);
1895 }
else if ((*it) < sec.
s) {
1897 #ifdef DEBUG_VARIABLE_WIDTHS 1899 std::cout <<
" skip early split=" << (*it) <<
" s=" << sec.
s <<
"\n";
1902 it = splitPositions.erase(it);
1909 if (splitPositions.size() > 0) {
1910 #ifdef DEBUG_VARIABLE_WIDTHS 1912 std::cout <<
" road=" << e->
id <<
" splitMinWidths section=" << section
1913 <<
" start=" << sec.
s 1914 <<
" origStart=" << sec.
sOrig 1915 <<
" end=" << sectionEnd <<
" minDist=" << minDist
1916 <<
" splitPositions=" <<
toString(splitPositions) <<
"\n";
1919 #ifdef DEBUG_VARIABLE_WIDTHS 1921 std::cout <<
"first section...\n";
1925 for (std::vector<double>::iterator it = splitPositions.begin(); it != splitPositions.end(); ++it) {
1928 #ifdef DEBUG_VARIABLE_WIDTHS 1930 std::cout <<
"splitAt " << secNew.
s <<
"\n";
1933 newSections.push_back(secNew);
1940 double end = (it + 1) == splitPositions.end() ? sectionEnd : *(it + 1);
1952 int section,
double sectionStart,
double sectionEnd,
1953 std::vector<double>& splitPositions) {
1955 for (std::vector<OpenDriveLane>::iterator k = lanes.begin(); k != lanes.end(); ++k) {
1960 double wPrev = l.
widthData.front().computeAt(sPrev);
1962 <<
"findWidthSplit section=" << section
1963 <<
" sectionStart=" << sectionStart
1964 <<
" sectionEnd=" << sectionEnd
1966 <<
" type=" << l.
type 1967 <<
" widthEntries=" << l.
widthData.size() <<
"\n" 1971 for (std::vector<OpenDriveWidth>::iterator it_w = l.
widthData.begin(); it_w != l.
widthData.end(); ++it_w) {
1972 double sEnd = (it_w + 1) != l.
widthData.end() ? (*(it_w + 1)).s : sectionEnd - sectionStart;
1973 double w = (*it_w).computeAt(sEnd);
1976 <<
" s=" << (*it_w).s
1977 <<
" a=" << (*it_w).a <<
" b=" << (*it_w).b <<
" c=" << (*it_w).c <<
" d=" << (*it_w).d
1980 const double changeDist = fabs(
myMinWidth - wPrev);
1983 double splitPos = sPrev + (sEnd - sPrev) / fabs(w - wPrev) * changeDist;
1984 double wSplit = (*it_w).computeAt(splitPos);
1986 std::cout <<
" candidate splitPos=" << splitPos <<
" w=" << wSplit <<
"\n";
1993 if (splitPos < sPrev) {
1995 std::cout <<
" aborting search splitPos=" << splitPos <<
" wSplit=" << wSplit <<
" sPrev=" << sPrev <<
" wPrev=" << wPrev <<
"\n";
2003 if (splitPos > sEnd) {
2005 std::cout <<
" aborting search splitPos=" << splitPos <<
" wSplit=" << wSplit <<
" sEnd=" << sEnd <<
" w=" << w <<
"\n";
2011 wSplit = (*it_w).computeAt(splitPos);
2013 std::cout <<
" refined splitPos=" << splitPos <<
" w=" << wSplit <<
"\n";
2016 splitPositions.push_back(sectionStart + splitPos);
2034 for (std::vector<OpenDriveLane>::iterator k = lanes.begin(); k != lanes.end(); ++k) {
2035 (*k).predecessor = (*k).id;
2053 for (std::vector<OpenDriveLane>::iterator k = lanes.begin(); k != lanes.end(); ++k) {
2056 #ifdef DEBUG_VARIABLE_WIDTHS 2058 <<
"recomputeWidths lane=" << l.
id 2059 <<
" type=" << l.
type 2060 <<
" start=" << start
2062 <<
" sectionStart=" << sectionStart
2063 <<
" sectionEnd=" << sectionEnd
2064 <<
" widthEntries=" << l.
widthData.size() <<
"\n" 2069 double sPrevAbs = sPrev + sectionStart;
2070 for (std::vector<OpenDriveWidth>::iterator it_w = l.
widthData.begin(); it_w != l.
widthData.end(); ++it_w) {
2071 double sEnd = (it_w + 1) != l.
widthData.end() ? (*(it_w + 1)).s : sectionEnd - sectionStart;
2072 double sEndAbs = sEnd + sectionStart;
2073 #ifdef DEBUG_VARIABLE_WIDTHS 2075 <<
" sPrev=" << sPrev <<
" sPrevAbs=" << sPrevAbs
2076 <<
" sEnd=" << sEnd <<
" sEndAbs=" << sEndAbs
2077 <<
" widthData s=" << (*it_w).s
2078 <<
" a=" << (*it_w).a
2079 <<
" b=" << (*it_w).b
2080 <<
" c=" << (*it_w).c
2081 <<
" d=" << (*it_w).d
2084 if (sPrevAbs <= start && sEndAbs >= start) {
2085 #ifdef DEBUG_VARIABLE_WIDTHS 2087 std::cout <<
" atStart=" << start <<
" pos=" << start - sectionStart <<
" w=" << (*it_w).computeAt(start - sectionStart) <<
"\n";
2090 l.
width =
MAX2(l.
width, (*it_w).computeAt(start - sectionStart));
2092 if (sPrevAbs <= end && sEndAbs >= end) {
2093 #ifdef DEBUG_VARIABLE_WIDTHS 2095 std::cout <<
" atEnd=" << end <<
" pos=" << end - sectionStart <<
" w=" << (*it_w).computeAt(end - sectionStart) <<
"\n";
2100 if (start <= sPrevAbs && end >= sPrevAbs) {
2101 #ifdef DEBUG_VARIABLE_WIDTHS 2103 std::cout <<
" atSPrev=" << sPrev <<
" w=" << (*it_w).computeAt(sPrev) <<
"\n";
2108 if (start <= sEndAbs && end >= sEndAbs) {
2109 #ifdef DEBUG_VARIABLE_WIDTHS 2111 std::cout <<
" atSEnd=" << sEnd <<
" w=" << (*it_w).computeAt(sEnd) <<
"\n";
2116 #ifdef DEBUG_VARIABLE_WIDTHS 2118 std::cout <<
" sPrev=" << sPrev <<
" sEnd=" << sEnd <<
" l.width=" << l.
width <<
"\n";
std::map< std::string, OpenDriveEdge * > & myEdges
ContactPoint contactPoint
bool gDebugFlag1
global utility flags for debugging
std::vector< int > myElementStack
std::vector< std::string > getStringVector(const std::string &name) const
Returns the list of string-vector-value of the named option (only for Option_String) ...
std::string rightType
the composite type built from all used lane types
OpenDriveLaneSection(double sArg)
Constructor.
double sOrig
The original starting offset of this lane section (differs from s if the section had to be split) ...
static PositionVector geomFromLine(const OpenDriveEdge &e, const OpenDriveGeometry &g)
static StringBijection< int >::Entry openDriveAttrs[]
The names of openDrive-XML attributes (for passing to GenericSAXHandler)
NBTypeCont & getTypeCont()
Returns a reference to the type container.
OpenDriveLaneSection buildLaneSection(double startPos)
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
std::vector< OpenDriveWidth > widthData
double computeAt(double pos) const
void addLink(LinkType lt, const std::string &elementType, const std::string &elementID, const std::string &contactPoint)
Representation of an OpenDrive link.
static PositionVector geomFromArc(const OpenDriveEdge &e, const OpenDriveGeometry &g, double resolution)
static bool isReadable(std::string path)
Checks whether the given file is readable.
std::string junction
The id of the junction the edge belongs to.
std::vector< OpenDriveElevation > elevations
static void calculateCurveCenter(double *ad_x, double *ad_y, double ad_radius, double ad_hdg)
GeometryType
OpenDrive geometry type enumeration.
int rightLaneNumber
The number of lanes on the right and on the left side, respectively.
int gPrecision
the precision for floating point outputs
bool isTLControlled() const
Returns whether this node is controlled by any tls.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
double getWidth(const std::string &type) const
Returns the lane width for the given type [m].
double x() const
Returns the x-position.
Representation of a lane section.
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
The representation of a single edge during network building.
Representation of an openDrive "link".
The base class for traffic light logic definitions.
static const double UNSPECIFIED_OFFSET
unspecified lane offset
ContactPoint myCurrentContactPoint
void odrSpiral(double s, double cDot, double *x, double *y, double *t)
std::map< OpenDriveXMLTag, std::vector< OpenDriveLane > > lanesByDir
The lanes, sorted by their direction.
static bool transformCoordinates(PositionVector &from, bool includeInBoundary=true, GeoConvHelper *from_srs=0)
static PositionVector geomFromPoly(const OpenDriveEdge &e, const OpenDriveGeometry &g, double resolution)
PositionVector getSubpart2D(double beginOffset, double endOffset) const
get subpart of a position vector in two dimensions (Z is ignored)
static void calcPointOnCurve(double *ad_x, double *ad_y, double ad_centerX, double ad_centerY, double ad_r, double ad_length)
double length
The length of the edge.
std::set< Connection > connections
Poly3 OpenDriveElevation
LaneOffset has the same fields as Elevation.
Representation of a signal.
Lane & getLaneStruct(int lane)
static bool runParser(GenericSAXHandler &handler, const std::string &file, const bool isNet=false)
Runs the given handler on the given file; returns if everything's ok.
friend bool operator<(const Connection &c1, const Connection &c2)
#define UNUSED_PARAMETER(x)
static const double UNSPECIFIED_WIDTH
unspecified lane width
OpenDriveEdge myCurrentEdge
A class that stores a 2D geometrical boundary.
static NBNode * getOrBuildNode(const std::string &id, const Position &pos, NBNodeCont &nc)
Builds a node or returns the already built.
void error(const XERCES_CPP_NAMESPACE::SAXParseException &exception)
Handler for XML-errors.
#define WRITE_WARNING(msg)
The connection was computed and validated.
static OptionsCont & getOptions()
Retrieves the options.
static std::string revertID(const std::string &id)
static void findWidthSplit(const NBTypeCont &tc, std::vector< OpenDriveLane > &lanes, int section, double sectionStart, double sectionEnd, std::vector< double > &splitPositions)
std::string myCurrentConnectingRoad
PositionVector reverse() const
reverse position vector
Representation of a lane.
OpenDriveXMLTag myCurrentLaneDirection
An (internal) definition of a single lane of an edge.
const std::string & getID() const
Returns the id.
SVCPermissions permissions
List of vehicle types that are allowed on this lane.
std::vector< OpenDriveLink > links
static double naviDegree(const double angle)
A handler which converts occuring elements and attributes into enums.
void removeDoublePoints(double minDist=POSITION_EPS, bool assertLength=false)
Removes positions if too near.
static PositionVector geomFromSpiral(const OpenDriveEdge &e, const OpenDriveGeometry &g, double resolution)
static void buildConnectionsToOuter(const Connection &c, const std::map< std::string, OpenDriveEdge * > &innerEdges, std::vector< Connection > &into, std::set< Connection > &seen)
Poly3 OpenDriveLaneOffset
const std::string & getFileName() const
returns the current file name
static void setStraightConnections(std::vector< OpenDriveLane > &lanes)
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 insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
std::string type
The lane's type.
int getPriority(OpenDriveXMLTag dir) const
Returns the edge's priority, regarding the direction.
Encapsulated SAX-Attributes.
static StringBijection< TrafficLightType > TrafficLightTypes
traffic light types
static Position calculateStraightEndPoint(double hdg, double length, const Position &start)
static void recomputeWidths(OpenDriveLaneSection &sec, double start, double end, double sectionStart, double sectionEnd)
A point in 2D or 3D with translation and scaling methods.
NBEdgeCont & getEdgeCont()
std::string id
The id of the edge.
int indexOfClosest(const Position &p) const
index of the closest position to p
static void loadNetwork(const OptionsCont &oc, NBNetBuilder &nb)
Loads content of the optionally given SUMO file.
NIImporter_OpenDrive(const NBTypeCont &tc, std::map< std::string, OpenDriveEdge * > &edges)
Constructor.
bool isUsableFileList(const std::string &name) const
Checks whether the named option is usable as a file list (with at least a single file) ...
bool buildSpeedChanges(const NBTypeCont &tc, std::vector< OpenDriveLaneSection > &newSections)
static void splitMinWidths(OpenDriveEdge *e, const NBTypeCont &tc, double minDist)
const NBTypeCont & myTypeContainer
double y() const
Returns the y-position.
std::vector< OpenDriveLaneOffset > offsets
bool myConnectionWasEmpty
double speed
The lane's speed (set in post-processing)
std::string myCurrentJunctionID
std::vector< OpenDriveLaneSection > laneSections
std::map< int, int > laneMap
A mapping from OpenDrive to SUMO-index (the first is signed, the second unsigned) ...
#define PROGRESS_BEGIN_MESSAGE(msg)
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
Position positionAtOffset2D(double pos, double lateralOffset=0) const
Returns the position at the given length.
int insertAtClosest(const Position &p)
inserts p between the two closest positions and returns the insertion index
bool isDefault(const std::string &name) const
Returns the information whether the named option has still the default value.
OpenDriveXMLTag
Numbers representing openDrive-XML - element names.
static bool myImportWidths
bool knows(const std::string &type) const
Returns whether the named type is in the container.
The connection was given by the user.
double speed
The speed allowed on this lane.
double width
This lane's width.
void move2side(double amount)
move position vector to side using certain ammount
static PositionVector geomFromParamPoly(const OpenDriveEdge &e, const OpenDriveGeometry &g, double resolution)
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< int >::Entry openDriveTags[]
The names of openDrive-XML elements (for passing to GenericSAXHandler)
static bool myImportAllTypes
std::string origID
An original ID, if given.
void buildLaneMapping(const NBTypeCont &tc)
Build the mapping from OpenDrive to SUMO lanes.
std::vector< OpenDriveSignal > signals
LinkType
OpenDrive link type enumeration.
void addParameter(const std::string &key, const std::string &value)
Adds a parameter.
void rotate2D(double angle)
static void computeShapes(std::map< std::string, OpenDriveEdge * > &edges)
Computes a polygon representation of each edge's geometry.
NBNode * getToNode() const
Returns the destination node of the edge.
void addTrafficLight(NBTrafficLightDefinition *tlDef)
Adds a traffic light to the list of traffic lights that control this node.
~NIImporter_OpenDrive()
Destructor.
double length2D() const
Returns the length.
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
std::map< int, int > getInnerConnections(OpenDriveXMLTag dir, const OpenDriveLaneSection &prev)
Returns the links from the previous to this lane section.
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
NBNodeCont & getNodeCont()
Returns a reference to the node container.
Instance responsible for building networks.
Representation of an OpenDrive geometry part.
bool getShallBeDiscarded(const std::string &type) const
Returns the information whether edges of this type shall be discarded.
A storage for options typed value containers)
bool insert(const std::string &id, const Position &position, NBDistrict *district=0)
Inserts a node into the map.
NBTrafficLightLogicCont & getTLLogicCont()
Returns a reference to the traffic light logics container.
bool addLane2LaneConnection(int fromLane, NBEdge *dest, int toLane, Lane2LaneInfoType type, bool mayUseSameDestination=false, bool mayDefinitelyPass=false, bool keepClear=true, double contPos=UNSPECIFIED_CONTPOS, double visibility=UNSPECIFIED_VISIBILITY_DISTANCE)
Adds a connection between the specified this edge's lane and an approached one.
static void setEdgeLinks2(OpenDriveEdge &e, const std::map< std::string, OpenDriveEdge * > &edges)
std::vector< OpenDriveGeometry > geometries
Represents a single node (junction) during network building.
void addGeometryShape(GeometryType type, const std::vector< double > &vals)
T get(const std::string &str) const
A class for sorting lane sections by their s-value.
bool insert(NBTrafficLightDefinition *logic, bool forceInsert=false)
Adds a logic definition to the dictionary.
double getSpeed(const std::string &type) const
Returns the maximal velocity for the given type [m/s].
static void setNodeSecure(NBNodeCont &nc, OpenDriveEdge &e, const std::string &nodeID, NIImporter_OpenDrive::LinkType lt)
void push_back_noDoublePos(const Position &p)
insert in back a non double position
A connection between two roads.
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.
bool wasIgnored(std::string id) const
Returns whether the edge with the id was ignored during parsing.
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
SVCPermissions getPermissions(const std::string &type) const
Returns allowed vehicle classes for the given type.
Container for nodes during the netbuilding process.
std::vector< std::pair< double, double > > speeds
List of positions/speeds of speed changes.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
#define PROGRESS_DONE_MESSAGE()
A traffic light logics which must be computed (only nodes/edges are given)
void add(double xoff, double yoff, double zoff)
public emergency vehicles
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
const std::vector< Connection > & getConnections() const
Returns the connections.
Importer for networks stored in openDrive format.
double s
The starting offset of this lane section.
std::string myCurrentIncomingRoad
std::vector< double > params
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
bool exists(const std::string &name) const
Returns the information whether the named option is known.
A storage for available types of edges.
std::string streetName
The road name of the edge.
void myEndElement(int element)
Called when a closing tag occurs.
static void revisitLaneSections(const NBTypeCont &tc, std::map< std::string, OpenDriveEdge * > &edges)
Rechecks lane sections of the given edges.