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;
154 for (
const std::string& file : files) {
163 if (!readers.back()->parseFirst(file) || !readers.back()->parseSection(
SUMO_TAG_NODE) ||
176 for (
const std::string& file : files) {
178 readers[idx]->setHandler(edgesHandler);
183 readers[idx] =
nullptr;
190 if (!oc.
getBool(
"osm.skip-duplicates-check")) {
194 std::set<const Edge*, CompareEdges> dupsFinder;
196 if (dupsFinder.count(it->second) > 0) {
201 dupsFinder.insert(it->second);
206 if (numRemoved > 0) {
215 std::map<long long int, int> nodeUsage;
217 for (
const auto& edgeIt :
myEdges) {
218 assert(edgeIt.second->myCurrentIsRoad);
219 for (
const long long int node : edgeIt.second->myCurrentNodes) {
225 if (nodesIt.second->tlsControlled || nodesIt.second->railwaySignal || (nodesIt.second->pedestrianCrossing &&
myImportCrossings) ) {
228 nodeUsage[nodesIt.first]++;
237 for (
const auto& edgeIt :
myEdges) {
238 Edge*
const e = edgeIt.second;
250 NBNode* currentFrom = first;
252 std::vector<long long int> passed;
254 passed.push_back(*j);
257 running =
insertEdge(e, running, currentFrom, currentTo, passed, nb, first, last);
258 currentFrom = currentTo;
260 passed.push_back(*j);
266 insertEdge(e, running, currentFrom, last, passed, nb, first, last);
279 for (
const auto& nodeIt : nc) {
280 NBNode*
const n = nodeIt.second;
284 size_t incomingEdgesNo = incomingEdges.size();
285 size_t outgoingEdgesNo = outgoingEdges.size();
287 for (
size_t i = 0; i < incomingEdgesNo; i++) {
295 auto const iEdge = incomingEdges[i];
299 std::string
const& iEdgeId = iEdge->getID();
300 std::size_t
const m = iEdgeId.find_first_of(
"#");
301 std::string
const& iWayId = iEdgeId.substr(0, m);
302 for (
size_t j = 0; j < outgoingEdgesNo; j++) {
303 auto const oEdge = outgoingEdges[j];
306 if (oEdge->getID().find(iWayId) != std::string::npos
308 && oEdge->getID().rfind(iWayId, 0) != 0) {
311 edgeVector.push_back(oEdge);
321 for (
size_t i = 0; i < outgoingEdgesNo; i++) {
323 auto const oEdge = outgoingEdges[i];
327 std::string
const& oEdgeId = oEdge->getID();
328 std::size_t
const m = oEdgeId.find_first_of(
"#");
329 std::string
const& iWayId = oEdgeId.substr(0, m);
330 for (
size_t j = 0; j < incomingEdgesNo; j++) {
331 auto const iEdge = incomingEdges[j];
332 if (iEdge->getID().find(iWayId) != std::string::npos
334 && iEdge->getID().rfind(iWayId, 0) != 0) {
337 edgeVector.push_back(iEdge);
352 const double layerElevation = oc.
getFloat(
"osm.layer-elevation");
353 if (layerElevation > 0) {
365 for (
const std::string& file : files) {
366 if (readers[idx] !=
nullptr) {
368 readers[idx]->setHandler(relationHandler);
378 std::set<std::string> stopNames;
380 stopNames.insert(item.second->getName());
387 WRITE_ERRORF(
"Unable to project coordinates for node '%'.", n->
id);
399 if (node ==
nullptr) {
403 WRITE_ERRORF(
"Unable to project coordinates for junction '%'.",
id);
416 }
else if (n->
getParameter(
"crossing.light") ==
"yes") {
428 if (!tlsc.
insert(tlDef)) {
434 node->
setParameter(
"computePedestrianCrossing",
"true");
455 const std::vector<long long int>& passed,
NBNetBuilder& nb,
465 if (from ==
nullptr || to ==
nullptr) {
466 WRITE_ERRORF(
"Discarding edge '%' because the nodes could not be built.",
id);
475 assert(passed.size() >= 2);
476 if (passed.size() == 2) {
477 WRITE_WARNINGF(
TL(
"Discarding edge '%' which connects two identical nodes without geometry."),
id);
481 int intermediateIndex = (int) passed.size() / 2;
483 std::vector<long long int> part1(passed.begin(), passed.begin() + intermediateIndex + 1);
484 std::vector<long long int> part2(passed.begin() + intermediateIndex, passed.end());
485 index =
insertEdge(e, index, from, intermediate, part1, nb, first, last);
486 return insertEdge(e, index, intermediate, to, part2, nb, first, last);
488 const int newIndex = index + 1;
503 extra = extra & ~SVC_BUS;
505 SVCPermissions permissions = (defaultPermissions & ~extraDis) | extra;
506 if (defaultPermissions ==
SVC_SHIP) {
508 permissions = defaultPermissions;
511 defaultsToOneWay =
false;
519 double distanceStart =
myOSMNodes[passed.front()]->positionMeters;
520 double distanceEnd =
myOSMNodes[passed.back()]->positionMeters;
521 const bool useDistance = distanceStart != std::numeric_limits<double>::max() && distanceEnd != std::numeric_limits<double>::max();
524 if (distanceStart < distanceEnd) {
537 std::vector<std::shared_ptr<NBPTStop> > ptStops;
538 for (
long long i : passed) {
542 std::shared_ptr<NBPTStop> existingPtStop = sc.
get(
toString(n->
id));
543 if (existingPtStop !=
nullptr) {
544 existingPtStop->registerAdditionalEdge(
toString(e->
id), id);
548 WRITE_ERRORF(
"Unable to project coordinates for node '%'.", n->
id);
551 sc.
insert(ptStops.back());
558 shape.push_back(pos);
560#ifdef DEBUG_LAYER_ELEVATION
561 if (e->
id ==
"DEBUGID") {
566 <<
" nodeDirection=" << nodeDirection
578 WRITE_ERRORF(
"Unable to project coordinates for edge '%'.",
id);
584 if (streetName == e->
ref) {
601 const std::string& onewayBike = e->
myExtraTags[
"oneway:bicycle"];
602 if (onewayBike ==
"false" || onewayBike ==
"no" || onewayBike ==
"0") {
613 bool addForward =
true;
614 bool addBackward =
true;
615 const bool explicitTwoWay = e->
myIsOneWay ==
"no";
631 if (addBackward && (onewayBike ==
"true" || onewayBike ==
"yes" || onewayBike ==
"1")) {
634 if (addForward && (onewayBike ==
"reverse" || onewayBike ==
"-1")) {
637 if (!addBackward && (onewayBike ==
"false" || onewayBike ==
"no" || onewayBike ==
"0")) {
644 if (addForward && !addBackward) {
646 }
else if (!addForward && addBackward) {
654 numLanesForward = (int) std::ceil(e->
myNoLanes / 2.0);
656 numLanesBackward = e->
myNoLanes - numLanesForward;
659 numLanesForward =
MAX2(1, numLanesForward);
660 numLanesBackward =
MAX2(1, numLanesBackward);
683 numLanesBackward = 1;
686 const int taggedLanes = (addForward ? numLanesForward : 0) + (addBackward ? numLanesBackward : 0);
690 forwardWidth = e->
myWidth / taggedLanes;
691 backwardWidth = forwardWidth;
698 double speedBackward = speed;
702 if (speed <= 0 || speedBackward <= 0) {
709 if (!addForward && (cyclewayType &
WAY_FORWARD) != 0) {
712 forwardWidth = bikeLaneWidth;
717 if (!addBackward && (cyclewayType &
WAY_BACKWARD) != 0) {
720 backwardWidth = bikeLaneWidth;
721 numLanesBackward = 1;
733 if (!addForward && (sidewalkType &
WAY_FORWARD) != 0) {
740 }
else if (addSidewalk && addForward && (sidewalkType &
WAY_BOTH) == 0
741 && numLanesForward == 1 && numLanesBackward <= 1
748 if (!addBackward && (sidewalkType &
WAY_BACKWARD) != 0) {
752 numLanesBackward = 1;
755 }
else if (addSidewalk && addBackward && (sidewalkType &
WAY_BOTH) == 0
756 && numLanesBackward == 1 && numLanesForward <= 1
768 const int offsetFactor = lefthand ? -1 : 1;
780 const std::string reverseID =
"-" + id;
783 assert(numLanesForward > 0);
787 if (markOSMDirection) {
824 if ((
int)nbe->
getLanes().size() != numForwardLanesFromWidthKey) {
825 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."),
826 id, nbe->
getLanes().size(), numForwardLanesFromWidthKey);
828 for (
int i = 0; i < numForwardLanesFromWidthKey; i++) {
830 const int laneIndex = lefthand ? i : numForwardLanesFromWidthKey - i - 1;
842 assert(numLanesBackward > 0);
846 if (markOSMDirection) {
877 if ((
int)nbe->
getLanes().size() != numBackwardLanesFromWidthKey) {
878 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."),
879 id, nbe->
getLanes().size(), numBackwardLanesFromWidthKey);
881 for (
int i = 0; i < numBackwardLanesFromWidthKey; i++) {
883 const int laneIndex = lefthand ? i : numBackwardLanesFromWidthKey - i - 1;
927 std::set<NIOSMNode*, CompareNodes>& uniqueNodes,
const OptionsCont& oc) :
930 myCurrentNode(nullptr),
932 myUniqueNodes(uniqueNodes),
933 myImportElevation(oc.getBool(
"osm.elevation")),
938 if (kv ==
"DEFAULT") {
941 }
else if (kv ==
"ALL") {
958 if (myHierarchyLevel != 2) {
959 WRITE_ERROR(
"Node element on wrong XML hierarchy level (id='" + myLastNodeID +
960 "', level='" +
toString(myHierarchyLevel) +
"').");
964 if (action ==
"delete" || !ok) {
970 myCurrentNode =
nullptr;
971 const auto insertionIt = myToFill.lower_bound(
id);
972 if (insertionIt == myToFill.end() || insertionIt->first !=
id) {
974 const double tlon = attrs.
get<
double>(
SUMO_ATTR_LON, myLastNodeID.c_str(), ok);
975 const double tlat = attrs.
get<
double>(
SUMO_ATTR_LAT, myLastNodeID.c_str(), ok);
979 myCurrentNode =
new NIOSMNode(
id, tlon, tlat);
984 delete myCurrentNode;
985 myCurrentNode = *similarNode;
988 myToFill.emplace_hint(insertionIt,
id, myCurrentNode);
991 WRITE_ERROR(
TL(
"Attribute 'id' in the definition of a node is not of type long long int."));
995 if (element ==
SUMO_TAG_TAG && myCurrentNode !=
nullptr) {
996 if (myHierarchyLevel != 3) {
997 WRITE_ERROR(
TL(
"Tag element on wrong XML hierarchy level."));
1001 const std::string& key = attrs.
get<std::string>(
SUMO_ATTR_K, myLastNodeID.c_str(), ok,
false);
1003 if (key ==
"highway" || key ==
"ele" || key ==
"crossing" || key ==
"railway" || key ==
"public_transport"
1004 || key ==
"name" || key ==
"train" || key ==
"bus" || key ==
"tram" || key ==
"light_rail" || key ==
"subway" || key ==
"station" || key ==
"noexit"
1005 || key ==
"crossing:barrier"
1006 || key ==
"crossing:light"
1010 const std::string& value = attrs.
get<std::string>(
SUMO_ATTR_V, myLastNodeID.c_str(), ok,
false);
1011 if (key ==
"highway" && value.find(
"traffic_signal") != std::string::npos) {
1012 myCurrentNode->tlsControlled =
true;
1013 }
else if (key ==
"crossing" && value.find(
"traffic_signals") != std::string::npos) {
1014 myCurrentNode->tlsControlled =
true;
1015 }
else if (key ==
"highway" && value.find(
"crossing") != std::string::npos) {
1016 myCurrentNode->pedestrianCrossing =
true;
1017 }
else if ((key ==
"noexit" && value ==
"yes")
1018 || (key ==
"railway" && value ==
"buffer_stop")) {
1019 myCurrentNode->railwayBufferStop =
true;
1020 }
else if (key ==
"railway" && value.find(
"crossing") != std::string::npos) {
1021 myCurrentNode->railwayCrossing =
true;
1022 }
else if (key ==
"crossing:barrier") {
1023 myCurrentNode->setParameter(
"crossing:barrier", value);
1024 }
else if (key ==
"crossing:light") {
1025 myCurrentNode->setParameter(
"crossing:light", value);
1026 }
else if (key ==
"railway:signal:direction") {
1027 if (value ==
"both") {
1028 myCurrentNode->myRailDirection =
WAY_BOTH;
1029 }
else if (value ==
"backward") {
1031 }
else if (value ==
"forward") {
1035 std::string kv = key +
"=" + value;
1036 std::string kglob = key +
"=";
1037 if ((std::find(myRailSignalRules.begin(), myRailSignalRules.end(), kv) != myRailSignalRules.end())
1038 || (std::find(myRailSignalRules.begin(), myRailSignalRules.end(), kglob) != myRailSignalRules.end())) {
1039 myCurrentNode->railwaySignal =
true;
1041 }
else if (
StringUtils::startsWith(key,
"railway:position") && value.size() > myCurrentNode->position.size()) {
1043 myCurrentNode->position = value;
1044 }
else if ((key ==
"public_transport" && value ==
"stop_position") ||
1045 (key ==
"highway" && value ==
"bus_stop")) {
1046 myCurrentNode->ptStopPosition =
true;
1047 if (myCurrentNode->ptStopLength == 0) {
1049 myCurrentNode->ptStopLength = myOptionsCont.getFloat(
"osm.stop-output.length");
1051 }
else if (key ==
"name") {
1052 myCurrentNode->name = value;
1053 }
else if (myImportElevation && key ==
"ele") {
1056 if (std::isnan(elevation)) {
1057 WRITE_WARNINGF(
TL(
"Value of key '%' is invalid ('%') in node '%'."), key, value, myLastNodeID);
1059 myCurrentNode->ele = elevation;
1062 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in node '%'."), key, value, myLastNodeID);
1064 }
else if (key ==
"station") {
1072 const std::string info =
"node=" +
toString(myCurrentNode->id) +
", k=" + key;
1073 myCurrentNode->setParameter(key, attrs.
get<std::string>(
SUMO_ATTR_V, info.c_str(), ok,
false));
1082 myCurrentNode =
nullptr;
1092 const std::map<long long int, NIOSMNode*>& osmNodes,
1093 std::map<long long int, Edge*>& toFill, std::map<long long int, Edge*>& platformShapes):
1097 myPlatformShapesMap(platformShapes) {
1194 const long long int id = attrs.
get<
long long int>(
SUMO_ATTR_ID,
nullptr, ok);
1196 if (action ==
"delete" || !ok) {
1197 myCurrentEdge =
nullptr;
1200 myCurrentEdge =
new Edge(
id);
1203 if (element ==
SUMO_TAG_ND && myCurrentEdge !=
nullptr) {
1213 ref = node->second->id;
1214 if (myCurrentEdge->myCurrentNodes.empty() ||
1215 myCurrentEdge->myCurrentNodes.back() != ref) {
1216 myCurrentEdge->myCurrentNodes.push_back(ref);
1221 if (element ==
SUMO_TAG_TAG && myCurrentEdge !=
nullptr) {
1226 const std::string buswaySpec = key.substr(7);
1228 if (buswaySpec ==
"right") {
1230 }
else if (buswaySpec ==
"left") {
1232 }
else if (buswaySpec ==
"both") {
1233 myCurrentEdge->myBuswayType = (
WayType)(myCurrentEdge->myBuswayType |
WAY_BOTH);
1239 const std::string info =
"way=" +
toString(myCurrentEdge->id) +
", k=" + key;
1240 myCurrentEdge->setParameter(key, attrs.
get<std::string>(
SUMO_ATTR_V, info.c_str(), ok,
false));
1245 && key !=
"maxspeed" && key !=
"maxspeed:type"
1246 && key !=
"zone:maxspeed"
1247 && key !=
"maxspeed:forward" && key !=
"maxspeed:backward"
1248 && key !=
"junction" && key !=
"name" && key !=
"tracks" && key !=
"layer"
1253 && key !=
"highspeed"
1257 && key !=
"postal_code"
1258 && key !=
"railway:preferred_direction"
1259 && key !=
"railway:bidirectional"
1260 && key !=
"railway:track_ref"
1263 && key !=
"emergency"
1265 && key !=
"electrified"
1266 && key !=
"segregated"
1271 && key !=
"oneway:bicycle"
1272 && key !=
"oneway:bus"
1273 && key !=
"bus:lanes"
1274 && key !=
"bus:lanes:forward"
1275 && key !=
"bus:lanes:backward"
1276 && key !=
"psv:lanes"
1277 && key !=
"psv:lanes:forward"
1278 && key !=
"psv:lanes:backward"
1279 && key !=
"bicycle:lanes"
1280 && key !=
"bicycle:lanes:forward"
1281 && key !=
"bicycle:lanes:backward"
1284 && key !=
"public_transport") {
1287 const std::string value = attrs.
get<std::string>(
SUMO_ATTR_V,
toString(myCurrentEdge->id).c_str(), ok,
false);
1289 if ((key ==
"highway" && value !=
"platform") || key ==
"railway" || key ==
"waterway" ||
StringUtils::startsWith(key,
"cycleway")
1291 || key ==
"aeroway" || key ==
"aerialway" || key ==
"usage" || key ==
"service") {
1293 myCurrentEdge->myCurrentIsRoad =
true;
1295 if (key ==
"cycleway") {
1296 if (value ==
"no" || value ==
"none" || value ==
"separate") {
1297 myCurrentEdge->myCyclewayType =
WAY_NONE;
1298 }
else if (value ==
"both") {
1299 myCurrentEdge->myCyclewayType =
WAY_BOTH;
1300 }
else if (value ==
"right") {
1302 }
else if (value ==
"left") {
1304 }
else if (value ==
"opposite_track") {
1306 }
else if (value ==
"opposite_lane") {
1308 }
else if (value ==
"opposite") {
1313 if (key ==
"cycleway:left") {
1314 if (myCurrentEdge->myCyclewayType ==
WAY_UNKNOWN) {
1315 myCurrentEdge->myCyclewayType =
WAY_NONE;
1317 if (value ==
"yes" || value ==
"lane" || value ==
"track") {
1322 if (key ==
"cycleway:right") {
1323 if (myCurrentEdge->myCyclewayType ==
WAY_UNKNOWN) {
1324 myCurrentEdge->myCyclewayType =
WAY_NONE;
1326 if (value ==
"yes" || value ==
"lane" || value ==
"track") {
1327 myCurrentEdge->myCyclewayType = (
WayType)(myCurrentEdge->myCyclewayType |
WAY_FORWARD);
1331 if (key ==
"cycleway:both") {
1332 if (myCurrentEdge->myCyclewayType ==
WAY_UNKNOWN) {
1333 if (value ==
"no" || value ==
"none" || value ==
"separate") {
1334 myCurrentEdge->myCyclewayType =
WAY_NONE;
1336 if (value ==
"yes" || value ==
"lane" || value ==
"track") {
1337 myCurrentEdge->myCyclewayType =
WAY_BOTH;
1342 if (key ==
"cycleway" && value !=
"lane" && value !=
"track" && value !=
"opposite_track" && value !=
"opposite_lane") {
1351 if (key ==
"sidewalk") {
1352 if (value ==
"no" || value ==
"none" || value ==
"separate") {
1353 myCurrentEdge->mySidewalkType =
WAY_NONE;
1354 }
else if (value ==
"both") {
1355 myCurrentEdge->mySidewalkType =
WAY_BOTH;
1356 }
else if (value ==
"right") {
1358 }
else if (value ==
"left") {
1362 if (key ==
"sidewalk:left") {
1363 if (myCurrentEdge->mySidewalkType ==
WAY_UNKNOWN) {
1364 myCurrentEdge->mySidewalkType =
WAY_NONE;
1366 if (value ==
"yes") {
1370 if (key ==
"sidewalk:right") {
1371 if (myCurrentEdge->mySidewalkType ==
WAY_UNKNOWN) {
1372 myCurrentEdge->mySidewalkType =
WAY_NONE;
1374 if (value ==
"yes") {
1375 myCurrentEdge->mySidewalkType = (
WayType)(myCurrentEdge->mySidewalkType |
WAY_FORWARD);
1378 if (key ==
"sidewalk:both") {
1379 if (myCurrentEdge->mySidewalkType ==
WAY_UNKNOWN) {
1380 if (value ==
"no" || value ==
"none" || value ==
"separate") {
1381 myCurrentEdge->mySidewalkType =
WAY_NONE;
1383 if (value ==
"yes") {
1384 myCurrentEdge->mySidewalkType =
WAY_BOTH;
1393 if (key ==
"busway") {
1394 if (value ==
"no") {
1397 if (value ==
"opposite_track") {
1399 }
else if (value ==
"opposite_lane") {
1405 std::string singleTypeID = key +
"." + value;
1406 if (key ==
"highspeed") {
1407 if (value ==
"no") {
1410 singleTypeID =
"railway.highspeed";
1413 if (!myCurrentEdge->myHighWayType.empty() && singleTypeID !=
"railway.highspeed") {
1414 if (myCurrentEdge->myHighWayType ==
"railway.highspeed") {
1419 std::vector<std::string> types =
StringTokenizer(myCurrentEdge->myHighWayType,
1421 types.push_back(singleTypeID);
1424 myCurrentEdge->myHighWayType = singleTypeID;
1426 }
else if (key ==
"bus" || key ==
"psv") {
1430 myCurrentEdge->myExtraAllowed |=
SVC_BUS;
1432 myCurrentEdge->myExtraDisallowed |=
SVC_BUS;
1435 myCurrentEdge->myExtraAllowed |=
SVC_BUS;
1437 }
else if (key ==
"emergency") {
1445 }
else if (key ==
"access") {
1446 if (value ==
"no") {
1452 std::vector<double> widthLanes;
1453 for (std::string width : values) {
1455 widthLanes.push_back(parsedWidth);
1458 if (key ==
"width:lanes" || key ==
"width:lanes:forward") {
1459 myCurrentEdge->myWidthLanesForward = widthLanes;
1460 }
else if (key ==
"width:lanes:backward") {
1461 myCurrentEdge->myWidthLanesBackward = widthLanes;
1463 WRITE_WARNINGF(
TL(
"Using default lane width for edge '%' as key '%' could not be parsed."),
toString(myCurrentEdge->id), key);
1466 WRITE_WARNINGF(
TL(
"Using default lane width for edge '%' as value '%' could not be parsed."),
toString(myCurrentEdge->id), value);
1468 }
else if (key ==
"width") {
1472 WRITE_WARNINGF(
TL(
"Using default width for edge '%' as value '%' could not be parsed."),
toString(myCurrentEdge->id), value);
1474 }
else if (key ==
"foot") {
1475 if (value ==
"use_sidepath" || value ==
"no") {
1477 }
else if (value ==
"yes" || value ==
"designated" || value ==
"permissive") {
1480 }
else if (key ==
"bicycle") {
1481 if (value ==
"use_sidepath" || value ==
"no") {
1483 }
else if (value ==
"yes" || value ==
"designated" || value ==
"permissive") {
1486 }
else if (key ==
"oneway:bicycle") {
1487 myCurrentEdge->myExtraTags[
"oneway:bicycle"] = value;
1488 }
else if (key ==
"oneway:bus") {
1489 if (value ==
"no") {
1493 }
else if (key ==
"lanes") {
1499 std::vector<std::string> list = st.
getVector();
1500 if (list.size() >= 2) {
1501 int minLanes = std::numeric_limits<int>::max();
1503 for (
auto& i : list) {
1505 minLanes =
MIN2(minLanes, numLanes);
1507 myCurrentEdge->myNoLanes = minLanes;
1510 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
1514 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
1516 }
else if (key ==
"lanes:forward") {
1519 if (myCurrentEdge->myNoLanesForward < 0 && myCurrentEdge->myNoLanes < 0) {
1521 myCurrentEdge->myNoLanes = numLanes - myCurrentEdge->myNoLanesForward;
1523 myCurrentEdge->myNoLanesForward = numLanes;
1525 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
1527 }
else if (key ==
"lanes:backward") {
1530 if (myCurrentEdge->myNoLanesForward > 0 && myCurrentEdge->myNoLanes < 0) {
1532 myCurrentEdge->myNoLanes = numLanes + myCurrentEdge->myNoLanesForward;
1535 myCurrentEdge->myNoLanesForward = -numLanes;
1537 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
1540 (key ==
"maxspeed" || key ==
"maxspeed:type" || key ==
"maxspeed:forward" || key ==
"zone:maxspeed")) {
1542 myCurrentEdge->myMaxSpeed = interpretSpeed(key, value);
1543 }
else if (key ==
"maxspeed:backward" && myCurrentEdge->myMaxSpeedBackward ==
MAXSPEED_UNGIVEN) {
1544 myCurrentEdge->myMaxSpeedBackward = interpretSpeed(key, value);
1545 }
else if (key ==
"junction") {
1546 if ((value ==
"roundabout" || value ==
"circular") && myCurrentEdge->myIsOneWay.empty()) {
1547 myCurrentEdge->myIsOneWay =
"yes";
1549 if (value ==
"roundabout") {
1550 myCurrentEdge->myAmInRoundabout =
true;
1552 }
else if (key ==
"oneway") {
1553 myCurrentEdge->myIsOneWay = value;
1554 }
else if (key ==
"name") {
1555 myCurrentEdge->streetName = value;
1556 }
else if (key ==
"ref") {
1557 myCurrentEdge->ref = value;
1558 myCurrentEdge->setParameter(
"ref", value);
1559 }
else if (key ==
"layer") {
1563 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
1565 }
else if (key ==
"tracks") {
1568 myCurrentEdge->myIsOneWay =
"true";
1570 WRITE_WARNINGF(
TL(
"Ignoring track count % for edge '%'."), value, myCurrentEdge->id);
1573 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
1575 }
else if (key ==
"railway:preferred_direction") {
1576 if (value ==
"both") {
1577 myCurrentEdge->myRailDirection =
WAY_BOTH;
1578 }
else if (myCurrentEdge->myRailDirection ==
WAY_UNKNOWN) {
1579 if (value ==
"backward") {
1581 }
else if (value ==
"forward") {
1585 }
else if (key ==
"railway:bidirectional") {
1586 if (value ==
"regular") {
1587 myCurrentEdge->myRailDirection =
WAY_BOTH;
1589 }
else if (key ==
"electrified" || key ==
"segregated") {
1590 if (value !=
"no") {
1591 myCurrentEdge->myExtraTags[key] = value;
1593 }
else if (key ==
"railway:track_ref") {
1594 myCurrentEdge->setParameter(key, value);
1595 }
else if (key ==
"public_transport" && value ==
"platform") {
1596 myCurrentEdge->myExtraTags[
"platform"] =
"yes";
1603 }
else if (key ==
"change" || key ==
"change:lanes") {
1604 myCurrentEdge->myChangeForward = myCurrentEdge->myChangeBackward = interpretChangeType(value);
1605 }
else if (key ==
"change:forward" || key ==
"change:lanes:forward") {
1606 myCurrentEdge->myChangeForward = interpretChangeType(value);
1607 }
else if (key ==
"change:backward" || key ==
"change:lanes:backward") {
1608 myCurrentEdge->myChangeBackward = interpretChangeType(value);
1609 }
else if (key ==
"vehicle:lanes" || key ==
"vehicle:lanes:forward") {
1612 }
else if (key ==
"vehicle:lanes:backward") {
1615 }
else if (key ==
"bus:lanes" || key ==
"bus:lanes:forward") {
1616 interpretLaneUse(value,
SVC_BUS,
true);
1617 }
else if (key ==
"bus:lanes:backward") {
1618 interpretLaneUse(value,
SVC_BUS,
false);
1619 }
else if (key ==
"psv:lanes" || key ==
"psv:lanes:forward") {
1620 interpretLaneUse(value,
SVC_BUS,
true);
1621 interpretLaneUse(value,
SVC_TAXI,
true);
1622 }
else if (key ==
"psv:lanes:backward") {
1623 interpretLaneUse(value,
SVC_BUS,
false);
1624 interpretLaneUse(value,
SVC_TAXI,
false);
1625 }
else if (key ==
"bicycle:lanes" || key ==
"bicycle:lanes:forward") {
1627 }
else if (key ==
"bicycle:lanes:backward") {
1641 std::vector<int> turnCodes;
1642 for (std::string codeList : values) {
1645 if (codes.size() == 0) {
1648 for (std::string code : codes) {
1649 if (code ==
"" || code ==
"none" || code ==
"through") {
1651 }
else if (code ==
"left" || code ==
"sharp_left") {
1653 }
else if (code ==
"right" || code ==
"sharp_right") {
1655 }
else if (code ==
"slight_left") {
1657 }
else if (code ==
"slight_right") {
1659 }
else if (code ==
"reverse") {
1661 }
else if (code ==
"merge_to_left" || code ==
"merge_to_right") {
1665 turnCodes.push_back(turnCode);
1682 if (mySpeedMap.find(value) != mySpeedMap.end()) {
1683 return mySpeedMap[value];
1686 if (value.size() > 3 && value[2] ==
':') {
1687 if (value.substr(3, 4) ==
"zone") {
1688 value = value.substr(7);
1690 value = value.substr(3);
1696 WRITE_WARNING(
"Value of key '" + key +
"' is not numeric ('" + value +
"') in edge '" +
1697 toString(myCurrentEdge->id) +
"'.");
1708 for (
const std::string& val : values) {
1711 }
else if (val ==
"not_left") {
1713 }
else if (val ==
"not_right") {
1716 result = result << 2;
1719 result = result >> 2;
1721 if (values.size() > 1) {
1732 std::vector<bool>& designated = forward ? myCurrentEdge->myDesignatedLaneForward : myCurrentEdge->myDesignatedLaneBackward;
1733 std::vector<SVCPermissions>& allowed = forward ? myCurrentEdge->myAllowedLaneForward : myCurrentEdge->myAllowedLaneBackward;
1734 std::vector<SVCPermissions>& disallowed = forward ? myCurrentEdge->myDisallowedLaneForward : myCurrentEdge->myDisallowedLaneBackward;
1735 designated.resize(
MAX2(designated.size(), values.size()),
false);
1739 for (
const std::string& val : values) {
1740 if (val ==
"yes" || val ==
"permissive") {
1742 }
else if (val ==
"lane" || val ==
"designated") {
1744 designated[i] =
true;
1745 }
else if (val ==
"no") {
1746 disallowed[i] |= svc;
1748 WRITE_WARNINGF(
TL(
"Unknown lane use specifier '%' ignored for way '%'"), val, myCurrentEdge->id);
1757 if (element ==
SUMO_TAG_WAY && myCurrentEdge !=
nullptr) {
1758 if (myCurrentEdge->myCurrentIsRoad) {
1759 const auto insertionIt = myEdgeMap.lower_bound(myCurrentEdge->id);
1760 if (insertionIt == myEdgeMap.end() || insertionIt->first != myCurrentEdge->id) {
1762 myEdgeMap.emplace_hint(insertionIt, myCurrentEdge->id, myCurrentEdge);
1764 delete myCurrentEdge;
1766 }
else if (myCurrentEdge->myExtraTags.count(
"platform") != 0) {
1767 const auto insertionIt = myPlatformShapesMap.lower_bound(myCurrentEdge->id);
1768 if (insertionIt == myPlatformShapesMap.end() || insertionIt->first != myCurrentEdge->id) {
1770 myPlatformShapesMap.emplace_hint(insertionIt, myCurrentEdge->id, myCurrentEdge);
1772 delete myCurrentEdge;
1775 delete myCurrentEdge;
1777 myCurrentEdge =
nullptr;
1786 const std::map<long long int, NIOSMNode*>& osmNodes,
1787 const std::map<long long int, Edge*>& osmEdges,
NBPTStopCont* nbptStopCont,
1788 const std::map<long long int, Edge*>& platformShapes,
1793 myOSMEdges(osmEdges),
1795 myNBPTStopCont(nbptStopCont),
1796 myNBPTLineCont(nbptLineCont),
1808 myIsRestriction =
false;
1814 myRestrictionType = RestrictionType::UNKNOWN;
1815 myPlatforms.clear();
1817 myPlatformStops.clear();
1819 myIsStopArea =
false;
1822 myRouteColor.setValid(
false);
1830 myCurrentRelation = attrs.
get<
long long int>(
SUMO_ATTR_ID,
nullptr, ok);
1832 if (action ==
"delete" || !ok) {
1838 myNightService =
"";
1847 const long long int ref = attrs.
get<
long long int>(
SUMO_ATTR_REF,
nullptr, ok);
1848 if (role ==
"via") {
1851 if (memberType ==
"way" && checkEdgeRef(ref)) {
1853 }
else if (memberType ==
"node") {
1860 }
else if (role ==
"from" && checkEdgeRef(ref)) {
1862 }
else if (role ==
"to" && checkEdgeRef(ref)) {
1864 }
else if (role ==
"stop") {
1865 myStops.push_back(ref);
1866 }
else if (role ==
"platform") {
1868 if (memberType ==
"way") {
1869 const std::map<long long int, NIImporter_OpenStreetMap::Edge*>::const_iterator& wayIt =
myPlatformShapes.find(ref);
1872 platform.
isWay =
true;
1874 myPlatforms.push_back(platform);
1876 }
else if (memberType ==
"node") {
1878 myStops.push_back(ref);
1879 myPlatformStops.insert(ref);
1881 platform.
isWay =
false;
1883 myPlatforms.push_back(platform);
1886 }
else if (role.empty()) {
1888 if (memberType ==
"way") {
1889 myWays.push_back(ref);
1890 }
else if (memberType ==
"node") {
1891 myStops.push_back(ref);
1901 if (key ==
"type" || key ==
"restriction") {
1903 if (key ==
"type" && value ==
"restriction") {
1904 myIsRestriction =
true;
1907 if (key ==
"type" && value ==
"route") {
1911 if (key ==
"restriction") {
1914 if (value.substr(0, 5) ==
"only_") {
1915 myRestrictionType = RestrictionType::ONLY;
1916 }
else if (value.substr(0, 3) ==
"no_") {
1917 myRestrictionType = RestrictionType::NO;
1923 }
else if (key ==
"except") {
1927 myRestrictionException |=
SVC_BUS;
1928 }
else if (v ==
"bicycle") {
1930 }
else if (v ==
"hgv") {
1932 }
else if (v ==
"motorcar") {
1934 }
else if (v ==
"emergency") {
1938 }
else if (key ==
"public_transport") {
1940 if (value ==
"stop_area") {
1941 myIsStopArea =
true;
1943 }
else if (key ==
"route") {
1945 if (value ==
"train" || value ==
"subway" || value ==
"light_rail" || value ==
"monorail" || value ==
"tram" || value ==
"bus"
1946 || value ==
"trolleybus" || value ==
"aerialway" || value ==
"ferry" || value ==
"share_taxi" || value ==
"minibus") {
1947 myPTRouteType = value;
1950 }
else if (key ==
"name") {
1952 }
else if (key ==
"colour") {
1957 WRITE_WARNINGF(
TL(
"Invalid color value '%' in relation %"), value, myCurrentRelation);
1959 }
else if (key ==
"ref") {
1961 }
else if (key ==
"interval" || key ==
"headway") {
1963 }
else if (key ==
"by_night") {
1972 if (myOSMEdges.find(ref) != myOSMEdges.end()) {
1983 if (myIsRestriction) {
1986 if (myRestrictionType == RestrictionType::UNKNOWN) {
2002 if (ok && !applyRestriction()) {
2005 }
else if (myIsStopArea) {
2006 for (
long long ref : myStops) {
2007 myStopAreas[ref] = myCurrentRelation;
2016 std::shared_ptr<NBPTStop> ptStop = myNBPTStopCont->get(
toString(n->
id));
2017 if (ptStop ==
nullptr) {
2024 if (myPlatform.isWay) {
2028 WRITE_WARNINGF(
TL(
"Platform '%' in relation: '%' is given as polygon, which currently is not supported."), myPlatform.ref, myCurrentRelation);
2043 WRITE_ERRORF(
"Unable to project coordinates for node '%'.", pNode->
id);
2046 p.push_back(pNodePos);
2048 if (p.size() == 0) {
2049 WRITE_WARNINGF(
TL(
"Referenced platform: '%' in relation: '%' is corrupt. Probably OSM file is incomplete."),
2054 ptStop->addPlatformCand(platform);
2065 WRITE_ERRORF(
"Unable to project coordinates for node '%'.", pNode->
id);
2067 NBPTPlatform platform(platformPos, myOptionsCont.getFloat(
"osm.stop-output.length"));
2068 ptStop->addPlatformCand(platform);
2072 ptStop->setIsMultipleStopPositions(myStops.size() > 1, myCurrentRelation);
2074 }
else if (myPTRouteType !=
"" && myIsRoute) {
2075 NBPTLine* ptLine =
new NBPTLine(
toString(myCurrentRelation), myName, myPTRouteType, myRef, myInterval, myNightService,
2077 bool hadGap =
false;
2078 int missingBefore = 0;
2079 int missingAfter = 0;
2081 for (
long long ref : myStops) {
2096 WRITE_WARNINGF(
TL(
"PT line '%' in relation % seems to be split, only keeping first part."), myName, myCurrentRelation);
2097 missingAfter = (int)myStops.size() - missingBefore - (int)ptLine->
getStops().size();
2101 const NIOSMNode*
const n = nodeIt->second;
2102 std::shared_ptr<NBPTStop> ptStop = myNBPTStopCont->get(
toString(n->
id));
2103 if (ptStop ==
nullptr) {
2107 WRITE_ERRORF(
"Unable to project coordinates for node '%'.", n->
id);
2110 myNBPTStopCont->insert(ptStop);
2111 if (myStopAreas.count(n->
id)) {
2112 ptStop->setIsMultipleStopPositions(
false, myStopAreas[n->
id]);
2114 if (myPlatformStops.count(n->
id) > 0) {
2115 ptStop->setIsPlatform();
2120 for (
long long& myWay : myWays) {
2121 auto entr = myOSMEdges.find(myWay);
2122 if (entr != myOSMEdges.end()) {
2123 Edge* edge = entr->second;
2129 ptLine->
setNumOfStops((
int)myStops.size(), missingBefore, missingAfter);
2131 WRITE_WARNINGF(
TL(
"PT line in relation % with no stops ignored. Probably OSM file is incomplete."), myCurrentRelation);
2136 if (!myNBPTLineCont->insert(ptLine)) {
2151 if (viaNode ==
nullptr) {
2157 if (from ==
nullptr) {
2161 if (to ==
nullptr) {
2165 if (myRestrictionType == RestrictionType::ONLY) {
2192 WRITE_WARNINGF(
TL(
"direction of restriction relation could not be determined%"),
"");
2200 const std::vector<NBEdge*>& candidates)
const {
2201 const std::string prefix =
toString(wayRef);
2202 const std::string backPrefix =
"-" + prefix;
2203 NBEdge* result =
nullptr;
2205 for (
auto candidate : candidates) {
2206 if ((candidate->getID().substr(0, prefix.size()) == prefix) ||
2207 (candidate->getID().substr(0, backPrefix.size()) == backPrefix)) {
2213 WRITE_WARNINGF(
TL(
"Ambiguous way reference '%' in restriction relation"), prefix);
2227 std::map<NBNode*, std::vector<std::pair<double, double> > > layerForces;
2230 std::set<NBNode*> knownElevation;
2231 for (
auto& myEdge :
myEdges) {
2232 Edge* e = myEdge.second;
2236 if (node !=
nullptr) {
2237 knownElevation.insert(node);
2238 layerForces[node].emplace_back(e->
myLayer * layerElevation, POSITION_EPS);
2243#ifdef DEBUG_LAYER_ELEVATION
2244 std::cout <<
"known elevations:\n";
2245 for (std::set<NBNode*>::iterator it = knownElevation.begin(); it != knownElevation.end(); ++it) {
2246 const std::vector<std::pair<double, double> >& primaryLayers = layerForces[*it];
2247 std::cout <<
" node=" << (*it)->
getID() <<
" ele=";
2248 for (std::vector<std::pair<double, double> >::const_iterator it_ele = primaryLayers.begin(); it_ele != primaryLayers.end(); ++it_ele) {
2249 std::cout << it_ele->first <<
" ";
2257 std::map<NBNode*, double> knownEleMax;
2258 for (
auto it : knownElevation) {
2259 double eleMax = -std::numeric_limits<double>::max();
2260 const std::vector<std::pair<double, double> >& primaryLayers = layerForces[it];
2261 for (
const auto& primaryLayer : primaryLayers) {
2262 eleMax =
MAX2(eleMax, primaryLayer.first);
2264 knownEleMax[it] = eleMax;
2267 bool changed =
true;
2270 for (
auto it = knownElevation.begin(); it != knownElevation.end(); ++it) {
2273 / gradeThreshold * 3,
2275 for (
auto& neighbor : neighbors) {
2276 if (knownElevation.count(neighbor.first) != 0) {
2277 const double grade = fabs(knownEleMax[*it] - knownEleMax[neighbor.first])
2278 /
MAX2(POSITION_EPS, neighbor.second.first);
2279#ifdef DEBUG_LAYER_ELEVATION
2280 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";
2282 if (grade > gradeThreshold * 50 / 3.6 / neighbor.second.second) {
2284 const double eleMax =
MAX2(knownEleMax[*it], knownEleMax[neighbor.first]);
2285 if (knownEleMax[*it] < eleMax) {
2286 knownEleMax[*it] = eleMax;
2288 knownEleMax[neighbor.first] = eleMax;
2298 std::set<NBNode*> unknownElevation;
2299 for (
auto it = knownElevation.begin(); it != knownElevation.end(); ++it) {
2300 const double eleMax = knownEleMax[*it];
2301 const double maxDist = fabs(eleMax) * 100 / layerElevation;
2302 std::map<NBNode*, std::pair<double, double> > neighbors =
getNeighboringNodes(*it, maxDist, knownElevation);
2303 for (
auto& neighbor : neighbors) {
2304 if (knownElevation.count(neighbor.first) == 0) {
2305 unknownElevation.insert(neighbor.first);
2306 layerForces[neighbor.first].emplace_back(eleMax, neighbor.second.first);
2312 for (
auto it = unknownElevation.begin(); it != unknownElevation.end(); ++it) {
2313 double eleMax = -std::numeric_limits<double>::max();
2314 const std::vector<std::pair<double, double> >& primaryLayers = layerForces[*it];
2315 for (
const auto& primaryLayer : primaryLayers) {
2316 eleMax =
MAX2(eleMax, primaryLayer.first);
2318 const double maxDist = fabs(eleMax) * 100 / layerElevation;
2319 std::map<NBNode*, std::pair<double, double> > neighbors =
getNeighboringNodes(*it, maxDist, knownElevation);
2320 for (
auto& neighbor : neighbors) {
2321 if (knownElevation.count(neighbor.first) == 0 && unknownElevation.count(neighbor.first) == 0) {
2322 layerForces[*it].emplace_back(0, neighbor.second.first);
2327#ifdef DEBUG_LAYER_ELEVATION
2328 std::cout <<
"summation of forces\n";
2330 std::map<NBNode*, double> nodeElevation;
2331 for (
auto& layerForce : layerForces) {
2332 const std::vector<std::pair<double, double> >& forces = layerForce.second;
2333 if (knownElevation.count(layerForce.first) != 0) {
2341#ifdef DEBUG_LAYER_ELEVATION
2342 std::cout <<
" node=" << it->first->getID() <<
" knownElevation=" << knownEleMax[it->first] <<
"\n";
2344 nodeElevation[layerForce.first] = knownEleMax[layerForce.first];
2345 }
else if (forces.size() == 1) {
2346 nodeElevation[layerForce.first] = forces.front().first;
2350 for (
const auto& force : forces) {
2351 distSum += force.second;
2353 double weightSum = 0;
2354 double elevation = 0;
2355#ifdef DEBUG_LAYER_ELEVATION
2356 std::cout <<
" node=" << it->first->getID() <<
" distSum=" << distSum <<
"\n";
2358 for (
const auto& force : forces) {
2359 const double weight = (distSum - force.second) / distSum;
2360 weightSum += weight;
2361 elevation += force.first * weight;
2363#ifdef DEBUG_LAYER_ELEVATION
2364 std::cout <<
" force=" << it_force->first <<
" dist=" << it_force->second <<
" weight=" << weight <<
" ele=" << elevation <<
"\n";
2367 nodeElevation[layerForce.first] = elevation / weightSum;
2370#ifdef DEBUG_LAYER_ELEVATION
2371 std::cout <<
"final elevations:\n";
2372 for (std::map<NBNode*, double>::iterator it = nodeElevation.begin(); it != nodeElevation.end(); ++it) {
2373 std::cout <<
" node=" << (it->first)->getID() <<
" ele=" << it->second <<
"\n";
2377 for (
auto& it : nodeElevation) {
2384 for (
const auto& it : ec) {
2385 NBEdge* edge = it.second;
2387 const double length = geom.
length2D();
2388 const double zFrom = nodeElevation[edge->
getFromNode()];
2389 const double zTo = nodeElevation[edge->
getToNode()];
2394 for (
auto it_pos = geom.begin(); it_pos != geom.end(); ++it_pos) {
2395 if (it_pos != geom.begin()) {
2396 dist += (*it_pos).distanceTo2D(*(it_pos - 1));
2398 newGeom.push_back((*it_pos) +
Position(0, 0, zFrom + (zTo - zFrom) * dist / length));
2404std::map<NBNode*, std::pair<double, double> >
2406 std::map<NBNode*, std::pair<double, double> > result;
2407 std::set<NBNode*> visited;
2408 std::vector<NBNode*> open;
2409 open.push_back(node);
2410 result[node] = std::make_pair(0, 0);
2411 while (!open.empty()) {
2414 if (visited.count(n) != 0) {
2419 for (
auto e : edges) {
2422 s = e->getFromNode();
2426 const double dist = result[n].first + e->getGeometry().length2D();
2427 const double speed =
MAX2(e->getSpeed(), result[n].second);
2428 if (result.count(s) == 0) {
2429 result[s] = std::make_pair(dist, speed);
2431 result[s] = std::make_pair(
MIN2(dist, result[s].first),
MAX2(speed, result[s].second));
2433 if (dist < maxDist && knownElevation.count(s) == 0) {
2445 if (tc.
knows(type)) {
2456 std::vector<std::string> types;
2458 std::string t = tok.
next();
2460 if (std::find(types.begin(), types.end(), t) == types.end()) {
2463 }
else if (tok.
size() > 1) {
2465 WRITE_WARNINGF(
TL(
"Discarding unknown compound '%' in type '%' (first occurrence for edge '%')."), t, type,
id);
2469 if (types.empty()) {
2471 WRITE_WARNINGF(
TL(
"Discarding unusable type '%' (first occurrence for edge '%')."), type,
id);
2477 if (tc.
knows(newType)) {
2485 double maxSpeed = 0;
2490 bool defaultIsOneWay =
true;
2493 bool discard =
true;
2494 bool hadDiscard =
false;
2495 for (
auto& type2 : types) {
2512 if (hadDiscard && permissions == 0) {
2516 WRITE_WARNINGF(
TL(
"Discarding compound type '%' (first occurrence for edge '%')."), newType,
id);
2531 WRITE_MESSAGEF(
TL(
"Adding new type '%' (first occurrence for edge '%')."), type,
id);
2532 tc.
insertEdgeType(newType, numLanes, maxSpeed, prio, permissions, spreadType, width,
2533 defaultIsOneWay, sidewalkWidth, bikelaneWidth, 0, 0, 0);
2534 for (
auto& type3 : types) {
2549 std::vector<NIOSMNode*> nodes;
2550 std::vector<double> usablePositions;
2551 std::vector<int> usableIndex;
2555 if (node->
positionMeters != std::numeric_limits<double>::max()) {
2557 usableIndex.push_back((
int)nodes.size());
2559 nodes.push_back(node);
2561 if (usablePositions.size() == 0) {
2564 bool forward =
true;
2565 if (usablePositions.size() == 1) {
2566 WRITE_WARNINGF(
TL(
"Ambiguous railway kilometrage direction for way '%' (assuming forward)"),
id);
2568 forward = usablePositions.front() < usablePositions.back();
2571 for (
int i = 1; i < (int)usablePositions.size(); i++) {
2572 if ((usablePositions[i - 1] < usablePositions[i]) != forward) {
2573 WRITE_WARNINGF(
TL(
"Inconsistent railway kilometrage direction for way '%': % (skipping)"),
id,
toString(usablePositions));
2577 if (nodes.size() > usablePositions.size()) {
2581 shape.push_back(
Position(node->lon, node->lat, 0));
2586 double sign = forward ? 1 : -1;
2588 for (
int i = usableIndex.front() - 1; i >= 0; i--) {
2589 nodes[i]->positionMeters = nodes[i + 1]->positionMeters - sign * shape[i].distanceTo2D(shape[i + 1]);
2592 for (
int i = usableIndex.front() + 1; i < (int)nodes.size(); i++) {
2593 if (nodes[i]->positionMeters == std::numeric_limits<double>::max()) {
2594 nodes[i]->positionMeters = nodes[i - 1]->positionMeters + sign * shape[i].distanceTo2D(shape[i - 1]);
2621 return std::numeric_limits<double>::max();
2627 if (type ==
"train") {
2629 }
else if (type ==
"subway") {
2631 }
else if (type ==
"aerialway") {
2633 }
else if (type ==
"light_rail" || type ==
"monorail") {
2635 }
else if (type ==
"share_taxi") {
2637 }
else if (type ==
"minibus") {
2639 }
else if (type ==
"trolleybus") {
2644 std::string stop =
"";
2647 }
else if (result ==
SVC_BUS) {
2662 bool multiLane = changeProhibition > 3;
2664 for (
int lane = 0; changeProhibition > 0 && lane < e->
getNumLanes(); lane++) {
2665 int code = changeProhibition % 4;
2670 changeProhibition = changeProhibition >> 2;
2684 for (
int lane = 0; lane < numLanes; lane++) {
2686 const int i = lefthand ? lane : numLanes - 1 - lane;
2691 if (i < (
int)designated.size() && designated[i]) {
2703 if (signs.empty()) {
2704 signs.insert(signs.begin(), signs2.begin(), signs2.end());
2706 for (
int i = 0; i < (int)
MIN2(signs.size(), signs2.size()); i++) {
2707 signs[i] |= signs2[i];
2719 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 permissions 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
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
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 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 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.