60 #define DEBUG_COND(road) ((road)->id == "18")
61 #define DEBUG_COND2(edgeID) (StringUtils::startsWith((edgeID), "-18."))
62 #define DEBUG_COND3(roadID) (roadID == "18")
187 std::map<std::string, OpenDriveEdge*> edges;
190 std::vector<std::string> files = oc.
getStringVector(
"opendrive-files");
191 for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
193 WRITE_ERROR(
"Could not open opendrive file '" + *file +
"'.");
202 for (
auto& item : edges) {
204 if (signal.
type ==
"") {
218 std::map<std::string, OpenDriveEdge*> innerEdges, outerEdges;
219 for (std::map<std::string, OpenDriveEdge*>::iterator i = edges.begin(); i != edges.end(); ++i) {
220 if ((*i).second->isInner) {
221 innerEdges[(*i).first] = (*i).second;
223 outerEdges[(*i).first] = (*i).second;
238 std::map<std::string, Boundary> posMap;
239 std::map<std::string, std::string> edge2junction;
240 std::vector<NodeSet> joinedNodeIDs;
242 for (std::map<std::string, OpenDriveEdge*>::iterator i = innerEdges.begin(); i != innerEdges.end(); ++i) {
246 if (posMap.find(e->
junction) == posMap.end()) {
252 for (std::map<std::string, Boundary>::iterator i = posMap.begin(); i != posMap.end(); ++i) {
255 throw ProcessError(
"Could not add node '" + (*i).first +
"'.");
259 for (std::map<std::string, OpenDriveEdge*>::iterator i = outerEdges.begin(); i != outerEdges.end(); ++i) {
261 for (std::vector<OpenDriveLink>::iterator j = e->
links.begin(); j != e->
links.end(); ++j) {
269 throw ProcessError(
"Could not build node '" + nid +
"'.");
276 if (edge2junction.find(l.
elementID) != edge2junction.end()) {
288 for (std::map<std::string, OpenDriveEdge*>::iterator i = outerEdges.begin(); i != outerEdges.end(); ++i) {
290 for (std::vector<OpenDriveLink>::iterator j = e->
links.begin(); j != e->
links.end(); ++j) {
297 std::string id1 = e->
id;
302 std::string nid = id1 +
"." + id2;
307 throw ProcessError(
"Could not build node '" + nid +
"'.");
325 for (std::map<std::string, OpenDriveEdge*>::iterator i = outerEdges.begin(); i != outerEdges.end(); ++i) {
327 if (e->
to !=
nullptr && e->
from !=
nullptr) {
330 for (std::map<std::string, OpenDriveEdge*>::iterator j = innerEdges.begin(); j != innerEdges.end(); ++j) {
332 for (std::vector<OpenDriveLink>::iterator k = ie->
links.begin(); k != ie->
links.end(); ++k) {
338 std::string nid = edge2junction[ie->
id];
350 for (std::map<std::string, OpenDriveEdge*>::iterator i = outerEdges.begin(); i != outerEdges.end(); ++i) {
352 if ((e->
from ==
nullptr || e->
to ==
nullptr) && e->
geom.size() == 0) {
355 if (e->
from ==
nullptr) {
356 const std::string nid = e->
id +
".begin";
359 if (e->
to ==
nullptr) {
360 const std::string nid = e->
id +
".end";
365 std::map<NBNode*, NBNode*> joinedNodes;
366 for (
NodeSet& joined : joinedNodeIDs) {
368 for (
NBNode* j : joined) {
369 joinedPos = joinedPos + j->getPosition();
371 joinedPos = joinedPos * (1.0 / joined.size());
373 if (!nc.
insert(joinedID, joinedPos)) {
374 throw ProcessError(
"Could not add node '" + joinedID +
"'.");
377 for (
NBNode* j : joined) {
381 for (std::map<std::string, OpenDriveEdge*>::iterator i = outerEdges.begin(); i != outerEdges.end(); ++i) {
383 if (joinedNodes.count(e->
from) != 0) {
387 if (joinedNodes.count(e->
to) != 0) {
389 e->
to = joinedNodes[e->
to];
400 std::map<std::pair<NBEdge*, int>,
int> laneIndexMap;
402 for (std::map<std::string, OpenDriveEdge*>::iterator i = outerEdges.begin(); i != outerEdges.end(); ++i) {
404 if (e->
geom.size() < 2) {
408 bool lanesBuilt =
false;
432 const double length2D = geomWithOffset.
length2D();
433 double cF = length2D == 0 ? 1 : e->
length / length2D;
434 NBEdge* prevRight =
nullptr;
435 NBEdge* prevLeft =
nullptr;
443 WRITE_WARNING(
"Edge '" + e->
id +
"' has to be split as it connects same junctions.")
447 const double minDist = oc.
getFloat(
"opendrive.curve-resolution");
458 double nextS = (j + 1)->s;
466 std::string
id = e->
id;
467 if (sFrom != e->
from || sTo != e->
to) {
472 #ifdef DEBUG_VARIABLE_WIDTHS
474 std::cout <<
" id=" <<
id <<
" sB=" << sB <<
" sE=" << sE <<
" geom=" << geom <<
"\n";
479 NBEdge* currRight =
nullptr;
480 if ((*j).rightLaneNumber > 0) {
481 currRight =
new NBEdge(
"-" +
id, sFrom, sTo, (*j).rightType, defaultSpeed, (*j).rightLaneNumber, priorityR,
485 for (std::vector<OpenDriveLane>::const_iterator k = lanes.begin(); k != lanes.end(); ++k) {
486 std::map<int, int>::const_iterator lp = (*j).laneMap.find((*k).id);
487 if (lp != (*j).laneMap.end()) {
488 int sumoLaneIndex = lp->second;
490 laneIndexMap[std::make_pair(currRight, sumoLaneIndex)] = (*k).id;
500 if (prevRight !=
nullptr) {
502 for (std::map<int, int>::const_iterator k = connections.begin(); k != connections.end(); ++k) {
503 #ifdef DEBUG_CONNECTIONS
505 std::cout <<
"addCon1 from=" << prevRight->
getID() <<
"_" << (*k).first <<
" to=" << currRight->
getID() <<
"_" << (*k).second <<
"\n";
511 prevRight = currRight;
516 NBEdge* currLeft =
nullptr;
517 if ((*j).leftLaneNumber > 0) {
518 currLeft =
new NBEdge(
id, sTo, sFrom, (*j).leftType, defaultSpeed, (*j).leftLaneNumber, priorityL,
522 for (std::vector<OpenDriveLane>::const_iterator k = lanes.begin(); k != lanes.end(); ++k) {
523 std::map<int, int>::const_iterator lp = (*j).laneMap.find((*k).id);
524 if (lp != (*j).laneMap.end()) {
525 int sumoLaneIndex = lp->second;
527 laneIndexMap[std::make_pair(currLeft, sumoLaneIndex)] = (*k).id;
537 if (prevLeft !=
nullptr) {
538 std::map<int, int> connections = (*j).getInnerConnections(
OPENDRIVE_TAG_LEFT, *(j - 1));
539 for (std::map<int, int>::const_iterator k = connections.begin(); k != connections.end(); ++k) {
540 #ifdef DEBUG_CONNECTIONS
542 std::cout <<
"addCon2 from=" << currLeft->
getID() <<
"_" << (*k).first <<
" to=" << prevLeft->
getID() <<
"_" << (*k).second <<
"\n";
558 if (oc.
isSet(
"polygon-output")) {
577 centerLine.push_back(
Position(-o.length / 2, 0));
578 centerLine.push_back(
Position(o.length / 2, 0));
580 centerLine.
rotate2D(roadHdg + o.hdg);
592 for (
int i = 0; i < (int) shape.size(); i++) {
611 for (std::map<std::string, OpenDriveEdge*>::iterator i = edges.begin(); i != edges.end(); ++i) {
615 std::vector<Connection> connections2;
616 for (std::map<std::string, OpenDriveEdge*>::iterator j = edges.begin(); j != edges.end(); ++j) {
617 const std::set<Connection>& conns = (*j).second->connections;
619 for (std::set<Connection>::const_iterator i = conns.begin(); i != conns.end(); ++i) {
620 if (innerEdges.find((*i).fromEdge) != innerEdges.end()) {
624 if (innerEdges.find((*i).toEdge) != innerEdges.end()) {
625 std::set<Connection> seen;
628 connections2.push_back(*i);
633 for (std::vector<Connection>::const_iterator i = connections2.begin(); i != connections2.end(); ++i) {
634 #ifdef DEBUG_CONNECTIONS
635 std::cout <<
"connections2 " << (*i).getDescription() <<
"\n";
637 std::string fromEdge = (*i).fromEdge;
638 if (edges.find(fromEdge) == edges.end()) {
639 WRITE_WARNING(
"While setting connections: from-edge '" + fromEdge +
"' is not known.");
643 int fromLane = (*i).fromLane;
647 std::string toEdge = (*i).toEdge;
648 if (edges.find(toEdge) == edges.end()) {
649 WRITE_WARNING(
"While setting connections: to-edge '" + toEdge +
"' is not known.");
654 int toLane = (*i).toLane;
674 if (from ==
nullptr) {
675 WRITE_WARNING(
"Could not find fromEdge representation of '" + fromEdge +
"' in connection '" + (*i).origID +
"'.");
678 WRITE_WARNING(
"Could not find fromEdge representation of '" + toEdge +
"' in connection '" + (*i).origID +
"'.");
680 if (from ==
nullptr || to ==
nullptr) {
684 #ifdef DEBUG_CONNECTIONS
686 std::cout <<
"addCon3 from=" << from->
getID() <<
"_" << fromLane <<
" to=" << to->
getID() <<
"_" << toLane <<
"\n";
697 if ((*i).origID !=
"" && saveOrigIDs) {
700 for (std::vector<NBEdge::Connection>::iterator k = cons.begin(); k != cons.end(); ++k) {
701 if ((*k).fromLane == fromLane && (*k).toEdge == to && (*k).toLane == toLane) {
713 std::map<std::string, std::string> tlsControlled;
714 for (std::map<std::string, OpenDriveEdge*>::iterator i = edges.begin(); i != edges.end(); ++i) {
717 if (signal.
type !=
"1000001") {
721 WRITE_WARNING(
"Edge '" + e->
id +
"' has signals but no lane sections.");
724 std::vector<OpenDriveLaneSection>::iterator k = e->
laneSections.begin();
727 if (signal.
s > (*k).s && signal.
s <= (*(k + 1)).s) {
734 std::string
id = (*k).sumoID;
739 std::string fromID, toID;
740 for (std::vector<OpenDriveLink>::const_iterator l = e->
links.begin(); l != e->
links.end(); ++l) {
749 fromID =
"-" + fromID;
754 fromID =
"-" + fromID;
772 if (from ==
nullptr) {
773 WRITE_WARNINGF(
"Could not find edge '%' for signal '%'.", fromID, signal.
id);
779 bool fromForward = from->
getID()[0] ==
'-';
780 bool lanesForward = signal.
maxLane < 0;
781 if (fromForward != lanesForward) {
782 std::swap(fromID, toID);
787 if (from ==
nullptr) {
788 WRITE_WARNINGF(
"Could not find edge '%' for signal '%'.", fromID, signal.
id);
794 if (c.toEdge == to) {
795 int odLane = laneIndexMap[std::make_pair(from, c.fromLane)];
798 c.setParameter(
"signalID", signal.
id);
806 WRITE_WARNINGF(
"Found a traffic light signal on an unknown edge (original edge id='%').", e->
id);
816 if (edge ==
nullptr) {
823 int odLane = laneIndexMap[std::make_pair(edge, c.fromLane)];
825 c.setParameter(
"signalID", signal.
id);
838 for (std::map<std::string, OpenDriveEdge*>::iterator i = edges.begin(); i != edges.end(); ++i) {
843 std::pair<NBEdge*, NBEdge*>
855 return std::make_pair(from, to);
893 if (sumoLane.
width >= 0 && widthResolution > 0) {
894 sumoLane.
width = floor(sumoLane.
width / widthResolution + 0.5) * widthResolution;
896 sumoLane.
width -= widthResolution;
897 if (sumoLane.
width <= 0) {
900 }
else if (sumoLane.
width == 0) {
902 sumoLane.
width = widthResolution;
908 if (forbiddenNarrow) {
918 #ifdef DEBUG_CONNECTIONS
920 std::cout <<
" buildConnectionsToOuter " << c.
getDescription() <<
"\n";
921 std::cout <<
" dest=" << (dest ==
nullptr ?
"NULL" : dest->
id) <<
" seenlist=";
922 for (std::set<Connection>::const_iterator i = seen.begin(); i != seen.end(); ++i) {
923 std::cout <<
" " << (*i).fromEdge <<
"," << (*i).toEdge <<
" ";
928 if (dest ==
nullptr) {
933 const std::set<Connection>& conts = dest->
connections;
934 for (std::set<Connection>::const_iterator i = conts.begin(); i != conts.end(); ++i) {
935 auto innerEdgesIt = innerEdges.find((*i).toEdge);
936 #ifdef DEBUG_CONNECTIONS
938 std::cout <<
" toInner=" << (innerEdgesIt != innerEdges.end()) <<
" destCon " << (*i).getDescription() <<
"\n";
941 if (innerEdgesIt != innerEdges.end()) {
942 std::vector<Connection> t;
943 if (seen.count(*i) == 0) {
945 for (std::vector<Connection>::const_iterator j = t.begin(); j != t.end(); ++j) {
953 cn.shape = innerEdgesIt->second->geom + c.
shape;
962 int out = (*i).fromLane;
967 #ifdef DEBUG_CONNECTIONS
969 std::cout <<
" laneSectionsConnected dest=" << dest->
id <<
" in=" << in <<
" out=" << out
986 int referenceLane = 0;
987 int offsetFactor = 1;
991 for (
const auto& destLane : dest->
laneSections.front().lanesByDir[lanesDir]) {
992 if (destLane.successor == c.
fromLane) {
993 referenceLane = destLane.id;
999 for (
const auto& destLane : dest->
laneSections.front().lanesByDir[lanesDir]) {
1000 if (destLane.predecessor == c.
fromLane) {
1001 referenceLane = destLane.id;
1010 std::vector<double> offsets(dest->
geom.size(), 0);
1014 #ifdef DEBUG_INTERNALSHAPES
1015 std::string destPred;
1019 for (
int laneSectionIndex = 0; laneSectionIndex < (int)dest->
laneSections.size(); laneSectionIndex++) {
1020 auto& laneSection = dest->
laneSections[laneSectionIndex];
1021 const double nextS = laneSectionIndex + 1 < (int)dest->
laneSections.size() ? dest->
laneSections[laneSectionIndex + 1].s : std::numeric_limits<double>::max();
1026 for (
const OpenDriveLane& destLane : laneSection.lanesByDir[lanesDir]) {
1028 double sectionS = 0;
1031 #ifdef DEBUG_INTERNALSHAPES
1032 destPred +=
" lane=" +
toString(destLane.id)
1033 +
" pred=" +
toString(destLane.predecessor)
1034 +
" succ=" +
toString(destLane.successor)
1035 +
" wStart=" +
toString(destLane.widthData.front().computeAt(0))
1036 +
" wEnd=" +
toString(destLane.widthData.front().computeAt(
cn.shape.length2D()))
1037 +
" width=" +
toString(destLane.width) +
"\n";
1039 if (abs(destLane.id) <= abs(referenceLane)) {
1040 const double multiplier = offsetFactor * (destLane.id == referenceLane ? 0.5 : 1);
1041 #ifdef DEBUG_INTERNALSHAPES
1042 destPred +=
" multiplier=" +
toString(multiplier) +
"\n";
1044 int widthDataIndex = 0;
1045 while (s < nextS && i < (
int)
cn.shape.size()) {
1047 const double dist =
cn.shape[i - 1].distanceTo2D(
cn.shape[i]);
1052 while (widthDataIndex + 1 < (
int)destLane.widthData.size()
1053 && sectionS >= destLane.widthData[widthDataIndex + 1].s) {
1056 offsets[i] += destLane.widthData[widthDataIndex].computeAt(sectionS) * multiplier;
1064 }
else if (finalS == s) {
1066 while (s < nextS && i < (
int)
cn.shape.size()) {
1068 const double dist =
cn.shape[i - 1].distanceTo2D(
cn.shape[i]);
1084 cn.shape.move2side(offsets);
1089 #ifdef DEBUG_INTERNALSHAPES
1090 std::cout <<
"internalShape "
1092 <<
" dest=" << dest->
id
1093 <<
" refLane=" << referenceLane
1094 <<
" destPred\n" << destPred
1095 <<
" offsets=" << offsets
1096 <<
"\n shape=" << dest->
geom
1097 <<
"\n shape2=" <<
cn.shape
1101 cn.shape =
cn.shape.reverse();
1104 #ifdef DEBUG_CONNECTIONS
1106 std::cout <<
" added connection\n";
1126 if (lane.id == in) {
1127 in = lane.successor;
1134 if (lane.id == in) {
1135 in = lane.successor;
1148 for (std::vector<OpenDriveLink>::iterator i = e.
links.begin(); i != e.
links.end(); ++i) {
1155 std::string connectedEdge = l.
elementID;
1156 std::string edgeID = e.
id;
1159 const std::map<int, int>& laneMap = laneSection.
laneMap;
1160 #ifdef DEBUG_CONNECTIONS
1162 std::cout <<
"edge=" << e.
id <<
" eType=" << l.
elementType <<
" lType=" << l.
linkType <<
" connectedEdge=" << connectedEdge <<
" laneSection=" << laneSection.
s <<
" map:\n";
1168 for (std::vector<OpenDriveLane>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
1177 c.
toEdge = connectedEdge;
1185 if (edges.find(c.
fromEdge) == edges.end()) {
1186 WRITE_ERROR(
"While setting connections: incoming road '" + c.
fromEdge +
"' is not known.");
1190 #ifdef DEBUG_CONNECTIONS
1192 std::cout <<
"insertConRight from=" << src->
id <<
"_" << c.
fromLane <<
" to=" << c.
toEdge <<
"_" << c.
toLane <<
"\n";
1200 for (std::vector<OpenDriveLane>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
1217 if (edges.find(c.
fromEdge) == edges.end()) {
1218 WRITE_ERROR(
"While setting connections: incoming road '" + c.
fromEdge +
"' is not known.");
1222 #ifdef DEBUG_CONNECTIONS
1224 std::cout <<
"insertConLeft from=" << src->
id <<
"_" << c.
fromLane <<
" to=" << c.
toEdge <<
"_" << c.
toLane <<
"\n";
1236 return id.substr(1);
1247 if (!nc.
insert(
id, pos)) {
1249 throw ProcessError(
"Could not add node '" +
id +
"'.");
1261 throw ProcessError(
"Could not find node '" + nodeID +
"'.");
1263 NBNode* toJoin =
nullptr;
1265 if (e.
to !=
nullptr && e.
to != n) {
1270 if (e.
from !=
nullptr && e.
from != n) {
1275 if (toJoin !=
nullptr) {
1279 for (
NodeSet& joined : joinedNodeIDs) {
1280 if (joined.count(toJoin) != 0) {
1283 if (joined.count(n) != 0) {
1287 if (set1 ==
nullptr && set2 ==
nullptr) {
1288 joinedNodeIDs.push_back(
NodeSet());
1289 joinedNodeIDs.back().insert(n);
1290 joinedNodeIDs.back().insert(toJoin);
1291 }
else if (set1 ==
nullptr && set2 !=
nullptr) {
1292 set2->insert(toJoin);
1293 }
else if (set1 !=
nullptr && set2 ==
nullptr) {
1296 set1->insert(set2->begin(), set2->end());
1297 joinedNodeIDs.erase(std::find(joinedNodeIDs.begin(), joinedNodeIDs.end(), *set2));
1308 if (el.
c != 0 || el.
d != 0) {
1318 const double res = oc.
getFloat(
"opendrive.curve-resolution");
1319 for (std::map<std::string, OpenDriveEdge*>::iterator i = edges.begin(); i != edges.end(); ++i) {
1324 for (std::vector<OpenDriveGeometry>::iterator j = e.
geometries.begin(); j != e.
geometries.end(); ++j) {
1352 if (!e.
geom.back().almostSame(geom.front())) {
1353 const int index = (int)(j - e.
geometries.begin());
1359 for (PositionVector::iterator k = geom.begin(); k != geom.end(); ++k) {
1365 if (e.
geom.size() == 1 && e.
geom.front() != last) {
1367 e.
geom.push_back(last);
1369 if (oc.
exists(
"geometry.min-dist") && !oc.
isDefault(
"geometry.min-dist")) {
1373 WRITE_ERROR(
"Unable to project coordinates for edge '" + e.
id +
"'.");
1379 for (std::vector<OpenDriveElevation>::iterator j = e.
elevations.begin(); j != e.
elevations.end(); ++j) {
1381 const double sNext = (j + 1) == e.
elevations.end() ? std::numeric_limits<double>::max() : (*(j + 1)).s;
1382 while (k < (
int)e.
geom.size() && pos < sNext) {
1387 if (k < (
int)e.
geom.size()) {
1390 pos += e.
geom[k - 1].distanceTo2D(e.
geom[k]);
1397 for (std::vector<OpenDriveLaneOffset>::iterator j = e.
offsets.begin(); j != e.
offsets.end(); ++j) {
1412 for (std::vector<OpenDriveLaneOffset>::iterator j = e.
offsets.begin(); j != e.
offsets.end(); ++j) {
1414 const double sNext = (j + 1) == e.
offsets.end() ? std::numeric_limits<double>::max() : (*(j + 1)).s;
1415 while (k < (
int)e.
geom.size() && pos < sNext) {
1416 const double offset = el.
computeAt(pos);
1417 e.
laneOffsets.push_back(fabs(offset) > POSITION_EPS ? -offset : 0);
1419 if (k < (
int)e.
geom.size()) {
1422 pos += e.
geom[k - 1].distanceTo2D(e.
geom[k]);
1434 for (std::map<std::string, OpenDriveEdge*>::iterator i = edges.begin(); i != edges.end(); ++i) {
1436 #ifdef DEBUG_VARIABLE_SPEED
1439 std::cout <<
"revisitLaneSections e=" << e.
id <<
"\n";
1442 std::vector<OpenDriveLaneSection>& laneSections = e.
laneSections;
1444 std::vector<OpenDriveLaneSection> newSections;
1445 for (std::vector<OpenDriveLaneSection>::iterator j = laneSections.begin(); j != laneSections.end(); ++j) {
1446 std::vector<OpenDriveLaneSection> splitSections;
1447 bool splitBySpeed = (*j).buildSpeedChanges(tc, splitSections);
1448 if (!splitBySpeed) {
1449 newSections.push_back(*j);
1451 std::copy(splitSections.begin(), splitSections.end(), back_inserter(newSections));
1460 for (std::vector<OpenDriveLaneSection>::const_iterator j = laneSections.begin(); j != laneSections.end() && sorted; ++j) {
1461 if ((*j).s <= lastS) {
1467 WRITE_WARNING(
"The sections of edge '" + e.
id +
"' are not sorted properly.");
1473 for (std::vector<OpenDriveLaneSection>::iterator j = laneSections.begin(); j != laneSections.end();) {
1474 bool simlarToLast = fabs((*j).s - lastS) < POSITION_EPS;
1478 if (simlarToLast && !e.
isInner) {
1479 WRITE_WARNING(
"Almost duplicate s-value '" +
toString(lastS) +
"' for lane sections occurred at edge '" + e.
id +
"'; second entry was removed.");
1480 j = laneSections.erase(j);
1485 #ifdef DEBUG_VARIABLE_SPEED
1498 if (resolution > 0 && g.
length > 0) {
1499 const int numPoints = (int)ceil(g.
length / resolution) + 1;
1500 double dx = (end.
x() - start.
x()) / (numPoints - 1);
1501 double dy = (end.
y() - start.
y()) / (numPoints - 1);
1502 for (
int i = 0; i < numPoints; i++) {
1503 ret.push_back(
Position(g.
x + i * dx, g.
y + i * dy));
1506 ret.push_back(start);
1517 double curveStart = g.
params[0];
1518 double curveEnd = g.
params[1];
1520 double cDot = (curveEnd - curveStart) / g.
length;
1521 if (cDot == 0 || g.
length == 0) {
1526 double sStart = curveStart / cDot;
1527 double sEnd = curveEnd / cDot;
1533 odrSpiral(sStart, cDot, &x, &y, &tStart);
1534 for (s = sStart; s <= sEnd; s += resolution) {
1545 assert(ret.size() >= 2);
1546 assert(ret[0] != ret[1]);
1549 ret.
add(ret.front() * -1);
1555 << std::setprecision(4)
1556 <<
"edge=" << e.
id <<
" s=" << g.
s
1557 <<
" cStart=" << curveStart
1558 <<
" cEnd=" << curveEnd
1560 <<
" sStart=" << sStart
1564 <<
"\n beforeShift=" << ret1
1565 <<
"\n beforeRot=" << ret2
1569 ret.
add(g.
x, g.
y, 0);
1570 }
catch (
const std::runtime_error&
error) {
1571 WRITE_WARNING(
"Could not compute spiral geometry for edge '" + e.
id +
"' (" +
error.what() +
").");
1583 double centerX = g.
x;
1584 double centerY = g.
y;
1586 double curvature = g.
params[0];
1587 double radius = 1. / curvature;
1592 double startX = g.
x;
1593 double startY = g.
y;
1594 double geo_posS = g.
s;
1595 double geo_posE = g.
s;
1598 geo_posE += resolution;
1599 if (geo_posE - g.
s > g.
length) {
1602 if (geo_posE - g.
s > g.
length) {
1605 calcPointOnCurve(&endX, &endY, centerX, centerY, radius, geo_posE - geo_posS);
1607 dist += (geo_posE - geo_posS);
1609 ret.push_back(
Position(startX, startY));
1613 geo_posS = geo_posE;
1615 if (geo_posE - (g.
s + g.
length) < 0.001 && geo_posE - (g.
s + g.
length) > -0.001) {
1626 const double s = sin(g.
hdg);
1627 const double c = cos(g.
hdg);
1629 for (
double off = 0; off < g.
length + 2.; off += resolution) {
1632 double xnew = x * c - y * s;
1633 double ynew = x * s + y * c;
1634 ret.push_back(
Position(g.
x + xnew, g.
y + ynew));
1643 const double s = sin(g.
hdg);
1644 const double c = cos(g.
hdg);
1646 const double pStep = pMax / ceil(g.
length / resolution);
1648 for (
double p = 0; p <= pMax + pStep; p += pStep) {
1651 double xnew = x * c - y * s;
1652 double ynew = x * s + y * c;
1653 ret.push_back(
Position(g.
x + xnew, g.
y + ynew));
1661 double normx = 1.0f;
1662 double normy = 0.0f;
1663 double x2 = normx * cos(hdg) - normy * sin(hdg);
1664 double y2 = normx * sin(hdg) + normy * cos(hdg);
1665 normx = x2 * length;
1666 normy = y2 * length;
1667 return Position(start.
x() + normx, start.
y() + normy);
1677 if (ad_radius > 0) {
1684 normX = normX * cos(ad_hdg) + normY * sin(ad_hdg);
1685 normY = tmpX * sin(ad_hdg) + normY * cos(ad_hdg);
1688 normX = turn * normY;
1689 normY = -turn * tmpX;
1691 normX = fabs(ad_radius) * normX;
1692 normY = fabs(ad_radius) * normY;
1701 double ad_r,
double ad_length) {
1702 double rotAngle = ad_length / fabs(ad_r);
1703 double vx = *ad_x - ad_centerX;
1704 double vy = *ad_y - ad_centerY;
1714 vx = vx * cos(rotAngle) + turn * vy * sin(rotAngle);
1715 vy = -1 * turn * tmpx * sin(rotAngle) + vy * cos(rotAngle);
1716 *ad_x = vx + ad_centerX;
1717 *ad_y = vy + ad_centerY;
1734 bool singleType =
true;
1735 std::vector<std::string> types;
1736 const std::vector<OpenDriveLane>& dirLanesR = lanesByDir.find(
OPENDRIVE_TAG_RIGHT)->second;
1737 for (std::vector<OpenDriveLane>::const_reverse_iterator i = dirLanesR.rbegin(); i != dirLanesR.rend(); ++i) {
1739 laneMap[(*i).id] = sumoLane++;
1740 types.push_back((*i).type);
1741 if (types.front() != types.back()) {
1746 rightLaneNumber = sumoLane;
1747 rightType = sumoLane > 0 ? (singleType ? types.front() :
joinToString(types,
"|")) :
"";
1751 const std::vector<OpenDriveLane>& dirLanesL = lanesByDir.find(
OPENDRIVE_TAG_LEFT)->second;
1752 for (std::vector<OpenDriveLane>::const_iterator i = dirLanesL.begin(); i != dirLanesL.end(); ++i) {
1754 laneMap[(*i).id] = sumoLane++;
1755 types.push_back((*i).type);
1756 if (types.front() != types.back()) {
1761 leftLaneNumber = sumoLane;
1762 leftType = sumoLane > 0 ? (singleType ? types.front() :
joinToString(types,
"|")) :
"";
1768 std::map<int, int> ret;
1769 const std::vector<OpenDriveLane>& dirLanes = lanesByDir.find(dir)->second;
1770 for (std::vector<OpenDriveLane>::const_reverse_iterator i = dirLanes.rbegin(); i != dirLanes.rend(); ++i) {
1771 std::map<int, int>::const_iterator toP = laneMap.find((*i).id);
1772 if (toP == laneMap.end()) {
1776 int to = (*toP).second;
1779 from = (*i).predecessor;
1782 std::map<int, int>::const_iterator fromP = prev.
laneMap.find(from);
1783 if (fromP != prev.
laneMap.end()) {
1784 from = (*fromP).second;
1790 if (ret.find(from) != ret.end()) {
1794 std::swap(from, to);
1813 if (i != l.
speeds.end()) {
1814 l.
speed = (*i).second;
1821 if (i != l.
speeds.end()) {
1822 l.
speed = (*i).second;
1831 std::set<double> speedChangePositions;
1834 for (std::vector<std::pair<double, double> >::const_iterator l = (*k).speeds.begin(); l != (*k).speeds.end(); ++l) {
1835 speedChangePositions.insert((*l).first);
1836 if ((*l).first == 0) {
1837 (*k).speed = (*l).second;
1842 for (std::vector<std::pair<double, double> >::const_iterator l = (*k).speeds.begin(); l != (*k).speeds.end(); ++l) {
1843 speedChangePositions.insert((*l).first);
1844 if ((*l).first == 0) {
1845 (*k).speed = (*l).second;
1850 if (speedChangePositions.size() == 0) {
1853 if (*speedChangePositions.begin() > 0) {
1854 speedChangePositions.insert(0);
1856 #ifdef DEBUG_VARIABLE_SPEED
1858 <<
" buildSpeedChanges sectionStart=" << s
1859 <<
" speedChangePositions=" <<
joinToString(speedChangePositions,
", ")
1862 for (std::set<double>::iterator i = speedChangePositions.begin(); i != speedChangePositions.end(); ++i) {
1863 if (i == speedChangePositions.begin()) {
1864 newSections.push_back(*
this);
1866 newSections.push_back(buildLaneSection(*i));
1870 for (
int i = 0; i != (int)newSections.size(); ++i) {
1872 std::map<OpenDriveXMLTag, std::vector<OpenDriveLane> >& lanesByDir = ls.
lanesByDir;
1873 for (std::map<
OpenDriveXMLTag, std::vector<OpenDriveLane> >::iterator k = lanesByDir.begin(); k != lanesByDir.end(); ++k) {
1874 std::vector<OpenDriveLane>& lanes = (*k).second;
1875 for (
int j = 0; j != (int)lanes.size(); ++j) {
1881 l.
speed = newSections[i - 1].lanesByDir[(*k).first][j].speed;
1900 for (std::vector<OpenDriveSignal>::const_iterator i = signals.begin(); i != signals.end(); ++i) {
1902 if ((*i).type ==
"301" || (*i).type ==
"306") {
1905 if ((*i).type ==
"205" ) {
2010 std::vector<double> vals;
2016 std::vector<double> vals;
2023 std::vector<double> vals;
2029 std::vector<double> vals;
2038 std::vector<double> vals;
2048 if (pRange ==
"normalized") {
2049 vals.push_back(1.0);
2050 }
else if (pRange ==
"arcLength") {
2051 vals.push_back(-1.0);
2054 vals.push_back(1.0);
2102 int orientationCode = orientation ==
"-" ? -1 : orientation ==
"+" ? 1 : 0;
2113 int orientationCode = orientation ==
"-" ? -1 : orientation ==
"+" ? 1 : 0;
2150 WRITE_ERROR(
"In laneLink-element: incoming road '" + c.fromEdge +
"' is not known.");
2166 l.width =
MAX2(l.width, a);
2168 #ifdef DEBUG_VARIABLE_WIDTHS
2175 <<
" type=" << l.type
2176 <<
" width=" << l.width
2182 <<
" entries=" << l.widthData.size()
2196 if (!unit.empty()) {
2198 if (unit ==
"km/h") {
2201 if (unit ==
"mph") {
2202 speed *= 1.609344 / 3.6;
2234 const std::string baseID = o.
id;
2249 for (
double x = 0; x <= length + NUMERICAL_EPS; x += dist) {
2251 const double a = x / length;
2252 o.
width = wStart * (1 - a) + wEnd * a;
2253 o.
t = tStart * (1 - a) + tEnd * a;
2270 size_t i = cdata.find(
"+proj");
2271 if (i != std::string::npos) {
2272 const std::string proj = cdata.substr(i);
2282 result =
new GeoConvHelper(proj, networkOffset, origBoundary, convBoundary);
2285 WRITE_ERROR(
"Could not set projection. (" + std::string(e.what()) +
")");
2289 WRITE_WARNING(
"geoReference format '" + cdata +
"' currently not supported");
2333 const std::string& elementID,
2334 const std::string& contactPoint) {
2337 if (elementType ==
"road") {
2339 }
else if (elementType ==
"junction") {
2343 if (contactPoint ==
"start") {
2345 }
else if (contactPoint ==
"end") {
2385 #ifdef DEBUG_VARIABLE_WIDTHS
2388 std::cout <<
"sanitizeWidths e=" << e->
id <<
" sections=" << e->
laneSections.size() <<
"\n";
2406 if (l.widthData.size() > 0) {
2407 auto& wd = l.widthData;
2408 const double threshold = POSITION_EPS;
2409 double maxNoShort = -std::numeric_limits<double>::max();
2411 for (
int i = 0; i < (int)wd.size(); i++) {
2412 const double wdLength = i < (int)wd.size() - 1 ? wd[i + 1].s - wd[i].s : length - seen;
2414 if (wdLength > threshold) {
2415 maxNoShort =
MAX2(maxNoShort, wd[i].a);
2418 if (maxNoShort > 0) {
2419 l.width = maxNoShort;
2428 std::vector<OpenDriveLaneSection> newSections;
2429 #ifdef DEBUG_VARIABLE_WIDTHS
2432 std::cout <<
"splitMinWidths e=" << e->
id <<
" sections=" << e->
laneSections.size() <<
"\n";
2437 std::vector<double> splitPositions;
2438 const double sectionEnd = (j + 1) == e->
laneSections.end() ? e->
length : (*(j + 1)).s;
2439 const int section = (int)(j - e->
laneSections.begin());
2440 #ifdef DEBUG_VARIABLE_WIDTHS
2442 std::cout <<
" findWidthSplit section=" << section <<
" sectionStart=" << sec.
s <<
" sectionOrigStart=" << sec.
sOrig <<
" sectionEnd=" << sectionEnd <<
"\n";
2451 newSections.push_back(sec);
2452 std::sort(splitPositions.begin(), splitPositions.end());
2454 double prevSplit = sec.
s;
2455 for (std::vector<double>::iterator it = splitPositions.begin(); it != splitPositions.end();) {
2456 if ((*it) - prevSplit < minDist || sectionEnd - (*it) < minDist) {
2458 #ifdef DEBUG_VARIABLE_WIDTHS
2460 std::cout <<
" skip close split=" << (*it) <<
" prevSplit=" << prevSplit <<
"\n";
2463 it = splitPositions.erase(it);
2464 }
else if ((*it) < sec.
s) {
2466 #ifdef DEBUG_VARIABLE_WIDTHS
2468 std::cout <<
" skip early split=" << (*it) <<
" s=" << sec.
s <<
"\n";
2471 it = splitPositions.erase(it);
2478 if (splitPositions.size() > 0) {
2479 #ifdef DEBUG_VARIABLE_WIDTHS
2481 std::cout <<
" road=" << e->
id <<
" splitMinWidths section=" << section
2482 <<
" start=" << sec.
s
2483 <<
" origStart=" << sec.
sOrig
2484 <<
" end=" << sectionEnd <<
" minDist=" << minDist
2485 <<
" splitPositions=" <<
toString(splitPositions) <<
"\n";
2488 #ifdef DEBUG_VARIABLE_WIDTHS
2490 std::cout <<
"first section...\n";
2494 for (std::vector<double>::iterator it = splitPositions.begin(); it != splitPositions.end(); ++it) {
2497 #ifdef DEBUG_VARIABLE_WIDTHS
2499 std::cout <<
"splitAt " << secNew.
s <<
"\n";
2502 newSections.push_back(secNew);
2509 double end = (it + 1) == splitPositions.end() ? sectionEnd : *(it + 1);
2521 int section,
double sectionStart,
double sectionEnd,
2522 std::vector<double>& splitPositions) {
2524 for (std::vector<OpenDriveLane>::iterator k = lanes.begin(); k != lanes.end(); ++k) {
2529 double wPrev = l.
widthData.front().computeAt(sPrev);
2531 <<
"findWidthSplit section=" << section
2532 <<
" sectionStart=" << sectionStart
2533 <<
" sectionEnd=" << sectionEnd
2535 <<
" type=" << l.
type
2536 <<
" widthEntries=" << l.
widthData.size() <<
"\n"
2540 for (std::vector<OpenDriveWidth>::iterator it_w = l.
widthData.begin(); it_w != l.
widthData.end(); ++it_w) {
2541 double sEnd = (it_w + 1) != l.
widthData.end() ? (*(it_w + 1)).s : sectionEnd - sectionStart;
2542 double w = (*it_w).computeAt(sEnd);
2545 <<
" s=" << (*it_w).s
2546 <<
" a=" << (*it_w).a <<
" b=" << (*it_w).b <<
" c=" << (*it_w).c <<
" d=" << (*it_w).d
2549 const double changeDist = fabs(
myMinWidth - wPrev);
2552 double splitPos = sPrev + (sEnd - sPrev) / fabs(w - wPrev) * changeDist;
2553 double wSplit = (*it_w).computeAt(splitPos);
2555 std::cout <<
" candidate splitPos=" << splitPos <<
" w=" << wSplit <<
"\n";
2561 splitPos -= POSITION_EPS;
2562 if (splitPos < sPrev) {
2564 std::cout <<
" aborting search splitPos=" << splitPos <<
" wSplit=" << wSplit <<
" sPrev=" << sPrev <<
" wPrev=" << wPrev <<
"\n";
2571 splitPos += POSITION_EPS;
2572 if (splitPos > sEnd) {
2574 std::cout <<
" aborting search splitPos=" << splitPos <<
" wSplit=" << wSplit <<
" sEnd=" << sEnd <<
" w=" << w <<
"\n";
2580 wSplit = (*it_w).computeAt(splitPos);
2582 std::cout <<
" refined splitPos=" << splitPos <<
" w=" << wSplit <<
"\n";
2585 splitPositions.push_back(sectionStart + splitPos);
2603 for (std::vector<OpenDriveLane>::iterator k = lanes.begin(); k != lanes.end(); ++k) {
2604 (*k).predecessor = (*k).id;
2622 for (std::vector<OpenDriveLane>::iterator k = lanes.begin(); k != lanes.end(); ++k) {
2625 #ifdef DEBUG_VARIABLE_WIDTHS
2627 <<
"recomputeWidths lane=" << l.
id
2628 <<
" type=" << l.
type
2629 <<
" start=" << start
2631 <<
" sectionStart=" << sectionStart
2632 <<
" sectionEnd=" << sectionEnd
2633 <<
" widthEntries=" << l.
widthData.size() <<
"\n"
2638 double sPrevAbs = sPrev + sectionStart;
2639 for (std::vector<OpenDriveWidth>::iterator it_w = l.
widthData.begin(); it_w != l.
widthData.end(); ++it_w) {
2640 double sEnd = (it_w + 1) != l.
widthData.end() ? (*(it_w + 1)).s : sectionEnd - sectionStart;
2641 double sEndAbs = sEnd + sectionStart;
2642 #ifdef DEBUG_VARIABLE_WIDTHS
2644 <<
" sPrev=" << sPrev <<
" sPrevAbs=" << sPrevAbs
2645 <<
" sEnd=" << sEnd <<
" sEndAbs=" << sEndAbs
2646 <<
" widthData s=" << (*it_w).s
2647 <<
" a=" << (*it_w).a
2648 <<
" b=" << (*it_w).b
2649 <<
" c=" << (*it_w).c
2650 <<
" d=" << (*it_w).d
2653 if (sPrevAbs <= start && sEndAbs >= start) {
2654 #ifdef DEBUG_VARIABLE_WIDTHS
2656 std::cout <<
" atStart=" << start <<
" pos=" << start - sectionStart <<
" w=" << (*it_w).computeAt(start - sectionStart) <<
"\n";
2659 l.
width =
MAX2(l.
width, (*it_w).computeAt(start - sectionStart));
2661 if (sPrevAbs <= end && sEndAbs >= end) {
2662 #ifdef DEBUG_VARIABLE_WIDTHS
2664 std::cout <<
" atEnd=" << end <<
" pos=" << end - sectionStart <<
" w=" << (*it_w).computeAt(end - sectionStart) <<
"\n";
2669 if (start <= sPrevAbs && end >= sPrevAbs) {
2670 #ifdef DEBUG_VARIABLE_WIDTHS
2672 std::cout <<
" atSPrev=" << sPrev <<
" w=" << (*it_w).computeAt(sPrev) <<
"\n";
2677 if (start <= sEndAbs && end >= sEndAbs) {
2678 #ifdef DEBUG_VARIABLE_WIDTHS
2680 std::cout <<
" atSEnd=" << sEnd <<
" w=" << (*it_w).computeAt(sEnd) <<
"\n";
2685 #ifdef DEBUG_VARIABLE_WIDTHS
2687 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.
static GeoConvHelper & getLoaded()
the coordinate transformation that was loaded fron an input file
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
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
bool addLane2LaneConnection(int fromLane, NBEdge *dest, int toLane, Lane2LaneInfoType type, bool mayUseSameDestination=false, bool mayDefinitelyPass=false, KeepClear keepClear=KEEPCLEAR_UNSPECIFIED, double contPos=UNSPECIFIED_CONTPOS, double visibility=UNSPECIFIED_VISIBILITY_DISTANCE, double speed=UNSPECIFIED_SPEED, double length=myDefaultConnectionLength, const PositionVector &customShape=PositionVector::EMPTY, const bool uncontrolled=UNSPECIFIED_CONNECTION_UNCONTROLLED, SVCPermissions=SVC_UNSPECIFIED, bool postProcess=false)
Adds a connection between the specified this edge's lane and an approached one.
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)
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 buildConnectionsToOuter(const Connection &c, const std::map< std::string, OpenDriveEdge * > &innerEdges, std::vector< Connection > &into, std::set< Connection > &seen)
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.
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 >())
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 double posLat=0.)
A point in 2D or 3D with translation and scaling methods.
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 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)
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.
void removeDoublePoints(double minDist=POSITION_EPS, bool assertLength=false)
Removes positions if too near.
int insertAtClosest(const Position &p, bool interpolateZ)
inserts p between the two closest positions
int indexOfClosest(const Position &p) const
index of the closest position to p
void push_back_noDoublePos(const Position &p)
insert in back a non double position
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.
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