117 importer.
load(oc, nb);
129 delete myEdge.second;
133 delete myPlatformShape.second;
139 if (!oc.
isSet(
"osm-files")) {
142 const std::vector<std::string> files = oc.
getStringVector(
"osm-files");
143 std::vector<SUMOSAXReader*> readers;
166 for (
const std::string& file : files) {
175 if (!readers.back()->parseFirst(file) || !readers.back()->parseSection(
SUMO_TAG_NODE) ||
188 for (
const std::string& file : files) {
190 readers[idx]->setHandler(edgesHandler);
195 readers[idx] =
nullptr;
202 if (!oc.
getBool(
"osm.skip-duplicates-check")) {
206 std::set<const Edge*, CompareEdges> dupsFinder;
208 if (dupsFinder.count(it->second) > 0) {
213 dupsFinder.insert(it->second);
218 if (numRemoved > 0) {
227 std::map<long long int, int> nodeUsage;
229 for (
const auto& edgeIt :
myEdges) {
230 assert(edgeIt.second->myCurrentIsRoad);
231 for (
const long long int node : edgeIt.second->myCurrentNodes) {
237 if (nodesIt.second->tlsControlled || nodesIt.second->railwaySignal !=
SIGNAL_NONE || (nodesIt.second->pedestrianCrossing &&
myImportCrossings) ) {
240 nodeUsage[nodesIt.first]++;
249 for (
const auto& edgeIt :
myEdges) {
250 Edge*
const e = edgeIt.second;
264 NBNode* currentFrom = first;
266 std::vector<long long int> passed;
268 passed.push_back(*j);
271 running =
insertEdge(e, running, currentFrom, currentTo, passed, nb, first, last);
272 currentFrom = currentTo;
274 passed.push_back(*j);
280 insertEdge(e, running, currentFrom, last, passed, nb, first, last);
283 WRITE_MESSAGEF(
TL(
"Skipped applying OSM placement on % edge(s): % due to non-explicit one-way and % due to opposite-direction auxiliary edges."),
299 for (
auto item : nodeUsage) {
305 size_t incomingEdgesNo = incomingEdges.size();
306 size_t outgoingEdgesNo = outgoingEdges.size();
308 for (
size_t i = 0; i < incomingEdgesNo; i++) {
316 auto const iEdge = incomingEdges[i];
320 std::string
const& iEdgeId = iEdge->getID();
321 std::size_t
const m = iEdgeId.find_first_of(
"#");
322 std::string
const& iWayId = iEdgeId.substr(0, m);
323 for (
size_t j = 0; j < outgoingEdgesNo; j++) {
324 auto const oEdge = outgoingEdges[j];
327 if (oEdge->getID().find(iWayId) != std::string::npos
329 && oEdge->getID().rfind(iWayId, 0) != 0) {
332 edgeVector.push_back(oEdge);
342 for (
size_t i = 0; i < outgoingEdgesNo; i++) {
344 auto const oEdge = outgoingEdges[i];
348 std::string
const& oEdgeId = oEdge->getID();
349 std::size_t
const m = oEdgeId.find_first_of(
"#");
350 std::string
const& iWayId = oEdgeId.substr(0, m);
351 for (
size_t j = 0; j < incomingEdgesNo; j++) {
352 auto const iEdge = incomingEdges[j];
353 if (iEdge->getID().find(iWayId) != std::string::npos
355 && iEdge->getID().rfind(iWayId, 0) != 0) {
358 edgeVector.push_back(iEdge);
372 const double layerElevation = oc.
getFloat(
"osm.layer-elevation");
373 if (layerElevation > 0) {
386 for (
const std::string& file : files) {
387 if (readers[idx] !=
nullptr) {
389 readers[idx]->setHandler(relationHandler);
399 std::set<std::string> stopNames;
401 stopNames.insert(item.second->getName());
408 WRITE_ERRORF(
"Unable to project coordinates for node '%'.", n->
id);
424 if (
node ==
nullptr) {
428 WRITE_ERRORF(
"Unable to project coordinates for junction '%'.",
id);
447 node->setParameter(
"virtual",
"true");
450 node->setParameter(
"moving-block",
"true");
459 if (!tlsc.
insert(tlDef)) {
466 node->setParameter(
"buffer_stop",
"true");
484 const std::vector<long long int>& passed,
NBNetBuilder& nb,
494 if (from ==
nullptr || to ==
nullptr) {
495 WRITE_ERRORF(
"Discarding edge '%' because the nodes could not be built.",
id);
504 assert(passed.size() >= 2);
505 if (passed.size() == 2) {
506 WRITE_WARNINGF(
TL(
"Discarding edge '%' which connects two identical nodes without geometry."),
id);
510 int intermediateIndex = (int) passed.size() / 2;
512 std::vector<long long int> part1(passed.begin(), passed.begin() + intermediateIndex + 1);
513 std::vector<long long int> part2(passed.begin() + intermediateIndex, passed.end());
514 index =
insertEdge(e, index, from, intermediate, part1, nb, first, last);
515 return insertEdge(e, index, intermediate, to, part2, nb, first, last);
517 const int newIndex = index + 1;
522 std::string routingType =
"";
530 std::vector<SumoXMLAttr> defaults;
533 extra = extra & ~SVC_BUS;
535 SVCPermissions permissions = (defaultPermissions & ~extraDis) | extra;
541 defaultsToOneWay =
true;
543 if (defaultPermissions ==
SVC_SHIP) {
545 permissions = defaultPermissions;
548 defaultsToOneWay =
false;
556 double distanceStart =
myOSMNodes[passed.front()]->positionMeters;
557 double distanceEnd =
myOSMNodes[passed.back()]->positionMeters;
558 const bool useDistance = distanceStart != std::numeric_limits<double>::max() && distanceEnd != std::numeric_limits<double>::max();
561 if (distanceStart < distanceEnd) {
581 std::vector<std::shared_ptr<NBPTStop> > ptStops;
582 for (
long long i : passed) {
586 std::shared_ptr<NBPTStop> existingPtStop = sc.
get(
toString(n->
id));
587 if (existingPtStop !=
nullptr) {
588 existingPtStop->registerAdditionalEdge(
toString(e->
id), id);
592 WRITE_ERRORF(
"Unable to project coordinates for node '%'.", n->
id);
596 sc.
insert(ptStops.back());
603 shape.push_back(pos);
623 WRITE_ERRORF(
"Unable to project coordinates for edge '%'.",
id);
629 if (streetName == e->
ref) {
646 const std::string& onewayBike = e->
myExtraTags[
"oneway:bicycle"];
647 if (onewayBike ==
"false" || onewayBike ==
"no" || onewayBike ==
"0") {
658 bool addForward =
true;
659 bool addBackward =
true;
675 if (addBackward && (onewayBike ==
"true" || onewayBike ==
"yes" || onewayBike ==
"1")) {
678 if (addForward && (onewayBike ==
"reverse" || onewayBike ==
"-1")) {
681 if (!addBackward && (onewayBike ==
"false" || onewayBike ==
"no" || onewayBike ==
"0")) {
687 if (addForward && !addBackward) {
689 }
else if (!addForward && addBackward) {
697 numLanesForward = (int) std::ceil(e->
myNoLanes / 2.0);
699 numLanesBackward = e->
myNoLanes - numLanesForward;
702 numLanesForward =
MAX2(1, numLanesForward);
703 numLanesBackward =
MAX2(1, numLanesBackward);
714 numLanesForward =
MAX2(numLanesForward, 2);
720 numLanesBackward =
MAX2(numLanesForward, 2);
735 numLanesBackward = 1;
738 const int taggedLanes = (addForward ? numLanesForward : 0) + (addBackward ? numLanesBackward : 0);
742 forwardWidth = e->
myWidth / taggedLanes;
743 backwardWidth = forwardWidth;
752 double speedBackward = speed;
757 if (speed <= 0 || speedBackward <= 0) {
761 if (e->
myNoLanes == 1 && addForward && addBackward) {
774 routingType =
"narrow";
780 if (!addForward && (cyclewayType &
WAY_FORWARD) != 0) {
783 forwardWidth = bikeLaneWidth;
788 if (!addBackward && (cyclewayType &
WAY_BACKWARD) != 0) {
791 backwardWidth = bikeLaneWidth;
792 numLanesBackward = 1;
806 if (!addForward && (sidewalkType &
WAY_FORWARD) != 0) {
813 }
else if (addSidewalk && addForward && (sidewalkType &
WAY_BOTH) == 0
814 && numLanesForward == 1 && numLanesBackward <= 1
821 if (!addBackward && (sidewalkType &
WAY_BACKWARD) != 0) {
825 numLanesBackward = 1;
828 }
else if (addSidewalk && addBackward && (sidewalkType &
WAY_BOTH) == 0
829 && numLanesBackward == 1 && numLanesForward <= 1
838 bool applyPlacement =
false;
839 double placementOffset = 0;
841 if (!explicitOneWay) {
845 }
else if (!(addForward && !addBackward)) {
849 }
else if (numLanesForward <= 0) {
851 WRITE_WARNINGF(
TL(
"Ignoring placement for edge '%' because lane count is invalid."),
id);
856 std::vector<double> laneWidths((
size_t)numLanesForward, defaultPlacementWidth);
859 for (
int i = 0; i < numLanesForward; ++i) {
866 WRITE_WARNINGF(
TL(
"Ignoring placement for edge '%' because lane index '%' is out of range [1, %]."),
871 double leftOffset = 0;
872 for (
int i = 0; i < laneIndex; ++i) {
873 leftOffset += laneWidths[(size_t)i];
875 double placementRefOffset = leftOffset;
877 placementRefOffset += laneWidths[(size_t)laneIndex];
879 placementRefOffset += laneWidths[(size_t)laneIndex] / 2.;
881 double totalWidth = 0;
882 for (
double laneWidth : laneWidths) {
883 totalWidth += laneWidth;
885 placementOffset = totalWidth / 2. - placementRefOffset;
886 applyPlacement =
true;
890 if (applyPlacement && fabs(placementOffset) > POSITION_EPS) {
895 WRITE_WARNINGF(
TL(
"Ignoring placement for edge '%' because offset shape computation failed."),
id);
897 applyPlacement =
false;
903 const int offsetFactor = lefthand ? -1 : 1;
917 if (applyPlacement) {
921 if (defaults.size() > 0) {
926 const std::string reverseID =
"-" + id;
929 assert(numLanesForward > 0);
933 if (markOSMDirection) {
970 if ((
int)nbe->
getLanes().size() != numForwardLanesFromWidthKey) {
971 WRITE_WARNINGF(
TL(
"Forward lanes count for edge '%' ('%') is not matching the number of lanes defined in width:lanes:forward key ('%'). Using default width values."),
972 id, nbe->
getLanes().size(), numForwardLanesFromWidthKey);
974 for (
int i = 0; i < numForwardLanesFromWidthKey; i++) {
976 const int laneIndex = lefthand ? i : numForwardLanesFromWidthKey - i - 1;
993 assert(numLanesBackward > 0);
997 if (markOSMDirection) {
1028 if ((
int)nbe->
getLanes().size() != numBackwardLanesFromWidthKey) {
1029 WRITE_WARNINGF(
TL(
"Backward lanes count for edge '%' ('%') is not matching the number of lanes defined in width:lanes:backward key ('%'). Using default width values."),
1030 id, nbe->
getLanes().size(), numBackwardLanesFromWidthKey);
1032 for (
int i = 0; i < numBackwardLanesFromWidthKey; i++) {
1034 const int laneIndex = lefthand ? i : numBackwardLanesFromWidthKey - i - 1;
1085 std::map<NBNode*, std::vector<std::pair<double, double> > > layerForces;
1088 std::set<NBNode*> knownElevation;
1089 for (
auto& myEdge :
myEdges) {
1090 Edge* e = myEdge.second;
1094 if (
node !=
nullptr) {
1095 knownElevation.insert(
node);
1096 layerForces[
node].emplace_back(e->
myLayer * layerElevation, POSITION_EPS);
1101#ifdef DEBUG_LAYER_ELEVATION
1102 std::cout <<
"known elevations:\n";
1103 for (std::set<NBNode*>::iterator it = knownElevation.begin(); it != knownElevation.end(); ++it) {
1104 const std::vector<std::pair<double, double> >& primaryLayers = layerForces[*it];
1105 std::cout <<
" node=" << (*it)->
getID() <<
" ele=";
1106 for (std::vector<std::pair<double, double> >::const_iterator it_ele = primaryLayers.begin(); it_ele != primaryLayers.end(); ++it_ele) {
1107 std::cout << it_ele->first <<
" ";
1115 std::map<NBNode*, double> knownEleMax;
1116 for (
auto it : knownElevation) {
1117 double eleMax = -std::numeric_limits<double>::max();
1118 const std::vector<std::pair<double, double> >& primaryLayers = layerForces[it];
1119 for (
const auto& primaryLayer : primaryLayers) {
1120 eleMax =
MAX2(eleMax, primaryLayer.first);
1122 knownEleMax[it] = eleMax;
1125 bool changed =
true;
1128 for (
auto it = knownElevation.begin(); it != knownElevation.end(); ++it) {
1131 / gradeThreshold * 3,
1133 for (
auto& neighbor : neighbors) {
1134 if (knownElevation.count(neighbor.first) != 0) {
1135 const double grade = fabs(knownEleMax[*it] - knownEleMax[neighbor.first])
1136 /
MAX2(POSITION_EPS, neighbor.second.first);
1137#ifdef DEBUG_LAYER_ELEVATION
1138 std::cout <<
" grade at node=" << (*it)->getID() <<
" ele=" << knownEleMax[*it] <<
" neigh=" << it_neigh->first->getID() <<
" neighEle=" << knownEleMax[it_neigh->first] <<
" grade=" << grade <<
" dist=" << it_neigh->second.first <<
" speed=" << it_neigh->second.second <<
"\n";
1140 if (grade > gradeThreshold * 50 / 3.6 / neighbor.second.second) {
1142 const double eleMax =
MAX2(knownEleMax[*it], knownEleMax[neighbor.first]);
1143 if (knownEleMax[*it] < eleMax) {
1144 knownEleMax[*it] = eleMax;
1146 knownEleMax[neighbor.first] = eleMax;
1156 std::set<NBNode*> unknownElevation;
1157 for (
auto it = knownElevation.begin(); it != knownElevation.end(); ++it) {
1158 const double eleMax = knownEleMax[*it];
1159 const double maxDist = fabs(eleMax) * 100 / layerElevation;
1160 std::map<NBNode*, std::pair<double, double> > neighbors =
getNeighboringNodes(*it, maxDist, knownElevation);
1161 for (
auto& neighbor : neighbors) {
1162 if (knownElevation.count(neighbor.first) == 0) {
1163 unknownElevation.insert(neighbor.first);
1164 layerForces[neighbor.first].emplace_back(eleMax, neighbor.second.first);
1170 for (
auto it = unknownElevation.begin(); it != unknownElevation.end(); ++it) {
1171 double eleMax = -std::numeric_limits<double>::max();
1172 const std::vector<std::pair<double, double> >& primaryLayers = layerForces[*it];
1173 for (
const auto& primaryLayer : primaryLayers) {
1174 eleMax =
MAX2(eleMax, primaryLayer.first);
1176 const double maxDist = fabs(eleMax) * 100 / layerElevation;
1177 std::map<NBNode*, std::pair<double, double> > neighbors =
getNeighboringNodes(*it, maxDist, knownElevation);
1178 for (
auto& neighbor : neighbors) {
1179 if (knownElevation.count(neighbor.first) == 0 && unknownElevation.count(neighbor.first) == 0) {
1180 layerForces[*it].emplace_back(0, neighbor.second.first);
1185#ifdef DEBUG_LAYER_ELEVATION
1186 std::cout <<
"summation of forces\n";
1188 std::map<NBNode*, double> nodeElevation;
1189 for (
auto& layerForce : layerForces) {
1190 const std::vector<std::pair<double, double> >& forces = layerForce.second;
1191 if (knownElevation.count(layerForce.first) != 0) {
1199#ifdef DEBUG_LAYER_ELEVATION
1200 std::cout <<
" node=" << it->first->getID() <<
" knownElevation=" << knownEleMax[it->first] <<
"\n";
1202 nodeElevation[layerForce.first] = knownEleMax[layerForce.first];
1203 }
else if (forces.size() == 1) {
1204 nodeElevation[layerForce.first] = forces.front().first;
1208 for (
const auto& force : forces) {
1209 distSum += force.second;
1211 double weightSum = 0;
1212 double elevation = 0;
1213#ifdef DEBUG_LAYER_ELEVATION
1214 std::cout <<
" node=" << it->first->getID() <<
" distSum=" << distSum <<
"\n";
1216 for (
const auto& force : forces) {
1217 const double weight = (distSum - force.second) / distSum;
1219 elevation += force.first *
weight;
1221#ifdef DEBUG_LAYER_ELEVATION
1222 std::cout <<
" force=" << it_force->first <<
" dist=" << it_force->second <<
" weight=" <<
weight <<
" ele=" << elevation <<
"\n";
1225 nodeElevation[layerForce.first] = elevation / weightSum;
1228#ifdef DEBUG_LAYER_ELEVATION
1229 std::cout <<
"final elevations:\n";
1230 for (std::map<NBNode*, double>::iterator it = nodeElevation.begin(); it != nodeElevation.end(); ++it) {
1231 std::cout <<
" node=" << (it->first)->getID() <<
" ele=" << it->second <<
"\n";
1235 for (
auto& it : nodeElevation) {
1241 for (
const auto& it : ec) {
1242 NBEdge* edge = it.second;
1244 const double length = geom.
length2D();
1245 const double zFrom = nodeElevation[edge->
getFromNode()];
1246 const double zTo = nodeElevation[edge->
getToNode()];
1251 for (
auto it_pos = geom.begin(); it_pos != geom.end(); ++it_pos) {
1252 if (it_pos != geom.begin()) {
1253 dist += (*it_pos).distanceTo2D(*(it_pos - 1));
1255 newGeom.push_back((*it_pos) +
Position(0, 0, zFrom + (zTo - zFrom) * dist / length));
1261std::map<NBNode*, std::pair<double, double> >
1263 std::map<NBNode*, std::pair<double, double> > result;
1264 std::set<NBNode*> visited;
1265 std::vector<NBNode*> open;
1266 open.push_back(
node);
1267 result[
node] = std::make_pair(0, 0);
1268 while (!open.empty()) {
1271 if (visited.count(n) != 0) {
1276 for (
auto e : edges) {
1279 s = e->getFromNode();
1283 const double dist = result[n].first + e->getGeometry().length2D();
1284 const double speed =
MAX2(e->getSpeed(), result[n].second);
1285 if (result.count(s) == 0) {
1286 result[s] = std::make_pair(dist, speed);
1288 result[s] = std::make_pair(
MIN2(dist, result[s].first),
MAX2(speed, result[s].second));
1290 if (dist < maxDist && knownElevation.count(s) == 0) {
1302 if (tc.
knows(type)) {
1313 std::vector<std::string> types;
1315 std::string t = tok.
next();
1317 if (std::find(types.begin(), types.end(), t) == types.end()) {
1320 }
else if (tok.
size() > 1) {
1322 WRITE_WARNINGF(
TL(
"Discarding unknown compound '%' in type '%' (first occurrence for edge '%')."), t, type,
id);
1326 if (types.empty()) {
1328 WRITE_WARNINGF(
TL(
"Discarding unusable type '%' (first occurrence for edge '%')."), type,
id);
1334 if (tc.
knows(newType)) {
1342 double maxSpeed = 0;
1347 bool defaultIsOneWay =
true;
1350 bool discard =
true;
1351 bool hadDiscard =
false;
1352 for (
auto& type2 : types) {
1369 if (hadDiscard && permissions == 0) {
1373 WRITE_WARNINGF(
TL(
"Discarding compound type '%' (first occurrence for edge '%')."), newType,
id);
1388 WRITE_MESSAGEF(
TL(
"Adding new type '%' (first occurrence for edge '%')."), type,
id);
1389 tc.
insertEdgeType(newType, numLanes, maxSpeed, prio, permissions, spreadType, width,
1390 defaultIsOneWay, sidewalkWidth, bikelaneWidth, 0, 0, 0);
1391 for (
auto& type3 : types) {
1406 std::vector<NIOSMNode*> nodes;
1407 std::vector<double> usablePositions;
1408 std::vector<int> usableIndex;
1412 if (
node->positionMeters != std::numeric_limits<double>::max()) {
1413 usablePositions.push_back(
node->positionMeters);
1414 usableIndex.push_back((
int)nodes.size());
1416 nodes.push_back(
node);
1418 if (usablePositions.size() == 0) {
1422 if (usablePositions.size() == 1) {
1423 WRITE_WARNINGF(
TL(
"Ambiguous railway kilometrage direction for way '%' (assuming forward)"),
id);
1425 forward = usablePositions.front() < usablePositions.back();
1428 for (
int i = 1; i < (int)usablePositions.size(); i++) {
1429 if ((usablePositions[i - 1] < usablePositions[i]) !=
forward) {
1430 WRITE_WARNINGF(
TL(
"Inconsistent railway kilometrage direction for way '%': % (skipping)"),
id,
toString(usablePositions));
1434 if (nodes.size() > usablePositions.size()) {
1443 double sign =
forward ? 1 : -1;
1445 for (
int i = usableIndex.front() - 1; i >= 0; i--) {
1446 nodes[i]->positionMeters = nodes[i + 1]->positionMeters - sign * shape[i].distanceTo2D(shape[i + 1]);
1449 for (
int i = usableIndex.front() + 1; i < (int)nodes.size(); i++) {
1450 if (nodes[i]->positionMeters == std::numeric_limits<double>::max()) {
1451 nodes[i]->positionMeters = nodes[i - 1]->positionMeters + sign * shape[i].distanceTo2D(shape[i - 1]);
1467 if (
node->position.size() > 0) {
1478 return std::numeric_limits<double>::max();
1484 if (type ==
"train") {
1486 }
else if (type ==
"subway") {
1488 }
else if (type ==
"aerialway") {
1490 }
else if (type ==
"light_rail" || type ==
"monorail") {
1492 }
else if (type ==
"share_taxi") {
1494 }
else if (type ==
"minibus") {
1496 }
else if (type ==
"trolleybus") {
1501 std::string stop =
"";
1504 }
else if (result ==
SVC_BUS) {
1519 bool multiLane = changeProhibition > 3;
1521 for (
int lane = 0; changeProhibition > 0 && lane < e->
getNumLanes(); lane++) {
1522 int code = changeProhibition % 4;
1527 changeProhibition = changeProhibition >> 2;
1541 for (
int lane = 0; lane < numLanes; lane++) {
1543 const int i = lefthand ? lane : numLanes - 1 - lane;
1548 if (i < (
int)designated.size() && designated[i]) {
1560 if (signs.empty()) {
1561 signs.insert(signs.begin(), signs2.begin(), signs2.end());
1563 for (
int i = 0; i < (int)
MIN2(signs.size(), signs2.size()); i++) {
1564 signs[i] |= signs2[i];
1576 for (
int i = 0; i < (int)turnSigns.size(); i++) {
1593 std::set<NIOSMNode*, CompareNodes>& uniqueNodes,
const OptionsCont& oc) :
1596 myCurrentNode(nullptr),
1598 myHierarchyLevel(0),
1599 myUniqueNodes(uniqueNodes),
1600 myImportElevation(oc.getBool(
"osm.elevation")),
1601 myDuplicateNodes(0),
1605 if (kv ==
"DEFAULT") {
1608 }
else if (kv ==
"ALL") {
1625 if (myHierarchyLevel != 2) {
1626 WRITE_ERROR(
"Node element on wrong XML hierarchy level (id='" + myLastNodeID +
1627 "', level='" +
toString(myHierarchyLevel) +
"').");
1631 if (action ==
"delete" || !ok) {
1637 myCurrentNode =
nullptr;
1638 const auto insertionIt = myToFill.lower_bound(
id);
1639 if (insertionIt == myToFill.end() || insertionIt->first !=
id) {
1641 const double tlon = attrs.
get<
double>(
SUMO_ATTR_LON, myLastNodeID.c_str(), ok);
1642 const double tlat = attrs.
get<
double>(
SUMO_ATTR_LAT, myLastNodeID.c_str(), ok);
1646 myCurrentNode =
new NIOSMNode(
id, tlon, tlat);
1651 delete myCurrentNode;
1652 myCurrentNode = *similarNode;
1655 myToFill.emplace_hint(insertionIt,
id, myCurrentNode);
1658 WRITE_ERROR(
TL(
"Attribute 'id' in the definition of a node is not of type long long int."));
1662 if (element ==
SUMO_TAG_TAG && myCurrentNode !=
nullptr) {
1663 if (myHierarchyLevel != 3) {
1664 WRITE_ERROR(
TL(
"Tag element on wrong XML hierarchy level."));
1668 const std::string& key = attrs.
get<std::string>(
SUMO_ATTR_K, myLastNodeID.c_str(), ok,
false);
1670 if (key ==
"highway" || key ==
"ele" || key ==
"crossing" || key ==
"railway" || key ==
"public_transport"
1671 || key ==
"name" || key ==
"train" || key ==
"bus" || key ==
"tram" || key ==
"light_rail" || key ==
"subway" || key ==
"station" || key ==
"noexit"
1672 || key ==
"crossing:barrier"
1673 || key ==
"crossing:light"
1674 || key ==
"railway:ref"
1678 const std::string& value = attrs.
get<std::string>(
SUMO_ATTR_V, myLastNodeID.c_str(), ok,
false);
1679 if (key ==
"highway" && value.find(
"traffic_signal") != std::string::npos) {
1680 myCurrentNode->tlsControlled =
true;
1681 }
else if (key ==
"crossing" && value.find(
"traffic_signals") != std::string::npos) {
1682 myCurrentNode->tlsControlled =
true;
1683 }
else if (key ==
"highway" && value.find(
"crossing") != std::string::npos) {
1684 myCurrentNode->pedestrianCrossing =
true;
1685 }
else if ((key ==
"noexit" && value ==
"yes")
1686 || (key ==
"railway" && value ==
"buffer_stop")) {
1687 myCurrentNode->railwayBufferStop =
true;
1688 }
else if (key ==
"railway" && value.find(
"crossing") != std::string::npos) {
1689 myCurrentNode->railwayCrossing =
true;
1690 }
else if (key ==
"crossing:barrier") {
1691 myCurrentNode->setParameter(
"crossing:barrier", value);
1692 }
else if (key ==
"crossing:light") {
1693 myCurrentNode->setParameter(
"crossing:light", value);
1694 }
else if (key ==
"railway:signal:direction") {
1695 if (value ==
"both") {
1696 myCurrentNode->myRailDirection =
WAY_BOTH;
1697 }
else if (value ==
"backward") {
1699 }
else if (value ==
"forward") {
1703 std::string kv = key +
"=" + value;
1704 std::string kglob = key +
"=";
1705 if (key ==
"railway:signal:train_protection" && value ==
"DE-ESO:ne14") {
1707 }
else if (myCurrentNode->railwaySignal ==
SIGNAL_NONE) {
1708 if ((std::find(myRailSignalRules.begin(), myRailSignalRules.end(), kv) != myRailSignalRules.end())
1709 || (std::find(myRailSignalRules.begin(), myRailSignalRules.end(), kglob) != myRailSignalRules.end())) {
1713 }
else if (
StringUtils::startsWith(key,
"railway:position") && value.size() > myCurrentNode->position.size()) {
1715 myCurrentNode->position = value;
1716 }
else if ((key ==
"public_transport" && value ==
"stop_position") ||
1717 (key ==
"highway" && value ==
"bus_stop")) {
1718 myCurrentNode->ptStopPosition =
true;
1719 if (myCurrentNode->ptStopLength == 0) {
1721 myCurrentNode->ptStopLength = myOptionsCont.getFloat(
"osm.stop-output.length");
1723 }
else if (key ==
"name") {
1724 myCurrentNode->name = value;
1725 }
else if (myImportElevation && key ==
"ele") {
1728 if (std::isnan(elevation)) {
1729 WRITE_WARNINGF(
TL(
"Value of key '%' is invalid ('%') in node '%'."), key, value, myLastNodeID);
1731 myCurrentNode->ele = elevation;
1734 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in node '%'."), key, value, myLastNodeID);
1736 }
else if (key ==
"station") {
1739 }
else if (key ==
"railway:ref") {
1740 myRailwayRef = value;
1747 const std::string info =
"node=" +
toString(myCurrentNode->id) +
", k=" + key;
1748 myCurrentNode->setParameter(key, attrs.
get<std::string>(
SUMO_ATTR_V, info.c_str(), ok,
false));
1757 if (myIsStation && myRailwayRef !=
"") {
1758 myCurrentNode->setParameter(
"railway:ref", myRailwayRef);
1760 myCurrentNode =
nullptr;
1761 myIsStation =
false;
1772 const std::map<long long int, NIOSMNode*>& osmNodes,
1773 std::map<long long int, Edge*>& toFill, std::map<long long int, Edge*>& platformShapes,
1778 myPlatformShapesMap(platformShapes),
1876 const long long int id = attrs.
get<
long long int>(
SUMO_ATTR_ID,
nullptr, ok);
1878 if (action ==
"delete" || !ok) {
1879 myCurrentEdge =
nullptr;
1882 myCurrentEdge =
new Edge(
id);
1885 if (element ==
SUMO_TAG_ND && myCurrentEdge !=
nullptr) {
1895 ref =
node->second->id;
1896 if (myCurrentEdge->myCurrentNodes.empty() ||
1897 myCurrentEdge->myCurrentNodes.back() != ref) {
1898 myCurrentEdge->myCurrentNodes.push_back(ref);
1903 if (element ==
SUMO_TAG_TAG && myCurrentEdge !=
nullptr) {
1908 const std::string buswaySpec = key.substr(7);
1910 if (buswaySpec ==
"right") {
1912 }
else if (buswaySpec ==
"left") {
1914 }
else if (buswaySpec ==
"both") {
1915 myCurrentEdge->myBuswayType = (
WayType)(myCurrentEdge->myBuswayType |
WAY_BOTH);
1921 const std::string info =
"way=" +
toString(myCurrentEdge->id) +
", k=" + key;
1922 myCurrentEdge->setParameter(key, attrs.
get<std::string>(
SUMO_ATTR_V, info.c_str(), ok,
false));
1927 && key !=
"maxspeed" && key !=
"maxspeed:type"
1928 && key !=
"zone:maxspeed"
1929 && key !=
"maxspeed:forward" && key !=
"maxspeed:backward"
1930 && key !=
"junction" && key !=
"name" && key !=
"tracks" && key !=
"layer"
1935 && key !=
"highspeed"
1939 && key !=
"postal_code"
1940 && key !=
"railway:preferred_direction"
1941 && key !=
"railway:bidirectional"
1942 && key !=
"railway:track_ref"
1945 && key !=
"emergency"
1947 && key !=
"electrified"
1948 && key !=
"segregated"
1953 && key !=
"oneway:bicycle"
1954 && key !=
"oneway:bus"
1955 && key !=
"oneway:psv"
1956 && key !=
"placement"
1957 && key !=
"bus:lanes"
1958 && key !=
"bus:lanes:forward"
1959 && key !=
"bus:lanes:backward"
1960 && key !=
"psv:lanes"
1961 && key !=
"psv:lanes:forward"
1962 && key !=
"psv:lanes:backward"
1963 && key !=
"bicycle:lanes"
1964 && key !=
"bicycle:lanes:forward"
1965 && key !=
"bicycle:lanes:backward"
1968 && key !=
"public_transport") {
1971 const std::string value = attrs.
get<std::string>(
SUMO_ATTR_V,
toString(myCurrentEdge->id).c_str(), ok,
false);
1975 || key ==
"aeroway" || key ==
"aerialway" || key ==
"usage" || key ==
"service") {
1977 if (key !=
"highway" || myTypeCont.knows(key +
"." + value)) {
1978 myCurrentEdge->myCurrentIsRoad =
true;
1981 if (key ==
"cycleway") {
1982 if (value ==
"no" || value ==
"none" || value ==
"separate") {
1983 myCurrentEdge->myCyclewayType =
WAY_NONE;
1984 }
else if (value ==
"both") {
1985 myCurrentEdge->myCyclewayType =
WAY_BOTH;
1986 }
else if (value ==
"right") {
1988 }
else if (value ==
"left") {
1990 }
else if (value ==
"opposite_track") {
1992 }
else if (value ==
"opposite_lane") {
1994 }
else if (value ==
"opposite") {
1999 if (key ==
"cycleway:left") {
2000 if (myCurrentEdge->myCyclewayType ==
WAY_UNKNOWN) {
2001 myCurrentEdge->myCyclewayType =
WAY_NONE;
2003 if (value ==
"yes" || value ==
"lane" || value ==
"track") {
2008 if (key ==
"cycleway:right") {
2009 if (myCurrentEdge->myCyclewayType ==
WAY_UNKNOWN) {
2010 myCurrentEdge->myCyclewayType =
WAY_NONE;
2012 if (value ==
"yes" || value ==
"lane" || value ==
"track") {
2013 myCurrentEdge->myCyclewayType = (
WayType)(myCurrentEdge->myCyclewayType |
WAY_FORWARD);
2017 if (key ==
"cycleway:both") {
2018 if (myCurrentEdge->myCyclewayType ==
WAY_UNKNOWN) {
2019 if (value ==
"no" || value ==
"none" || value ==
"separate") {
2020 myCurrentEdge->myCyclewayType =
WAY_NONE;
2022 if (value ==
"yes" || value ==
"lane" || value ==
"track") {
2023 myCurrentEdge->myCyclewayType =
WAY_BOTH;
2028 if (key ==
"cycleway" && value !=
"lane" && value !=
"track" && value !=
"opposite_track" && value !=
"opposite_lane") {
2037 if (key ==
"sidewalk") {
2038 if (value ==
"no" || value ==
"none" || value ==
"separate") {
2039 myCurrentEdge->mySidewalkType =
WAY_NONE;
2040 if (value ==
"separate") {
2043 }
else if (value ==
"both" || value ==
"yes") {
2044 myCurrentEdge->mySidewalkType =
WAY_BOTH;
2045 }
else if (value ==
"right") {
2047 }
else if (value ==
"left") {
2051 if (key ==
"sidewalk:left") {
2052 if (myCurrentEdge->mySidewalkType ==
WAY_UNKNOWN) {
2053 myCurrentEdge->mySidewalkType =
WAY_NONE;
2055 if (value ==
"yes") {
2059 if (key ==
"sidewalk:right") {
2060 if (myCurrentEdge->mySidewalkType ==
WAY_UNKNOWN) {
2061 myCurrentEdge->mySidewalkType =
WAY_NONE;
2063 if (value ==
"yes") {
2064 myCurrentEdge->mySidewalkType = (
WayType)(myCurrentEdge->mySidewalkType |
WAY_FORWARD);
2066 if (value ==
"separate") {
2070 if (key ==
"sidewalk:both") {
2071 if (myCurrentEdge->mySidewalkType ==
WAY_UNKNOWN) {
2072 if (value ==
"no" || value ==
"none" || value ==
"separate") {
2073 myCurrentEdge->mySidewalkType =
WAY_NONE;
2074 if (value ==
"separate") {
2078 if (value ==
"yes") {
2079 myCurrentEdge->mySidewalkType =
WAY_BOTH;
2088 if (key ==
"busway") {
2089 if (value ==
"no") {
2092 if (value ==
"opposite_track") {
2094 }
else if (value ==
"opposite_lane") {
2100 std::string singleTypeID = key +
"." + value;
2101 if (key ==
"highspeed") {
2102 if (value ==
"no") {
2105 singleTypeID =
"railway.highspeed";
2107 addType(singleTypeID);
2109 }
else if (key ==
"bus" || key ==
"psv") {
2113 myCurrentEdge->myExtraAllowed |=
SVC_BUS;
2116 myCurrentEdge->myExtraDisallowed |=
SVC_BUS;
2119 myCurrentEdge->myExtraAllowed |=
SVC_BUS;
2122 }
else if (key ==
"emergency") {
2130 }
else if (key ==
"access") {
2131 if (value ==
"no") {
2137 std::vector<double> widthLanes;
2138 for (std::string width : values) {
2140 widthLanes.push_back(parsedWidth);
2143 if (key ==
"width:lanes" || key ==
"width:lanes:forward") {
2144 myCurrentEdge->myWidthLanesForward = widthLanes;
2145 }
else if (key ==
"width:lanes:backward") {
2146 myCurrentEdge->myWidthLanesBackward = widthLanes;
2148 WRITE_WARNINGF(
TL(
"Using default lane width for edge '%' as key '%' could not be parsed."),
toString(myCurrentEdge->id), key);
2151 WRITE_WARNINGF(
TL(
"Using default lane width for edge '%' as value '%' could not be parsed."),
toString(myCurrentEdge->id), value);
2153 }
else if (key ==
"width") {
2157 WRITE_WARNINGF(
TL(
"Using default width for edge '%' as value '%' could not be parsed."),
toString(myCurrentEdge->id), value);
2159 }
else if (key ==
"foot") {
2160 if (value ==
"use_sidepath" || value ==
"no") {
2162 }
else if (value ==
"yes" || value ==
"designated" || value ==
"permissive") {
2165 }
else if (key ==
"bicycle") {
2166 if (value ==
"use_sidepath" || value ==
"no") {
2168 }
else if (value ==
"yes" || value ==
"designated" || value ==
"permissive") {
2171 }
else if (key ==
"oneway:bicycle") {
2172 myCurrentEdge->myExtraTags[
"oneway:bicycle"] = value;
2173 }
else if (key ==
"oneway:bus" || key ==
"oneway:psv") {
2174 if (value ==
"no") {
2178 }
else if (key ==
"placement") {
2179 if (!interpretPlacement(value, myCurrentEdge->myPlacement, myCurrentEdge->myPlacementLane)) {
2180 WRITE_WARNINGF(
TL(
"Ignoring unsupported placement value '%' for edge '%'."), value, myCurrentEdge->id);
2182 }
else if (key ==
"lanes") {
2188 std::vector<std::string> list = st.
getVector();
2189 if (list.size() >= 2) {
2190 int minLanes = std::numeric_limits<int>::max();
2192 for (
auto& i : list) {
2194 minLanes =
MIN2(minLanes, numLanes);
2196 myCurrentEdge->myNoLanes = minLanes;
2199 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
2203 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
2205 }
else if (key ==
"lanes:forward") {
2208 if (myCurrentEdge->myNoLanesForward < 0 && myCurrentEdge->myNoLanes < 0) {
2210 myCurrentEdge->myNoLanes = numLanes - myCurrentEdge->myNoLanesForward;
2212 myCurrentEdge->myNoLanesForward = numLanes;
2214 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
2216 }
else if (key ==
"lanes:backward") {
2219 if (myCurrentEdge->myNoLanesForward > 0 && myCurrentEdge->myNoLanes < 0) {
2221 myCurrentEdge->myNoLanes = numLanes + myCurrentEdge->myNoLanesForward;
2224 myCurrentEdge->myNoLanesForward = -numLanes;
2226 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
2229 (key ==
"maxspeed" || key ==
"maxspeed:type" || key ==
"maxspeed:forward" || key ==
"zone:maxspeed")) {
2231 myCurrentEdge->myMaxSpeed = interpretSpeed(key, value);
2232 }
else if (key ==
"maxspeed:backward" && myCurrentEdge->myMaxSpeedBackward ==
MAXSPEED_UNGIVEN) {
2233 myCurrentEdge->myMaxSpeedBackward = interpretSpeed(key, value);
2234 }
else if (key ==
"junction") {
2235 if ((value ==
"roundabout" || value ==
"circular") && myCurrentEdge->myIsOneWay.empty()) {
2236 myCurrentEdge->myIsOneWay =
"yes";
2238 if (value ==
"roundabout") {
2239 myCurrentEdge->myAmInRoundabout =
true;
2241 }
else if (key ==
"oneway") {
2242 myCurrentEdge->myIsOneWay = value;
2243 }
else if (key ==
"name") {
2244 myCurrentEdge->streetName = value;
2245 }
else if (key ==
"ref") {
2246 myCurrentEdge->ref = value;
2247 myCurrentEdge->setParameter(
"ref", value);
2248 }
else if (key ==
"layer") {
2252 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
2254 }
else if (key ==
"tracks") {
2257 myCurrentEdge->myIsOneWay =
"true";
2259 WRITE_WARNINGF(
TL(
"Ignoring track count % for edge '%'."), value, myCurrentEdge->id);
2262 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
2264 }
else if (key ==
"railway:preferred_direction") {
2265 if (value ==
"both") {
2267 }
else if (value ==
"backward") {
2269 }
else if (value ==
"forward") {
2272 }
else if (key ==
"railway:bidirectional") {
2273 if (value ==
"regular") {
2274 myCurrentEdge->myRailDirection = (myCurrentEdge->myRailDirection |
WAY_BOTH) & ~
WAY_UNKNOWN;
2276 }
else if (key ==
"electrified" || key ==
"segregated") {
2277 if (value !=
"no") {
2278 myCurrentEdge->myExtraTags[key] = value;
2280 }
else if (key ==
"railway:track_ref") {
2281 myCurrentEdge->setParameter(key, value);
2282 }
else if (key ==
"public_transport" && value ==
"platform") {
2283 myCurrentEdge->myExtraTags[
"platform"] =
"yes";
2288 }
else if ((key ==
"parking:right" || key ==
"parking:lane:right") && !
StringUtils::startsWith(value,
"no")) {
2290 }
else if (key ==
"change" || key ==
"change:lanes") {
2291 myCurrentEdge->myChangeForward = myCurrentEdge->myChangeBackward = interpretChangeType(value);
2292 }
else if (key ==
"change:forward" || key ==
"change:lanes:forward") {
2293 myCurrentEdge->myChangeForward = interpretChangeType(value);
2294 }
else if (key ==
"change:backward" || key ==
"change:lanes:backward") {
2295 myCurrentEdge->myChangeBackward = interpretChangeType(value);
2296 }
else if (key ==
"vehicle:lanes" || key ==
"vehicle:lanes:forward") {
2299 }
else if (key ==
"vehicle:lanes:backward") {
2302 }
else if (key ==
"bus:lanes" || key ==
"bus:lanes:forward") {
2303 interpretLaneUse(value,
SVC_BUS,
true);
2304 }
else if (key ==
"bus:lanes:backward") {
2305 interpretLaneUse(value,
SVC_BUS,
false);
2306 }
else if (key ==
"psv:lanes" || key ==
"psv:lanes:forward") {
2307 interpretLaneUse(value,
SVC_BUS,
true);
2308 interpretLaneUse(value,
SVC_TAXI,
true);
2309 }
else if (key ==
"psv:lanes:backward") {
2310 interpretLaneUse(value,
SVC_BUS,
false);
2311 interpretLaneUse(value,
SVC_TAXI,
false);
2312 }
else if (key ==
"bicycle:lanes" || key ==
"bicycle:lanes:forward") {
2314 }
else if (key ==
"bicycle:lanes:backward") {
2328 std::vector<int> turnCodes;
2329 for (std::string codeList : values) {
2332 if (codes.size() == 0) {
2335 for (std::string code : codes) {
2336 if (code ==
"" || code ==
"none" || code ==
"through") {
2338 }
else if (code ==
"left" || code ==
"sharp_left") {
2340 }
else if (code ==
"right" || code ==
"sharp_right") {
2342 }
else if (code ==
"slight_left") {
2344 }
else if (code ==
"slight_right") {
2346 }
else if (code ==
"reverse") {
2348 }
else if (code ==
"merge_to_left" || code ==
"merge_to_right") {
2352 turnCodes.push_back(turnCode);
2370 if (!myCurrentEdge->myHighWayType.empty() && singleTypeID !=
"railway.highspeed") {
2371 if (myCurrentEdge->myHighWayType ==
"railway.highspeed") {
2376 std::vector<std::string> types =
StringTokenizer(myCurrentEdge->myHighWayType,
2378 types.push_back(singleTypeID);
2381 myCurrentEdge->myHighWayType = singleTypeID;
2388 if (mySpeedMap.find(value) != mySpeedMap.end()) {
2389 return mySpeedMap[value];
2392 if (value.size() > 3 && value[2] ==
':') {
2393 if (value.substr(3, 4) ==
"zone") {
2394 value = value.substr(7);
2396 value = value.substr(3);
2402 WRITE_WARNING(
"Value of key '" + key +
"' is not numeric ('" + value +
"') in edge '" +
2403 toString(myCurrentEdge->id) +
"'.");
2414 for (
const std::string& val : values) {
2417 }
else if (val ==
"not_left") {
2419 }
else if (val ==
"not_right") {
2422 result = result << 2;
2425 result = result >> 2;
2427 if (values.size() > 1) {
2440 if (tokens.size() != 2) {
2444 if (where ==
"left_of") {
2446 }
else if (where ==
"right_of") {
2448 }
else if (where ==
"middle_of") {
2460 if (laneIndex <= 0) {
2472 std::vector<bool>& designated =
forward ? myCurrentEdge->myDesignatedLaneForward : myCurrentEdge->myDesignatedLaneBackward;
2473 std::vector<SVCPermissions>& allowed =
forward ? myCurrentEdge->myAllowedLaneForward : myCurrentEdge->myAllowedLaneBackward;
2474 std::vector<SVCPermissions>& disallowed =
forward ? myCurrentEdge->myDisallowedLaneForward : myCurrentEdge->myDisallowedLaneBackward;
2475 designated.resize(
MAX2(designated.size(), values.size()),
false);
2479 for (
const std::string& val : values) {
2480 if (val ==
"yes" || val ==
"permissive") {
2482 }
else if (val ==
"lane" || val ==
"designated") {
2484 designated[i] =
true;
2485 }
else if (val ==
"no") {
2486 disallowed[i] |= svc;
2488 WRITE_WARNINGF(
TL(
"Unknown lane use specifier '%' ignored for way '%'"), val, myCurrentEdge->id);
2497 if (element ==
SUMO_TAG_WAY && myCurrentEdge !=
nullptr) {
2498 if (myCurrentEdge->myCurrentIsRoad) {
2499 const auto insertionIt = myEdgeMap.lower_bound(myCurrentEdge->id);
2500 if (insertionIt == myEdgeMap.end() || insertionIt->first != myCurrentEdge->id) {
2502 myEdgeMap.emplace_hint(insertionIt, myCurrentEdge->id, myCurrentEdge);
2504 delete myCurrentEdge;
2506 }
else if (myCurrentEdge->myExtraTags.count(
"platform") != 0) {
2507 const auto insertionIt = myPlatformShapesMap.lower_bound(myCurrentEdge->id);
2508 if (insertionIt == myPlatformShapesMap.end() || insertionIt->first != myCurrentEdge->id) {
2510 myPlatformShapesMap.emplace_hint(insertionIt, myCurrentEdge->id, myCurrentEdge);
2512 delete myCurrentEdge;
2515 delete myCurrentEdge;
2517 myCurrentEdge =
nullptr;
2526 const std::map<long long int, NIOSMNode*>& osmNodes,
2527 const std::map<long long int, Edge*>& osmEdges,
NBPTStopCont* nbptStopCont,
2528 const std::map<long long int, Edge*>& platformShapes,
2533 myOSMEdges(osmEdges),
2535 myNBPTStopCont(nbptStopCont),
2536 myNBPTLineCont(nbptLineCont),
2548 myIsRestriction =
false;
2555 myRestrictionType = RestrictionType::UNKNOWN;
2556 myPlatforms.clear();
2558 myPlatformStops.clear();
2560 myIsStopArea =
false;
2563 myRouteColor.setValid(
false);
2571 myCurrentRelation = attrs.
get<
long long int>(
SUMO_ATTR_ID,
nullptr, ok);
2573 if (action ==
"delete" || !ok) {
2579 myNightService =
"";
2588 const long long int ref = attrs.
get<
long long int>(
SUMO_ATTR_REF,
nullptr, ok);
2589 if (role ==
"via") {
2592 if (memberType ==
"way" && checkEdgeRef(ref)) {
2594 }
else if (memberType ==
"node") {
2601 }
else if (role ==
"from" && checkEdgeRef(ref)) {
2603 }
else if (role ==
"to" && checkEdgeRef(ref)) {
2607 myStops.push_back(ref);
2611 if (memberType ==
"way") {
2612 const std::map<long long int, NIImporter_OpenStreetMap::Edge*>::const_iterator& wayIt =
myPlatformShapes.find(ref);
2615 platform.
isWay =
true;
2617 myPlatforms.push_back(platform);
2619 }
else if (memberType ==
"node") {
2621 myStops.push_back(ref);
2622 myPlatformStops.insert(ref);
2624 platform.
isWay =
false;
2626 myPlatforms.push_back(platform);
2629 }
else if (role ==
"station") {
2631 }
else if (role.empty()) {
2633 if (memberType ==
"way") {
2634 myWays.push_back(ref);
2635 }
else if (memberType ==
"node") {
2637 if (it !=
myOSMNodes.end() && it->second->hasParameter(
"railway:ref")) {
2640 myStops.push_back(ref);
2651 if (key ==
"type" || key ==
"restriction") {
2653 if (key ==
"type" && value ==
"restriction") {
2654 myIsRestriction =
true;
2657 if (key ==
"type" && value ==
"route") {
2661 if (key ==
"restriction") {
2664 if (value.substr(0, 5) ==
"only_") {
2665 myRestrictionType = RestrictionType::ONLY;
2666 }
else if (value.substr(0, 3) ==
"no_") {
2667 myRestrictionType = RestrictionType::NO;
2673 }
else if (key ==
"except") {
2677 myRestrictionException |=
SVC_BUS;
2678 }
else if (v ==
"bicycle") {
2680 }
else if (v ==
"hgv") {
2682 }
else if (v ==
"motorcar") {
2684 }
else if (v ==
"emergency") {
2688 }
else if (key ==
"public_transport") {
2690 if (value ==
"stop_area") {
2691 myIsStopArea =
true;
2693 }
else if (key ==
"route") {
2695 if (value ==
"train" || value ==
"subway" || value ==
"light_rail" || value ==
"monorail" || value ==
"tram" || value ==
"bus"
2696 || value ==
"trolleybus" || value ==
"aerialway" || value ==
"ferry" || value ==
"share_taxi" || value ==
"minibus") {
2697 myPTRouteType = value;
2700 }
else if (key ==
"name") {
2702 }
else if (key ==
"colour") {
2707 WRITE_WARNINGF(
TL(
"Invalid color value '%' in relation %"), value, myCurrentRelation);
2709 }
else if (key ==
"ref") {
2711 }
else if (key ==
"interval" || key ==
"headway") {
2713 }
else if (key ==
"by_night") {
2722 if (myOSMEdges.find(ref) != myOSMEdges.end()) {
2733 if (myIsRestriction) {
2736 if (myRestrictionType == RestrictionType::UNKNOWN) {
2752 if (ok && !applyRestriction()) {
2755 }
else if (myIsStopArea) {
2756 for (
long long ref : myStops) {
2757 myStopAreas[ref] = myCurrentRelation;
2766 std::shared_ptr<NBPTStop> ptStop = myNBPTStopCont->get(
toString(n->
id));
2767 if (ptStop ==
nullptr) {
2774 if (myPlatform.isWay) {
2778 WRITE_WARNINGF(
TL(
"Platform '%' in relation: '%' is given as polygon, which currently is not supported."), myPlatform.ref, myCurrentRelation);
2793 WRITE_ERRORF(
"Unable to project coordinates for node '%'.", pNode->
id);
2796 p.push_back(pNodePos);
2798 if (p.size() == 0) {
2799 WRITE_WARNINGF(
TL(
"Referenced platform: '%' in relation: '%' is corrupt. Probably OSM file is incomplete."),
2804 ptStop->addPlatformCand(platform);
2815 WRITE_ERRORF(
"Unable to project coordinates for node '%'.", pNode->
id);
2817 NBPTPlatform platform(platformPos, myOptionsCont.getFloat(
"osm.stop-output.length"));
2818 ptStop->addPlatformCand(platform);
2822 ptStop->setIsMultipleStopPositions(myStops.size() > 1, myCurrentRelation);
2824 const auto& nodeIt =
myOSMNodes.find(myStation);
2827 if (station !=
nullptr) {
2835 }
else if (myPTRouteType !=
"" && myIsRoute) {
2836 NBPTLine* ptLine =
new NBPTLine(
toString(myCurrentRelation), myName, myPTRouteType, myRef, myInterval, myNightService,
2838 int consecutiveGap =
false;
2839 int missingBefore = 0;
2840 int missingAfter = 0;
2841 for (
long long ref : myStops) {
2853 if (consecutiveGap > 1) {
2854 WRITE_WARNINGF(
TL(
"PT line '%' in relation % has a gap of % stops, only keeping first part."), myName, myCurrentRelation, consecutiveGap);
2855 missingAfter = (int)myStops.size() - missingBefore - (int)ptLine->
getStops().size();
2861 const NIOSMNode*
const n = nodeIt->second;
2862 std::shared_ptr<NBPTStop> ptStop = myNBPTStopCont->get(
toString(n->
id));
2863 if (ptStop ==
nullptr) {
2867 WRITE_ERRORF(
"Unable to project coordinates for node '%'.", n->
id);
2871 myNBPTStopCont->insert(ptStop);
2872 if (myStopAreas.count(n->
id)) {
2873 ptStop->setIsMultipleStopPositions(
false, myStopAreas[n->
id]);
2875 if (myPlatformStops.count(n->
id) > 0) {
2876 ptStop->setIsPlatform();
2881 for (
long long& myWay : myWays) {
2882 auto entr = myOSMEdges.find(myWay);
2883 if (entr != myOSMEdges.end()) {
2884 Edge* edge = entr->second;
2890 ptLine->
setNumOfStops((
int)myStops.size(), missingBefore, missingAfter);
2892 WRITE_WARNINGF(
TL(
"PT line in relation % with no stops ignored. Probably OSM file is incomplete."), myCurrentRelation);
2897 if (!myNBPTLineCont->insert(ptLine)) {
2912 if (viaNode ==
nullptr) {
2918 if (from ==
nullptr) {
2922 if (to ==
nullptr) {
2926 if (myRestrictionType == RestrictionType::ONLY) {
2953 WRITE_WARNINGF(
TL(
"direction of restriction relation could not be determined%"),
"");
2961 const std::vector<NBEdge*>& candidates)
const {
2962 const std::string prefix =
toString(wayRef);
2963 const std::string backPrefix =
"-" + prefix;
2964 NBEdge* result =
nullptr;
2966 for (
auto candidate : candidates) {
2967 if ((candidate->getID().substr(0, prefix.size()) == prefix) ||
2968 (candidate->getID().substr(0, backPrefix.size()) == backPrefix)) {
2974 WRITE_WARNINGF(
TL(
"Ambiguous way reference '%' in restriction relation"), prefix);
#define WRITE_WARNINGF(...)
#define WRITE_MESSAGEF(...)
#define WRITE_ERRORF(...)
#define WRITE_WARNING(msg)
#define PROGRESS_BEGIN_TIME_MESSAGE(msg)
#define PROGRESS_TIME_MESSAGE(before)
#define PROGRESS_DONE_MESSAGE()
#define PROGRESS_BEGIN_MESSAGE(msg)
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
SVCPermissions extraDisallowed(SVCPermissions disallowed, const MMVersion &networkVersion)
Interprets disallowed vehicles depending on network version.
const SVCPermissions SVCAll
all VClasses are allowed
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permissions is a (exclusive) railway edge.
StringBijection< SUMOVehicleClass > SumoVehicleClassStrings(sumoVehicleClassStringInitializer, SVC_CUSTOM2, false)
long long int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_SHIP
is an arbitrary ship
@ SVC_PRIVATE
private vehicles
@ SVC_TRUCK
vehicle is a large transport vehicle
@ SVC_IGNORING
vehicles ignoring classes
@ SVC_RAIL
vehicle is a not electrified rail
@ SVC_RAIL_CLASSES
classes which drive on tracks
@ SVC_PASSENGER
vehicle is a passenger car (a "normal" car)
@ SVC_BICYCLE
vehicle is a bicycle
@ SVC_RAIL_FAST
vehicle that is allowed to drive on high-speed rail tracks
@ SVC_TRAILER
vehicle is a large transport vehicle
@ SVC_RAIL_ELECTRIC
rail vehicle that requires electrified tracks
@ SVC_RAIL_URBAN
vehicle is a city rail
@ SVC_EMERGENCY
public emergency vehicles
@ SVC_AUTHORITY
authorities vehicles
@ SVC_TRAM
vehicle is a light rail
@ SVC_PUBLIC_CLASSES
public transport
@ SVC_TAXI
vehicle is a taxi
@ SVC_BUS
vehicle is a bus
@ SVC_PEDESTRIAN
pedestrian
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_BUS_STOP
A bus stop.
@ SUMO_TAG_TRAIN_STOP
A train stop (alias for bus stop)
@ SUMO_TAG_NODE
alternative definition for junction
LaneSpreadFunction
Numbers representing special SUMO-XML-attribute values Information how the edge's lateral offset shal...
@ PARTLEFT
The link is a partial left direction.
@ RIGHT
The link is a (hard) right direction.
@ TURN
The link is a 180 degree turn.
@ LEFT
The link is a (hard) left direction.
@ STRAIGHT
The link is a straight direction.
@ PARTRIGHT
The link is a partial right direction.
@ NODIR
The link has no direction (is a dead end link)
const double SUMO_const_laneWidth
std::string joinToStringSorting(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
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)
static bool isReadable(std::string path)
Checks whether the given file is readable.
void setFileName(const std::string &name)
Sets the current file name.
bool wasInformed() const
Returns the information whether any messages were added.
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Storage for edges, including some functionality operating on multiple edges.
int extractRoundabouts()
Determines which edges have been marked as roundabouts and stores them internally.
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
The representation of a single edge during network building.
static const int TURN_SIGN_SHIFT_BUS
shift values for decoding turn signs
static const int TURN_SIGN_SHIFT_BICYCLE
void setPermittedChanging(int lane, SVCPermissions changeLeft, SVCPermissions changeRight)
set allowed classes for changing to the left and right from the given lane
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
void setPermissions(SVCPermissions permissions, int lane=-1)
set allowed/disallowed classes for the given lane or for all lanes if -1 is given
void addBikeLane(double width)
add a bicycle lane of the given width and shift existing connections
NBNode * getToNode() const
Returns the destination node of the edge.
static const double UNSPECIFIED_FRICTION
unspecified lane friction
Lane & getLaneStruct(int lane)
const PositionVector & getGeometry() const
Returns the geometry of the edge.
bool addEdge2EdgeConnection(NBEdge *dest, bool overrideRemoval=false, SVCPermissions permission=SVC_UNSPECIFIED)
Adds a connection to another edge.
void setTurnSignTarget(const std::string &target)
void setDistance(double distance)
set kilometrage at start of edge (negative value implies couting down along the edge)
const std::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
const std::string & getID() const
void setLaneWidth(int lane, double width)
set lane specific width (negative lane implies set for all lanes)
void addSidewalk(double width)
add a pedestrian sidewalk of the given width and shift existing connections
int getNumLanes() const
Returns the number of lanes.
void removeFromConnections(NBEdge *toEdge, int fromLane=-1, int toLane=-1, bool tryLater=false, const bool adaptToLaneRemoval=false, const bool keepPossibleTurns=false)
Removes the specified connection(s)
bool isConnectedTo(const NBEdge *e, const bool ignoreTurnaround=false) const
Returns the information whethe a connection to the given edge has been added (or computed)
static const int TURN_SIGN_SHIFT_TAXI
void preferVehicleClass(int lane, SVCPermissions vclasses)
prefer certain vehicle classes for the given lane or for all lanes if -1 is given (ensures also permi...
NBNode * getFromNode() const
Returns the origin node of the edge.
static const double UNSPECIFIED_WIDTH
unspecified lane width
void setRoutingType(const std::string &routingType)
set the routingType for this edge
static const double UNSPECIFIED_OFFSET
unspecified lane offset
void setJunctionPriority(const NBNode *const node, int prio)
Sets the junction priority of the edge.
void setGeometry(const PositionVector &g, bool inner=false)
(Re)sets the edge's geometry
Instance responsible for building networks.
static bool transformCoordinates(PositionVector &from, bool includeInBoundary=true, GeoConvHelper *from_srs=nullptr)
NBPTLineCont & getPTLineCont()
Returns a reference to the pt line container.
NBParkingCont & getParkingCont()
NBPTStopCont & getPTStopCont()
Returns a reference to the pt stop container.
NBNodeCont & getNodeCont()
Returns a reference to the node container.
NBEdgeCont & getEdgeCont()
NBTypeCont & getTypeCont()
Returns a reference to the type container.
NBTrafficLightLogicCont & getTLLogicCont()
Returns a reference to the traffic light logics container.
static bool transformCoordinate(Position &from, bool includeInBoundary=true, GeoConvHelper *from_srs=nullptr)
transforms loaded coordinates handles projections, offsets (using GeoConvHelper) and import of height...
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.
Represents a single node (junction) during network building.
bool hasIncoming(const NBEdge *const e) const
Returns whether the given edge ends at this node.
NBNode::Crossing * addCrossing(EdgeVector edges, double width, bool priority, int tlIndex=-1, int tlIndex2=-1, const PositionVector &customShape=PositionVector::EMPTY, bool fromSumoNet=false, const Parameterised *params=nullptr)
add a pedestrian crossing to this node
void reinit(const Position &position, SumoXMLNodeType type, bool updateEdgeGeometries=false)
Resets initial values.
SumoXMLNodeType getType() const
Returns the type of this node.
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges (The edges which yield in this node)
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges (The edges which start at this node)
bool checkCrossingDuplicated(EdgeVector edges)
return true if there already exist a crossing with the same edges as the input
const Position & getPosition() const
const EdgeVector & getEdges() const
Returns all edges which participate in this node (Edges that start or end at this node)
static const int FORWARD
edge directions (for pedestrian related stuff)
A traffic light logics which must be computed (only nodes/edges are given)
void setNumOfStops(int numStops, int missingBefore, int missingAfter)
void addWayNode(long long int way, long long int node)
const std::vector< std::shared_ptr< NBPTStop > > & getStops()
void addPTStop(std::shared_ptr< NBPTStop > pStop)
Container for public transport stops during the net building process.
const std::map< std::string, std::shared_ptr< NBPTStop > > & getStops() const
Returns an unmodifiable reference to the stored pt stops.
int cleanupDeleted(NBEdgeCont &cont, bool reAssign=false)
remove stops on non existing (removed) edges
std::shared_ptr< NBPTStop > get(std::string id) const
Retrieve a previously inserted pt stop.
bool insert(std::shared_ptr< NBPTStop > ptStop, bool floating=false)
Inserts a node into the map.
The representation of an imported parking area.
static const std::string OSM_DIRECTION
processing parameter for rail signal edges and nodes
static const std::string OSM_SIGNAL_DIRECTION
A container for traffic light definitions and built programs.
bool insert(NBTrafficLightDefinition *logic, bool forceInsert=false)
Adds a logic definition to the dictionary.
A storage for available edgeTypes of edges.
bool getEdgeTypeShallBeDiscarded(const std::string &edgeType) const
Returns the information whether edges of this edgeType shall be discarded.
void insertEdgeType(const std::string &id, int numLanes, double maxSpeed, int prio, SVCPermissions permissions, LaneSpreadFunction spreadType, double width, bool oneWayIsDefault, double sidewalkWidth, double bikeLaneWidth, double widthResolution, double maxWidth, double minWidth)
Adds a edgeType into the list.
bool copyEdgeTypeRestrictionsAndAttrs(const std::string &fromId, const std::string &toId)
Copy restrictions to a edgeType.
double getEdgeTypeSpeed(const std::string &edgeType) const
Returns the maximal velocity for the given edgeType [m/s].
int getEdgeTypePriority(const std::string &edgeType) const
Returns the priority for the given edgeType.
int getEdgeTypeNumLanes(const std::string &edgeType) const
Returns the number of lanes for the given edgeType.
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.
bool knows(const std::string &edgeType) const
Returns whether the named edgeType is in the container.
double getEdgeTypeSidewalkWidth(const std::string &edgeType) const
Returns the lane width for a sidewalk to be added [m].
LaneSpreadFunction getEdgeTypeSpreadType(const std::string &edgeType) const
Returns spreadType for the given edgeType.
double getEdgeTypeBikeLaneWidth(const std::string &edgeType) const
Returns the lane width for a bike lane to be added [m].
bool getEdgeTypeIsOneWay(const std::string &edgeType) const
Returns whether edges are one-way per default for the given edgeType.
Functor which compares two Edges.
bool operator()(const Edge *e1, const Edge *e2) const
An internal definition of a loaded edge.
int myPlacementLane
1-based lane index for placement specification
std::vector< SVCPermissions > myDisallowedLaneBackward
(optional) information about additional disallowed SVCs on backward lane(s)
std::map< std::string, std::string > myExtraTags
Additionally tagged information.
std::vector< double > myWidthLanesForward
Information on lane width.
WayType mySidewalkType
Information about the kind of sidwalk along this road.
std::vector< double > myWidthLanesBackward
std::vector< SVCPermissions > myDisallowedLaneForward
(optional) information about additional disallowed SVCs on forward lane(s)
bool myCurrentIsRoad
Information whether this is a road.
WayType myCyclewayType
Information about the kind of cycleway along this road.
std::vector< int > myTurnSignsBackward
int myNoLanesForward
number of lanes in forward direction or 0 if unknown, negative if backwards lanes are meant
double myMaxSpeed
maximum speed in km/h, or MAXSPEED_UNGIVEN
std::string ref
The edge's track name.
std::vector< SVCPermissions > myAllowedLaneForward
(optional) information about additional allowed SVCs on forward lane(s)
std::string myHighWayType
The type, stored in "highway" key.
const long long int id
The edge's id.
bool myAmInRoundabout
Information whether this road is part of a roundabout.
int myLayer
Information about the relative z-ordering of ways.
int myRailDirection
Information about the direction(s) of railway usage.
std::vector< bool > myDesignatedLaneBackward
(optional) information about whether the backward lanes are designated to some SVCs
SVCPermissions myExtraDisallowed
Extra permissions prohibited from tags instead of highway type.
std::vector< SVCPermissions > myAllowedLaneBackward
(optional) information about additional allowed SVCs on backward lane(s)
int myNoLanes
number of lanes, or -1 if unknown
std::vector< int > myTurnSignsForward
turning direction (arrows printed on the road)
std::vector< long long int > myCurrentNodes
The list of nodes this edge is made of.
int myParkingType
Information about road-side parking.
double myMaxSpeedBackward
maximum speed in km/h, or MAXSPEED_UNGIVEN
WayType myBuswayType
Information about the kind of busway along this road.
int myChangeForward
Information about change prohibitions (forward direction.
SVCPermissions myExtraAllowed
Extra permissions added from tags instead of highway type.
int myChangeBackward
Information about change prohibitions (backward direction.
std::string streetName
The edge's street name.
PlacementType myPlacement
placement of the OSM way geometry relative to lanes
std::vector< bool > myDesignatedLaneForward
(optional) information about whether the forward lanes are designated to some SVCs
std::string myIsOneWay
Information whether this is an one-way road.
A class which extracts OSM-edges from a parsed OSM-file.
void addType(const std::string &singleTypeID)
void interpretLaneUse(const std::string &value, SUMOVehicleClass svc, const bool forward) const
int interpretChangeType(const std::string &value) const
EdgesHandler(const std::map< long long int, NIOSMNode * > &osmNodes, std::map< long long int, Edge * > &toFill, std::map< long long int, Edge * > &platformShapes, const NBTypeCont &tc)
Constructor.
~EdgesHandler() override
Destructor.
void myEndElement(int element) override
Called when a closing tag occurs.
bool interpretPlacement(const std::string &value, NIImporter_OpenStreetMap::PlacementType &placement, int &laneIndex) const
double interpretSpeed(const std::string &key, std::string value)
std::map< std::string, double > mySpeedMap
A map of non-numeric speed descriptions to their numeric values.
void myStartElement(int element, const SUMOSAXAttributes &attrs) override
Called on the opening of a tag;.
A class which extracts OSM-nodes from a parsed OSM-file.
~NodesHandler() override
Destructor.
int getDuplicateNodes() const
void myStartElement(int element, const SUMOSAXAttributes &attrs) override
Called on the opening of a tag;.
NodesHandler(std::map< long long int, NIOSMNode * > &toFill, std::set< NIOSMNode *, CompareNodes > &uniqueNodes, const OptionsCont &cont)
Constructor.
void myEndElement(int element) override
Called when a closing tag occurs.
StringVector myRailSignalRules
custom requirements for rail signal tagging
A class which extracts relevant relation information from a parsed OSM-file.
void myEndElement(int element) override
Called when a closing tag occurs.
void resetValues()
reset members to their defaults for parsing a new relation
void myStartElement(int element, const SUMOSAXAttributes &attrs) override
Called on the opening of a tag;.
~RelationHandler() override
Destructor.
RelationHandler(const std::map< long long int, NIOSMNode * > &osmNodes, const std::map< long long int, Edge * > &osmEdges, NBPTStopCont *nbptStopCont, const std::map< long long int, Edge * > &platfromShapes, NBPTLineCont *nbptLineCont, const OptionsCont &oc)
Constructor.
bool checkEdgeRef(long long int ref) const
check whether a referenced way has a corresponding edge
bool applyRestriction() const
try to apply the parsed restriction and return whether successful
NBEdge * findEdgeRef(long long int wayRef, const std::vector< NBEdge * > &candidates) const
try to find the way segment among candidates
Importer for networks stored in OpenStreetMap format.
int insertEdge(Edge *e, int index, NBNode *from, NBNode *to, const std::vector< long long int > &passed, NBNetBuilder &nb, const NBNode *first, const NBNode *last)
Builds an NBEdge.
std::map< long long int, Edge * > myEdges
the map from OSM way ids to edge objects
bool myImportCrossings
import crossings
std::map< long long int, NIOSMNode * > myOSMNodes
the map from OSM node ids to actual nodes
NIImporter_OpenStreetMap()
static void loadNetwork(const OptionsCont &oc, NBNetBuilder &nb)
Loads content of the optionally given OSM file.
static const long long int INVALID_ID
WayType
details on the kind of sidewalk, cycleway, busway along this road
void applyLaneUse(NBEdge *e, NIImporter_OpenStreetMap::Edge *nie, const bool forward)
Applies lane use information from nie to e.
static const double MAXSPEED_UNGIVEN
bool myOnewayDualSidewalk
import sidewalks
~NIImporter_OpenStreetMap()
std::map< long long int, Edge * > myPlatformShapes
the map from OSM way ids to platform shapes
void load(const OptionsCont &oc, NBNetBuilder &nb)
void applyTurnSigns(NBEdge *e, const std::vector< int > &turnSigns)
bool myImportSidewalks
import sidewalks
std::set< NIOSMNode *, CompareNodes > myUniqueNodes
the set of unique nodes used in NodesHandler, used when freeing memory
static bool myAllAttributes
whether additional way and node attributes shall be imported
void reconstructLayerElevation(double layerElevation, NBNetBuilder &nb)
reconstruct elevation from layer info
static SUMOVehicleClass interpretTransportType(const std::string &type, NIOSMNode *toSet=nullptr)
translate osm transport designations into sumo vehicle class
int myPlacementSkippedNonExplicitOneWay
number of placement skips due to non-explicit oneway
bool myImportLaneAccess
import lane specific access restrictions
bool myImportTurnSigns
import turning signals (turn:lanes) to guide connection building
std::map< std::string, std::string > myKnownCompoundTypes
The compound types that have already been mapped to other known types.
static const std::string compoundTypeSeparator
The separator within newly created compound type names.
std::set< std::string > myUnusableTypes
The compounds types that do not contain known types.
bool myETCS_movingBlock
whether ETCS signals default to moving block
std::map< NBNode *, std::pair< double, double > > getNeighboringNodes(NBNode *node, double maxDist, const std::set< NBNode * > &knownElevation)
collect neighboring nodes with their road distance and maximum between-speed. Search does not continu...
static std::set< std::string > myExtraAttributes
extra attributes to import
bool myImportBikeAccess
import bike path specific permissions and directions
bool myAnnotateDefaults
whether edges should carry information on the use of typemap defaults
static double interpretDistance(NIOSMNode *node)
read distance value from node and return value in m
NBNode * insertNodeChecking(long long int id, NBNodeCont &nc, NBTrafficLightLogicCont &tlsc)
Builds an NBNode.
static void mergeTurnSigns(std::vector< int > &signs, std::vector< int > signs2)
void extendRailwayDistances(Edge *e, NBTypeCont &tc)
extend kilometrage data for all nodes along railway
int myPlacementSkippedAuxOppositeDirection
number of placement skips due to generated opposite-direction auxiliary edges
std::string usableType(const std::string &type, const std::string &id, NBTypeCont &tc)
check whether the type is known or consists of known type compounds. return empty string otherwise
static void applyChangeProhibition(NBEdge *e, int changeProhibition)
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 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.
void unsetParameter(const std::string &key)
Removes a parameter.
bool hasParameter(const std::string &key) const
Returns whether the parameter is set.
virtual const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
const Parameterised::Map & getParametersMap() const
Returns the inner key/value map.
virtual void setParameter(const std::string &key, const std::string &value)
Sets a parameter.
void updateParameters(const Parameterised::Map &mapArg)
Adds or updates all given parameters from the map.
A point in 2D or 3D with translation and scaling methods.
double length2D() const
Returns the length.
double length() const
Returns the length.
void move2side(double amount, double maxExtension=100)
move position vector to side using certain amount
PositionVector reverse() const
reverse position vector
static RGBColor parseColor(std::string coldef)
Parses a color information.
Encapsulated SAX-Attributes.
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue=T(), bool report=true) const
Tries to read given attribute assuming it is an int.
virtual std::string getStringSecure(int id, const std::string &def) const =0
Returns the string-value of the named (by its enum-value) attribute.
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.
SAX-handler base for SUMO-files.
static StringBijection< TrafficLightType > TrafficLightTypes
traffic light types
T get(const std::string &str) const
get key
int size() const
returns the number of existing substrings
std::vector< std::string > getVector()
return vector of strings
bool hasNext()
returns the information whether further substrings exist
std::string next()
returns the next substring when it exists. Otherwise the behaviour is undefined
static bool isBool(const std::string &sData)
check if the given value can be converted to bool
static long long int toLong(const std::string &sData)
converts a string into the long value described by it by calling the char-type converter,...
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
static std::string escapeXML(const std::string &orig, const bool maskDoubleHyphen=false)
Replaces the standard escapes by their XML entities.
static std::string prune(const std::string &str)
Removes trailing and leading whitechars.
static double parseDist(const std::string &sData)
parse a distance, length or width value with a unit
static bool startsWith(const std::string &str, const std::string prefix)
Checks whether a given string starts with the prefix.
static double parseSpeed(const std::string &sData, const bool defaultKmph=true)
parse a speed value with a unit
static bool endsWith(const std::string &str, const std::string suffix)
Checks whether a given string ends with the suffix.
static int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter,...
static bool toBool(const std::string &sData)
converts a string into the bool value described by it by calling the char-type converter
static SUMOSAXReader * getSAXReader(SUMOSAXHandler &handler, const bool isNet=false, const bool isRoute=false)
Builds a reader and assigns the handler to it.
An (internal) definition of a single lane of an edge.
int turnSigns
turning signs printed on the road, bitset of LinkDirection (imported from OSM)
An internal representation of an OSM-node.
SVCPermissions permissions
type of pt stop
int railwaySignal
Whether this is a railway (main) signal.
NBNode * node
the NBNode that was instantiated
double positionMeters
position converted to m (using highest precision available)
const long long int id
The node's id.
bool pedestrianCrossing
Whether this is a pedestrian crossing.
bool tlsControlled
Whether this is a tls controlled junction.
double ptStopLength
The length of the pt stop.
bool ptStopPosition
Whether this is a public transport stop position.
std::string name
The name of the node.
bool railwayCrossing
Whether this is a railway crossing.
double ele
The elevation of this node.
bool railwayBufferStop
Whether this is a railway buffer stop.
const double lon
The longitude the node is located at.
const double lat
The latitude the node is located at.
WayType myRailDirection
Information about the direction(s) of railway usage.