170 std::map<std::string, OpenDriveEdge*> edges;
173 std::vector<std::string> files = oc.
getStringVector(
"opendrive-files");
174 for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
176 WRITE_ERROR(
"Could not open opendrive file '" + *file +
"'.");
179 handler.setFileName(*file);
185 std::map<std::string, OpenDriveEdge*> innerEdges, outerEdges;
186 for (std::map<std::string, OpenDriveEdge*>::iterator i = edges.begin(); i != edges.end(); ++i) {
187 if ((*i).second->isInner) {
188 innerEdges[(*i).first] = (*i).second;
190 outerEdges[(*i).first] = (*i).second;
205 std::map<std::string, Boundary> posMap;
206 std::map<std::string, std::string> edge2junction;
208 for (std::map<std::string, OpenDriveEdge*>::iterator i = innerEdges.begin(); i != innerEdges.end(); ++i) {
212 if (posMap.find(e->
junction) == posMap.end()) {
218 for (std::map<std::string, Boundary>::iterator i = posMap.begin(); i != posMap.end(); ++i) {
221 throw ProcessError(
"Could not add node '" + (*i).first +
"'.");
225 for (std::map<std::string, OpenDriveEdge*>::iterator i = outerEdges.begin(); i != outerEdges.end(); ++i) {
227 for (std::vector<OpenDriveLink>::iterator j = e->
links.begin(); j != e->
links.end(); ++j) {
235 throw ProcessError(
"Could not build node '" + nid +
"'.");
242 if (edge2junction.find(l.
elementID) != edge2junction.end()) {
254 for (std::map<std::string, OpenDriveEdge*>::iterator i = outerEdges.begin(); i != outerEdges.end(); ++i) {
256 for (std::vector<OpenDriveLink>::iterator j = e->
links.begin(); j != e->
links.end(); ++j) {
263 std::string id1 = e->
id;
268 std::string nid = id1 +
"." + id2;
273 throw ProcessError(
"Could not build node '" + nid +
"'.");
291 for (std::map<std::string, OpenDriveEdge*>::iterator i = outerEdges.begin(); i != outerEdges.end(); ++i) {
293 if (e->
to != 0 && e->
from != 0) {
296 for (std::map<std::string, OpenDriveEdge*>::iterator j = innerEdges.begin(); j != innerEdges.end(); ++j) {
298 for (std::vector<OpenDriveLink>::iterator k = ie->
links.begin(); k != ie->
links.end(); ++k) {
304 std::string nid = edge2junction[ie->
id];
316 for (std::map<std::string, OpenDriveEdge*>::iterator i = outerEdges.begin(); i != outerEdges.end(); ++i) {
318 if ((e->
from == 0 || e->
to == 0) && e->
geom.size() == 0) {
322 const std::string nid = e->
id +
".begin";
326 const std::string nid = e->
id +
".end";
335 const double defaultSpeed = tc.
getSpeed(
"");
338 for (std::map<std::string, OpenDriveEdge*>::iterator i = outerEdges.begin(); i != outerEdges.end(); ++i) {
340 if (e->
geom.size() == 0) {
344 bool lanesBuilt =
false;
360 double cF = length2D == 0 ? 1 : e->
length / length2D;
370 WRITE_WARNING(
"Edge '" + e->
id +
"' has to be split as it connects same junctions.")
373 const double minDist = oc.
getFloat(
"opendrive.curve-resolution");
384 double nextS = (j + 1)->s;
392 std::string
id = e->
id;
393 if (sFrom != e->
from || sTo != e->
to) {
398 #ifdef DEBUG_VARIABLE_WIDTHS 400 std::cout <<
" id=" <<
id <<
" sB=" << sB <<
" sE=" << sE <<
" geom=" << geom <<
"\n";
406 if ((*j).rightLaneNumber > 0) {
407 currRight =
new NBEdge(
"-" +
id, sFrom, sTo, (*j).rightType, defaultSpeed, (*j).rightLaneNumber, priorityR,
411 for (std::vector<OpenDriveLane>::const_iterator k = lanes.begin(); k != lanes.end(); ++k) {
412 std::map<int, int>::const_iterator lp = (*j).laneMap.find((*k).id);
413 if (lp != (*j).laneMap.end()) {
414 int sumoLaneIndex = lp->second;
438 if (prevRight != 0) {
440 for (std::map<int, int>::const_iterator k = connections.begin(); k != connections.end(); ++k) {
441 #ifdef DEBUG_CONNECTIONS 443 std::cout <<
"addCon1 from=" << prevRight->
getID() <<
"_" << (*k).first <<
" to=" << currRight->
getID() <<
"_" << (*k).second <<
"\n";
449 prevRight = currRight;
455 if ((*j).leftLaneNumber > 0) {
456 currLeft =
new NBEdge(
id, sTo, sFrom, (*j).leftType, defaultSpeed, (*j).leftLaneNumber, priorityL,
460 for (std::vector<OpenDriveLane>::const_iterator k = lanes.begin(); k != lanes.end(); ++k) {
461 std::map<int, int>::const_iterator lp = (*j).laneMap.find((*k).id);
462 if (lp != (*j).laneMap.end()) {
463 int sumoLaneIndex = lp->second;
488 std::map<int, int> connections = (*j).getInnerConnections(
OPENDRIVE_TAG_LEFT, *(j - 1));
489 for (std::map<int, int>::const_iterator k = connections.begin(); k != connections.end(); ++k) {
490 #ifdef DEBUG_CONNECTIONS 492 std::cout <<
"addCon2 from=" << currLeft->
getID() <<
"_" << (*k).first <<
" to=" << prevLeft->
getID() <<
"_" << (*k).second <<
"\n";
516 for (std::map<std::string, OpenDriveEdge*>::iterator i = edges.begin(); i != edges.end(); ++i) {
520 std::vector<Connection> connections2;
521 for (std::map<std::string, OpenDriveEdge*>::iterator j = edges.begin(); j != edges.end(); ++j) {
522 const std::set<Connection>& conns = (*j).second->connections;
524 for (std::set<Connection>::const_iterator i = conns.begin(); i != conns.end(); ++i) {
525 if (innerEdges.find((*i).fromEdge) != innerEdges.end()) {
529 if (innerEdges.find((*i).toEdge) != innerEdges.end()) {
530 std::set<Connection> seen;
533 connections2.push_back(*i);
538 for (std::vector<Connection>::const_iterator i = connections2.begin(); i != connections2.end(); ++i) {
539 std::string fromEdge = (*i).fromEdge;
540 if (edges.find(fromEdge) == edges.end()) {
541 WRITE_WARNING(
"While setting connections: from-edge '" + fromEdge +
"' is not known.");
545 int fromLane = (*i).fromLane;
546 bool fromLast = ((*i).fromCP ==
OPENDRIVE_CP_END) ^ ((*i).fromLane > 0 && !(*i).all);
549 std::string toEdge = (*i).toEdge;
550 if (edges.find(toEdge) == edges.end()) {
551 WRITE_WARNING(
"While setting connections: to-edge '" + toEdge +
"' is not known.");
556 int toLane = (*i).toLane;
577 WRITE_WARNING(
"Could not find fromEdge representation of '" + fromEdge +
"' in connection '" + (*i).origID +
"'.");
580 WRITE_WARNING(
"Could not find fromEdge representation of '" + toEdge +
"' in connection '" + (*i).origID +
"'.");
582 if (from == 0 || to == 0) {
586 #ifdef DEBUG_CONNECTIONS 588 std::cout <<
"addCon3 from=" << from->
getID() <<
"_" << fromLane <<
" to=" << to->
getID() <<
"_" << toLane <<
"\n";
597 if ((*i).origID !=
"" && saveOrigIDs) {
600 for (std::vector<NBEdge::Connection>::iterator k = cons.begin(); k != cons.end(); ++k) {
601 if ((*k).fromLane == fromLane && (*k).toEdge == to && (*k).toLane == toLane) {
613 std::map<std::string, std::string> tlsControlled;
614 for (std::map<std::string, OpenDriveEdge*>::iterator i = edges.begin(); i != edges.end(); ++i) {
616 for (std::vector<OpenDriveSignal>::const_iterator j = e->
signals.begin(); j != e->
signals.end(); ++j) {
617 if ((*j).type !=
"1000001") {
620 std::vector<OpenDriveLaneSection>::iterator k = e->
laneSections.begin();
623 if ((*j).s > (*k).s && (*j).s <= (*(k + 1)).s) {
633 std::string
id = (*k).sumoID;
637 std::string fromID, toID;
638 for (std::vector<OpenDriveLink>::const_iterator l = e->
links.begin(); l != e->
links.end(); ++l) {
646 if ((*j).orientation < 0) {
647 fromID =
"-" + fromID;
651 if ((*j).orientation > 0) {
652 fromID =
"-" + fromID;
664 id = fromID +
"->" + toID;
666 WRITE_WARNING(
"Found a traffic light signal on an unknown edge (original edge id='" + e->
id +
"').");
670 if ((*j).orientation > 0) {
674 tlsControlled[id] = (*j).name;
678 for (std::map<std::string, std::string>::iterator i = tlsControlled.begin(); i != tlsControlled.end(); ++i) {
679 std::string
id = (*i).first;
680 if (
id.find(
"->") != std::string::npos) {
681 id =
id.substr(0,
id.find(
"->"));
685 WRITE_WARNING(
"Could not find edge '" +
id +
"' while building its traffic light.");
707 for (std::map<std::string, OpenDriveEdge*>::iterator i = edges.begin(); i != edges.end(); ++i) {
738 const std::set<Connection>& conts = dest->
connections;
739 for (std::set<Connection>::const_iterator i = conts.begin(); i != conts.end(); ++i) {
740 auto innerEdgesIt = innerEdges.find((*i).toEdge);
741 if (innerEdgesIt != innerEdges.end()) {
742 std::vector<Connection> t;
743 if (seen.count(*i) == 0) {
745 for (std::vector<Connection>::const_iterator j = t.begin(); j != t.end(); ++j) {
753 cn.
shape = innerEdgesIt->second->geom + c.
shape;
761 if ((*i).fromLane == c.
toLane) {
773 if (rightLane.predecessor < c.
fromLane) {
774 offset += rightLane.width;
775 }
else if (rightLane.predecessor == c.
fromLane) {
776 offset += rightLane.width / 2;
796 for (std::vector<OpenDriveLink>::iterator i = e.
links.begin(); i != e.
links.end(); ++i) {
804 std::string edgeID = e.
id;
807 const std::map<int, int>& laneMap = laneSection.
laneMap;
808 #ifdef DEBUG_CONNECTIONS 810 std::cout <<
"edge=" << e.
id <<
" eType=" << l.
elementType <<
" lType=" << l.
linkType <<
" connectedEdge=" << connectedEdge <<
" laneSection=" << laneSection.
s <<
" map:\n";
816 for (std::vector<OpenDriveLane>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
833 if (edges.find(c.
fromEdge) == edges.end()) {
834 WRITE_ERROR(
"While setting connections: incoming road '" + c.
fromEdge +
"' is not known.");
838 #ifdef DEBUG_CONNECTIONS 846 for (std::vector<OpenDriveLane>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
863 if (edges.find(c.
fromEdge) == edges.end()) {
864 WRITE_ERROR(
"While setting connections: incoming road '" + c.
fromEdge +
"' is not known.");
868 #ifdef DEBUG_CONNECTIONS 870 std::cout <<
"insertConLeft from=" << src->
id <<
"_" << c.
fromLane <<
" to=" << c.
toEdge <<
"_" << c.
toLane <<
"\n";
893 if (!nc.
insert(
id, pos)) {
907 throw ProcessError(
"Could not find node '" + nodeID +
"'.");
910 if (e.
to != 0 && e.
to != n) {
926 const double res = oc.
getFloat(
"opendrive.curve-resolution");
927 for (std::map<std::string, OpenDriveEdge*>::iterator i = edges.begin(); i != edges.end(); ++i) {
930 for (std::vector<OpenDriveGeometry>::iterator j = e.
geometries.begin(); j != e.
geometries.end(); ++j) {
958 if (!e.
geom.back().almostSame(geom.front())) {
959 const int index = (int)(j - e.
geometries.begin());
965 for (PositionVector::iterator k = geom.begin(); k != geom.end(); ++k) {
970 if (oc.
exists(
"geometry.min-dist") && !oc.
isDefault(
"geometry.min-dist")) {
974 WRITE_ERROR(
"Unable to project coordinates for edge '" + e.
id +
"'.");
979 for (std::vector<OpenDriveElevation>::iterator j = e.
elevations.begin(); j != e.
elevations.end(); ++j) {
981 const double sNext = (j + 1) == e.
elevations.end() ? std::numeric_limits<double>::max() : (*(j + 1)).s;
982 while (k < (
int)e.
geom.size() && pos < sNext) {
987 if (k < (
int)e.
geom.size()) {
990 pos += e.
geom[k - 1].distanceTo2D(e.
geom[k]);
997 for (std::vector<OpenDriveLaneOffset>::iterator j = e.
offsets.begin(); j != e.
offsets.end(); ++j) {
1013 for (std::vector<OpenDriveLaneOffset>::iterator j = e.
offsets.begin(); j != e.
offsets.end(); ++j) {
1015 const double sNext = (j + 1) == e.
offsets.end() ? std::numeric_limits<double>::max() : (*(j + 1)).s;
1016 while (k < (
int)e.
geom.size() && pos < sNext) {
1017 const double offset = el.
computeAt(pos);
1025 geom2.push_back(tmp[k]);
1027 geom2.push_back(e.
geom[k]);
1030 geom2.push_back(e.
geom[k]);
1033 if (k < (
int)e.
geom.size()) {
1036 pos += e.
geom[k - 1].distanceTo2D(e.
geom[k]);
1040 assert(e.
geom.size() == geom2.size());
1050 for (std::map<std::string, OpenDriveEdge*>::iterator i = edges.begin(); i != edges.end(); ++i) {
1052 #ifdef DEBUG_VARIABLE_SPEED 1055 std::cout <<
"revisitLaneSections e=" << e.
id <<
"\n";
1058 std::vector<OpenDriveLaneSection>& laneSections = e.
laneSections;
1060 std::vector<OpenDriveLaneSection> newSections;
1061 for (std::vector<OpenDriveLaneSection>::iterator j = laneSections.begin(); j != laneSections.end(); ++j) {
1062 std::vector<OpenDriveLaneSection> splitSections;
1063 bool splitBySpeed = (*j).buildSpeedChanges(tc, splitSections);
1064 if (!splitBySpeed) {
1065 newSections.push_back(*j);
1067 std::copy(splitSections.begin(), splitSections.end(), back_inserter(newSections));
1076 for (std::vector<OpenDriveLaneSection>::const_iterator j = laneSections.begin(); j != laneSections.end() && sorted; ++j) {
1077 if ((*j).s <= lastS) {
1083 WRITE_WARNING(
"The sections of edge '" + e.
id +
"' are not sorted properly.");
1089 for (std::vector<OpenDriveLaneSection>::iterator j = laneSections.begin(); j != laneSections.end();) {
1090 bool simlarToLast = fabs((*j).s - lastS) <
POSITION_EPS;
1093 WRITE_WARNING(
"Almost duplicate s-value '" +
toString(lastS) +
"' for lane sections occurred at edge '" + e.
id +
"'; second entry was removed.");
1094 j = laneSections.erase(j);
1099 #ifdef DEBUG_VARIABLE_SPEED 1120 double curveStart = g.
params[0];
1121 double curveEnd = g.
params[1];
1123 double cDot = (curveEnd - curveStart) / g.
length;
1124 if (cDot == 0 || g.
length == 0) {
1129 double sStart = curveStart / cDot;
1130 double sEnd = curveEnd / cDot;
1136 odrSpiral(sStart, cDot, &x, &y, &tStart);
1137 for (s = sStart; s <= sEnd; s += resolution) {
1148 assert(ret.size() >= 2);
1149 assert(ret[0] != ret[1]);
1152 ret.
add(ret.front() * -1);
1158 << std::setprecision(4)
1159 <<
"edge=" << e.
id <<
" s=" << g.
s 1160 <<
" cStart=" << curveStart
1161 <<
" cEnd=" << curveEnd
1163 <<
" sStart=" << sStart
1167 <<
"\n beforeShift=" << ret1
1168 <<
"\n beforeRot=" << ret2
1172 ret.
add(g.
x, g.
y, 0);
1173 }
catch (
const std::runtime_error&
error) {
1174 WRITE_WARNING(
"Could not compute spiral geometry for edge '" + e.
id +
"' (" + error.what() +
").");
1186 double centerX = g.
x;
1187 double centerY = g.
y;
1189 double curvature = g.
params[0];
1190 double radius = 1. / curvature;
1195 double startX = g.
x;
1196 double startY = g.
y;
1197 double geo_posS = g.
s;
1198 double geo_posE = g.
s;
1201 geo_posE += resolution;
1202 if (geo_posE - g.
s > g.
length) {
1205 if (geo_posE - g.
s > g.
length) {
1208 calcPointOnCurve(&endX, &endY, centerX, centerY, radius, geo_posE - geo_posS);
1210 dist += (geo_posE - geo_posS);
1212 ret.push_back(
Position(startX, startY));
1216 geo_posS = geo_posE;
1218 if (geo_posE - (g.
s + g.
length) < 0.001 && geo_posE - (g.
s + g.
length) > -0.001) {
1229 const double s = sin(g.
hdg);
1230 const double c = cos(g.
hdg);
1232 for (
double off = 0; off < g.
length + 2.; off += resolution) {
1235 double xnew = x * c - y * s;
1236 double ynew = x * s + y * c;
1237 ret.push_back(
Position(g.
x + xnew, g.
y + ynew));
1246 const double s = sin(g.
hdg);
1247 const double c = cos(g.
hdg);
1249 const double pStep = pMax / ceil(g.
length / resolution);
1251 for (
double p = 0; p <= pMax + pStep; p += pStep) {
1254 double xnew = x * c - y * s;
1255 double ynew = x * s + y * c;
1256 ret.push_back(
Position(g.
x + xnew, g.
y + ynew));
1264 double normx = 1.0f;
1265 double normy = 0.0f;
1266 double x2 = normx * cos(hdg) - normy * sin(hdg);
1267 double y2 = normx * sin(hdg) + normy * cos(hdg);
1268 normx = x2 * length;
1269 normy = y2 * length;
1270 return Position(start.
x() + normx, start.
y() + normy);
1280 if (ad_radius > 0) {
1287 normX = normX * cos(ad_hdg) + normY * sin(ad_hdg);
1288 normY = tmpX * sin(ad_hdg) + normY * cos(ad_hdg);
1291 normX = turn * normY;
1292 normY = -turn * tmpX;
1294 normX = fabs(ad_radius) * normX;
1295 normY = fabs(ad_radius) * normY;
1304 double ad_r,
double ad_length) {
1305 double rotAngle = ad_length / fabs(ad_r);
1306 double vx = *ad_x - ad_centerX;
1307 double vy = *ad_y - ad_centerY;
1317 vx = vx * cos(rotAngle) + turn * vy * sin(rotAngle);
1318 vy = -1 * turn * tmpx * sin(rotAngle) + vy * cos(rotAngle);
1319 *ad_x = vx + ad_centerX;
1320 *ad_y = vy + ad_centerY;
1337 bool singleType =
true;
1338 std::vector<std::string> types;
1340 for (std::vector<OpenDriveLane>::const_reverse_iterator i = dirLanesR.rbegin(); i != dirLanesR.rend(); ++i) {
1342 laneMap[(*i).id] = sumoLane++;
1343 types.push_back((*i).type);
1344 if (types.front() != types.back()) {
1355 for (std::vector<OpenDriveLane>::const_iterator i = dirLanesL.begin(); i != dirLanesL.end(); ++i) {
1357 laneMap[(*i).id] = sumoLane++;
1358 types.push_back((*i).type);
1359 if (types.front() != types.back()) {
1371 std::map<int, int> ret;
1372 const std::vector<OpenDriveLane>& dirLanes =
lanesByDir.find(dir)->second;
1373 for (std::vector<OpenDriveLane>::const_reverse_iterator i = dirLanes.rbegin(); i != dirLanes.rend(); ++i) {
1374 std::map<int, int>::const_iterator toP =
laneMap.find((*i).id);
1379 int to = (*toP).second;
1382 from = (*i).predecessor;
1385 std::map<int, int>::const_iterator fromP = prev.
laneMap.find(from);
1386 if (fromP != prev.
laneMap.end()) {
1387 from = (*fromP).second;
1393 if (ret.find(from) != ret.end()) {
1397 std::swap(from, to);
1416 if (i != l.
speeds.end()) {
1417 l.
speed = (*i).second;
1424 if (i != l.
speeds.end()) {
1425 l.
speed = (*i).second;
1434 std::set<double> speedChangePositions;
1437 for (std::vector<std::pair<double, double> >::const_iterator l = (*k).speeds.begin(); l != (*k).speeds.end(); ++l) {
1438 speedChangePositions.insert((*l).first);
1439 if ((*l).first == 0) {
1440 (*k).speed = (*l).second;
1445 for (std::vector<std::pair<double, double> >::const_iterator l = (*k).speeds.begin(); l != (*k).speeds.end(); ++l) {
1446 speedChangePositions.insert((*l).first);
1447 if ((*l).first == 0) {
1448 (*k).speed = (*l).second;
1453 if (speedChangePositions.size() == 0) {
1456 if (*speedChangePositions.begin() > 0) {
1457 speedChangePositions.insert(0);
1459 #ifdef DEBUG_VARIABLE_SPEED 1461 <<
" buildSpeedChanges sectionStart=" <<
s 1462 <<
" speedChangePositions=" <<
joinToString(speedChangePositions,
", ")
1465 for (std::set<double>::iterator i = speedChangePositions.begin(); i != speedChangePositions.end(); ++i) {
1466 if (i == speedChangePositions.begin()) {
1467 newSections.push_back(*
this);
1473 for (
int i = 0; i != (int)newSections.size(); ++i) {
1476 for (std::map<
OpenDriveXMLTag, std::vector<OpenDriveLane> >::iterator k = lanesByDir.begin(); k != lanesByDir.end(); ++k) {
1477 std::vector<OpenDriveLane>& lanes = (*k).second;
1478 for (
int j = 0; j != (int)lanes.size(); ++j) {
1484 l.
speed = newSections[i - 1].lanesByDir[(*k).first][j].speed;
1503 for (std::vector<OpenDriveSignal>::const_iterator i = signals.begin(); i != signals.end(); ++i) {
1505 if ((*i).type ==
"301" || (*i).type ==
"306") {
1508 if ((*i).type ==
"205" ) {
1545 if (majorVersion != 1 || minorVersion != 2) {
1611 std::vector<double> vals;
1617 std::vector<double> vals;
1624 std::vector<double> vals;
1630 std::vector<double> vals;
1639 std::vector<double> vals;
1649 if (pRange ==
"normalized") {
1650 vals.push_back(1.0);
1651 }
else if (pRange ==
"arcLength") {
1652 vals.push_back(-1.0);
1655 vals.push_back(1.0);
1727 WRITE_ERROR(
"In laneLink-element: incoming road '" + c.fromEdge +
"' is not known.");
1743 l.width =
MAX2(l.width, a);
1745 #ifdef DEBUG_VARIABLE_WIDTHS 1752 <<
" type=" << l.type
1753 <<
" width=" << l.width
1759 <<
" entries=" << l.widthData.size()
1773 if (!unit.empty()) {
1775 if (unit ==
"km/h") {
1778 if (unit ==
"mph") {
1779 speed *= 1.609344 / 3.6;
1797 size_t i = cdata.find(
"+proj");
1798 if (i != std::string::npos) {
1799 const std::string proj = cdata.substr(i);
1809 result =
new GeoConvHelper(proj, networkOffset, origBoundary, convBoundary);
1812 WRITE_ERROR(
"Could not set projection. (" + std::string(e.what()) +
")");
1816 WRITE_WARNING(
"geoReference format '" + cdata +
"' currently not supported");
1860 const std::string& elementID,
1861 const std::string& contactPoint) {
1864 if (elementType ==
"road") {
1866 }
else if (elementType ==
"junction") {
1870 if (contactPoint ==
"start") {
1872 }
else if (contactPoint ==
"end") {
1913 std::vector<OpenDriveLaneSection> newSections;
1914 #ifdef DEBUG_VARIABLE_WIDTHS 1917 std::cout <<
"splitMinWidths e=" << e->
id <<
" sections=" << e->
laneSections.size() <<
"\n";
1922 std::vector<double> splitPositions;
1923 const double sectionEnd = (j + 1) == e->
laneSections.end() ? e->
length : (*(j + 1)).s;
1924 const int section = (int)(j - e->
laneSections.begin());
1925 #ifdef DEBUG_VARIABLE_WIDTHS 1927 std::cout <<
" findWidthSplit section=" << section <<
" sectionStart=" << sec.
s <<
" sectionOrigStart=" << sec.
sOrig <<
" sectionEnd=" << sectionEnd <<
"\n";
1936 newSections.push_back(sec);
1937 std::sort(splitPositions.begin(), splitPositions.end());
1939 double prevSplit = sec.
s;
1940 for (std::vector<double>::iterator it = splitPositions.begin(); it != splitPositions.end();) {
1941 if ((*it) - prevSplit < minDist || sectionEnd - (*it) < minDist) {
1943 #ifdef DEBUG_VARIABLE_WIDTHS 1945 std::cout <<
" skip close split=" << (*it) <<
" prevSplit=" << prevSplit <<
"\n";
1948 it = splitPositions.erase(it);
1949 }
else if ((*it) < sec.
s) {
1951 #ifdef DEBUG_VARIABLE_WIDTHS 1953 std::cout <<
" skip early split=" << (*it) <<
" s=" << sec.
s <<
"\n";
1956 it = splitPositions.erase(it);
1963 if (splitPositions.size() > 0) {
1964 #ifdef DEBUG_VARIABLE_WIDTHS 1966 std::cout <<
" road=" << e->
id <<
" splitMinWidths section=" << section
1967 <<
" start=" << sec.
s 1968 <<
" origStart=" << sec.
sOrig 1969 <<
" end=" << sectionEnd <<
" minDist=" << minDist
1970 <<
" splitPositions=" <<
toString(splitPositions) <<
"\n";
1973 #ifdef DEBUG_VARIABLE_WIDTHS 1975 std::cout <<
"first section...\n";
1979 for (std::vector<double>::iterator it = splitPositions.begin(); it != splitPositions.end(); ++it) {
1982 #ifdef DEBUG_VARIABLE_WIDTHS 1984 std::cout <<
"splitAt " << secNew.
s <<
"\n";
1987 newSections.push_back(secNew);
1994 double end = (it + 1) == splitPositions.end() ? sectionEnd : *(it + 1);
2006 int section,
double sectionStart,
double sectionEnd,
2007 std::vector<double>& splitPositions) {
2009 for (std::vector<OpenDriveLane>::iterator k = lanes.begin(); k != lanes.end(); ++k) {
2014 double wPrev = l.
widthData.front().computeAt(sPrev);
2016 <<
"findWidthSplit section=" << section
2017 <<
" sectionStart=" << sectionStart
2018 <<
" sectionEnd=" << sectionEnd
2020 <<
" type=" << l.
type 2021 <<
" widthEntries=" << l.
widthData.size() <<
"\n" 2025 for (std::vector<OpenDriveWidth>::iterator it_w = l.
widthData.begin(); it_w != l.
widthData.end(); ++it_w) {
2026 double sEnd = (it_w + 1) != l.
widthData.end() ? (*(it_w + 1)).s : sectionEnd - sectionStart;
2027 double w = (*it_w).computeAt(sEnd);
2030 <<
" s=" << (*it_w).s
2031 <<
" a=" << (*it_w).a <<
" b=" << (*it_w).b <<
" c=" << (*it_w).c <<
" d=" << (*it_w).d
2034 const double changeDist = fabs(
myMinWidth - wPrev);
2037 double splitPos = sPrev + (sEnd - sPrev) / fabs(w - wPrev) * changeDist;
2038 double wSplit = (*it_w).computeAt(splitPos);
2040 std::cout <<
" candidate splitPos=" << splitPos <<
" w=" << wSplit <<
"\n";
2047 if (splitPos < sPrev) {
2049 std::cout <<
" aborting search splitPos=" << splitPos <<
" wSplit=" << wSplit <<
" sPrev=" << sPrev <<
" wPrev=" << wPrev <<
"\n";
2057 if (splitPos > sEnd) {
2059 std::cout <<
" aborting search splitPos=" << splitPos <<
" wSplit=" << wSplit <<
" sEnd=" << sEnd <<
" w=" << w <<
"\n";
2065 wSplit = (*it_w).computeAt(splitPos);
2067 std::cout <<
" refined splitPos=" << splitPos <<
" w=" << wSplit <<
"\n";
2070 splitPositions.push_back(sectionStart + splitPos);
2088 for (std::vector<OpenDriveLane>::iterator k = lanes.begin(); k != lanes.end(); ++k) {
2089 (*k).predecessor = (*k).id;
2107 for (std::vector<OpenDriveLane>::iterator k = lanes.begin(); k != lanes.end(); ++k) {
2110 #ifdef DEBUG_VARIABLE_WIDTHS 2112 <<
"recomputeWidths lane=" << l.
id 2113 <<
" type=" << l.
type 2114 <<
" start=" << start
2116 <<
" sectionStart=" << sectionStart
2117 <<
" sectionEnd=" << sectionEnd
2118 <<
" widthEntries=" << l.
widthData.size() <<
"\n" 2123 double sPrevAbs = sPrev + sectionStart;
2124 for (std::vector<OpenDriveWidth>::iterator it_w = l.
widthData.begin(); it_w != l.
widthData.end(); ++it_w) {
2125 double sEnd = (it_w + 1) != l.
widthData.end() ? (*(it_w + 1)).s : sectionEnd - sectionStart;
2126 double sEndAbs = sEnd + sectionStart;
2127 #ifdef DEBUG_VARIABLE_WIDTHS 2129 <<
" sPrev=" << sPrev <<
" sPrevAbs=" << sPrevAbs
2130 <<
" sEnd=" << sEnd <<
" sEndAbs=" << sEndAbs
2131 <<
" widthData s=" << (*it_w).s
2132 <<
" a=" << (*it_w).a
2133 <<
" b=" << (*it_w).b
2134 <<
" c=" << (*it_w).c
2135 <<
" d=" << (*it_w).d
2138 if (sPrevAbs <= start && sEndAbs >= start) {
2139 #ifdef DEBUG_VARIABLE_WIDTHS 2141 std::cout <<
" atStart=" << start <<
" pos=" << start - sectionStart <<
" w=" << (*it_w).computeAt(start - sectionStart) <<
"\n";
2144 l.
width =
MAX2(l.
width, (*it_w).computeAt(start - sectionStart));
2146 if (sPrevAbs <= end && sEndAbs >= end) {
2147 #ifdef DEBUG_VARIABLE_WIDTHS 2149 std::cout <<
" atEnd=" << end <<
" pos=" << end - sectionStart <<
" w=" << (*it_w).computeAt(end - sectionStart) <<
"\n";
2154 if (start <= sPrevAbs && end >= sPrevAbs) {
2155 #ifdef DEBUG_VARIABLE_WIDTHS 2157 std::cout <<
" atSPrev=" << sPrev <<
" w=" << (*it_w).computeAt(sPrev) <<
"\n";
2162 if (start <= sEndAbs && end >= sEndAbs) {
2163 #ifdef DEBUG_VARIABLE_WIDTHS 2165 std::cout <<
" atSEnd=" << sEnd <<
" w=" << (*it_w).computeAt(sEnd) <<
"\n";
2170 #ifdef DEBUG_VARIABLE_WIDTHS 2172 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
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
std::vector< int > myElementStack
std::string rightType
the composite type built from all used lane types
double length2D() const
Returns the length.
OpenDriveLaneSection(double sArg)
Constructor.
double sOrig
The original starting offset of this lane section (differs from s if the section had to be split) ...
double getSpeed(const std::string &type) const
Returns the maximal velocity for the given type [m/s].
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)
std::vector< OpenDriveWidth > widthData
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.
static const double UNSPECIFIED_VISIBILITY_DISTANCE
unspecified foe visibility for connections
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)
int indexOfClosest(const Position &p) const
index of the closest position to p
GeometryType
OpenDrive geometry type enumeration.
int rightLaneNumber
The number of lanes on the right and on the left side, respectively.
static void computeShapes(std::map< std::string, OpenDriveEdge *> &edges)
Computes a polygon representation of each edge's geometry.
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
int gPrecision
the precision for floating point outputs
Position positionAtOffset2D(double pos, double lateralOffset=0) const
Returns the position at the given length.
Representation of a lane section.
const std::string & getFileName() const
returns the current file name
double y() const
Returns the y-position.
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
The representation of a single edge during network building.
NIImporter_OpenDrive(const NBTypeCont &tc, std::map< std::string, OpenDriveEdge *> &edges)
Constructor.
Representation of an openDrive "link".
static bool myImportInternalShapes
static void setLoaded(const GeoConvHelper &loaded)
sets the coordinate transformation loaded from a location element
double x() const
Returns the x-position.
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)
PositionVector reverse() const
reverse position vector
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)
void myCharacters(int element, const std::string &chars)
Callback method for characters to implement by derived classes.
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.
bool getShallBeDiscarded(const std::string &type) const
Returns the information whether edges of this type shall be discarded.
std::set< Connection > connections
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
Poly3 OpenDriveElevation
LaneOffset has the same fields as Elevation.
Representation of a signal.
const std::string & getID() const
Returns the id.
bool isDefault(const std::string &name) const
Returns the information whether the named option has still the default value.
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)
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list...
#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.
double getWidth(const std::string &type) const
Returns the lane width for the given type [m].
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
static const double UNSPECIFIED_SPEED
unspecified lane speed
Representation of a lane.
bool addLane2LaneConnection(int fromLane, NBEdge *dest, int toLane, Lane2LaneInfoType type, bool mayUseSameDestination=false, bool mayDefinitelyPass=false, bool keepClear=true, double contPos=UNSPECIFIED_CONTPOS, double visibility=UNSPECIFIED_VISIBILITY_DISTANCE, double speed=UNSPECIFIED_SPEED, const PositionVector &customShape=PositionVector::EMPTY, const bool uncontrolled=UNSPECIFIED_CONNECTION_UNCONTROLLED)
Adds a connection between the specified this edge's lane and an approached one.
OpenDriveXMLTag myCurrentLaneDirection
An (internal) definition of a single lane of an edge.
SVCPermissions permissions
List of vehicle types that are allowed on this lane.
bool isTLControlled() const
Returns whether this node is controlled by any tls.
std::vector< OpenDriveLink > links
static double naviDegree(const double angle)
A handler which converts occuring elements and attributes into enums.
int getPriority(OpenDriveXMLTag dir) const
Returns the edge's priority, regarding the direction.
void removeDoublePoints(double minDist=POSITION_EPS, bool assertLength=false)
Removes positions if too near.
bool knows(const std::string &type) const
Returns whether the named type is in the container.
static PositionVector geomFromSpiral(const OpenDriveEdge &e, const OpenDriveGeometry &g, double resolution)
Poly3 OpenDriveLaneOffset
static void setStraightConnections(std::vector< OpenDriveLane > &lanes)
static methods for processing the coordinates conversion for the current net
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.
bool isUsableFileList(const std::string &name) const
Checks whether the named option is usable as a file list (with at least a single file) ...
Encapsulated SAX-Attributes.
static StringBijection< TrafficLightType > TrafficLightTypes
traffic light types
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
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.
static void loadNetwork(const OptionsCont &oc, NBNetBuilder &nb)
Loads content of the optionally given SUMO file.
bool buildSpeedChanges(const NBTypeCont &tc, std::vector< OpenDriveLaneSection > &newSections)
static void splitMinWidths(OpenDriveEdge *e, const NBTypeCont &tc, double minDist)
const NBTypeCont & myTypeContainer
static const double UNSPECIFIED_CONTPOS
unspecified internal junction position
T get(const std::string &str) const
std::vector< OpenDriveLaneOffset > offsets
bool myConnectionWasEmpty
double speed
The lane's speed (set in post-processing)
bool exists(const std::string &name) const
Returns the information whether the named option is known.
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) ...
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) ...
#define PROGRESS_BEGIN_MESSAGE(msg)
void setParameter(const std::string &key, const std::string &value)
Sets a parameter.
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
int insertAtClosest(const Position &p)
inserts p between the two closest positions and returns the insertion index
OpenDriveXMLTag
Numbers representing openDrive-XML - element names.
static bool myImportWidths
The connection was given by the user.
double speed
The speed allowed on this lane.
double width
This lane's width.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
void move2side(double amount)
move position vector to side using certain ammount
vehicle is a passenger car (a "normal" car)
static PositionVector geomFromParamPoly(const OpenDriveEdge &e, const OpenDriveGeometry &g, double resolution)
static StringBijection< int >::Entry openDriveTags[]
The names of openDrive-XML elements (for passing to GenericSAXHandler)
static bool myImportAllTypes
void buildLaneMapping(const NBTypeCont &tc)
Build the mapping from OpenDrive to SUMO lanes.
std::vector< OpenDriveSignal > signals
LinkType
OpenDrive link type enumeration.
PositionVector getSubpart2D(double beginOffset, double endOffset) const
get subpart of a position vector in two dimensions (Z is ignored)
void rotate2D(double angle)
static void revisitLaneSections(const NBTypeCont &tc, std::map< std::string, OpenDriveEdge *> &edges)
Rechecks lane sections of the given edges.
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.
void addTrafficLight(NBTrafficLightDefinition *tlDef)
Adds a traffic light to the list of traffic lights that control this node.
~NIImporter_OpenDrive()
Destructor.
std::map< int, int > getInnerConnections(OpenDriveXMLTag dir, const OpenDriveLaneSection &prev)
Returns the links from the previous to this lane section.
const std::vector< Connection > & getConnections() const
Returns the connections.
NBNodeCont & getNodeCont()
Returns a reference to the node container.
Instance responsible for building networks.
const std::set< NBTrafficLightDefinition * > & getControllingTLS() const
Returns the traffic lights that were assigned to this node (The set of tls that control this node) ...
Representation of an OpenDrive geometry part.
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
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.
const std::string SUMO_PARAM_ORIGID
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)
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 computeAt(double pos) const
static void setNodeSecure(NBNodeCont &nc, OpenDriveEdge &e, const std::string &nodeID, NIImporter_OpenDrive::LinkType lt)
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
void push_back_noDoublePos(const Position &p)
insert in back a non double position
A connection between two roads.
bool wasIgnored(std::string id) const
Returns whether the edge with the id was ignored during parsing.
Container for nodes during the netbuilding process.
std::vector< std::pair< double, double > > speeds
List of positions/speeds of speed changes.
#define PROGRESS_DONE_MESSAGE()
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
A traffic light logics which must be computed (only nodes/edges are given)
void add(double xoff, double yoff, double zoff)
public emergency vehicles
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
Importer for networks stored in openDrive format.
double s
The starting offset of this lane section.
std::string myCurrentIncomingRoad
NBNode * getToNode() const
Returns the destination node of the edge.
std::vector< double > params
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
SVCPermissions getPermissions(const std::string &type) const
Returns allowed vehicle classes for the given type.
A storage for available types of edges.
std::string streetName
The road name of the edge.
static void buildConnectionsToOuter(const Connection &c, const std::map< std::string, OpenDriveEdge *> &innerEdges, std::vector< Connection > &into, std::set< Connection > &seen)
void myEndElement(int element)
Called when a closing tag occurs.