110 importer.
load(oc, nb);
122 delete myEdge.second;
126 delete myPlatformShape.second;
132 if (!oc.
isSet(
"osm-files")) {
135 const std::vector<std::string> files = oc.
getStringVector(
"osm-files");
136 std::vector<SUMOSAXReader*> readers;
156 for (
const std::string& file : files) {
165 if (!readers.back()->parseFirst(file) || !readers.back()->parseSection(
SUMO_TAG_NODE) ||
178 for (
const std::string& file : files) {
180 readers[idx]->setHandler(edgesHandler);
185 readers[idx] =
nullptr;
192 if (!oc.
getBool(
"osm.skip-duplicates-check")) {
196 std::set<const Edge*, CompareEdges> dupsFinder;
198 if (dupsFinder.count(it->second) > 0) {
203 dupsFinder.insert(it->second);
208 if (numRemoved > 0) {
217 std::map<long long int, int> nodeUsage;
219 for (
const auto& edgeIt :
myEdges) {
220 assert(edgeIt.second->myCurrentIsRoad);
221 for (
const long long int node : edgeIt.second->myCurrentNodes) {
227 if (nodesIt.second->tlsControlled || nodesIt.second->railwaySignal || (nodesIt.second->pedestrianCrossing &&
myImportCrossings) ) {
230 nodeUsage[nodesIt.first]++;
239 for (
const auto& edgeIt :
myEdges) {
240 Edge*
const e = edgeIt.second;
254 NBNode* currentFrom = first;
256 std::vector<long long int> passed;
258 passed.push_back(*j);
261 running =
insertEdge(e, running, currentFrom, currentTo, passed, nb, first, last);
262 currentFrom = currentTo;
264 passed.push_back(*j);
270 insertEdge(e, running, currentFrom, last, passed, nb, first, last);
283 for (
auto item : nodeUsage) {
289 size_t incomingEdgesNo = incomingEdges.size();
290 size_t outgoingEdgesNo = outgoingEdges.size();
292 for (
size_t i = 0; i < incomingEdgesNo; i++) {
300 auto const iEdge = incomingEdges[i];
304 std::string
const& iEdgeId = iEdge->getID();
305 std::size_t
const m = iEdgeId.find_first_of(
"#");
306 std::string
const& iWayId = iEdgeId.substr(0, m);
307 for (
size_t j = 0; j < outgoingEdgesNo; j++) {
308 auto const oEdge = outgoingEdges[j];
311 if (oEdge->getID().find(iWayId) != std::string::npos
313 && oEdge->getID().rfind(iWayId, 0) != 0) {
316 edgeVector.push_back(oEdge);
326 for (
size_t i = 0; i < outgoingEdgesNo; i++) {
328 auto const oEdge = outgoingEdges[i];
332 std::string
const& oEdgeId = oEdge->getID();
333 std::size_t
const m = oEdgeId.find_first_of(
"#");
334 std::string
const& iWayId = oEdgeId.substr(0, m);
335 for (
size_t j = 0; j < incomingEdgesNo; j++) {
336 auto const iEdge = incomingEdges[j];
337 if (iEdge->getID().find(iWayId) != std::string::npos
339 && iEdge->getID().rfind(iWayId, 0) != 0) {
342 edgeVector.push_back(iEdge);
356 const double layerElevation = oc.
getFloat(
"osm.layer-elevation");
357 if (layerElevation > 0) {
369 for (
const std::string& file : files) {
370 if (readers[idx] !=
nullptr) {
372 readers[idx]->setHandler(relationHandler);
382 std::set<std::string> stopNames;
384 stopNames.insert(item.second->getName());
391 WRITE_ERRORF(
"Unable to project coordinates for node '%'.", n->
id);
407 if (node ==
nullptr) {
411 WRITE_ERRORF(
"Unable to project coordinates for junction '%'.",
id);
424 }
else if (n->
getParameter(
"crossing.light") ==
"yes") {
436 if (!tlsc.
insert(tlDef)) {
461 const std::vector<long long int>& passed,
NBNetBuilder& nb,
471 if (from ==
nullptr || to ==
nullptr) {
472 WRITE_ERRORF(
"Discarding edge '%' because the nodes could not be built.",
id);
481 assert(passed.size() >= 2);
482 if (passed.size() == 2) {
483 WRITE_WARNINGF(
TL(
"Discarding edge '%' which connects two identical nodes without geometry."),
id);
487 int intermediateIndex = (int) passed.size() / 2;
489 std::vector<long long int> part1(passed.begin(), passed.begin() + intermediateIndex + 1);
490 std::vector<long long int> part2(passed.begin() + intermediateIndex, passed.end());
491 index =
insertEdge(e, index, from, intermediate, part1, nb, first, last);
492 return insertEdge(e, index, intermediate, to, part2, nb, first, last);
494 const int newIndex = index + 1;
499 std::string routingType =
"";
507 std::vector<SumoXMLAttr> defaults;
510 extra = extra & ~SVC_BUS;
512 SVCPermissions permissions = (defaultPermissions & ~extraDis) | extra;
518 defaultsToOneWay =
true;
520 if (defaultPermissions ==
SVC_SHIP) {
522 permissions = defaultPermissions;
525 defaultsToOneWay =
false;
533 double distanceStart =
myOSMNodes[passed.front()]->positionMeters;
534 double distanceEnd =
myOSMNodes[passed.back()]->positionMeters;
535 const bool useDistance = distanceStart != std::numeric_limits<double>::max() && distanceEnd != std::numeric_limits<double>::max();
538 if (distanceStart < distanceEnd) {
551 std::vector<std::shared_ptr<NBPTStop> > ptStops;
552 for (
long long i : passed) {
556 std::shared_ptr<NBPTStop> existingPtStop = sc.
get(
toString(n->
id));
557 if (existingPtStop !=
nullptr) {
558 existingPtStop->registerAdditionalEdge(
toString(e->
id), id);
562 WRITE_ERRORF(
"Unable to project coordinates for node '%'.", n->
id);
566 sc.
insert(ptStops.back());
573 shape.push_back(pos);
575#ifdef DEBUG_LAYER_ELEVATION
576 if (e->
id ==
"DEBUGID") {
581 <<
" nodeDirection=" << nodeDirection
593 WRITE_ERRORF(
"Unable to project coordinates for edge '%'.",
id);
599 if (streetName == e->
ref) {
616 const std::string& onewayBike = e->
myExtraTags[
"oneway:bicycle"];
617 if (onewayBike ==
"false" || onewayBike ==
"no" || onewayBike ==
"0") {
628 bool addForward =
true;
629 bool addBackward =
true;
630 const bool explicitTwoWay = e->
myIsOneWay ==
"no";
646 if (addBackward && (onewayBike ==
"true" || onewayBike ==
"yes" || onewayBike ==
"1")) {
649 if (addForward && (onewayBike ==
"reverse" || onewayBike ==
"-1")) {
652 if (!addBackward && (onewayBike ==
"false" || onewayBike ==
"no" || onewayBike ==
"0")) {
659 if (addForward && !addBackward) {
661 }
else if (!addForward && addBackward) {
669 numLanesForward = (int) std::ceil(e->
myNoLanes / 2.0);
671 numLanesBackward = e->
myNoLanes - numLanesForward;
674 numLanesForward =
MAX2(1, numLanesForward);
675 numLanesBackward =
MAX2(1, numLanesBackward);
686 numLanesForward =
MAX2(numLanesForward, 2);
692 numLanesBackward =
MAX2(numLanesForward, 2);
707 numLanesBackward = 1;
710 const int taggedLanes = (addForward ? numLanesForward : 0) + (addBackward ? numLanesBackward : 0);
714 forwardWidth = e->
myWidth / taggedLanes;
715 backwardWidth = forwardWidth;
724 double speedBackward = speed;
728 if (speed <= 0 || speedBackward <= 0) {
732 if (e->
myNoLanes == 1 && addForward && addBackward) {
745 routingType =
"narrow";
751 if (!addForward && (cyclewayType &
WAY_FORWARD) != 0) {
754 forwardWidth = bikeLaneWidth;
759 if (!addBackward && (cyclewayType &
WAY_BACKWARD) != 0) {
762 backwardWidth = bikeLaneWidth;
763 numLanesBackward = 1;
777 if (!addForward && (sidewalkType &
WAY_FORWARD) != 0) {
784 }
else if (addSidewalk && addForward && (sidewalkType &
WAY_BOTH) == 0
785 && numLanesForward == 1 && numLanesBackward <= 1
792 if (!addBackward && (sidewalkType &
WAY_BACKWARD) != 0) {
796 numLanesBackward = 1;
799 }
else if (addSidewalk && addBackward && (sidewalkType &
WAY_BOTH) == 0
800 && numLanesBackward == 1 && numLanesForward <= 1
812 const int offsetFactor = lefthand ? -1 : 1;
822 if (defaults.size() > 0) {
827 const std::string reverseID =
"-" + id;
830 assert(numLanesForward > 0);
834 if (markOSMDirection) {
871 if ((
int)nbe->
getLanes().size() != numForwardLanesFromWidthKey) {
872 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."),
873 id, nbe->
getLanes().size(), numForwardLanesFromWidthKey);
875 for (
int i = 0; i < numForwardLanesFromWidthKey; i++) {
877 const int laneIndex = lefthand ? i : numForwardLanesFromWidthKey - i - 1;
890 assert(numLanesBackward > 0);
894 if (markOSMDirection) {
925 if ((
int)nbe->
getLanes().size() != numBackwardLanesFromWidthKey) {
926 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."),
927 id, nbe->
getLanes().size(), numBackwardLanesFromWidthKey);
929 for (
int i = 0; i < numBackwardLanesFromWidthKey; i++) {
931 const int laneIndex = lefthand ? i : numBackwardLanesFromWidthKey - i - 1;
979 std::map<NBNode*, std::vector<std::pair<double, double> > > layerForces;
982 std::set<NBNode*> knownElevation;
984 Edge* e = myEdge.second;
988 if (node !=
nullptr) {
989 knownElevation.insert(node);
990 layerForces[node].emplace_back(e->
myLayer * layerElevation, POSITION_EPS);
995#ifdef DEBUG_LAYER_ELEVATION
996 std::cout <<
"known elevations:\n";
997 for (std::set<NBNode*>::iterator it = knownElevation.begin(); it != knownElevation.end(); ++it) {
998 const std::vector<std::pair<double, double> >& primaryLayers = layerForces[*it];
999 std::cout <<
" node=" << (*it)->
getID() <<
" ele=";
1000 for (std::vector<std::pair<double, double> >::const_iterator it_ele = primaryLayers.begin(); it_ele != primaryLayers.end(); ++it_ele) {
1001 std::cout << it_ele->first <<
" ";
1009 std::map<NBNode*, double> knownEleMax;
1010 for (
auto it : knownElevation) {
1011 double eleMax = -std::numeric_limits<double>::max();
1012 const std::vector<std::pair<double, double> >& primaryLayers = layerForces[it];
1013 for (
const auto& primaryLayer : primaryLayers) {
1014 eleMax =
MAX2(eleMax, primaryLayer.first);
1016 knownEleMax[it] = eleMax;
1019 bool changed =
true;
1022 for (
auto it = knownElevation.begin(); it != knownElevation.end(); ++it) {
1025 / gradeThreshold * 3,
1027 for (
auto& neighbor : neighbors) {
1028 if (knownElevation.count(neighbor.first) != 0) {
1029 const double grade = fabs(knownEleMax[*it] - knownEleMax[neighbor.first])
1030 /
MAX2(POSITION_EPS, neighbor.second.first);
1031#ifdef DEBUG_LAYER_ELEVATION
1032 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";
1034 if (grade > gradeThreshold * 50 / 3.6 / neighbor.second.second) {
1036 const double eleMax =
MAX2(knownEleMax[*it], knownEleMax[neighbor.first]);
1037 if (knownEleMax[*it] < eleMax) {
1038 knownEleMax[*it] = eleMax;
1040 knownEleMax[neighbor.first] = eleMax;
1050 std::set<NBNode*> unknownElevation;
1051 for (
auto it = knownElevation.begin(); it != knownElevation.end(); ++it) {
1052 const double eleMax = knownEleMax[*it];
1053 const double maxDist = fabs(eleMax) * 100 / layerElevation;
1054 std::map<NBNode*, std::pair<double, double> > neighbors =
getNeighboringNodes(*it, maxDist, knownElevation);
1055 for (
auto& neighbor : neighbors) {
1056 if (knownElevation.count(neighbor.first) == 0) {
1057 unknownElevation.insert(neighbor.first);
1058 layerForces[neighbor.first].emplace_back(eleMax, neighbor.second.first);
1064 for (
auto it = unknownElevation.begin(); it != unknownElevation.end(); ++it) {
1065 double eleMax = -std::numeric_limits<double>::max();
1066 const std::vector<std::pair<double, double> >& primaryLayers = layerForces[*it];
1067 for (
const auto& primaryLayer : primaryLayers) {
1068 eleMax =
MAX2(eleMax, primaryLayer.first);
1070 const double maxDist = fabs(eleMax) * 100 / layerElevation;
1071 std::map<NBNode*, std::pair<double, double> > neighbors =
getNeighboringNodes(*it, maxDist, knownElevation);
1072 for (
auto& neighbor : neighbors) {
1073 if (knownElevation.count(neighbor.first) == 0 && unknownElevation.count(neighbor.first) == 0) {
1074 layerForces[*it].emplace_back(0, neighbor.second.first);
1079#ifdef DEBUG_LAYER_ELEVATION
1080 std::cout <<
"summation of forces\n";
1082 std::map<NBNode*, double> nodeElevation;
1083 for (
auto& layerForce : layerForces) {
1084 const std::vector<std::pair<double, double> >& forces = layerForce.second;
1085 if (knownElevation.count(layerForce.first) != 0) {
1093#ifdef DEBUG_LAYER_ELEVATION
1094 std::cout <<
" node=" << it->first->getID() <<
" knownElevation=" << knownEleMax[it->first] <<
"\n";
1096 nodeElevation[layerForce.first] = knownEleMax[layerForce.first];
1097 }
else if (forces.size() == 1) {
1098 nodeElevation[layerForce.first] = forces.front().first;
1102 for (
const auto& force : forces) {
1103 distSum += force.second;
1105 double weightSum = 0;
1106 double elevation = 0;
1107#ifdef DEBUG_LAYER_ELEVATION
1108 std::cout <<
" node=" << it->first->getID() <<
" distSum=" << distSum <<
"\n";
1110 for (
const auto& force : forces) {
1111 const double weight = (distSum - force.second) / distSum;
1112 weightSum += weight;
1113 elevation += force.first * weight;
1115#ifdef DEBUG_LAYER_ELEVATION
1116 std::cout <<
" force=" << it_force->first <<
" dist=" << it_force->second <<
" weight=" << weight <<
" ele=" << elevation <<
"\n";
1119 nodeElevation[layerForce.first] = elevation / weightSum;
1122#ifdef DEBUG_LAYER_ELEVATION
1123 std::cout <<
"final elevations:\n";
1124 for (std::map<NBNode*, double>::iterator it = nodeElevation.begin(); it != nodeElevation.end(); ++it) {
1125 std::cout <<
" node=" << (it->first)->getID() <<
" ele=" << it->second <<
"\n";
1129 for (
auto& it : nodeElevation) {
1135 for (
const auto& it : ec) {
1136 NBEdge* edge = it.second;
1138 const double length = geom.
length2D();
1139 const double zFrom = nodeElevation[edge->
getFromNode()];
1140 const double zTo = nodeElevation[edge->
getToNode()];
1145 for (
auto it_pos = geom.begin(); it_pos != geom.end(); ++it_pos) {
1146 if (it_pos != geom.begin()) {
1147 dist += (*it_pos).distanceTo2D(*(it_pos - 1));
1149 newGeom.push_back((*it_pos) +
Position(0, 0, zFrom + (zTo - zFrom) * dist / length));
1155std::map<NBNode*, std::pair<double, double> >
1157 std::map<NBNode*, std::pair<double, double> > result;
1158 std::set<NBNode*> visited;
1159 std::vector<NBNode*> open;
1160 open.push_back(node);
1161 result[node] = std::make_pair(0, 0);
1162 while (!open.empty()) {
1165 if (visited.count(n) != 0) {
1170 for (
auto e : edges) {
1173 s = e->getFromNode();
1177 const double dist = result[n].first + e->getGeometry().length2D();
1178 const double speed =
MAX2(e->getSpeed(), result[n].second);
1179 if (result.count(s) == 0) {
1180 result[s] = std::make_pair(dist, speed);
1182 result[s] = std::make_pair(
MIN2(dist, result[s].first),
MAX2(speed, result[s].second));
1184 if (dist < maxDist && knownElevation.count(s) == 0) {
1196 if (tc.
knows(type)) {
1207 std::vector<std::string> types;
1209 std::string t = tok.
next();
1211 if (std::find(types.begin(), types.end(), t) == types.end()) {
1214 }
else if (tok.
size() > 1) {
1216 WRITE_WARNINGF(
TL(
"Discarding unknown compound '%' in type '%' (first occurrence for edge '%')."), t, type,
id);
1220 if (types.empty()) {
1222 WRITE_WARNINGF(
TL(
"Discarding unusable type '%' (first occurrence for edge '%')."), type,
id);
1228 if (tc.
knows(newType)) {
1236 double maxSpeed = 0;
1241 bool defaultIsOneWay =
true;
1244 bool discard =
true;
1245 bool hadDiscard =
false;
1246 for (
auto& type2 : types) {
1263 if (hadDiscard && permissions == 0) {
1267 WRITE_WARNINGF(
TL(
"Discarding compound type '%' (first occurrence for edge '%')."), newType,
id);
1282 WRITE_MESSAGEF(
TL(
"Adding new type '%' (first occurrence for edge '%')."), type,
id);
1283 tc.
insertEdgeType(newType, numLanes, maxSpeed, prio, permissions, spreadType, width,
1284 defaultIsOneWay, sidewalkWidth, bikelaneWidth, 0, 0, 0);
1285 for (
auto& type3 : types) {
1300 std::vector<NIOSMNode*> nodes;
1301 std::vector<double> usablePositions;
1302 std::vector<int> usableIndex;
1306 if (node->
positionMeters != std::numeric_limits<double>::max()) {
1308 usableIndex.push_back((
int)nodes.size());
1310 nodes.push_back(node);
1312 if (usablePositions.size() == 0) {
1315 bool forward =
true;
1316 if (usablePositions.size() == 1) {
1317 WRITE_WARNINGF(
TL(
"Ambiguous railway kilometrage direction for way '%' (assuming forward)"),
id);
1319 forward = usablePositions.front() < usablePositions.back();
1322 for (
int i = 1; i < (int)usablePositions.size(); i++) {
1323 if ((usablePositions[i - 1] < usablePositions[i]) != forward) {
1324 WRITE_WARNINGF(
TL(
"Inconsistent railway kilometrage direction for way '%': % (skipping)"),
id,
toString(usablePositions));
1328 if (nodes.size() > usablePositions.size()) {
1332 shape.push_back(
Position(node->lon, node->lat, 0));
1337 double sign = forward ? 1 : -1;
1339 for (
int i = usableIndex.front() - 1; i >= 0; i--) {
1340 nodes[i]->positionMeters = nodes[i + 1]->positionMeters - sign * shape[i].distanceTo2D(shape[i + 1]);
1343 for (
int i = usableIndex.front() + 1; i < (int)nodes.size(); i++) {
1344 if (nodes[i]->positionMeters == std::numeric_limits<double>::max()) {
1345 nodes[i]->positionMeters = nodes[i - 1]->positionMeters + sign * shape[i].distanceTo2D(shape[i - 1]);
1372 return std::numeric_limits<double>::max();
1378 if (type ==
"train") {
1380 }
else if (type ==
"subway") {
1382 }
else if (type ==
"aerialway") {
1384 }
else if (type ==
"light_rail" || type ==
"monorail") {
1386 }
else if (type ==
"share_taxi") {
1388 }
else if (type ==
"minibus") {
1390 }
else if (type ==
"trolleybus") {
1395 std::string stop =
"";
1398 }
else if (result ==
SVC_BUS) {
1413 bool multiLane = changeProhibition > 3;
1415 for (
int lane = 0; changeProhibition > 0 && lane < e->
getNumLanes(); lane++) {
1416 int code = changeProhibition % 4;
1421 changeProhibition = changeProhibition >> 2;
1435 for (
int lane = 0; lane < numLanes; lane++) {
1437 const int i = lefthand ? lane : numLanes - 1 - lane;
1442 if (i < (
int)designated.size() && designated[i]) {
1454 if (signs.empty()) {
1455 signs.insert(signs.begin(), signs2.begin(), signs2.end());
1457 for (
int i = 0; i < (int)
MIN2(signs.size(), signs2.size()); i++) {
1458 signs[i] |= signs2[i];
1470 for (
int i = 0; i < (int)turnSigns.size(); i++) {
1487 std::set<NIOSMNode*, CompareNodes>& uniqueNodes,
const OptionsCont& oc) :
1490 myCurrentNode(nullptr),
1492 myHierarchyLevel(0),
1493 myUniqueNodes(uniqueNodes),
1494 myImportElevation(oc.getBool(
"osm.elevation")),
1495 myDuplicateNodes(0),
1499 if (kv ==
"DEFAULT") {
1502 }
else if (kv ==
"ALL") {
1519 if (myHierarchyLevel != 2) {
1520 WRITE_ERROR(
"Node element on wrong XML hierarchy level (id='" + myLastNodeID +
1521 "', level='" +
toString(myHierarchyLevel) +
"').");
1525 if (action ==
"delete" || !ok) {
1531 myCurrentNode =
nullptr;
1532 const auto insertionIt = myToFill.lower_bound(
id);
1533 if (insertionIt == myToFill.end() || insertionIt->first !=
id) {
1535 const double tlon = attrs.
get<
double>(
SUMO_ATTR_LON, myLastNodeID.c_str(), ok);
1536 const double tlat = attrs.
get<
double>(
SUMO_ATTR_LAT, myLastNodeID.c_str(), ok);
1540 myCurrentNode =
new NIOSMNode(
id, tlon, tlat);
1545 delete myCurrentNode;
1546 myCurrentNode = *similarNode;
1549 myToFill.emplace_hint(insertionIt,
id, myCurrentNode);
1552 WRITE_ERROR(
TL(
"Attribute 'id' in the definition of a node is not of type long long int."));
1556 if (element ==
SUMO_TAG_TAG && myCurrentNode !=
nullptr) {
1557 if (myHierarchyLevel != 3) {
1558 WRITE_ERROR(
TL(
"Tag element on wrong XML hierarchy level."));
1562 const std::string& key = attrs.
get<std::string>(
SUMO_ATTR_K, myLastNodeID.c_str(), ok,
false);
1564 if (key ==
"highway" || key ==
"ele" || key ==
"crossing" || key ==
"railway" || key ==
"public_transport"
1565 || key ==
"name" || key ==
"train" || key ==
"bus" || key ==
"tram" || key ==
"light_rail" || key ==
"subway" || key ==
"station" || key ==
"noexit"
1566 || key ==
"crossing:barrier"
1567 || key ==
"crossing:light"
1568 || key ==
"railway:ref"
1572 const std::string& value = attrs.
get<std::string>(
SUMO_ATTR_V, myLastNodeID.c_str(), ok,
false);
1573 if (key ==
"highway" && value.find(
"traffic_signal") != std::string::npos) {
1574 myCurrentNode->tlsControlled =
true;
1575 }
else if (key ==
"crossing" && value.find(
"traffic_signals") != std::string::npos) {
1576 myCurrentNode->tlsControlled =
true;
1577 }
else if (key ==
"highway" && value.find(
"crossing") != std::string::npos) {
1578 myCurrentNode->pedestrianCrossing =
true;
1579 }
else if ((key ==
"noexit" && value ==
"yes")
1580 || (key ==
"railway" && value ==
"buffer_stop")) {
1581 myCurrentNode->railwayBufferStop =
true;
1582 }
else if (key ==
"railway" && value.find(
"crossing") != std::string::npos) {
1583 myCurrentNode->railwayCrossing =
true;
1584 }
else if (key ==
"crossing:barrier") {
1585 myCurrentNode->setParameter(
"crossing:barrier", value);
1586 }
else if (key ==
"crossing:light") {
1587 myCurrentNode->setParameter(
"crossing:light", value);
1588 }
else if (key ==
"railway:signal:direction") {
1589 if (value ==
"both") {
1590 myCurrentNode->myRailDirection =
WAY_BOTH;
1591 }
else if (value ==
"backward") {
1593 }
else if (value ==
"forward") {
1597 std::string kv = key +
"=" + value;
1598 std::string kglob = key +
"=";
1599 if ((std::find(myRailSignalRules.begin(), myRailSignalRules.end(), kv) != myRailSignalRules.end())
1600 || (std::find(myRailSignalRules.begin(), myRailSignalRules.end(), kglob) != myRailSignalRules.end())) {
1601 myCurrentNode->railwaySignal =
true;
1603 }
else if (
StringUtils::startsWith(key,
"railway:position") && value.size() > myCurrentNode->position.size()) {
1605 myCurrentNode->position = value;
1606 }
else if ((key ==
"public_transport" && value ==
"stop_position") ||
1607 (key ==
"highway" && value ==
"bus_stop")) {
1608 myCurrentNode->ptStopPosition =
true;
1609 if (myCurrentNode->ptStopLength == 0) {
1611 myCurrentNode->ptStopLength = myOptionsCont.getFloat(
"osm.stop-output.length");
1613 }
else if (key ==
"name") {
1614 myCurrentNode->name = value;
1615 }
else if (myImportElevation && key ==
"ele") {
1618 if (std::isnan(elevation)) {
1619 WRITE_WARNINGF(
TL(
"Value of key '%' is invalid ('%') in node '%'."), key, value, myLastNodeID);
1621 myCurrentNode->ele = elevation;
1624 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in node '%'."), key, value, myLastNodeID);
1626 }
else if (key ==
"station") {
1629 }
else if (key ==
"railway:ref") {
1630 myRailwayRef = value;
1637 const std::string info =
"node=" +
toString(myCurrentNode->id) +
", k=" + key;
1638 myCurrentNode->setParameter(key, attrs.
get<std::string>(
SUMO_ATTR_V, info.c_str(), ok,
false));
1647 if (myIsStation && myRailwayRef !=
"") {
1648 myCurrentNode->setParameter(
"railway:ref", myRailwayRef);
1650 myCurrentNode =
nullptr;
1651 myIsStation =
false;
1662 const std::map<long long int, NIOSMNode*>& osmNodes,
1663 std::map<long long int, Edge*>& toFill, std::map<long long int, Edge*>& platformShapes,
1668 myPlatformShapesMap(platformShapes),
1766 const long long int id = attrs.
get<
long long int>(
SUMO_ATTR_ID,
nullptr, ok);
1768 if (action ==
"delete" || !ok) {
1769 myCurrentEdge =
nullptr;
1772 myCurrentEdge =
new Edge(
id);
1775 if (element ==
SUMO_TAG_ND && myCurrentEdge !=
nullptr) {
1785 ref = node->second->id;
1786 if (myCurrentEdge->myCurrentNodes.empty() ||
1787 myCurrentEdge->myCurrentNodes.back() != ref) {
1788 myCurrentEdge->myCurrentNodes.push_back(ref);
1793 if (element ==
SUMO_TAG_TAG && myCurrentEdge !=
nullptr) {
1798 const std::string buswaySpec = key.substr(7);
1800 if (buswaySpec ==
"right") {
1802 }
else if (buswaySpec ==
"left") {
1804 }
else if (buswaySpec ==
"both") {
1805 myCurrentEdge->myBuswayType = (
WayType)(myCurrentEdge->myBuswayType |
WAY_BOTH);
1811 const std::string info =
"way=" +
toString(myCurrentEdge->id) +
", k=" + key;
1812 myCurrentEdge->setParameter(key, attrs.
get<std::string>(
SUMO_ATTR_V, info.c_str(), ok,
false));
1817 && key !=
"maxspeed" && key !=
"maxspeed:type"
1818 && key !=
"zone:maxspeed"
1819 && key !=
"maxspeed:forward" && key !=
"maxspeed:backward"
1820 && key !=
"junction" && key !=
"name" && key !=
"tracks" && key !=
"layer"
1825 && key !=
"highspeed"
1829 && key !=
"postal_code"
1830 && key !=
"railway:preferred_direction"
1831 && key !=
"railway:bidirectional"
1832 && key !=
"railway:track_ref"
1835 && key !=
"emergency"
1837 && key !=
"electrified"
1838 && key !=
"segregated"
1843 && key !=
"oneway:bicycle"
1844 && key !=
"oneway:bus"
1845 && key !=
"oneway:psv"
1846 && key !=
"bus:lanes"
1847 && key !=
"bus:lanes:forward"
1848 && key !=
"bus:lanes:backward"
1849 && key !=
"psv:lanes"
1850 && key !=
"psv:lanes:forward"
1851 && key !=
"psv:lanes:backward"
1852 && key !=
"bicycle:lanes"
1853 && key !=
"bicycle:lanes:forward"
1854 && key !=
"bicycle:lanes:backward"
1857 && key !=
"public_transport") {
1860 const std::string value = attrs.
get<std::string>(
SUMO_ATTR_V,
toString(myCurrentEdge->id).c_str(), ok,
false);
1864 || key ==
"aeroway" || key ==
"aerialway" || key ==
"usage" || key ==
"service") {
1866 if (key !=
"highway" || myTypeCont.knows(key +
"." + value)) {
1867 myCurrentEdge->myCurrentIsRoad =
true;
1870 if (key ==
"cycleway") {
1871 if (value ==
"no" || value ==
"none" || value ==
"separate") {
1872 myCurrentEdge->myCyclewayType =
WAY_NONE;
1873 }
else if (value ==
"both") {
1874 myCurrentEdge->myCyclewayType =
WAY_BOTH;
1875 }
else if (value ==
"right") {
1877 }
else if (value ==
"left") {
1879 }
else if (value ==
"opposite_track") {
1881 }
else if (value ==
"opposite_lane") {
1883 }
else if (value ==
"opposite") {
1888 if (key ==
"cycleway:left") {
1889 if (myCurrentEdge->myCyclewayType ==
WAY_UNKNOWN) {
1890 myCurrentEdge->myCyclewayType =
WAY_NONE;
1892 if (value ==
"yes" || value ==
"lane" || value ==
"track") {
1897 if (key ==
"cycleway:right") {
1898 if (myCurrentEdge->myCyclewayType ==
WAY_UNKNOWN) {
1899 myCurrentEdge->myCyclewayType =
WAY_NONE;
1901 if (value ==
"yes" || value ==
"lane" || value ==
"track") {
1902 myCurrentEdge->myCyclewayType = (
WayType)(myCurrentEdge->myCyclewayType |
WAY_FORWARD);
1906 if (key ==
"cycleway:both") {
1907 if (myCurrentEdge->myCyclewayType ==
WAY_UNKNOWN) {
1908 if (value ==
"no" || value ==
"none" || value ==
"separate") {
1909 myCurrentEdge->myCyclewayType =
WAY_NONE;
1911 if (value ==
"yes" || value ==
"lane" || value ==
"track") {
1912 myCurrentEdge->myCyclewayType =
WAY_BOTH;
1917 if (key ==
"cycleway" && value !=
"lane" && value !=
"track" && value !=
"opposite_track" && value !=
"opposite_lane") {
1926 if (key ==
"sidewalk") {
1927 if (value ==
"no" || value ==
"none" || value ==
"separate") {
1928 myCurrentEdge->mySidewalkType =
WAY_NONE;
1929 }
else if (value ==
"both") {
1930 myCurrentEdge->mySidewalkType =
WAY_BOTH;
1931 }
else if (value ==
"right") {
1933 }
else if (value ==
"left") {
1937 if (key ==
"sidewalk:left") {
1938 if (myCurrentEdge->mySidewalkType ==
WAY_UNKNOWN) {
1939 myCurrentEdge->mySidewalkType =
WAY_NONE;
1941 if (value ==
"yes") {
1945 if (key ==
"sidewalk:right") {
1946 if (myCurrentEdge->mySidewalkType ==
WAY_UNKNOWN) {
1947 myCurrentEdge->mySidewalkType =
WAY_NONE;
1949 if (value ==
"yes") {
1950 myCurrentEdge->mySidewalkType = (
WayType)(myCurrentEdge->mySidewalkType |
WAY_FORWARD);
1953 if (key ==
"sidewalk:both") {
1954 if (myCurrentEdge->mySidewalkType ==
WAY_UNKNOWN) {
1955 if (value ==
"no" || value ==
"none" || value ==
"separate") {
1956 myCurrentEdge->mySidewalkType =
WAY_NONE;
1958 if (value ==
"yes") {
1959 myCurrentEdge->mySidewalkType =
WAY_BOTH;
1968 if (key ==
"busway") {
1969 if (value ==
"no") {
1972 if (value ==
"opposite_track") {
1974 }
else if (value ==
"opposite_lane") {
1980 std::string singleTypeID = key +
"." + value;
1981 if (key ==
"highspeed") {
1982 if (value ==
"no") {
1985 singleTypeID =
"railway.highspeed";
1987 addType(singleTypeID);
1989 }
else if (key ==
"bus" || key ==
"psv") {
1993 myCurrentEdge->myExtraAllowed |=
SVC_BUS;
1996 myCurrentEdge->myExtraDisallowed |=
SVC_BUS;
1999 myCurrentEdge->myExtraAllowed |=
SVC_BUS;
2002 }
else if (key ==
"emergency") {
2010 }
else if (key ==
"access") {
2011 if (value ==
"no") {
2017 std::vector<double> widthLanes;
2018 for (std::string width : values) {
2020 widthLanes.push_back(parsedWidth);
2023 if (key ==
"width:lanes" || key ==
"width:lanes:forward") {
2024 myCurrentEdge->myWidthLanesForward = widthLanes;
2025 }
else if (key ==
"width:lanes:backward") {
2026 myCurrentEdge->myWidthLanesBackward = widthLanes;
2028 WRITE_WARNINGF(
TL(
"Using default lane width for edge '%' as key '%' could not be parsed."),
toString(myCurrentEdge->id), key);
2031 WRITE_WARNINGF(
TL(
"Using default lane width for edge '%' as value '%' could not be parsed."),
toString(myCurrentEdge->id), value);
2033 }
else if (key ==
"width") {
2037 WRITE_WARNINGF(
TL(
"Using default width for edge '%' as value '%' could not be parsed."),
toString(myCurrentEdge->id), value);
2039 }
else if (key ==
"foot") {
2040 if (value ==
"use_sidepath" || value ==
"no") {
2042 }
else if (value ==
"yes" || value ==
"designated" || value ==
"permissive") {
2045 }
else if (key ==
"bicycle") {
2046 if (value ==
"use_sidepath" || value ==
"no") {
2048 }
else if (value ==
"yes" || value ==
"designated" || value ==
"permissive") {
2051 }
else if (key ==
"oneway:bicycle") {
2052 myCurrentEdge->myExtraTags[
"oneway:bicycle"] = value;
2053 }
else if (key ==
"oneway:bus" || key ==
"oneway:psv") {
2054 if (value ==
"no") {
2058 }
else if (key ==
"lanes") {
2064 std::vector<std::string> list = st.
getVector();
2065 if (list.size() >= 2) {
2066 int minLanes = std::numeric_limits<int>::max();
2068 for (
auto& i : list) {
2070 minLanes =
MIN2(minLanes, numLanes);
2072 myCurrentEdge->myNoLanes = minLanes;
2075 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
2079 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
2081 }
else if (key ==
"lanes:forward") {
2084 if (myCurrentEdge->myNoLanesForward < 0 && myCurrentEdge->myNoLanes < 0) {
2086 myCurrentEdge->myNoLanes = numLanes - myCurrentEdge->myNoLanesForward;
2088 myCurrentEdge->myNoLanesForward = numLanes;
2090 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
2092 }
else if (key ==
"lanes:backward") {
2095 if (myCurrentEdge->myNoLanesForward > 0 && myCurrentEdge->myNoLanes < 0) {
2097 myCurrentEdge->myNoLanes = numLanes + myCurrentEdge->myNoLanesForward;
2100 myCurrentEdge->myNoLanesForward = -numLanes;
2102 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
2105 (key ==
"maxspeed" || key ==
"maxspeed:type" || key ==
"maxspeed:forward" || key ==
"zone:maxspeed")) {
2107 myCurrentEdge->myMaxSpeed = interpretSpeed(key, value);
2108 }
else if (key ==
"maxspeed:backward" && myCurrentEdge->myMaxSpeedBackward ==
MAXSPEED_UNGIVEN) {
2109 myCurrentEdge->myMaxSpeedBackward = interpretSpeed(key, value);
2110 }
else if (key ==
"junction") {
2111 if ((value ==
"roundabout" || value ==
"circular") && myCurrentEdge->myIsOneWay.empty()) {
2112 myCurrentEdge->myIsOneWay =
"yes";
2114 if (value ==
"roundabout") {
2115 myCurrentEdge->myAmInRoundabout =
true;
2117 }
else if (key ==
"oneway") {
2118 myCurrentEdge->myIsOneWay = value;
2119 }
else if (key ==
"name") {
2120 myCurrentEdge->streetName = value;
2121 }
else if (key ==
"ref") {
2122 myCurrentEdge->ref = value;
2123 myCurrentEdge->setParameter(
"ref", value);
2124 }
else if (key ==
"layer") {
2128 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
2130 }
else if (key ==
"tracks") {
2133 myCurrentEdge->myIsOneWay =
"true";
2135 WRITE_WARNINGF(
TL(
"Ignoring track count % for edge '%'."), value, myCurrentEdge->id);
2138 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
2140 }
else if (key ==
"railway:preferred_direction") {
2141 if (value ==
"both") {
2142 myCurrentEdge->myRailDirection =
WAY_BOTH;
2143 }
else if (myCurrentEdge->myRailDirection ==
WAY_UNKNOWN) {
2144 if (value ==
"backward") {
2146 }
else if (value ==
"forward") {
2150 }
else if (key ==
"railway:bidirectional") {
2151 if (value ==
"regular") {
2152 myCurrentEdge->myRailDirection =
WAY_BOTH;
2154 }
else if (key ==
"electrified" || key ==
"segregated") {
2155 if (value !=
"no") {
2156 myCurrentEdge->myExtraTags[key] = value;
2158 }
else if (key ==
"railway:track_ref") {
2159 myCurrentEdge->setParameter(key, value);
2160 }
else if (key ==
"public_transport" && value ==
"platform") {
2161 myCurrentEdge->myExtraTags[
"platform"] =
"yes";
2166 }
else if ((key ==
"parking:right" || key ==
"parking:lane:right") && !
StringUtils::startsWith(value,
"no")) {
2168 }
else if (key ==
"change" || key ==
"change:lanes") {
2169 myCurrentEdge->myChangeForward = myCurrentEdge->myChangeBackward = interpretChangeType(value);
2170 }
else if (key ==
"change:forward" || key ==
"change:lanes:forward") {
2171 myCurrentEdge->myChangeForward = interpretChangeType(value);
2172 }
else if (key ==
"change:backward" || key ==
"change:lanes:backward") {
2173 myCurrentEdge->myChangeBackward = interpretChangeType(value);
2174 }
else if (key ==
"vehicle:lanes" || key ==
"vehicle:lanes:forward") {
2177 }
else if (key ==
"vehicle:lanes:backward") {
2180 }
else if (key ==
"bus:lanes" || key ==
"bus:lanes:forward") {
2181 interpretLaneUse(value,
SVC_BUS,
true);
2182 }
else if (key ==
"bus:lanes:backward") {
2183 interpretLaneUse(value,
SVC_BUS,
false);
2184 }
else if (key ==
"psv:lanes" || key ==
"psv:lanes:forward") {
2185 interpretLaneUse(value,
SVC_BUS,
true);
2186 interpretLaneUse(value,
SVC_TAXI,
true);
2187 }
else if (key ==
"psv:lanes:backward") {
2188 interpretLaneUse(value,
SVC_BUS,
false);
2189 interpretLaneUse(value,
SVC_TAXI,
false);
2190 }
else if (key ==
"bicycle:lanes" || key ==
"bicycle:lanes:forward") {
2192 }
else if (key ==
"bicycle:lanes:backward") {
2206 std::vector<int> turnCodes;
2207 for (std::string codeList : values) {
2210 if (codes.size() == 0) {
2213 for (std::string code : codes) {
2214 if (code ==
"" || code ==
"none" || code ==
"through") {
2216 }
else if (code ==
"left" || code ==
"sharp_left") {
2218 }
else if (code ==
"right" || code ==
"sharp_right") {
2220 }
else if (code ==
"slight_left") {
2222 }
else if (code ==
"slight_right") {
2224 }
else if (code ==
"reverse") {
2226 }
else if (code ==
"merge_to_left" || code ==
"merge_to_right") {
2230 turnCodes.push_back(turnCode);
2248 if (!myCurrentEdge->myHighWayType.empty() && singleTypeID !=
"railway.highspeed") {
2249 if (myCurrentEdge->myHighWayType ==
"railway.highspeed") {
2254 std::vector<std::string> types =
StringTokenizer(myCurrentEdge->myHighWayType,
2256 types.push_back(singleTypeID);
2259 myCurrentEdge->myHighWayType = singleTypeID;
2266 if (mySpeedMap.find(value) != mySpeedMap.end()) {
2267 return mySpeedMap[value];
2270 if (value.size() > 3 && value[2] ==
':') {
2271 if (value.substr(3, 4) ==
"zone") {
2272 value = value.substr(7);
2274 value = value.substr(3);
2280 WRITE_WARNING(
"Value of key '" + key +
"' is not numeric ('" + value +
"') in edge '" +
2281 toString(myCurrentEdge->id) +
"'.");
2292 for (
const std::string& val : values) {
2295 }
else if (val ==
"not_left") {
2297 }
else if (val ==
"not_right") {
2300 result = result << 2;
2303 result = result >> 2;
2305 if (values.size() > 1) {
2316 std::vector<bool>& designated = forward ? myCurrentEdge->myDesignatedLaneForward : myCurrentEdge->myDesignatedLaneBackward;
2317 std::vector<SVCPermissions>& allowed = forward ? myCurrentEdge->myAllowedLaneForward : myCurrentEdge->myAllowedLaneBackward;
2318 std::vector<SVCPermissions>& disallowed = forward ? myCurrentEdge->myDisallowedLaneForward : myCurrentEdge->myDisallowedLaneBackward;
2319 designated.resize(
MAX2(designated.size(), values.size()),
false);
2323 for (
const std::string& val : values) {
2324 if (val ==
"yes" || val ==
"permissive") {
2326 }
else if (val ==
"lane" || val ==
"designated") {
2328 designated[i] =
true;
2329 }
else if (val ==
"no") {
2330 disallowed[i] |= svc;
2332 WRITE_WARNINGF(
TL(
"Unknown lane use specifier '%' ignored for way '%'"), val, myCurrentEdge->id);
2341 if (element ==
SUMO_TAG_WAY && myCurrentEdge !=
nullptr) {
2342 if (myCurrentEdge->myCurrentIsRoad) {
2343 const auto insertionIt = myEdgeMap.lower_bound(myCurrentEdge->id);
2344 if (insertionIt == myEdgeMap.end() || insertionIt->first != myCurrentEdge->id) {
2346 myEdgeMap.emplace_hint(insertionIt, myCurrentEdge->id, myCurrentEdge);
2348 delete myCurrentEdge;
2350 }
else if (myCurrentEdge->myExtraTags.count(
"platform") != 0) {
2351 const auto insertionIt = myPlatformShapesMap.lower_bound(myCurrentEdge->id);
2352 if (insertionIt == myPlatformShapesMap.end() || insertionIt->first != myCurrentEdge->id) {
2354 myPlatformShapesMap.emplace_hint(insertionIt, myCurrentEdge->id, myCurrentEdge);
2356 delete myCurrentEdge;
2359 delete myCurrentEdge;
2361 myCurrentEdge =
nullptr;
2370 const std::map<long long int, NIOSMNode*>& osmNodes,
2371 const std::map<long long int, Edge*>& osmEdges,
NBPTStopCont* nbptStopCont,
2372 const std::map<long long int, Edge*>& platformShapes,
2377 myOSMEdges(osmEdges),
2379 myNBPTStopCont(nbptStopCont),
2380 myNBPTLineCont(nbptLineCont),
2392 myIsRestriction =
false;
2399 myRestrictionType = RestrictionType::UNKNOWN;
2400 myPlatforms.clear();
2402 myPlatformStops.clear();
2404 myIsStopArea =
false;
2407 myRouteColor.setValid(
false);
2415 myCurrentRelation = attrs.
get<
long long int>(
SUMO_ATTR_ID,
nullptr, ok);
2417 if (action ==
"delete" || !ok) {
2423 myNightService =
"";
2432 const long long int ref = attrs.
get<
long long int>(
SUMO_ATTR_REF,
nullptr, ok);
2433 if (role ==
"via") {
2436 if (memberType ==
"way" && checkEdgeRef(ref)) {
2438 }
else if (memberType ==
"node") {
2445 }
else if (role ==
"from" && checkEdgeRef(ref)) {
2447 }
else if (role ==
"to" && checkEdgeRef(ref)) {
2451 myStops.push_back(ref);
2455 if (memberType ==
"way") {
2456 const std::map<long long int, NIImporter_OpenStreetMap::Edge*>::const_iterator& wayIt =
myPlatformShapes.find(ref);
2459 platform.
isWay =
true;
2461 myPlatforms.push_back(platform);
2463 }
else if (memberType ==
"node") {
2465 myStops.push_back(ref);
2466 myPlatformStops.insert(ref);
2468 platform.
isWay =
false;
2470 myPlatforms.push_back(platform);
2473 }
else if (role ==
"station") {
2475 }
else if (role.empty()) {
2477 if (memberType ==
"way") {
2478 myWays.push_back(ref);
2479 }
else if (memberType ==
"node") {
2481 if (it !=
myOSMNodes.end() && it->second->hasParameter(
"railway:ref")) {
2484 myStops.push_back(ref);
2495 if (key ==
"type" || key ==
"restriction") {
2497 if (key ==
"type" && value ==
"restriction") {
2498 myIsRestriction =
true;
2501 if (key ==
"type" && value ==
"route") {
2505 if (key ==
"restriction") {
2508 if (value.substr(0, 5) ==
"only_") {
2509 myRestrictionType = RestrictionType::ONLY;
2510 }
else if (value.substr(0, 3) ==
"no_") {
2511 myRestrictionType = RestrictionType::NO;
2517 }
else if (key ==
"except") {
2521 myRestrictionException |=
SVC_BUS;
2522 }
else if (v ==
"bicycle") {
2524 }
else if (v ==
"hgv") {
2526 }
else if (v ==
"motorcar") {
2528 }
else if (v ==
"emergency") {
2532 }
else if (key ==
"public_transport") {
2534 if (value ==
"stop_area") {
2535 myIsStopArea =
true;
2537 }
else if (key ==
"route") {
2539 if (value ==
"train" || value ==
"subway" || value ==
"light_rail" || value ==
"monorail" || value ==
"tram" || value ==
"bus"
2540 || value ==
"trolleybus" || value ==
"aerialway" || value ==
"ferry" || value ==
"share_taxi" || value ==
"minibus") {
2541 myPTRouteType = value;
2544 }
else if (key ==
"name") {
2546 }
else if (key ==
"colour") {
2551 WRITE_WARNINGF(
TL(
"Invalid color value '%' in relation %"), value, myCurrentRelation);
2553 }
else if (key ==
"ref") {
2555 }
else if (key ==
"interval" || key ==
"headway") {
2557 }
else if (key ==
"by_night") {
2566 if (myOSMEdges.find(ref) != myOSMEdges.end()) {
2577 if (myIsRestriction) {
2580 if (myRestrictionType == RestrictionType::UNKNOWN) {
2596 if (ok && !applyRestriction()) {
2599 }
else if (myIsStopArea) {
2600 for (
long long ref : myStops) {
2601 myStopAreas[ref] = myCurrentRelation;
2610 std::shared_ptr<NBPTStop> ptStop = myNBPTStopCont->get(
toString(n->
id));
2611 if (ptStop ==
nullptr) {
2618 if (myPlatform.isWay) {
2622 WRITE_WARNINGF(
TL(
"Platform '%' in relation: '%' is given as polygon, which currently is not supported."), myPlatform.ref, myCurrentRelation);
2637 WRITE_ERRORF(
"Unable to project coordinates for node '%'.", pNode->
id);
2640 p.push_back(pNodePos);
2642 if (p.size() == 0) {
2643 WRITE_WARNINGF(
TL(
"Referenced platform: '%' in relation: '%' is corrupt. Probably OSM file is incomplete."),
2648 ptStop->addPlatformCand(platform);
2659 WRITE_ERRORF(
"Unable to project coordinates for node '%'.", pNode->
id);
2661 NBPTPlatform platform(platformPos, myOptionsCont.getFloat(
"osm.stop-output.length"));
2662 ptStop->addPlatformCand(platform);
2666 ptStop->setIsMultipleStopPositions(myStops.size() > 1, myCurrentRelation);
2668 const auto& nodeIt =
myOSMNodes.find(myStation);
2671 if (station !=
nullptr) {
2679 }
else if (myPTRouteType !=
"" && myIsRoute) {
2680 NBPTLine* ptLine =
new NBPTLine(
toString(myCurrentRelation), myName, myPTRouteType, myRef, myInterval, myNightService,
2682 int consecutiveGap =
false;
2683 int missingBefore = 0;
2684 int missingAfter = 0;
2685 for (
long long ref : myStops) {
2697 if (consecutiveGap > 1) {
2698 WRITE_WARNINGF(
TL(
"PT line '%' in relation % has a gap of % stops, only keeping first part."), myName, myCurrentRelation, consecutiveGap);
2699 missingAfter = (int)myStops.size() - missingBefore - (int)ptLine->
getStops().size();
2705 const NIOSMNode*
const n = nodeIt->second;
2706 std::shared_ptr<NBPTStop> ptStop = myNBPTStopCont->get(
toString(n->
id));
2707 if (ptStop ==
nullptr) {
2711 WRITE_ERRORF(
"Unable to project coordinates for node '%'.", n->
id);
2715 myNBPTStopCont->insert(ptStop);
2716 if (myStopAreas.count(n->
id)) {
2717 ptStop->setIsMultipleStopPositions(
false, myStopAreas[n->
id]);
2719 if (myPlatformStops.count(n->
id) > 0) {
2720 ptStop->setIsPlatform();
2725 for (
long long& myWay : myWays) {
2726 auto entr = myOSMEdges.find(myWay);
2727 if (entr != myOSMEdges.end()) {
2728 Edge* edge = entr->second;
2734 ptLine->
setNumOfStops((
int)myStops.size(), missingBefore, missingAfter);
2736 WRITE_WARNINGF(
TL(
"PT line in relation % with no stops ignored. Probably OSM file is incomplete."), myCurrentRelation);
2741 if (!myNBPTLineCont->insert(ptLine)) {
2756 if (viaNode ==
nullptr) {
2762 if (from ==
nullptr) {
2766 if (to ==
nullptr) {
2770 if (myRestrictionType == RestrictionType::ONLY) {
2797 WRITE_WARNINGF(
TL(
"direction of restriction relation could not be determined%"),
"");
2805 const std::vector<NBEdge*>& candidates)
const {
2806 const std::string prefix =
toString(wayRef);
2807 const std::string backPrefix =
"-" + prefix;
2808 NBEdge* result =
nullptr;
2810 for (
auto candidate : candidates) {
2811 if ((candidate->getID().substr(0, prefix.size()) == prefix) ||
2812 (candidate->getID().substr(0, backPrefix.size()) == backPrefix)) {
2818 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 connctions
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 connctions
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)
void setFringeType(FringeType fringeType)
set fringe type
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.
int cleanupDeleted(NBEdgeCont &cont)
remove stops on non existing (removed) edges
const std::map< std::string, std::shared_ptr< NBPTStop > > & getStops() const
Returns an unmodifiable reference to the stored pt stops.
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.
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.
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.
WayType myRailDirection
Information about the direction(s) of railway usage.
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.
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
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
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.
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
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.
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 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
NBNode * node
the NBNode that was instantiated
double positionMeters
position converted to m (using highest precision available)
std::string position
kilometrage/mileage
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.
bool railwaySignal
Whether this is a railway (main) signal.
WayType myRailDirection
Information about the direction(s) of railway usage.