58 #define KM_PER_MILE 1.609344
112 importer.
load(oc, nb);
124 delete myEdge.second;
128 delete myPlatformShape.second;
134 if (!oc.
isSet(
"osm-files")) {
137 const std::vector<std::string> files = oc.
getStringVector(
"osm-files");
138 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;
252 NBNode* currentFrom = first;
254 std::vector<long long int> passed;
256 passed.push_back(*j);
259 running =
insertEdge(e, running, currentFrom, currentTo, passed, nb, first, last);
260 currentFrom = currentTo;
262 passed.push_back(*j);
268 insertEdge(e, running, currentFrom, last, passed, nb, first, last);
281 for (
const auto& nodeIt : nc) {
282 NBNode*
const n = nodeIt.second;
286 size_t incomingEdgesNo = incomingEdges.size();
287 size_t outgoingEdgesNo = outgoingEdges.size();
289 for (
size_t i = 0; i < incomingEdgesNo; i++) {
297 auto const iEdge = incomingEdges[i];
301 std::string
const& iEdgeId = iEdge->getID();
302 std::size_t
const m = iEdgeId.find_first_of(
"#");
303 std::string
const& iWayId = iEdgeId.substr(0, m);
304 for (
size_t j = 0; j < outgoingEdgesNo; j++) {
305 auto const oEdge = outgoingEdges[j];
308 if (oEdge->getID().find(iWayId) != std::string::npos
310 && oEdge->getID().rfind(iWayId, 0) != 0) {
313 edgeVector.push_back(oEdge);
323 for (
size_t i = 0; i < outgoingEdgesNo; i++) {
325 auto const oEdge = outgoingEdges[i];
329 std::string
const& oEdgeId = oEdge->getID();
330 std::size_t
const m = oEdgeId.find_first_of(
"#");
331 std::string
const& iWayId = oEdgeId.substr(0, m);
332 for (
size_t j = 0; j < incomingEdgesNo; j++) {
333 auto const iEdge = incomingEdges[j];
334 if (iEdge->getID().find(iWayId) != std::string::npos
336 && iEdge->getID().rfind(iWayId, 0) != 0) {
339 edgeVector.push_back(iEdge);
354 const double layerElevation = oc.
getFloat(
"osm.layer-elevation");
355 if (layerElevation > 0) {
367 for (
const std::string& file : files) {
368 if (readers[idx] !=
nullptr) {
370 readers[idx]->setHandler(relationHandler);
380 std::set<std::string> stopNames;
382 stopNames.insert(item.second->getName());
389 WRITE_ERRORF(
"Unable to project coordinates for node '%'.", n->
id);
401 if (node ==
nullptr) {
405 WRITE_ERRORF(
"Unable to project coordinates for junction '%'.",
id);
418 }
else if (n->
getParameter(
"crossing.light") ==
"yes") {
430 if (!tlsc.
insert(tlDef)) {
436 node->
setParameter(
"computePedestrianCrossing",
"true");
457 const std::vector<long long int>& passed,
NBNetBuilder& nb,
467 if (from ==
nullptr || to ==
nullptr) {
468 WRITE_ERRORF(
"Discarding edge '%' because the nodes could not be built.",
id);
477 assert(passed.size() >= 2);
478 if (passed.size() == 2) {
479 WRITE_WARNINGF(
TL(
"Discarding edge '%' which connects two identical nodes without geometry."),
id);
483 int intermediateIndex = (int) passed.size() / 2;
485 std::vector<long long int> part1(passed.begin(), passed.begin() + intermediateIndex + 1);
486 std::vector<long long int> part2(passed.begin() + intermediateIndex, passed.end());
487 index =
insertEdge(e, index, from, intermediate, part1, nb, first, last);
488 return insertEdge(e, index, intermediate, to, part2, nb, first, last);
490 const int newIndex = index + 1;
504 SVCPermissions permissions = (defaultPermissions & ~extraDis) | extra;
505 if (defaultPermissions ==
SVC_SHIP) {
507 permissions = defaultPermissions;
510 defaultsToOneWay =
false;
518 double distanceStart =
myOSMNodes[passed.front()]->positionMeters;
519 double distanceEnd =
myOSMNodes[passed.back()]->positionMeters;
520 const bool useDistance = distanceStart != std::numeric_limits<double>::max() && distanceEnd != std::numeric_limits<double>::max();
523 if (distanceStart < distanceEnd) {
536 std::vector<std::shared_ptr<NBPTStop> > ptStops;
537 for (
long long i : passed) {
541 std::shared_ptr<NBPTStop> existingPtStop = sc.
get(
toString(n->
id));
542 if (existingPtStop !=
nullptr) {
543 existingPtStop->registerAdditionalEdge(
toString(e->
id),
id);
547 WRITE_ERRORF(
"Unable to project coordinates for node '%'.", n->
id);
550 sc.
insert(ptStops.back());
557 shape.push_back(pos);
559 #ifdef DEBUG_LAYER_ELEVATION
560 if (e->
id ==
"DEBUGID") {
565 <<
" nodeDirection=" << nodeDirection
577 WRITE_ERRORF(
"Unable to project coordinates for edge '%'.",
id);
583 if (streetName == e->
ref) {
600 const std::string& onewayBike = e->
myExtraTags[
"oneway:bicycle"];
601 if (onewayBike ==
"false" || onewayBike ==
"no" || onewayBike ==
"0") {
612 bool addForward =
true;
613 bool addBackward =
true;
614 const bool explicitTwoWay = e->
myIsOneWay ==
"no";
630 if (addBackward && (onewayBike ==
"true" || onewayBike ==
"yes" || onewayBike ==
"1")) {
633 if (addForward && (onewayBike ==
"reverse" || onewayBike ==
"-1")) {
636 if (!addBackward && (onewayBike ==
"false" || onewayBike ==
"no" || onewayBike ==
"0")) {
643 if (addForward && !addBackward) {
645 }
else if (!addForward && addBackward) {
653 numLanesForward = (int) std::ceil(e->
myNoLanes / 2.0);
655 numLanesBackward = e->
myNoLanes - numLanesForward;
658 numLanesForward =
MAX2(1, numLanesForward);
659 numLanesBackward =
MAX2(1, numLanesBackward);
682 numLanesBackward = 1;
685 const int taggedLanes = (addForward ? numLanesForward : 0) + (addBackward ? numLanesBackward : 0);
689 forwardWidth = e->
myWidth / taggedLanes;
690 backwardWidth = forwardWidth;
697 double speedBackward = speed;
701 if (speed <= 0 || speedBackward <= 0) {
708 if (!addForward && (cyclewayType &
WAY_FORWARD) != 0) {
711 forwardWidth = bikeLaneWidth;
716 if (!addBackward && (cyclewayType &
WAY_BACKWARD) != 0) {
719 backwardWidth = bikeLaneWidth;
720 numLanesBackward = 1;
732 if (!addForward && (sidewalkType &
WAY_FORWARD) != 0) {
739 }
else if (addSidewalk && addForward && (sidewalkType &
WAY_BOTH) == 0
740 && numLanesForward == 1 && numLanesBackward <= 1
747 if (!addBackward && (sidewalkType &
WAY_BACKWARD) != 0) {
751 numLanesBackward = 1;
754 }
else if (addSidewalk && addBackward && (sidewalkType &
WAY_BOTH) == 0
755 && numLanesBackward == 1 && numLanesForward <= 1
767 const int offsetFactor = lefthand ? -1 : 1;
779 const std::string reverseID =
"-" + id;
782 assert(numLanesForward > 0);
786 if (markOSMDirection) {
823 if ((
int)nbe->
getLanes().size() != numForwardLanesFromWidthKey) {
824 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."),
825 id, nbe->
getLanes().size(), numForwardLanesFromWidthKey);
827 for (
int i = 0; i < numForwardLanesFromWidthKey; i++) {
829 const int laneIndex = lefthand ? i : numForwardLanesFromWidthKey - i - 1;
841 assert(numLanesBackward > 0);
845 if (markOSMDirection) {
876 if ((
int)nbe->
getLanes().size() != numBackwardLanesFromWidthKey) {
877 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."),
878 id, nbe->
getLanes().size(), numBackwardLanesFromWidthKey);
880 for (
int i = 0; i < numBackwardLanesFromWidthKey; i++) {
882 const int laneIndex = lefthand ? i : numBackwardLanesFromWidthKey - i - 1;
926 std::set<NIOSMNode*, CompareNodes>& uniqueNodes,
const OptionsCont& oc) :
929 myCurrentNode(nullptr),
931 myUniqueNodes(uniqueNodes),
932 myImportElevation(oc.getBool(
"osm.elevation")),
937 if (kv ==
"DEFAULT") {
940 }
else if (kv ==
"ALL") {
957 if (myHierarchyLevel != 2) {
958 WRITE_ERROR(
"Node element on wrong XML hierarchy level (id='" + myLastNodeID +
959 "', level='" +
toString(myHierarchyLevel) +
"').");
963 if (action ==
"delete" || !ok) {
969 myCurrentNode =
nullptr;
970 const auto insertionIt = myToFill.lower_bound(
id);
971 if (insertionIt == myToFill.end() || insertionIt->first !=
id) {
973 const double tlon = attrs.
get<
double>(
SUMO_ATTR_LON, myLastNodeID.c_str(), ok);
974 const double tlat = attrs.
get<
double>(
SUMO_ATTR_LAT, myLastNodeID.c_str(), ok);
978 myCurrentNode =
new NIOSMNode(
id, tlon, tlat);
983 delete myCurrentNode;
984 myCurrentNode = *similarNode;
987 myToFill.emplace_hint(insertionIt,
id, myCurrentNode);
990 WRITE_ERROR(
TL(
"Attribute 'id' in the definition of a node is not of type long long int."));
994 if (element ==
SUMO_TAG_TAG && myCurrentNode !=
nullptr) {
995 if (myHierarchyLevel != 3) {
996 WRITE_ERROR(
TL(
"Tag element on wrong XML hierarchy level."));
1000 const std::string& key = attrs.
get<std::string>(
SUMO_ATTR_K, myLastNodeID.c_str(), ok,
false);
1002 if (key ==
"highway" || key ==
"ele" || key ==
"crossing" || key ==
"railway" || key ==
"public_transport"
1003 || key ==
"name" || key ==
"train" || key ==
"bus" || key ==
"tram" || key ==
"light_rail" || key ==
"subway" || key ==
"station" || key ==
"noexit"
1004 || key ==
"crossing:barrier"
1005 || key ==
"crossing:light"
1009 const std::string& value = attrs.
get<std::string>(
SUMO_ATTR_V, myLastNodeID.c_str(), ok,
false);
1010 if (key ==
"highway" && value.find(
"traffic_signal") != std::string::npos) {
1011 myCurrentNode->tlsControlled =
true;
1012 }
else if (key ==
"crossing" && value.find(
"traffic_signals") != std::string::npos) {
1013 myCurrentNode->tlsControlled =
true;
1014 }
else if (key ==
"highway" && value.find(
"crossing") != std::string::npos) {
1015 myCurrentNode->pedestrianCrossing =
true;
1016 }
else if ((key ==
"noexit" && value ==
"yes")
1017 || (key ==
"railway" && value ==
"buffer_stop")) {
1018 myCurrentNode->railwayBufferStop =
true;
1019 }
else if (key ==
"railway" && value.find(
"crossing") != std::string::npos) {
1020 myCurrentNode->railwayCrossing =
true;
1021 }
else if (key ==
"crossing:barrier") {
1022 myCurrentNode->setParameter(
"crossing:barrier", value);
1023 }
else if (key ==
"crossing:light") {
1024 myCurrentNode->setParameter(
"crossing:light", value);
1025 }
else if (key ==
"railway:signal:direction") {
1026 if (value ==
"both") {
1027 myCurrentNode->myRailDirection =
WAY_BOTH;
1028 }
else if (value ==
"backward") {
1030 }
else if (value ==
"forward") {
1034 std::string kv = key +
"=" + value;
1035 std::string kglob = key +
"=";
1036 if ((std::find(myRailSignalRules.begin(), myRailSignalRules.end(), kv) != myRailSignalRules.end())
1037 || (std::find(myRailSignalRules.begin(), myRailSignalRules.end(), kglob) != myRailSignalRules.end())) {
1038 myCurrentNode->railwaySignal =
true;
1040 }
else if (
StringUtils::startsWith(key,
"railway:position") && value.size() > myCurrentNode->position.size()) {
1042 myCurrentNode->position = value;
1043 }
else if ((key ==
"public_transport" && value ==
"stop_position") ||
1044 (key ==
"highway" && value ==
"bus_stop")) {
1045 myCurrentNode->ptStopPosition =
true;
1046 if (myCurrentNode->ptStopLength == 0) {
1048 myCurrentNode->ptStopLength = myOptionsCont.getFloat(
"osm.stop-output.length");
1050 }
else if (key ==
"name") {
1051 myCurrentNode->name = value;
1052 }
else if (myImportElevation && key ==
"ele") {
1055 if (std::isnan(elevation)) {
1056 WRITE_WARNINGF(
TL(
"Value of key '%' is invalid ('%') in node '%'."), key, value, myLastNodeID);
1058 myCurrentNode->ele = elevation;
1061 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in node '%'."), key, value, myLastNodeID);
1063 }
else if (key ==
"station") {
1071 const std::string info =
"node=" +
toString(myCurrentNode->id) +
", k=" + key;
1072 myCurrentNode->setParameter(key, attrs.
get<std::string>(
SUMO_ATTR_V, info.c_str(), ok,
false));
1081 myCurrentNode =
nullptr;
1091 const std::map<long long int, NIOSMNode*>& osmNodes,
1092 std::map<long long int, Edge*>& toFill, std::map<long long int, Edge*>& platformShapes):
1096 myPlatformShapesMap(platformShapes) {
1191 const long long int id = attrs.
get<
long long int>(
SUMO_ATTR_ID,
nullptr, ok);
1193 if (action ==
"delete" || !ok) {
1194 myCurrentEdge =
nullptr;
1197 myCurrentEdge =
new Edge(
id);
1200 if (element ==
SUMO_TAG_ND && myCurrentEdge !=
nullptr) {
1210 ref = node->second->id;
1211 if (myCurrentEdge->myCurrentNodes.empty() ||
1212 myCurrentEdge->myCurrentNodes.back() != ref) {
1213 myCurrentEdge->myCurrentNodes.push_back(ref);
1218 if (element ==
SUMO_TAG_TAG && myCurrentEdge !=
nullptr) {
1223 const std::string buswaySpec = key.substr(7);
1225 if (buswaySpec ==
"right") {
1227 }
else if (buswaySpec ==
"left") {
1229 }
else if (buswaySpec ==
"both") {
1230 myCurrentEdge->myBuswayType = (
WayType)(myCurrentEdge->myBuswayType |
WAY_BOTH);
1236 const std::string info =
"way=" +
toString(myCurrentEdge->id) +
", k=" + key;
1237 myCurrentEdge->setParameter(key, attrs.
get<std::string>(
SUMO_ATTR_V, info.c_str(), ok,
false));
1242 && key !=
"maxspeed" && key !=
"maxspeed:type"
1243 && key !=
"zone:maxspeed"
1244 && key !=
"maxspeed:forward" && key !=
"maxspeed:backward"
1245 && key !=
"junction" && key !=
"name" && key !=
"tracks" && key !=
"layer"
1250 && key !=
"highspeed"
1254 && key !=
"postal_code"
1255 && key !=
"railway:preferred_direction"
1256 && key !=
"railway:bidirectional"
1257 && key !=
"railway:track_ref"
1260 && key !=
"emergency"
1262 && key !=
"electrified"
1263 && key !=
"segregated"
1268 && key !=
"oneway:bicycle"
1269 && key !=
"oneway:bus"
1270 && key !=
"bus:lanes"
1271 && key !=
"bus:lanes:forward"
1272 && key !=
"bus:lanes:backward"
1273 && key !=
"psv:lanes"
1274 && key !=
"psv:lanes:forward"
1275 && key !=
"psv:lanes:backward"
1276 && key !=
"bicycle:lanes"
1277 && key !=
"bicycle:lanes:forward"
1278 && key !=
"bicycle:lanes:backward"
1281 && key !=
"public_transport") {
1284 const std::string value = attrs.
get<std::string>(
SUMO_ATTR_V,
toString(myCurrentEdge->id).c_str(), ok,
false);
1286 if ((key ==
"highway" && value !=
"platform") || key ==
"railway" || key ==
"waterway" ||
StringUtils::startsWith(key,
"cycleway")
1288 || key ==
"aeroway" || key ==
"aerialway" || key ==
"usage" || key ==
"service") {
1290 myCurrentEdge->myCurrentIsRoad =
true;
1292 if (key ==
"cycleway") {
1293 if (value ==
"no" || value ==
"none" || value ==
"separate") {
1294 myCurrentEdge->myCyclewayType =
WAY_NONE;
1295 }
else if (value ==
"both") {
1296 myCurrentEdge->myCyclewayType =
WAY_BOTH;
1297 }
else if (value ==
"right") {
1299 }
else if (value ==
"left") {
1301 }
else if (value ==
"opposite_track") {
1303 }
else if (value ==
"opposite_lane") {
1305 }
else if (value ==
"opposite") {
1310 if (key ==
"cycleway:left") {
1311 if (myCurrentEdge->myCyclewayType ==
WAY_UNKNOWN) {
1312 myCurrentEdge->myCyclewayType =
WAY_NONE;
1314 if (value ==
"yes" || value ==
"lane" || value ==
"track") {
1319 if (key ==
"cycleway:right") {
1320 if (myCurrentEdge->myCyclewayType ==
WAY_UNKNOWN) {
1321 myCurrentEdge->myCyclewayType =
WAY_NONE;
1323 if (value ==
"yes" || value ==
"lane" || value ==
"track") {
1324 myCurrentEdge->myCyclewayType = (
WayType)(myCurrentEdge->myCyclewayType |
WAY_FORWARD);
1328 if (key ==
"cycleway:both") {
1329 if (myCurrentEdge->myCyclewayType ==
WAY_UNKNOWN) {
1330 if (value ==
"no" || value ==
"none" || value ==
"separate") {
1331 myCurrentEdge->myCyclewayType =
WAY_NONE;
1333 if (value ==
"yes" || value ==
"lane" || value ==
"track") {
1334 myCurrentEdge->myCyclewayType =
WAY_BOTH;
1339 if (key ==
"cycleway" && value !=
"lane" && value !=
"track" && value !=
"opposite_track" && value !=
"opposite_lane") {
1348 if (key ==
"sidewalk") {
1349 if (value ==
"no" || value ==
"none" || value ==
"separate") {
1350 myCurrentEdge->mySidewalkType =
WAY_NONE;
1351 }
else if (value ==
"both") {
1352 myCurrentEdge->mySidewalkType =
WAY_BOTH;
1353 }
else if (value ==
"right") {
1355 }
else if (value ==
"left") {
1359 if (key ==
"sidewalk:left") {
1360 if (myCurrentEdge->mySidewalkType ==
WAY_UNKNOWN) {
1361 myCurrentEdge->mySidewalkType =
WAY_NONE;
1363 if (value ==
"yes") {
1367 if (key ==
"sidewalk:right") {
1368 if (myCurrentEdge->mySidewalkType ==
WAY_UNKNOWN) {
1369 myCurrentEdge->mySidewalkType =
WAY_NONE;
1371 if (value ==
"yes") {
1372 myCurrentEdge->mySidewalkType = (
WayType)(myCurrentEdge->mySidewalkType |
WAY_FORWARD);
1375 if (key ==
"sidewalk:both") {
1376 if (myCurrentEdge->mySidewalkType ==
WAY_UNKNOWN) {
1377 if (value ==
"no" || value ==
"none" || value ==
"separate") {
1378 myCurrentEdge->mySidewalkType =
WAY_NONE;
1380 if (value ==
"yes") {
1381 myCurrentEdge->mySidewalkType =
WAY_BOTH;
1390 if (key ==
"busway") {
1391 if (value ==
"no") {
1394 if (value ==
"opposite_track") {
1396 }
else if (value ==
"opposite_lane") {
1402 std::string singleTypeID = key +
"." + value;
1403 if (key ==
"highspeed") {
1404 if (value ==
"no") {
1407 singleTypeID =
"railway.highspeed";
1410 if (!myCurrentEdge->myHighWayType.empty() && singleTypeID !=
"railway.highspeed") {
1411 if (myCurrentEdge->myHighWayType ==
"railway.highspeed") {
1416 std::vector<std::string> types =
StringTokenizer(myCurrentEdge->myHighWayType,
1418 types.push_back(singleTypeID);
1421 myCurrentEdge->myHighWayType = singleTypeID;
1423 }
else if (key ==
"bus" || key ==
"psv") {
1427 myCurrentEdge->myExtraAllowed |=
SVC_BUS;
1429 myCurrentEdge->myExtraDisallowed |=
SVC_BUS;
1432 myCurrentEdge->myExtraAllowed |=
SVC_BUS;
1434 }
else if (key ==
"emergency") {
1442 }
else if (key ==
"access") {
1443 if (value ==
"no") {
1449 std::vector<double> widthLanes;
1450 for (std::string width : values) {
1451 double parsedWidth = width ==
""
1454 widthLanes.push_back(parsedWidth);
1457 if (key ==
"width:lanes" || key ==
"width:lanes:forward") {
1458 myCurrentEdge->myWidthLanesForward = widthLanes;
1459 }
else if (key ==
"width:lanes:backward") {
1460 myCurrentEdge->myWidthLanesBackward = widthLanes;
1462 WRITE_WARNINGF(
TL(
"Using default lane width for edge '%' as key '%' could not be parsed."),
toString(myCurrentEdge->id), key);
1465 WRITE_WARNINGF(
TL(
"Using default lane width for edge '%' as value '%' could not be parsed."),
toString(myCurrentEdge->id), value);
1467 }
else if (key ==
"width") {
1471 WRITE_WARNINGF(
TL(
"Using default width for edge '%' as value '%' could not be parsed."),
toString(myCurrentEdge->id), value);
1473 }
else if (key ==
"foot") {
1474 if (value ==
"use_sidepath" || value ==
"no") {
1476 }
else if (value ==
"yes" || value ==
"designated" || value ==
"permissive") {
1479 }
else if (key ==
"bicycle") {
1480 if (value ==
"use_sidepath" || value ==
"no") {
1482 }
else if (value ==
"yes" || value ==
"designated" || value ==
"permissive") {
1485 }
else if (key ==
"oneway:bicycle") {
1486 myCurrentEdge->myExtraTags[
"oneway:bicycle"] = value;
1487 }
else if (key ==
"oneway:bus") {
1488 if (value ==
"no") {
1492 }
else if (key ==
"lanes") {
1498 std::vector<std::string> list = st.
getVector();
1499 if (list.size() >= 2) {
1500 int minLanes = std::numeric_limits<int>::max();
1502 for (
auto& i : list) {
1504 minLanes =
MIN2(minLanes, numLanes);
1506 myCurrentEdge->myNoLanes = minLanes;
1509 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
1513 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
1515 }
else if (key ==
"lanes:forward") {
1518 if (myCurrentEdge->myNoLanesForward < 0 && myCurrentEdge->myNoLanes < 0) {
1520 myCurrentEdge->myNoLanes = numLanes - myCurrentEdge->myNoLanesForward;
1522 myCurrentEdge->myNoLanesForward = numLanes;
1524 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
1526 }
else if (key ==
"lanes:backward") {
1529 if (myCurrentEdge->myNoLanesForward > 0 && myCurrentEdge->myNoLanes < 0) {
1531 myCurrentEdge->myNoLanes = numLanes + myCurrentEdge->myNoLanesForward;
1534 myCurrentEdge->myNoLanesForward = -numLanes;
1536 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
1539 (key ==
"maxspeed" || key ==
"maxspeed:type" || key ==
"maxspeed:forward" || key ==
"zone:maxspeed")) {
1541 myCurrentEdge->myMaxSpeed = interpretSpeed(key, value);
1542 }
else if (key ==
"maxspeed:backward" && myCurrentEdge->myMaxSpeedBackward ==
MAXSPEED_UNGIVEN) {
1543 myCurrentEdge->myMaxSpeedBackward = interpretSpeed(key, value);
1544 }
else if (key ==
"junction") {
1545 if ((value ==
"roundabout" || value ==
"circular") && myCurrentEdge->myIsOneWay.empty()) {
1546 myCurrentEdge->myIsOneWay =
"yes";
1548 if (value ==
"roundabout") {
1549 myCurrentEdge->myAmInRoundabout =
true;
1551 }
else if (key ==
"oneway") {
1552 myCurrentEdge->myIsOneWay = value;
1553 }
else if (key ==
"name") {
1554 myCurrentEdge->streetName = value;
1555 }
else if (key ==
"ref") {
1556 myCurrentEdge->ref = value;
1557 myCurrentEdge->setParameter(
"ref", value);
1558 }
else if (key ==
"layer") {
1562 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
1564 }
else if (key ==
"tracks") {
1567 myCurrentEdge->myIsOneWay =
"true";
1569 WRITE_WARNINGF(
TL(
"Ignoring track count % for edge '%'."), value, myCurrentEdge->id);
1572 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
1574 }
else if (key ==
"railway:preferred_direction") {
1575 if (value ==
"both") {
1576 myCurrentEdge->myRailDirection =
WAY_BOTH;
1577 }
else if (myCurrentEdge->myRailDirection ==
WAY_UNKNOWN) {
1578 if (value ==
"backward") {
1580 }
else if (value ==
"forward") {
1584 }
else if (key ==
"railway:bidirectional") {
1585 if (value ==
"regular") {
1586 myCurrentEdge->myRailDirection =
WAY_BOTH;
1588 }
else if (key ==
"electrified" || key ==
"segregated") {
1589 if (value !=
"no") {
1590 myCurrentEdge->myExtraTags[key] = value;
1592 }
else if (key ==
"railway:track_ref") {
1593 myCurrentEdge->setParameter(key, value);
1594 }
else if (key ==
"public_transport" && value ==
"platform") {
1595 myCurrentEdge->myExtraTags[
"platform"] =
"yes";
1602 }
else if (key ==
"change" || key ==
"change:lanes") {
1603 myCurrentEdge->myChangeForward = myCurrentEdge->myChangeBackward = interpretChangeType(value);
1604 }
else if (key ==
"change:forward" || key ==
"change:lanes:forward") {
1605 myCurrentEdge->myChangeForward = interpretChangeType(value);
1606 }
else if (key ==
"change:backward" || key ==
"change:lanes:backward") {
1607 myCurrentEdge->myChangeBackward = interpretChangeType(value);
1608 }
else if (key ==
"vehicle:lanes" || key ==
"vehicle:lanes:forward") {
1611 }
else if (key ==
"vehicle:lanes:backward") {
1614 }
else if (key ==
"bus:lanes" || key ==
"bus:lanes:forward") {
1615 interpretLaneUse(value,
SVC_BUS,
true);
1616 }
else if (key ==
"bus:lanes:backward") {
1617 interpretLaneUse(value,
SVC_BUS,
false);
1618 }
else if (key ==
"psv:lanes" || key ==
"psv:lanes:forward") {
1619 interpretLaneUse(value,
SVC_BUS,
true);
1620 interpretLaneUse(value,
SVC_TAXI,
true);
1621 }
else if (key ==
"psv:lanes:backward") {
1622 interpretLaneUse(value,
SVC_BUS,
false);
1623 interpretLaneUse(value,
SVC_TAXI,
false);
1624 }
else if (key ==
"bicycle:lanes" || key ==
"bicycle:lanes:forward") {
1626 }
else if (key ==
"bicycle:lanes:backward") {
1640 std::vector<int> turnCodes;
1641 for (std::string codeList : values) {
1644 if (codes.size() == 0) {
1647 for (std::string code : codes) {
1648 if (code ==
"" || code ==
"none" || code ==
"through") {
1650 }
else if (code ==
"left" || code ==
"sharp_left") {
1652 }
else if (code ==
"right" || code ==
"sharp_right") {
1654 }
else if (code ==
"slight_left") {
1656 }
else if (code ==
"slight_right") {
1658 }
else if (code ==
"reverse") {
1660 }
else if (code ==
"merge_to_left" || code ==
"merge_to_right") {
1664 turnCodes.push_back(turnCode);
1681 if (mySpeedMap.find(value) != mySpeedMap.end()) {
1682 return mySpeedMap[value];
1685 if (value.size() > 3 && value[2] ==
':') {
1686 if (value.substr(3, 4) ==
"zone") {
1687 value = value.substr(7);
1689 value = value.substr(3);
1692 double conversion = 1;
1702 WRITE_WARNING(
"Value of key '" + key +
"' is not numeric ('" + value +
"') in edge '" +
1703 toString(myCurrentEdge->id) +
"'.");
1714 for (
const std::string& val : values) {
1717 }
else if (val ==
"not_left") {
1719 }
else if (val ==
"not_right") {
1722 result = result << 2;
1725 result = result >> 2;
1727 if (values.size() > 1) {
1738 std::vector<bool>& designated = forward ? myCurrentEdge->myDesignatedLaneForward : myCurrentEdge->myDesignatedLaneBackward;
1739 std::vector<SVCPermissions>& allowed = forward ? myCurrentEdge->myAllowedLaneForward : myCurrentEdge->myAllowedLaneBackward;
1740 std::vector<SVCPermissions>& disallowed = forward ? myCurrentEdge->myDisallowedLaneForward : myCurrentEdge->myDisallowedLaneBackward;
1741 designated.resize(
MAX2(designated.size(), values.size()),
false);
1745 for (
const std::string& val : values) {
1746 if (val ==
"yes" || val ==
"permissive") {
1748 }
else if (val ==
"lane" || val ==
"designated") {
1750 designated[i] =
true;
1751 }
else if (val ==
"no") {
1752 disallowed[i] |= svc;
1754 WRITE_WARNINGF(
TL(
"Unknown lane use specifier '%' ignored for way '%'"), val, myCurrentEdge->id);
1763 if (element ==
SUMO_TAG_WAY && myCurrentEdge !=
nullptr) {
1764 if (myCurrentEdge->myCurrentIsRoad) {
1765 const auto insertionIt = myEdgeMap.lower_bound(myCurrentEdge->id);
1766 if (insertionIt == myEdgeMap.end() || insertionIt->first != myCurrentEdge->id) {
1768 myEdgeMap.emplace_hint(insertionIt, myCurrentEdge->id, myCurrentEdge);
1770 delete myCurrentEdge;
1772 }
else if (myCurrentEdge->myExtraTags.count(
"platform") != 0) {
1773 const auto insertionIt = myPlatformShapesMap.lower_bound(myCurrentEdge->id);
1774 if (insertionIt == myPlatformShapesMap.end() || insertionIt->first != myCurrentEdge->id) {
1776 myPlatformShapesMap.emplace_hint(insertionIt, myCurrentEdge->id, myCurrentEdge);
1778 delete myCurrentEdge;
1781 delete myCurrentEdge;
1783 myCurrentEdge =
nullptr;
1792 const std::map<long long int, NIOSMNode*>& osmNodes,
1793 const std::map<long long int, Edge*>& osmEdges,
NBPTStopCont* nbptStopCont,
1794 const std::map<long long int, Edge*>& platformShapes,
1799 myOSMEdges(osmEdges),
1801 myNBPTStopCont(nbptStopCont),
1802 myNBPTLineCont(nbptLineCont),
1814 myIsRestriction =
false;
1820 myRestrictionType = RestrictionType::UNKNOWN;
1821 myPlatforms.clear();
1823 myPlatformStops.clear();
1825 myIsStopArea =
false;
1828 myRouteColor.setValid(
false);
1836 myCurrentRelation = attrs.
get<
long long int>(
SUMO_ATTR_ID,
nullptr, ok);
1838 if (action ==
"delete" || !ok) {
1844 myNightService =
"";
1853 const long long int ref = attrs.
get<
long long int>(
SUMO_ATTR_REF,
nullptr, ok);
1854 if (role ==
"via") {
1857 if (memberType ==
"way" && checkEdgeRef(ref)) {
1859 }
else if (memberType ==
"node") {
1866 }
else if (role ==
"from" && checkEdgeRef(ref)) {
1868 }
else if (role ==
"to" && checkEdgeRef(ref)) {
1870 }
else if (role ==
"stop") {
1871 myStops.push_back(ref);
1872 }
else if (role ==
"platform") {
1874 if (memberType ==
"way") {
1875 const std::map<long long int, NIImporter_OpenStreetMap::Edge*>::const_iterator& wayIt =
myPlatformShapes.find(ref);
1878 platform.
isWay =
true;
1880 myPlatforms.push_back(platform);
1882 }
else if (memberType ==
"node") {
1884 myStops.push_back(ref);
1885 myPlatformStops.insert(ref);
1887 platform.
isWay =
false;
1889 myPlatforms.push_back(platform);
1892 }
else if (role.empty()) {
1894 if (memberType ==
"way") {
1895 myWays.push_back(ref);
1896 }
else if (memberType ==
"node") {
1897 myStops.push_back(ref);
1907 if (key ==
"type" || key ==
"restriction") {
1909 if (key ==
"type" && value ==
"restriction") {
1910 myIsRestriction =
true;
1913 if (key ==
"type" && value ==
"route") {
1917 if (key ==
"restriction") {
1920 if (value.substr(0, 5) ==
"only_") {
1921 myRestrictionType = RestrictionType::ONLY;
1922 }
else if (value.substr(0, 3) ==
"no_") {
1923 myRestrictionType = RestrictionType::NO;
1929 }
else if (key ==
"except") {
1933 myRestrictionException |=
SVC_BUS;
1934 }
else if (v ==
"bicycle") {
1936 }
else if (v ==
"hgv") {
1938 }
else if (v ==
"motorcar") {
1940 }
else if (v ==
"emergency") {
1944 }
else if (key ==
"public_transport") {
1946 if (value ==
"stop_area") {
1947 myIsStopArea =
true;
1949 }
else if (key ==
"route") {
1951 if (value ==
"train" || value ==
"subway" || value ==
"light_rail" || value ==
"monorail" || value ==
"tram" || value ==
"bus"
1952 || value ==
"trolleybus" || value ==
"aerialway" || value ==
"ferry" || value ==
"share_taxi" || value ==
"minibus") {
1953 myPTRouteType = value;
1956 }
else if (key ==
"name") {
1958 }
else if (key ==
"colour") {
1963 WRITE_WARNINGF(
TL(
"Invalid color value '%' in relation %"), value, myCurrentRelation);
1965 }
else if (key ==
"ref") {
1967 }
else if (key ==
"interval" || key ==
"headway") {
1969 }
else if (key ==
"by_night") {
1978 if (myOSMEdges.find(ref) != myOSMEdges.end()) {
1989 if (myIsRestriction) {
1992 if (myRestrictionType == RestrictionType::UNKNOWN) {
2008 if (ok && !applyRestriction()) {
2011 }
else if (myIsStopArea) {
2012 for (
long long ref : myStops) {
2013 myStopAreas[ref] = myCurrentRelation;
2022 std::shared_ptr<NBPTStop> ptStop = myNBPTStopCont->get(
toString(n->
id));
2023 if (ptStop ==
nullptr) {
2030 if (myPlatform.isWay) {
2034 WRITE_WARNINGF(
TL(
"Platform '%' in relation: '%' is given as polygon, which currently is not supported."), myPlatform.ref, myCurrentRelation);
2049 WRITE_ERRORF(
"Unable to project coordinates for node '%'.", pNode->
id);
2052 p.push_back(pNodePos);
2054 if (p.size() == 0) {
2055 WRITE_WARNINGF(
TL(
"Referenced platform: '%' in relation: '%' is corrupt. Probably OSM file is incomplete."),
2060 ptStop->addPlatformCand(platform);
2071 WRITE_ERRORF(
"Unable to project coordinates for node '%'.", pNode->
id);
2073 NBPTPlatform platform(platformPos, myOptionsCont.getFloat(
"osm.stop-output.length"));
2074 ptStop->addPlatformCand(platform);
2078 ptStop->setIsMultipleStopPositions(myStops.size() > 1, myCurrentRelation);
2080 }
else if (myPTRouteType !=
"" && myIsRoute) {
2081 NBPTLine* ptLine =
new NBPTLine(
toString(myCurrentRelation), myName, myPTRouteType, myRef, myInterval, myNightService,
2083 bool hadGap =
false;
2084 int missingBefore = 0;
2085 int missingAfter = 0;
2087 for (
long long ref : myStops) {
2102 WRITE_WARNINGF(
TL(
"PT line '%' in relation % seems to be split, only keeping first part."), myName, myCurrentRelation);
2103 missingAfter = (int)myStops.size() - missingBefore - (int)ptLine->
getStops().size();
2107 const NIOSMNode*
const n = nodeIt->second;
2108 std::shared_ptr<NBPTStop> ptStop = myNBPTStopCont->get(
toString(n->
id));
2109 if (ptStop ==
nullptr) {
2113 WRITE_ERRORF(
"Unable to project coordinates for node '%'.", n->
id);
2116 myNBPTStopCont->insert(ptStop);
2117 if (myStopAreas.count(n->
id)) {
2118 ptStop->setIsMultipleStopPositions(
false, myStopAreas[n->
id]);
2120 if (myPlatformStops.count(n->
id) > 0) {
2121 ptStop->setIsPlatform();
2126 for (
long long& myWay : myWays) {
2127 auto entr = myOSMEdges.find(myWay);
2128 if (entr != myOSMEdges.end()) {
2129 Edge* edge = entr->second;
2135 ptLine->
setNumOfStops((
int)myStops.size(), missingBefore, missingAfter);
2137 WRITE_WARNINGF(
TL(
"PT line in relation % with no stops ignored. Probably OSM file is incomplete."), myCurrentRelation);
2142 if (!myNBPTLineCont->insert(ptLine)) {
2157 if (viaNode ==
nullptr) {
2163 if (from ==
nullptr) {
2167 if (to ==
nullptr) {
2171 if (myRestrictionType == RestrictionType::ONLY) {
2198 WRITE_WARNINGF(
TL(
"direction of restriction relation could not be determined%"),
"");
2206 const std::vector<NBEdge*>& candidates)
const {
2207 const std::string prefix =
toString(wayRef);
2208 const std::string backPrefix =
"-" + prefix;
2209 NBEdge* result =
nullptr;
2211 for (
auto candidate : candidates) {
2212 if ((candidate->getID().substr(0, prefix.size()) == prefix) ||
2213 (candidate->getID().substr(0, backPrefix.size()) == backPrefix)) {
2219 WRITE_WARNINGF(
TL(
"Ambiguous way reference '%' in restriction relation"), prefix);
2233 std::map<NBNode*, std::vector<std::pair<double, double> > > layerForces;
2236 std::set<NBNode*> knownElevation;
2237 for (
auto& myEdge :
myEdges) {
2238 Edge* e = myEdge.second;
2242 if (node !=
nullptr) {
2243 knownElevation.insert(node);
2244 layerForces[node].emplace_back(e->
myLayer * layerElevation, POSITION_EPS);
2249 #ifdef DEBUG_LAYER_ELEVATION
2250 std::cout <<
"known elevations:\n";
2251 for (std::set<NBNode*>::iterator it = knownElevation.begin(); it != knownElevation.end(); ++it) {
2252 const std::vector<std::pair<double, double> >& primaryLayers = layerForces[*it];
2253 std::cout <<
" node=" << (*it)->
getID() <<
" ele=";
2254 for (std::vector<std::pair<double, double> >::const_iterator it_ele = primaryLayers.begin(); it_ele != primaryLayers.end(); ++it_ele) {
2255 std::cout << it_ele->first <<
" ";
2263 std::map<NBNode*, double> knownEleMax;
2264 for (
auto it : knownElevation) {
2265 double eleMax = -std::numeric_limits<double>::max();
2266 const std::vector<std::pair<double, double> >& primaryLayers = layerForces[it];
2267 for (
const auto& primaryLayer : primaryLayers) {
2268 eleMax =
MAX2(eleMax, primaryLayer.first);
2270 knownEleMax[it] = eleMax;
2273 bool changed =
true;
2276 for (
auto it = knownElevation.begin(); it != knownElevation.end(); ++it) {
2279 / gradeThreshold * 3,
2281 for (
auto& neighbor : neighbors) {
2282 if (knownElevation.count(neighbor.first) != 0) {
2283 const double grade = fabs(knownEleMax[*it] - knownEleMax[neighbor.first])
2284 /
MAX2(POSITION_EPS, neighbor.second.first);
2285 #ifdef DEBUG_LAYER_ELEVATION
2286 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";
2288 if (grade > gradeThreshold * 50 / 3.6 / neighbor.second.second) {
2290 const double eleMax =
MAX2(knownEleMax[*it], knownEleMax[neighbor.first]);
2291 if (knownEleMax[*it] < eleMax) {
2292 knownEleMax[*it] = eleMax;
2294 knownEleMax[neighbor.first] = eleMax;
2304 std::set<NBNode*> unknownElevation;
2305 for (
auto it = knownElevation.begin(); it != knownElevation.end(); ++it) {
2306 const double eleMax = knownEleMax[*it];
2307 const double maxDist = fabs(eleMax) * 100 / layerElevation;
2308 std::map<NBNode*, std::pair<double, double> > neighbors =
getNeighboringNodes(*it, maxDist, knownElevation);
2309 for (
auto& neighbor : neighbors) {
2310 if (knownElevation.count(neighbor.first) == 0) {
2311 unknownElevation.insert(neighbor.first);
2312 layerForces[neighbor.first].emplace_back(eleMax, neighbor.second.first);
2318 for (
auto it = unknownElevation.begin(); it != unknownElevation.end(); ++it) {
2319 double eleMax = -std::numeric_limits<double>::max();
2320 const std::vector<std::pair<double, double> >& primaryLayers = layerForces[*it];
2321 for (
const auto& primaryLayer : primaryLayers) {
2322 eleMax =
MAX2(eleMax, primaryLayer.first);
2324 const double maxDist = fabs(eleMax) * 100 / layerElevation;
2325 std::map<NBNode*, std::pair<double, double> > neighbors =
getNeighboringNodes(*it, maxDist, knownElevation);
2326 for (
auto& neighbor : neighbors) {
2327 if (knownElevation.count(neighbor.first) == 0 && unknownElevation.count(neighbor.first) == 0) {
2328 layerForces[*it].emplace_back(0, neighbor.second.first);
2333 #ifdef DEBUG_LAYER_ELEVATION
2334 std::cout <<
"summation of forces\n";
2336 std::map<NBNode*, double> nodeElevation;
2337 for (
auto& layerForce : layerForces) {
2338 const std::vector<std::pair<double, double> >& forces = layerForce.second;
2339 if (knownElevation.count(layerForce.first) != 0) {
2347 #ifdef DEBUG_LAYER_ELEVATION
2348 std::cout <<
" node=" << it->first->getID() <<
" knownElevation=" << knownEleMax[it->first] <<
"\n";
2350 nodeElevation[layerForce.first] = knownEleMax[layerForce.first];
2351 }
else if (forces.size() == 1) {
2352 nodeElevation[layerForce.first] = forces.front().first;
2356 for (
const auto& force : forces) {
2357 distSum += force.second;
2359 double weightSum = 0;
2360 double elevation = 0;
2361 #ifdef DEBUG_LAYER_ELEVATION
2362 std::cout <<
" node=" << it->first->getID() <<
" distSum=" << distSum <<
"\n";
2364 for (
const auto& force : forces) {
2365 const double weight = (distSum - force.second) / distSum;
2366 weightSum += weight;
2367 elevation += force.first * weight;
2369 #ifdef DEBUG_LAYER_ELEVATION
2370 std::cout <<
" force=" << it_force->first <<
" dist=" << it_force->second <<
" weight=" << weight <<
" ele=" << elevation <<
"\n";
2373 nodeElevation[layerForce.first] = elevation / weightSum;
2376 #ifdef DEBUG_LAYER_ELEVATION
2377 std::cout <<
"final elevations:\n";
2378 for (std::map<NBNode*, double>::iterator it = nodeElevation.begin(); it != nodeElevation.end(); ++it) {
2379 std::cout <<
" node=" << (it->first)->getID() <<
" ele=" << it->second <<
"\n";
2383 for (
auto& it : nodeElevation) {
2390 for (
const auto& it : ec) {
2391 NBEdge* edge = it.second;
2393 const double length = geom.
length2D();
2394 const double zFrom = nodeElevation[edge->
getFromNode()];
2395 const double zTo = nodeElevation[edge->
getToNode()];
2400 for (
auto it_pos = geom.begin(); it_pos != geom.end(); ++it_pos) {
2401 if (it_pos != geom.begin()) {
2402 dist += (*it_pos).distanceTo2D(*(it_pos - 1));
2404 newGeom.push_back((*it_pos) +
Position(0, 0, zFrom + (zTo - zFrom) * dist / length));
2410 std::map<NBNode*, std::pair<double, double> >
2412 std::map<NBNode*, std::pair<double, double> > result;
2413 std::set<NBNode*> visited;
2414 std::vector<NBNode*> open;
2415 open.push_back(node);
2416 result[node] = std::make_pair(0, 0);
2417 while (!open.empty()) {
2420 if (visited.count(n) != 0) {
2425 for (
auto e : edges) {
2428 s = e->getFromNode();
2432 const double dist = result[n].first + e->getGeometry().length2D();
2433 const double speed =
MAX2(e->getSpeed(), result[n].second);
2434 if (result.count(s) == 0) {
2435 result[s] = std::make_pair(dist, speed);
2437 result[s] = std::make_pair(
MIN2(dist, result[s].first),
MAX2(speed, result[s].second));
2439 if (dist < maxDist && knownElevation.count(s) == 0) {
2451 if (tc.
knows(type)) {
2462 std::vector<std::string> types;
2464 std::string t = tok.
next();
2466 if (std::find(types.begin(), types.end(), t) == types.end()) {
2469 }
else if (tok.
size() > 1) {
2471 WRITE_WARNINGF(
TL(
"Discarding unknown compound '%' in type '%' (first occurrence for edge '%')."), t, type,
id);
2475 if (types.empty()) {
2477 WRITE_WARNINGF(
TL(
"Discarding unusable type '%' (first occurrence for edge '%')."), type,
id);
2483 if (tc.
knows(newType)) {
2491 double maxSpeed = 0;
2496 bool defaultIsOneWay =
true;
2499 bool discard =
true;
2500 bool hadDiscard =
false;
2501 for (
auto& type2 : types) {
2518 if (hadDiscard && permissions == 0) {
2522 WRITE_WARNINGF(
TL(
"Discarding compound type '%' (first occurrence for edge '%')."), newType,
id);
2537 WRITE_MESSAGEF(
TL(
"Adding new type '%' (first occurrence for edge '%')."), type,
id);
2538 tc.
insertEdgeType(newType, numLanes, maxSpeed, prio, permissions, spreadType, width,
2539 defaultIsOneWay, sidewalkWidth, bikelaneWidth, 0, 0, 0);
2540 for (
auto& type3 : types) {
2555 std::vector<NIOSMNode*> nodes;
2556 std::vector<double> usablePositions;
2557 std::vector<int> usableIndex;
2561 if (node->
positionMeters != std::numeric_limits<double>::max()) {
2563 usableIndex.push_back((
int)nodes.size());
2565 nodes.push_back(node);
2567 if (usablePositions.size() == 0) {
2570 bool forward =
true;
2571 if (usablePositions.size() == 1) {
2572 WRITE_WARNINGF(
TL(
"Ambiguous railway kilometrage direction for way '%' (assuming forward)"),
id);
2574 forward = usablePositions.front() < usablePositions.back();
2577 for (
int i = 1; i < (int)usablePositions.size(); i++) {
2578 if ((usablePositions[i - 1] < usablePositions[i]) != forward) {
2579 WRITE_WARNINGF(
TL(
"Inconsistent railway kilometrage direction for way '%': % (skipping)"),
id,
toString(usablePositions));
2583 if (nodes.size() > usablePositions.size()) {
2587 shape.push_back(
Position(node->lon, node->lat, 0));
2592 double sign = forward ? 1 : -1;
2594 for (
int i = usableIndex.front() - 1; i >= 0; i--) {
2595 nodes[i]->positionMeters = nodes[i + 1]->positionMeters - sign * shape[i].distanceTo2D(shape[i + 1]);
2598 for (
int i = usableIndex.front() + 1; i < (
int)nodes.size(); i++) {
2599 if (nodes[i]->positionMeters == std::numeric_limits<double>::max()) {
2600 nodes[i]->positionMeters = nodes[i - 1]->positionMeters + sign * shape[i].distanceTo2D(shape[i - 1]);
2627 return std::numeric_limits<double>::max();
2633 if (type ==
"train") {
2635 }
else if (type ==
"subway") {
2637 }
else if (type ==
"aerialway") {
2639 }
else if (type ==
"light_rail" || type ==
"monorail") {
2641 }
else if (type ==
"share_taxi") {
2643 }
else if (type ==
"minibus") {
2648 std::string stop =
"";
2651 }
else if (result ==
SVC_BUS) {
2666 bool multiLane = changeProhibition > 3;
2668 for (
int lane = 0; changeProhibition > 0 && lane < e->
getNumLanes(); lane++) {
2669 int code = changeProhibition % 4;
2674 changeProhibition = changeProhibition >> 2;
2688 for (
int lane = 0; lane < numLanes; lane++) {
2690 const int i = lefthand ? lane : numLanes - 1 - lane;
2695 if (i < (
int)designated.size() && designated[i]) {
2707 if (signs.empty()) {
2708 signs.insert(signs.begin(), signs2.begin(), signs2.end());
2710 for (
int i = 0; i < (int)
MIN2(signs.size(), signs2.size()); i++) {
2711 signs[i] |= signs2[i];
2723 for (
int i = 0; i < (int)turnSigns.size(); i++) {
#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 permission is a 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_ROAD_CLASSES
classes which drive on roads
@ 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
@ 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
static const double UNSPECIFIED_FRICTION
unspecified lane friction
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::string & getID() const
const std::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
NBNode * getToNode() const
Returns the destination node of the edge.
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.
const PositionVector & getGeometry() const
Returns the geometry of the edge.
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...
static const double UNSPECIFIED_WIDTH
unspecified lane width
static const double UNSPECIFIED_OFFSET
unspecified lane offset
Lane & getLaneStruct(int lane)
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
NBNode * getFromNode() const
Returns the origin node of the edge.
Instance responsible for building networks.
static bool transformCoordinates(PositionVector &from, bool includeInBoundary=true, GeoConvHelper *from_srs=nullptr)
NBTypeCont & getTypeCont()
Returns a reference to the type container.
NBParkingCont & getParkingCont()
NBPTLineCont & getPTLineCont()
Returns a reference to the pt line container.
NBEdgeCont & getEdgeCont()
NBPTStopCont & getPTStopCont()
Returns a reference to the pt stop 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...
NBNodeCont & getNodeCont()
Returns a reference to the node container.
NBTrafficLightLogicCont & getTLLogicCont()
Returns a reference to the traffic light logics container.
Container for nodes during the netbuilding process.
bool insert(const std::string &id, const Position &position, NBDistrict *district=0)
Inserts a node into the map.
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
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 & getOutgoingEdges() const
Returns this node's outgoing edges (The edges which start at this node)
const EdgeVector & getEdges() const
Returns all edges which participate in this node (Edges that start or end at this node)
bool checkCrossingDuplicated(EdgeVector edges)
return true if there already exist a crossing with the same edges as the input
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges (The edges which yield in this node)
const Position & getPosition() const
static const int FORWARD
edge directions (for pedestrian related stuff)
void setFringeType(FringeType fringeType)
set method for computing right-of-way
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 interpretLaneUse(const std::string &value, SUMOVehicleClass svc, const bool forward) const
EdgesHandler(const std::map< long long int, NIOSMNode * > &osmNodes, std::map< long long int, Edge * > &toFill, std::map< long long int, Edge * > &platformShapes)
Constructor.
int interpretChangeType(const std::string &value) const
~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
~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
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
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 std::string to_lower_case(const std::string &str)
Transfers the content to lower case.
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 bool startsWith(const std::string &str, const std::string prefix)
Checks whether a given string starts with the prefix.
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.