57#define KM_PER_MILE 1.609344
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);
275 for (
const auto& nodeIt : nc) {
276 NBNode*
const n = nodeIt.second;
280 size_t incomingEdgesNo = incomingEdges.size();
281 size_t outgoingEdgesNo = outgoingEdges.size();
283 for (
size_t i = 0; i < incomingEdgesNo; i++) {
291 auto const iEdge = incomingEdges[i];
295 std::string
const& iEdgeId = iEdge->getID();
296 std::size_t
const m = iEdgeId.find_first_of(
"#");
297 std::string
const& iWayId = iEdgeId.substr(0, m);
298 for (
size_t j = 0; j < outgoingEdgesNo; j++) {
299 auto const oEdge = outgoingEdges[j];
302 if (oEdge->getID().find(iWayId) != std::string::npos
304 && oEdge->getID().rfind(iWayId, 0) != 0) {
307 edgeVector.push_back(oEdge);
317 for (
size_t i = 0; i < outgoingEdgesNo; i++) {
319 auto const oEdge = outgoingEdges[i];
323 std::string
const& oEdgeId = oEdge->getID();
324 std::size_t
const m = oEdgeId.find_first_of(
"#");
325 std::string
const& iWayId = oEdgeId.substr(0, m);
326 for (
size_t j = 0; j < incomingEdgesNo; j++) {
327 auto const iEdge = incomingEdges[j];
328 if (iEdge->getID().find(iWayId) != std::string::npos
330 && iEdge->getID().rfind(iWayId, 0) != 0) {
333 edgeVector.push_back(iEdge);
348 const double layerElevation = oc.
getFloat(
"osm.layer-elevation");
349 if (layerElevation > 0) {
361 for (
const std::string& file : files) {
362 if (readers[idx] !=
nullptr) {
364 readers[idx]->setHandler(relationHandler);
374 std::set<std::string> stopNames;
376 stopNames.insert(item.second->getName());
383 WRITE_ERRORF(
"Unable to project coordinates for node '%'.", n->
id);
395 if (node ==
nullptr) {
399 WRITE_ERRORF(
"Unable to project coordinates for junction '%'.",
id);
420 if (!tlsc.
insert(tlDef)) {
426 node->
setParameter(
"computePedestrianCrossing",
"true");
440 const std::vector<long long int>& passed,
NBNetBuilder& nb,
450 if (from ==
nullptr || to ==
nullptr) {
451 WRITE_ERRORF(
"Discarding edge '%' because the nodes could not be built.",
id);
460 assert(passed.size() >= 2);
461 if (passed.size() == 2) {
462 WRITE_WARNINGF(
TL(
"Discarding edge '%' which connects two identical nodes without geometry."),
id);
466 int intermediateIndex = (int) passed.size() / 2;
468 std::vector<long long int> part1(passed.begin(), passed.begin() + intermediateIndex + 1);
469 std::vector<long long int> part2(passed.begin() + intermediateIndex, passed.end());
470 index =
insertEdge(e, index, from, intermediate, part1, nb, first, last);
471 return insertEdge(e, index, intermediate, to, part2, nb, first, last);
473 const int newIndex = index + 1;
486 SVCPermissions permissions = (defaultPermissions | extra) & ~extraDis;
488 defaultsToOneWay =
false;
496 double distanceStart =
myOSMNodes[passed.front()]->positionMeters;
497 double distanceEnd =
myOSMNodes[passed.back()]->positionMeters;
498 const bool useDistance = distanceStart != std::numeric_limits<double>::max() && distanceEnd != std::numeric_limits<double>::max();
501 if (distanceStart < distanceEnd) {
510 std::vector<std::shared_ptr<NBPTStop> > ptStops;
511 for (
long long i : passed) {
515 std::shared_ptr<NBPTStop> existingPtStop = sc.
get(
toString(n->
id));
516 if (existingPtStop !=
nullptr) {
517 existingPtStop->registerAdditionalEdge(
toString(e->
id), id);
521 WRITE_ERRORF(
"Unable to project coordinates for node '%'.", n->
id);
524 sc.
insert(ptStops.back());
528 shape.push_back(pos);
531 WRITE_ERRORF(
"Unable to project coordinates for edge '%'.",
id);
537 if (streetName == e->
ref) {
554 const std::string& onewayBike = e->
myExtraTags[
"oneway:bicycle"];
555 if (onewayBike ==
"false" || onewayBike ==
"no" || onewayBike ==
"0") {
564 bool addForward =
true;
565 bool addBackward =
true;
581 if (addBackward && (onewayBike ==
"true" || onewayBike ==
"yes" || onewayBike ==
"1")) {
584 if (addForward && (onewayBike ==
"reverse" || onewayBike ==
"-1")) {
587 if (!addBackward && (onewayBike ==
"false" || onewayBike ==
"no" || onewayBike ==
"0")) {
594 if (addForward && !addBackward) {
596 }
else if (!addForward && addBackward) {
604 numLanesForward = (int) std::ceil(e->
myNoLanes / 2.0);
606 numLanesBackward = e->
myNoLanes - numLanesForward;
609 numLanesForward =
MAX2(1, numLanesForward);
610 numLanesBackward =
MAX2(1, numLanesBackward);
628 double speedBackward = speed;
632 if (speed <= 0 || speedBackward <= 0) {
639 if (!addForward && (cyclewayType &
WAY_FORWARD) != 0) {
642 forwardWidth = bikeLaneWidth;
647 if (!addBackward && (cyclewayType &
WAY_BACKWARD) != 0) {
650 backwardWidth = bikeLaneWidth;
651 numLanesBackward = 1;
663 if (!addForward && (sidewalkType &
WAY_FORWARD) != 0) {
670 }
else if (addSidewalk && addForward && (sidewalkType &
WAY_BOTH) == 0
671 && numLanesForward == 1 && numLanesBackward <= 1
678 if (!addBackward && (sidewalkType &
WAY_BACKWARD) != 0) {
682 numLanesBackward = 1;
685 }
else if (addSidewalk && addBackward && (sidewalkType &
WAY_BOTH) == 0
686 && numLanesBackward == 1 && numLanesForward <= 1
703 numLanesBackward = 1;
709 const int offsetFactor = lefthand ? -1 : 1;
721 const std::string reverseID =
"-" + id;
724 assert(numLanesForward > 0);
751 if (numForwardLanesFromWidthKey > 0) {
752 if ((
int)nbe->
getLanes().size() != numForwardLanesFromWidthKey) {
753 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."),
754 id, nbe->
getLanes().size(), numForwardLanesFromWidthKey);
756 for (
int i = 0; i < numForwardLanesFromWidthKey; i++) {
758 const int laneIndex = lefthand ? i : numForwardLanesFromWidthKey - i - 1;
770 assert(numLanesBackward > 0);
797 if (numBackwardLanesFromWidthKey > 0) {
798 if ((
int)nbe->
getLanes().size() != numBackwardLanesFromWidthKey) {
799 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."),
800 id, nbe->
getLanes().size(), numBackwardLanesFromWidthKey);
802 for (
int i = 0; i < numBackwardLanesFromWidthKey; i++) {
804 const int laneIndex = lefthand ? i : numBackwardLanesFromWidthKey - i - 1;
848 std::set<NIOSMNode*, CompareNodes>& uniqueNodes,
const OptionsCont& oc) :
851 myCurrentNode(nullptr),
853 myUniqueNodes(uniqueNodes),
854 myImportElevation(oc.getBool(
"osm.elevation")),
867 if (myHierarchyLevel != 2) {
868 WRITE_ERROR(
"Node element on wrong XML hierarchy level (id='" + myLastNodeID +
869 "', level='" +
toString(myHierarchyLevel) +
"').");
873 if (action ==
"delete" || !ok) {
879 myCurrentNode =
nullptr;
880 const auto insertionIt = myToFill.lower_bound(
id);
881 if (insertionIt == myToFill.end() || insertionIt->first !=
id) {
883 const double tlon = attrs.
get<
double>(
SUMO_ATTR_LON, myLastNodeID.c_str(), ok);
884 const double tlat = attrs.
get<
double>(
SUMO_ATTR_LAT, myLastNodeID.c_str(), ok);
888 myCurrentNode =
new NIOSMNode(
id, tlon, tlat);
893 delete myCurrentNode;
894 myCurrentNode = *similarNode;
897 myToFill.emplace_hint(insertionIt,
id, myCurrentNode);
900 WRITE_ERROR(
TL(
"Attribute 'id' in the definition of a node is not of type long long int."));
904 if (element ==
SUMO_TAG_TAG && myCurrentNode !=
nullptr) {
905 if (myHierarchyLevel != 3) {
906 WRITE_ERROR(
TL(
"Tag element on wrong XML hierarchy level."));
910 const std::string& key = attrs.
get<std::string>(
SUMO_ATTR_K, myLastNodeID.c_str(), ok,
false);
912 if (key ==
"highway" || key ==
"ele" || key ==
"crossing" || key ==
"railway" || key ==
"public_transport"
913 || key ==
"name" || key ==
"train" || key ==
"bus" || key ==
"tram" || key ==
"light_rail" || key ==
"subway" || key ==
"station" || key ==
"noexit"
917 const std::string& value = attrs.
get<std::string>(
SUMO_ATTR_V, myLastNodeID.c_str(), ok,
false);
918 if (key ==
"highway" && value.find(
"traffic_signal") != std::string::npos) {
919 myCurrentNode->tlsControlled =
true;
920 }
else if (key ==
"crossing" && value.find(
"traffic_signals") != std::string::npos) {
921 myCurrentNode->tlsControlled =
true;
922 }
else if (key ==
"highway" && value.find(
"crossing") != std::string::npos) {
923 myCurrentNode->pedestrianCrossing =
true;
924 }
else if ((key ==
"noexit" && value ==
"yes")
925 || (key ==
"railway" && value ==
"buffer_stop")) {
926 myCurrentNode->railwayBufferStop =
true;
927 }
else if (key ==
"railway" && value.find(
"crossing") != std::string::npos) {
928 myCurrentNode->railwayCrossing =
true;
930 value ==
"block" || value ==
"entry" || value ==
"exit" || value ==
"intermediate")) {
931 myCurrentNode->railwaySignal =
true;
932 }
else if (
StringUtils::startsWith(key,
"railway:position") && value.size() > myCurrentNode->position.size()) {
934 myCurrentNode->position = value;
935 }
else if ((key ==
"public_transport" && value ==
"stop_position") ||
936 (key ==
"highway" && value ==
"bus_stop")) {
937 myCurrentNode->ptStopPosition =
true;
938 if (myCurrentNode->ptStopLength == 0) {
940 myCurrentNode->ptStopLength = myOptionsCont.getFloat(
"osm.stop-output.length");
942 }
else if (key ==
"name") {
943 myCurrentNode->name = value;
944 }
else if (myImportElevation && key ==
"ele") {
947 if (std::isnan(elevation)) {
948 WRITE_WARNINGF(
TL(
"Value of key '%' is invalid ('%') in node '%'."), key, value, myLastNodeID);
950 myCurrentNode->ele = elevation;
953 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in node '%'."), key, value, myLastNodeID);
955 }
else if (key ==
"station") {
963 const std::string info =
"node=" +
toString(myCurrentNode->id) +
", k=" + key;
964 myCurrentNode->setParameter(key, attrs.
get<std::string>(
SUMO_ATTR_V, info.c_str(), ok,
false));
973 myCurrentNode =
nullptr;
983 const std::map<long long int, NIOSMNode*>& osmNodes,
984 std::map<long long int, Edge*>& toFill, std::map<long long int, Edge*>& platformShapes):
988 myPlatformShapesMap(platformShapes) {
1083 const long long int id = attrs.
get<
long long int>(
SUMO_ATTR_ID,
nullptr, ok);
1085 if (action ==
"delete" || !ok) {
1086 myCurrentEdge =
nullptr;
1089 myCurrentEdge =
new Edge(
id);
1092 if (element ==
SUMO_TAG_ND && myCurrentEdge !=
nullptr) {
1102 ref = node->second->id;
1103 if (myCurrentEdge->myCurrentNodes.empty() ||
1104 myCurrentEdge->myCurrentNodes.back() != ref) {
1105 myCurrentEdge->myCurrentNodes.push_back(ref);
1110 if (element ==
SUMO_TAG_TAG && myCurrentEdge !=
nullptr) {
1115 const std::string buswaySpec = key.substr(7);
1117 if (buswaySpec ==
"right") {
1119 }
else if (buswaySpec ==
"left") {
1121 }
else if (buswaySpec ==
"both") {
1122 myCurrentEdge->myBuswayType = (
WayType)(myCurrentEdge->myBuswayType |
WAY_BOTH);
1128 const std::string info =
"way=" +
toString(myCurrentEdge->id) +
", k=" + key;
1129 myCurrentEdge->setParameter(key, attrs.
get<std::string>(
SUMO_ATTR_V, info.c_str(), ok,
false));
1134 && key !=
"maxspeed" && key !=
"maxspeed:type"
1135 && key !=
"zone:maxspeed"
1136 && key !=
"maxspeed:forward" && key !=
"maxspeed:backward"
1137 && key !=
"junction" && key !=
"name" && key !=
"tracks" && key !=
"layer"
1142 && key !=
"highspeed"
1146 && key !=
"postal_code"
1147 && key !=
"railway:preferred_direction"
1148 && key !=
"railway:bidirectional"
1149 && key !=
"railway:track_ref"
1152 && key !=
"electrified"
1153 && key !=
"segregated"
1158 && key !=
"oneway:bicycle"
1159 && key !=
"oneway:bus"
1160 && key !=
"bus:lanes"
1161 && key !=
"bus:lanes:forward"
1162 && key !=
"bus:lanes:backward"
1163 && key !=
"psv:lanes"
1164 && key !=
"psv:lanes:forward"
1165 && key !=
"psv:lanes:backward"
1166 && key !=
"bicycle:lanes"
1167 && key !=
"bicycle:lanes:forward"
1168 && key !=
"bicycle:lanes:backward"
1171 && key !=
"public_transport") {
1174 const std::string value = attrs.
get<std::string>(
SUMO_ATTR_V,
toString(myCurrentEdge->id).c_str(), ok,
false);
1176 if ((key ==
"highway" && value !=
"platform") || key ==
"railway" || key ==
"waterway" ||
StringUtils::startsWith(key,
"cycleway")
1178 || key ==
"aeroway" || key ==
"aerialway" || key ==
"usage" || key ==
"service") {
1180 myCurrentEdge->myCurrentIsRoad =
true;
1182 if (key ==
"cycleway") {
1183 if (value ==
"no" || value ==
"none" || value ==
"separate") {
1184 myCurrentEdge->myCyclewayType =
WAY_NONE;
1185 }
else if (value ==
"both") {
1186 myCurrentEdge->myCyclewayType =
WAY_BOTH;
1187 }
else if (value ==
"right") {
1189 }
else if (value ==
"left") {
1191 }
else if (value ==
"opposite_track") {
1193 }
else if (value ==
"opposite_lane") {
1195 }
else if (value ==
"opposite") {
1200 if (key ==
"cycleway:left") {
1201 if (myCurrentEdge->myCyclewayType ==
WAY_UNKNOWN) {
1202 myCurrentEdge->myCyclewayType =
WAY_NONE;
1204 if (value ==
"yes" || value ==
"lane" || value ==
"track") {
1209 if (key ==
"cycleway:right") {
1210 if (myCurrentEdge->myCyclewayType ==
WAY_UNKNOWN) {
1211 myCurrentEdge->myCyclewayType =
WAY_NONE;
1213 if (value ==
"yes" || value ==
"lane" || value ==
"track") {
1214 myCurrentEdge->myCyclewayType = (
WayType)(myCurrentEdge->myCyclewayType |
WAY_FORWARD);
1218 if (key ==
"cycleway:both") {
1219 if (myCurrentEdge->myCyclewayType ==
WAY_UNKNOWN) {
1220 if (value ==
"no" || value ==
"none" || value ==
"separate") {
1221 myCurrentEdge->myCyclewayType =
WAY_NONE;
1223 if (value ==
"yes" || value ==
"lane" || value ==
"track") {
1224 myCurrentEdge->myCyclewayType =
WAY_BOTH;
1229 if (key ==
"cycleway" && value !=
"lane" && value !=
"track" && value !=
"opposite_track" && value !=
"opposite_lane") {
1238 if (key ==
"sidewalk") {
1239 if (value ==
"no" || value ==
"none" || value ==
"separate") {
1240 myCurrentEdge->mySidewalkType =
WAY_NONE;
1241 }
else if (value ==
"both") {
1242 myCurrentEdge->mySidewalkType =
WAY_BOTH;
1243 }
else if (value ==
"right") {
1245 }
else if (value ==
"left") {
1249 if (key ==
"sidewalk:left") {
1250 if (myCurrentEdge->mySidewalkType ==
WAY_UNKNOWN) {
1251 myCurrentEdge->mySidewalkType =
WAY_NONE;
1253 if (value ==
"yes") {
1257 if (key ==
"sidewalk:right") {
1258 if (myCurrentEdge->mySidewalkType ==
WAY_UNKNOWN) {
1259 myCurrentEdge->mySidewalkType =
WAY_NONE;
1261 if (value ==
"yes") {
1262 myCurrentEdge->mySidewalkType = (
WayType)(myCurrentEdge->mySidewalkType |
WAY_FORWARD);
1265 if (key ==
"sidewalk:both") {
1266 if (myCurrentEdge->mySidewalkType ==
WAY_UNKNOWN) {
1267 if (value ==
"no" || value ==
"none" || value ==
"separate") {
1268 myCurrentEdge->mySidewalkType =
WAY_NONE;
1270 if (value ==
"yes") {
1271 myCurrentEdge->mySidewalkType =
WAY_BOTH;
1280 if (key ==
"busway") {
1281 if (value ==
"no") {
1284 if (value ==
"opposite_track") {
1286 }
else if (value ==
"opposite_lane") {
1292 std::string singleTypeID = key +
"." + value;
1293 if (key ==
"highspeed") {
1294 if (value ==
"no") {
1297 singleTypeID =
"railway.highspeed";
1300 if (!myCurrentEdge->myHighWayType.empty() && singleTypeID !=
"railway.highspeed") {
1301 if (myCurrentEdge->myHighWayType ==
"railway.highspeed") {
1306 std::vector<std::string> types =
StringTokenizer(myCurrentEdge->myHighWayType,
1308 types.push_back(singleTypeID);
1311 myCurrentEdge->myHighWayType = singleTypeID;
1313 }
else if (key ==
"bus" || key ==
"psv") {
1317 myCurrentEdge->myExtraAllowed |=
SVC_BUS;
1319 myCurrentEdge->myExtraDisallowed |=
SVC_BUS;
1322 myCurrentEdge->myExtraAllowed |=
SVC_BUS;
1327 std::vector<double> widthLanes;
1328 for (std::string width : values) {
1329 double parsedWidth = width ==
""
1332 widthLanes.push_back(parsedWidth);
1335 if (key ==
"width:lanes" || key ==
"width:lanes:forward") {
1336 myCurrentEdge->myWidthLanesForward = widthLanes;
1337 }
else if (key ==
"width:lanes:backward") {
1338 myCurrentEdge->myWidthLanesBackward = widthLanes;
1340 WRITE_WARNINGF(
TL(
"Using default lane width for edge '%' as key '%' could not be parsed."),
toString(myCurrentEdge->id), key);
1343 WRITE_WARNINGF(
TL(
"Using default lane width for edge '%' as value '%' could not be parsed."),
toString(myCurrentEdge->id), value);
1345 }
else if (key ==
"foot") {
1346 if (value ==
"use_sidepath" || value ==
"no") {
1348 }
else if (value ==
"yes" || value ==
"designated" || value ==
"permissive") {
1351 }
else if (key ==
"bicycle") {
1352 if (value ==
"use_sidepath" || value ==
"no") {
1354 }
else if (value ==
"yes" || value ==
"designated" || value ==
"permissive") {
1357 }
else if (key ==
"oneway:bicycle") {
1358 myCurrentEdge->myExtraTags[
"oneway:bicycle"] = value;
1359 }
else if (key ==
"oneway:bus") {
1360 if (value ==
"no") {
1364 }
else if (key ==
"lanes") {
1370 std::vector<std::string> list = st.
getVector();
1371 if (list.size() >= 2) {
1372 int minLanes = std::numeric_limits<int>::max();
1374 for (
auto& i : list) {
1376 minLanes =
MIN2(minLanes, numLanes);
1378 myCurrentEdge->myNoLanes = minLanes;
1381 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
1385 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
1387 }
else if (key ==
"lanes:forward") {
1390 if (myCurrentEdge->myNoLanesForward < 0 && myCurrentEdge->myNoLanes < 0) {
1392 myCurrentEdge->myNoLanes = numLanes - myCurrentEdge->myNoLanesForward;
1394 myCurrentEdge->myNoLanesForward = numLanes;
1396 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
1398 }
else if (key ==
"lanes:backward") {
1401 if (myCurrentEdge->myNoLanesForward > 0 && myCurrentEdge->myNoLanes < 0) {
1403 myCurrentEdge->myNoLanes = numLanes + myCurrentEdge->myNoLanesForward;
1406 myCurrentEdge->myNoLanesForward = -numLanes;
1408 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
1411 (key ==
"maxspeed" || key ==
"maxspeed:type" || key ==
"maxspeed:forward" || key ==
"zone:maxspeed")) {
1413 myCurrentEdge->myMaxSpeed = interpretSpeed(key, value);
1414 }
else if (key ==
"maxspeed:backward" && myCurrentEdge->myMaxSpeedBackward ==
MAXSPEED_UNGIVEN) {
1415 myCurrentEdge->myMaxSpeedBackward = interpretSpeed(key, value);
1416 }
else if (key ==
"junction") {
1417 if ((value ==
"roundabout" || value ==
"circular") && myCurrentEdge->myIsOneWay.empty()) {
1418 myCurrentEdge->myIsOneWay =
"yes";
1420 }
else if (key ==
"oneway") {
1421 myCurrentEdge->myIsOneWay = value;
1422 }
else if (key ==
"name") {
1423 myCurrentEdge->streetName = value;
1424 }
else if (key ==
"ref") {
1425 myCurrentEdge->ref = value;
1426 myCurrentEdge->setParameter(
"ref", value);
1427 }
else if (key ==
"layer") {
1431 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
1433 }
else if (key ==
"tracks") {
1436 myCurrentEdge->myIsOneWay =
"true";
1438 WRITE_WARNINGF(
TL(
"Ignoring track count % for edge '%'."), value, myCurrentEdge->id);
1441 WRITE_WARNINGF(
TL(
"Value of key '%' is not numeric ('%') in edge '%'."), key, value, myCurrentEdge->id);
1443 }
else if (key ==
"railway:preferred_direction") {
1444 if (value ==
"both") {
1445 myCurrentEdge->myRailDirection =
WAY_BOTH;
1446 }
else if (value ==
"backward") {
1449 }
else if (key ==
"railway:bidirectional") {
1450 if (value ==
"regular") {
1451 myCurrentEdge->myRailDirection =
WAY_BOTH;
1453 }
else if (key ==
"electrified" || key ==
"segregated") {
1454 if (value !=
"no") {
1455 myCurrentEdge->myExtraTags[key] = value;
1457 }
else if (key ==
"railway:track_ref") {
1458 myCurrentEdge->setParameter(key, value);
1459 }
else if (key ==
"public_transport" && value ==
"platform") {
1460 myCurrentEdge->myExtraTags[
"platform"] =
"yes";
1467 }
else if (key ==
"change" || key ==
"change:lanes") {
1468 myCurrentEdge->myChangeForward = myCurrentEdge->myChangeBackward = interpretChangeType(value);
1469 }
else if (key ==
"change:forward" || key ==
"change:lanes:forward") {
1470 myCurrentEdge->myChangeForward = interpretChangeType(value);
1471 }
else if (key ==
"change:backward" || key ==
"change:lanes:backward") {
1472 myCurrentEdge->myChangeBackward = interpretChangeType(value);
1473 }
else if (key ==
"vehicle:lanes" || key ==
"vehicle:lanes:forward") {
1476 }
else if (key ==
"vehicle:lanes:backward") {
1479 }
else if (key ==
"bus:lanes" || key ==
"bus:lanes:forward") {
1480 interpretLaneUse(value,
SVC_BUS,
true);
1481 }
else if (key ==
"bus:lanes:backward") {
1482 interpretLaneUse(value,
SVC_BUS,
false);
1483 }
else if (key ==
"psv:lanes" || key ==
"psv:lanes:forward") {
1484 interpretLaneUse(value,
SVC_BUS,
true);
1485 interpretLaneUse(value,
SVC_TAXI,
true);
1486 }
else if (key ==
"psv:lanes:backward") {
1487 interpretLaneUse(value,
SVC_BUS,
false);
1488 interpretLaneUse(value,
SVC_TAXI,
false);
1489 }
else if (key ==
"bicycle:lanes" || key ==
"bicycle:lanes:forward") {
1491 }
else if (key ==
"bicycle:lanes:backward") {
1495 std::vector<int> turnCodes;
1496 for (std::string codeList : values) {
1499 if (codes.size() == 0) {
1502 for (std::string code : codes) {
1503 if (code ==
"" || code ==
"none" || code ==
"through") {
1505 }
else if (code ==
"left" || code ==
"sharp_left") {
1507 }
else if (code ==
"right" || code ==
"sharp_right") {
1509 }
else if (code ==
"slight_left") {
1511 }
else if (code ==
"slight_right") {
1513 }
else if (code ==
"reverse") {
1515 }
else if (code ==
"merge_to_left" || code ==
"merge_to_right") {
1519 turnCodes.push_back(turnCode);
1521 if (key ==
"turn:lanes" || key ==
"turn:lanes:forward") {
1522 myCurrentEdge->myTurnSignsForward = turnCodes;
1523 }
else if (key ==
"turn:lanes:backward") {
1524 myCurrentEdge->myTurnSignsBackward = turnCodes;
1525 }
else if (key ==
"turn:lanes:both_ways") {
1526 myCurrentEdge->myTurnSignsForward = turnCodes;
1527 myCurrentEdge->myTurnSignsBackward = turnCodes;
1536 if (mySpeedMap.find(value) != mySpeedMap.end()) {
1537 return mySpeedMap[value];
1540 if (value.size() > 3 && value[2] ==
':') {
1541 if (value.substr(3, 4) ==
"zone") {
1542 value = value.substr(7);
1544 value = value.substr(3);
1547 double conversion = 1;
1557 WRITE_WARNING(
"Value of key '" + key +
"' is not numeric ('" + value +
"') in edge '" +
1558 toString(myCurrentEdge->id) +
"'.");
1569 for (
const std::string& val : values) {
1572 }
else if (val ==
"not_left") {
1574 }
else if (val ==
"not_right") {
1577 result = result << 2;
1580 result = result >> 2;
1582 if (values.size() > 1) {
1593 std::vector<bool>& designated = forward ? myCurrentEdge->myDesignatedLaneForward : myCurrentEdge->myDesignatedLaneBackward;
1594 std::vector<SVCPermissions>& allowed = forward ? myCurrentEdge->myAllowedLaneForward : myCurrentEdge->myAllowedLaneBackward;
1595 std::vector<SVCPermissions>& disallowed = forward ? myCurrentEdge->myDisallowedLaneForward : myCurrentEdge->myDisallowedLaneBackward;
1596 designated.resize(
MAX2(designated.size(), values.size()),
false);
1600 for (
const std::string& val : values) {
1601 if (val ==
"yes" || val ==
"permissive") {
1603 }
else if (val ==
"lane" || val ==
"designated") {
1605 designated[i] =
true;
1606 }
else if (val ==
"no") {
1607 disallowed[i] |= svc;
1609 WRITE_WARNINGF(
TL(
"Unknown lane use specifier '%' ignored for way '%'"), val, myCurrentEdge->id);
1618 if (element ==
SUMO_TAG_WAY && myCurrentEdge !=
nullptr) {
1619 if (myCurrentEdge->myCurrentIsRoad) {
1620 const auto insertionIt = myEdgeMap.lower_bound(myCurrentEdge->id);
1621 if (insertionIt == myEdgeMap.end() || insertionIt->first != myCurrentEdge->id) {
1623 myEdgeMap.emplace_hint(insertionIt, myCurrentEdge->id, myCurrentEdge);
1625 delete myCurrentEdge;
1627 }
else if (myCurrentEdge->myExtraTags.count(
"platform") != 0) {
1628 const auto insertionIt = myPlatformShapesMap.lower_bound(myCurrentEdge->id);
1629 if (insertionIt == myPlatformShapesMap.end() || insertionIt->first != myCurrentEdge->id) {
1631 myPlatformShapesMap.emplace_hint(insertionIt, myCurrentEdge->id, myCurrentEdge);
1633 delete myCurrentEdge;
1636 delete myCurrentEdge;
1638 myCurrentEdge =
nullptr;
1647 const std::map<long long int, NIOSMNode*>& osmNodes,
1648 const std::map<long long int, Edge*>& osmEdges,
NBPTStopCont* nbptStopCont,
1649 const std::map<long long int, Edge*>& platformShapes,
1654 myOSMEdges(osmEdges),
1656 myNBPTStopCont(nbptStopCont),
1657 myNBPTLineCont(nbptLineCont),
1669 myIsRestriction =
false;
1675 myRestrictionType = RestrictionType::UNKNOWN;
1676 myPlatforms.clear();
1678 myPlatformStops.clear();
1680 myIsStopArea =
false;
1683 myRouteColor.setValid(
false);
1691 myCurrentRelation = attrs.
get<
long long int>(
SUMO_ATTR_ID,
nullptr, ok);
1693 if (action ==
"delete" || !ok) {
1699 myNightService =
"";
1708 const long long int ref = attrs.
get<
long long int>(
SUMO_ATTR_REF,
nullptr, ok);
1709 if (role ==
"via") {
1712 if (memberType ==
"way" && checkEdgeRef(ref)) {
1714 }
else if (memberType ==
"node") {
1721 }
else if (role ==
"from" && checkEdgeRef(ref)) {
1723 }
else if (role ==
"to" && checkEdgeRef(ref)) {
1725 }
else if (role ==
"stop") {
1726 myStops.push_back(ref);
1727 }
else if (role ==
"platform") {
1729 if (memberType ==
"way") {
1730 const std::map<long long int, NIImporter_OpenStreetMap::Edge*>::const_iterator& wayIt =
myPlatformShapes.find(ref);
1733 platform.
isWay =
true;
1735 myPlatforms.push_back(platform);
1737 }
else if (memberType ==
"node") {
1739 myStops.push_back(ref);
1740 myPlatformStops.insert(ref);
1742 platform.
isWay =
false;
1744 myPlatforms.push_back(platform);
1747 }
else if (role.empty()) {
1749 if (memberType ==
"way") {
1750 myWays.push_back(ref);
1751 }
else if (memberType ==
"node") {
1752 myStops.push_back(ref);
1762 if (key ==
"type" || key ==
"restriction") {
1764 if (key ==
"type" && value ==
"restriction") {
1765 myIsRestriction =
true;
1768 if (key ==
"type" && value ==
"route") {
1772 if (key ==
"restriction") {
1775 if (value.substr(0, 5) ==
"only_") {
1776 myRestrictionType = RestrictionType::ONLY;
1777 }
else if (value.substr(0, 3) ==
"no_") {
1778 myRestrictionType = RestrictionType::NO;
1784 }
else if (key ==
"except") {
1788 myRestrictionException |=
SVC_BUS;
1789 }
else if (v ==
"bicycle") {
1791 }
else if (v ==
"hgv") {
1793 }
else if (v ==
"motorcar") {
1795 }
else if (v ==
"emergency") {
1799 }
else if (key ==
"public_transport") {
1801 if (value ==
"stop_area") {
1802 myIsStopArea =
true;
1804 }
else if (key ==
"route") {
1806 if (value ==
"train" || value ==
"subway" || value ==
"light_rail" || value ==
"monorail" || value ==
"tram" || value ==
"bus"
1807 || value ==
"trolleybus" || value ==
"aerialway" || value ==
"ferry" || value ==
"share_taxi" || value ==
"minibus") {
1808 myPTRouteType = value;
1811 }
else if (key ==
"name") {
1813 }
else if (key ==
"colour") {
1818 WRITE_WARNINGF(
TL(
"Invalid color value '%' in relation %"), value, myCurrentRelation);
1820 }
else if (key ==
"ref") {
1822 }
else if (key ==
"interval" || key ==
"headway") {
1824 }
else if (key ==
"by_night") {
1833 if (myOSMEdges.find(ref) != myOSMEdges.end()) {
1844 if (myIsRestriction) {
1847 if (myRestrictionType == RestrictionType::UNKNOWN) {
1863 if (ok && !applyRestriction()) {
1866 }
else if (myIsStopArea) {
1867 for (
long long ref : myStops) {
1868 myStopAreas[ref] = myCurrentRelation;
1877 std::shared_ptr<NBPTStop> ptStop = myNBPTStopCont->get(
toString(n->
id));
1878 if (ptStop ==
nullptr) {
1885 if (myPlatform.isWay) {
1889 WRITE_WARNINGF(
TL(
"Platform '%' in relation: '%' is given as polygon, which currently is not supported."), myPlatform.ref, myCurrentRelation);
1904 WRITE_ERRORF(
"Unable to project coordinates for node '%'.", pNode->
id);
1907 p.push_back(pNodePos);
1909 if (p.size() == 0) {
1910 WRITE_WARNINGF(
TL(
"Referenced platform: '%' in relation: '%' is corrupt. Probably OSM file is incomplete."),
1915 ptStop->addPlatformCand(platform);
1926 WRITE_ERRORF(
"Unable to project coordinates for node '%'.", pNode->
id);
1928 NBPTPlatform platform(platformPos, myOptionsCont.getFloat(
"osm.stop-output.length"));
1929 ptStop->addPlatformCand(platform);
1933 ptStop->setIsMultipleStopPositions(myStops.size() > 1, myCurrentRelation);
1935 }
else if (myPTRouteType !=
"" && myIsRoute) {
1936 NBPTLine* ptLine =
new NBPTLine(
toString(myCurrentRelation), myName, myPTRouteType, myRef, myInterval, myNightService,
1939 bool hadGap =
false;
1940 for (
long long ref : myStops) {
1943 if (!ptLine->
getStops().empty() && !hadGap) {
1949 WRITE_WARNINGF(
TL(
"PT line '%' in relation % seems to be split, only keeping first part."), myName, myCurrentRelation);
1953 const NIOSMNode*
const n = nodeIt->second;
1954 std::shared_ptr<NBPTStop> ptStop = myNBPTStopCont->get(
toString(n->
id));
1955 if (ptStop ==
nullptr) {
1959 WRITE_ERRORF(
"Unable to project coordinates for node '%'.", n->
id);
1962 myNBPTStopCont->insert(ptStop);
1963 if (myStopAreas.count(n->
id)) {
1964 ptStop->setIsMultipleStopPositions(
false, myStopAreas[n->
id]);
1966 if (myPlatformStops.count(n->
id) > 0) {
1967 ptStop->setIsPlatform();
1972 for (
long long& myWay : myWays) {
1973 auto entr = myOSMEdges.find(myWay);
1974 if (entr != myOSMEdges.end()) {
1975 Edge* edge = entr->second;
1982 WRITE_WARNINGF(
TL(
"PT line in relation % with no stops ignored. Probably OSM file is incomplete."), myCurrentRelation);
1987 if (!myNBPTLineCont->insert(ptLine)) {
2002 if (viaNode ==
nullptr) {
2008 if (from ==
nullptr) {
2012 if (to ==
nullptr) {
2016 if (myRestrictionType == RestrictionType::ONLY) {
2043 WRITE_WARNINGF(
TL(
"direction of restriction relation could not be determined%"),
"");
2051 const std::vector<NBEdge*>& candidates)
const {
2052 const std::string prefix =
toString(wayRef);
2053 const std::string backPrefix =
"-" + prefix;
2054 NBEdge* result =
nullptr;
2056 for (
auto candidate : candidates) {
2057 if ((candidate->getID().substr(0, prefix.size()) == prefix) ||
2058 (candidate->getID().substr(0, backPrefix.size()) == backPrefix)) {
2064 WRITE_WARNINGF(
TL(
"Ambiguous way reference '%' in restriction relation"), prefix);
2078 std::map<NBNode*, std::vector<std::pair<double, double> > > layerForces;
2081 std::set<NBNode*> knownElevation;
2082 for (
auto& myEdge :
myEdges) {
2083 Edge* e = myEdge.second;
2087 if (node !=
nullptr) {
2088 knownElevation.insert(node);
2089 layerForces[node].emplace_back(e->
myLayer * layerElevation, POSITION_EPS);
2094#ifdef DEBUG_LAYER_ELEVATION
2095 std::cout <<
"known elevations:\n";
2096 for (std::set<NBNode*>::iterator it = knownElevation.begin(); it != knownElevation.end(); ++it) {
2097 const std::vector<std::pair<double, double> >& primaryLayers = layerForces[*it];
2098 std::cout <<
" node=" << (*it)->
getID() <<
" ele=";
2099 for (std::vector<std::pair<double, double> >::const_iterator it_ele = primaryLayers.begin(); it_ele != primaryLayers.end(); ++it_ele) {
2100 std::cout << it_ele->first <<
" ";
2108 std::map<NBNode*, double> knownEleMax;
2109 for (
auto it : knownElevation) {
2110 double eleMax = -std::numeric_limits<double>::max();
2111 const std::vector<std::pair<double, double> >& primaryLayers = layerForces[it];
2112 for (
const auto& primaryLayer : primaryLayers) {
2113 eleMax =
MAX2(eleMax, primaryLayer.first);
2115 knownEleMax[it] = eleMax;
2118 bool changed =
true;
2121 for (
auto it = knownElevation.begin(); it != knownElevation.end(); ++it) {
2124 / gradeThreshold * 3,
2126 for (
auto& neighbor : neighbors) {
2127 if (knownElevation.count(neighbor.first) != 0) {
2128 const double grade = fabs(knownEleMax[*it] - knownEleMax[neighbor.first])
2129 /
MAX2(POSITION_EPS, neighbor.second.first);
2130#ifdef DEBUG_LAYER_ELEVATION
2131 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";
2133 if (grade > gradeThreshold * 50 / 3.6 / neighbor.second.second) {
2135 const double eleMax =
MAX2(knownEleMax[*it], knownEleMax[neighbor.first]);
2136 if (knownEleMax[*it] < eleMax) {
2137 knownEleMax[*it] = eleMax;
2139 knownEleMax[neighbor.first] = eleMax;
2149 std::set<NBNode*> unknownElevation;
2150 for (
auto it = knownElevation.begin(); it != knownElevation.end(); ++it) {
2151 const double eleMax = knownEleMax[*it];
2152 const double maxDist = fabs(eleMax) * 100 / layerElevation;
2153 std::map<NBNode*, std::pair<double, double> > neighbors =
getNeighboringNodes(*it, maxDist, knownElevation);
2154 for (
auto& neighbor : neighbors) {
2155 if (knownElevation.count(neighbor.first) == 0) {
2156 unknownElevation.insert(neighbor.first);
2157 layerForces[neighbor.first].emplace_back(eleMax, neighbor.second.first);
2163 for (
auto it = unknownElevation.begin(); it != unknownElevation.end(); ++it) {
2164 double eleMax = -std::numeric_limits<double>::max();
2165 const std::vector<std::pair<double, double> >& primaryLayers = layerForces[*it];
2166 for (
const auto& primaryLayer : primaryLayers) {
2167 eleMax =
MAX2(eleMax, primaryLayer.first);
2169 const double maxDist = fabs(eleMax) * 100 / layerElevation;
2170 std::map<NBNode*, std::pair<double, double> > neighbors =
getNeighboringNodes(*it, maxDist, knownElevation);
2171 for (
auto& neighbor : neighbors) {
2172 if (knownElevation.count(neighbor.first) == 0 && unknownElevation.count(neighbor.first) == 0) {
2173 layerForces[*it].emplace_back(0, neighbor.second.first);
2178#ifdef DEBUG_LAYER_ELEVATION
2179 std::cout <<
"summation of forces\n";
2181 std::map<NBNode*, double> nodeElevation;
2182 for (
auto& layerForce : layerForces) {
2183 const std::vector<std::pair<double, double> >& forces = layerForce.second;
2184 if (knownElevation.count(layerForce.first) != 0) {
2192#ifdef DEBUG_LAYER_ELEVATION
2193 std::cout <<
" node=" << it->first->getID() <<
" knownElevation=" << knownEleMax[it->first] <<
"\n";
2195 nodeElevation[layerForce.first] = knownEleMax[layerForce.first];
2196 }
else if (forces.size() == 1) {
2197 nodeElevation[layerForce.first] = forces.front().first;
2201 for (
const auto& force : forces) {
2202 distSum += force.second;
2204 double weightSum = 0;
2205 double elevation = 0;
2206#ifdef DEBUG_LAYER_ELEVATION
2207 std::cout <<
" node=" << it->first->getID() <<
" distSum=" << distSum <<
"\n";
2209 for (
const auto& force : forces) {
2210 const double weight = (distSum - force.second) / distSum;
2211 weightSum += weight;
2212 elevation += force.first * weight;
2214#ifdef DEBUG_LAYER_ELEVATION
2215 std::cout <<
" force=" << it_force->first <<
" dist=" << it_force->second <<
" weight=" << weight <<
" ele=" << elevation <<
"\n";
2218 nodeElevation[layerForce.first] = elevation / weightSum;
2221#ifdef DEBUG_LAYER_ELEVATION
2222 std::cout <<
"final elevations:\n";
2223 for (std::map<NBNode*, double>::iterator it = nodeElevation.begin(); it != nodeElevation.end(); ++it) {
2224 std::cout <<
" node=" << (it->first)->getID() <<
" ele=" << it->second <<
"\n";
2228 for (
auto& it : nodeElevation) {
2235 for (
const auto& it : ec) {
2236 NBEdge* edge = it.second;
2238 const double length = geom.
length2D();
2239 const double zFrom = nodeElevation[edge->
getFromNode()];
2240 const double zTo = nodeElevation[edge->
getToNode()];
2245 for (
auto it_pos = geom.begin(); it_pos != geom.end(); ++it_pos) {
2246 if (it_pos != geom.begin()) {
2247 dist += (*it_pos).distanceTo2D(*(it_pos - 1));
2249 newGeom.push_back((*it_pos) +
Position(0, 0, zFrom + (zTo - zFrom) * dist / length));
2255std::map<NBNode*, std::pair<double, double> >
2257 std::map<NBNode*, std::pair<double, double> > result;
2258 std::set<NBNode*> visited;
2259 std::vector<NBNode*> open;
2260 open.push_back(node);
2261 result[node] = std::make_pair(0, 0);
2262 while (!open.empty()) {
2265 if (visited.count(n) != 0) {
2270 for (
auto e : edges) {
2273 s = e->getFromNode();
2277 const double dist = result[n].first + e->getGeometry().length2D();
2278 const double speed =
MAX2(e->getSpeed(), result[n].second);
2279 if (result.count(s) == 0) {
2280 result[s] = std::make_pair(dist, speed);
2282 result[s] = std::make_pair(
MIN2(dist, result[s].first),
MAX2(speed, result[s].second));
2284 if (dist < maxDist && knownElevation.count(s) == 0) {
2296 if (tc.
knows(type)) {
2307 std::vector<std::string> types;
2309 std::string t = tok.
next();
2311 if (std::find(types.begin(), types.end(), t) == types.end()) {
2314 }
else if (tok.
size() > 1) {
2316 WRITE_WARNINGF(
TL(
"Discarding unknown compound '%' in type '%' (first occurrence for edge '%')."), t, type,
id);
2320 if (types.empty()) {
2322 WRITE_WARNINGF(
TL(
"Discarding unusable type '%' (first occurrence for edge '%')."), type,
id);
2328 if (tc.
knows(newType)) {
2336 double maxSpeed = 0;
2341 bool defaultIsOneWay =
true;
2344 bool discard =
true;
2345 bool hadDiscard =
false;
2346 for (
auto& type2 : types) {
2363 if (hadDiscard && permissions == 0) {
2367 WRITE_WARNINGF(
TL(
"Discarding compound type '%' (first occurrence for edge '%')."), newType,
id);
2382 WRITE_MESSAGEF(
TL(
"Adding new type '%' (first occurrence for edge '%')."), type,
id);
2383 tc.
insertEdgeType(newType, numLanes, maxSpeed, prio, permissions, spreadType, width,
2384 defaultIsOneWay, sidewalkWidth, bikelaneWidth, 0, 0, 0);
2385 for (
auto& type3 : types) {
2400 std::vector<NIOSMNode*> nodes;
2401 std::vector<double> usablePositions;
2402 std::vector<int> usableIndex;
2406 if (node->
positionMeters != std::numeric_limits<double>::max()) {
2408 usableIndex.push_back((
int)nodes.size());
2410 nodes.push_back(node);
2412 if (usablePositions.size() == 0) {
2415 bool forward =
true;
2416 if (usablePositions.size() == 1) {
2417 WRITE_WARNINGF(
TL(
"Ambiguous railway kilometrage direction for way '%' (assuming forward)"),
id);
2419 forward = usablePositions.front() < usablePositions.back();
2422 for (
int i = 1; i < (int)usablePositions.size(); i++) {
2423 if ((usablePositions[i - 1] < usablePositions[i]) != forward) {
2424 WRITE_WARNINGF(
TL(
"Inconsistent railway kilometrage direction for way '%': % (skipping)"),
id,
toString(usablePositions));
2428 if (nodes.size() > usablePositions.size()) {
2432 shape.push_back(
Position(node->lon, node->lat, 0));
2437 double sign = forward ? 1 : -1;
2439 for (
int i = usableIndex.front() - 1; i >= 0; i--) {
2440 nodes[i]->positionMeters = nodes[i + 1]->positionMeters - sign * shape[i].distanceTo2D(shape[i + 1]);
2443 for (
int i = usableIndex.front() + 1; i < (int)nodes.size(); i++) {
2444 if (nodes[i]->positionMeters == std::numeric_limits<double>::max()) {
2445 nodes[i]->positionMeters = nodes[i - 1]->positionMeters + sign * shape[i].distanceTo2D(shape[i - 1]);
2472 return std::numeric_limits<double>::max();
2478 if (type ==
"train") {
2480 }
else if (type ==
"subway" || type ==
"light_rail" || type ==
"monorail" || type ==
"aerialway") {
2482 }
else if (type ==
"share_taxi") {
2484 }
else if (type ==
"minibus") {
2489 std::string stop =
"";
2492 }
else if (result ==
SVC_BUS) {
2507 bool multiLane = changeProhibition > 3;
2509 for (
int lane = 0; changeProhibition > 0 && lane < e->
getNumLanes(); lane++) {
2510 int code = changeProhibition % 4;
2515 changeProhibition = changeProhibition >> 2;
2529 for (
int lane = 0; lane < numLanes; lane++) {
2531 const int i = lefthand ? lane : numLanes - 1 - lane;
2536 if (i < (
int)designated.size() && designated[i]) {
2554 for (
int i = 0; i < (int)turnSigns.size(); i++) {
2556 const int laneIndex = lefthand ? i : e->
getNumLanes() - 1 - 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
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)
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ 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_TAXI
vehicle is a taxi
@ SVC_BUS
vehicle is a bus
@ SVC_PEDESTRIAN
pedestrian
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
@ 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.
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
The representation of a single edge during network building.
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)
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 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.
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)
NBNode::Crossing * addCrossing(EdgeVector edges, double width, bool priority, int tlIndex=-1, int tlIndex2=-1, const PositionVector &customShape=PositionVector::EMPTY, bool fromSumoNet=false)
add a pedestrian crossing to 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 addWayNode(long long int way, long long int node)
const std::vector< std::shared_ptr< NBPTStop > > & getStops()
void setMyNumOfStops(int numStops)
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.
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.
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.
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.
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)
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.
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.
bool knowsParameter(const std::string &key) const
Returns whether the parameter is known.
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.