104 importer.
load(oc, nb);
116 delete myEdge.second;
120 delete myPlatformShape.second;
127 if (!oc.
isSet(
"osm-files")) {
135 for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
138 WRITE_ERROR(
"Could not open osm-file '" + *file +
"'.");
150 for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
159 if (!oc.
getBool(
"osm.skip-duplicates-check")) {
162 std::set<const Edge*, CompareEdges> dupsFinder;
164 if (dupsFinder.count(it->second) > 0) {
169 dupsFinder.insert(it->second);
180 std::map<long long int, int> nodeUsage;
182 for (std::map<long long int, Edge*>::const_iterator i =
myEdges.begin(); i !=
myEdges.end(); ++i) {
183 Edge* e = (*i).second;
185 for (std::vector<long long int>::const_iterator j = e->
myCurrentNodes.begin();
188 if (nodeUsage.find(*j) == nodeUsage.end()) {
191 nodeUsage[*j] = nodeUsage[*j] + 1;
195 for (std::map<long long int, NIOSMNode*>::const_iterator nodesIt =
myOSMNodes.begin();
198 if (nodesIt->second->tlsControlled || nodesIt->second->railwaySignal ) {
201 nodeUsage[nodesIt->first] += 1;
211 Edge* e = myEdge.second;
224 std::vector<long long int> passed;
226 passed.push_back(*j);
229 running =
insertEdge(e, running, currentFrom, currentTo, passed, nb);
230 currentFrom = currentTo;
232 passed.push_back(*j);
238 insertEdge(e, running, currentFrom, last, passed, nb);
241 const double layerElevation = oc.
getFloat(
"osm.layer-elevation");
242 if (layerElevation > 0) {
255 for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
267 if (node ==
nullptr) {
292 if (!tlsc.
insert(tlDef)) {
307 const std::vector<long long int>& passed,
NBNetBuilder& nb) {
316 if (from ==
nullptr || to ==
nullptr) {
317 WRITE_ERROR(
"Discarding edge '" +
id +
"' because the nodes could not be built.");
326 assert(passed.size() >= 2);
327 if (passed.size() == 2) {
328 WRITE_WARNINGF(
"Discarding edge '%' which connects two identical nodes without geometry.",
id);
332 int intermediateIndex = (int) passed.size() / 2;
334 std::vector<long long int> part1(passed.begin(), passed.begin() + intermediateIndex + 1);
335 std::vector<long long int> part2(passed.begin() + intermediateIndex, passed.end());
336 index =
insertEdge(e, index, from, intermediate, part1, nb);
337 return insertEdge(e, index, intermediate, to, part2, nb);
339 const int newIndex = index + 1;
343 double distanceStart =
myOSMNodes[passed.front()]->positionMeters;
344 double distanceEnd =
myOSMNodes[passed.back()]->positionMeters;
345 const bool useDistance = distanceStart != std::numeric_limits<double>::max() && distanceEnd != std::numeric_limits<double>::max();
348 if (distanceStart < distanceEnd) {
357 for (
long long i : passed) {
361 if (existingPtStop !=
nullptr) {
375 shape.push_back(pos);
378 WRITE_ERROR(
"Unable to project coordinates for edge '" +
id +
"'.");
398 if (streetName == e->
ref) {
401 double forwardWidth = tc.
getWidth(type);
402 double backwardWidth = tc.
getWidth(type);
406 bool addForward =
true;
407 bool addBackward =
true;
424 if (addForward && !addBackward) {
426 }
else if (!addForward && addBackward) {
434 numLanesForward = (int) std::ceil(e->
myNoLanes / 2.0);
436 numLanesBackward = e->
myNoLanes - numLanesForward;
439 numLanesForward =
MAX2(1, numLanesForward);
440 numLanesBackward =
MAX2(1, numLanesBackward);
443 WRITE_WARNINGF(
"Skipping edge '%' because it has zero lanes.",
id);
451 WRITE_WARNINGF(
"Skipping edge '%' because it has speed %.",
id, speed);
457 if (!addForward && (cyclewayType &
WAY_FORWARD) != 0) {
465 if (!addBackward && (cyclewayType &
WAY_BACKWARD) != 0) {
469 numLanesBackward = 1;
477 if (!addForward && (sidewalkType &
WAY_FORWARD) != 0) {
485 if (!addBackward && (sidewalkType &
WAY_BACKWARD) != 0) {
489 numLanesBackward = 1;
503 numLanesBackward = 1;
513 const std::string reverseID =
"-" + id;
516 assert(numLanesForward > 0);
541 assert(numLanesBackward > 0);
562 throw ProcessError(
"Could not add edge '-" +
id +
"'.");
597 std::set<NIOSMNode*, CompareNodes>& uniqueNodes,
604 myIsInValidNodeTag(false),
606 myUniqueNodes(uniqueNodes),
607 myImportElevation(oc.getBool(
"osm.elevation")),
618 if (myHierarchyLevel != 2) {
623 +
"', level='" +
toString(myHierarchyLevel) +
"').");
626 const long long int id = attrs.
get<
long long int>(
SUMO_ATTR_ID,
nullptr, ok);
628 if (action ==
"delete" || !ok) {
632 if (myToFill.find(
id) == myToFill.end()) {
656 auto* toAdd =
new NIOSMNode(
id, tlon, tlat);
657 myIsInValidNodeTag =
true;
664 toAdd = *similarNode;
667 myToFill[id] = toAdd;
671 if (myHierarchyLevel != 3) {
672 WRITE_ERROR(
"Tag element on wrong XML hierarchy level.");
678 if (key ==
"highway" || key ==
"ele" || key ==
"crossing" || key ==
"railway" || key ==
"public_transport"
679 || key ==
"name" || key ==
"train" || key ==
"bus" || key ==
"tram" || key ==
"light_rail" || key ==
"subway" || key ==
"station" || key ==
"noexit"
684 if (key ==
"highway" && value.find(
"traffic_signal") != std::string::npos) {
685 myToFill[myLastNodeID]->tlsControlled =
true;
686 }
else if (key ==
"crossing" && value.find(
"traffic_signals") != std::string::npos) {
687 myToFill[myLastNodeID]->tlsControlled =
true;
688 }
else if ((key ==
"noexit" && value ==
"yes")
689 || (key ==
"railway" && value ==
"buffer_stop")) {
690 myToFill[myLastNodeID]->railwayBufferStop =
true;
691 }
else if (key ==
"railway" && value.find(
"crossing") != std::string::npos) {
692 myToFill[myLastNodeID]->railwayCrossing =
true;
694 value ==
"block" || value ==
"entry" || value ==
"exit" || value ==
"intermediate")) {
695 myToFill[myLastNodeID]->railwaySignal =
true;
696 }
else if (
StringUtils::startsWith(key,
"railway:position") && value.size() > myToFill[myLastNodeID]->position.size()) {
698 myToFill[myLastNodeID]->position = value;
699 }
else if ((key ==
"public_transport" && value ==
"stop_position") ||
700 (key ==
"highway" && value ==
"bus_stop")) {
701 myToFill[myLastNodeID]->ptStopPosition =
true;
702 if (myToFill[myLastNodeID]->ptStopLength == 0) {
704 myToFill[myLastNodeID]->ptStopLength = myOptionsCont.getFloat(
"osm.stop-output.length");
706 }
else if (key ==
"name") {
707 myToFill[myLastNodeID]->name = value;
708 }
else if (myImportElevation && key ==
"ele") {
712 WRITE_WARNING(
"Value of key '" + key +
"' is not numeric ('" + value +
"') in node '" +
715 }
else if (key ==
"station") {
729 myIsInValidNodeTag =
false;
738 const std::map<long long int, NIOSMNode*>& osmNodes,
739 std::map<long long int, Edge*>& toFill, std::map<long long int, Edge*>& platformShapes):
743 myPlatformShapesMap(platformShapes) {
760 myParentElements.push_back(element);
764 const long long int id = attrs.
get<
long long int>(
SUMO_ATTR_ID,
nullptr, ok);
766 if (action ==
"delete" || !ok) {
767 myCurrentEdge =
nullptr;
770 myCurrentEdge =
new Edge(
id);
773 if (element ==
SUMO_TAG_ND && myCurrentEdge !=
nullptr) {
783 ref = node->second->id;
784 if (myCurrentEdge->myCurrentNodes.empty() ||
785 myCurrentEdge->myCurrentNodes.back() != ref) {
786 myCurrentEdge->myCurrentNodes.push_back(ref);
792 if (element ==
SUMO_TAG_TAG && myParentElements.size() > 2
793 && myParentElements[myParentElements.size() - 2] ==
SUMO_TAG_WAY) {
794 if (myCurrentEdge ==
nullptr) {
801 const std::string cyclewaySpec = key.substr(9);
803 if (cyclewaySpec ==
"right") {
804 myCurrentEdge->myCyclewayType = (
WayType)(myCurrentEdge->myCyclewayType |
WAY_FORWARD);
805 }
else if (cyclewaySpec ==
"left") {
807 }
else if (cyclewaySpec ==
"both") {
808 myCurrentEdge->myCyclewayType = (
WayType)(myCurrentEdge->myCyclewayType |
WAY_BOTH);
812 if ((myCurrentEdge->myCyclewayType &
WAY_BOTH) != 0) {
814 myCurrentEdge->myCyclewayType = (
WayType)(myCurrentEdge->myCyclewayType & ~
WAY_UNKNOWN);
818 const std::string buswaySpec = key.substr(7);
820 if (buswaySpec ==
"right") {
822 }
else if (buswaySpec ==
"left") {
824 }
else if (buswaySpec ==
"both") {
825 myCurrentEdge->myBuswayType = (
WayType)(myCurrentEdge->myBuswayType |
WAY_BOTH);
830 if (myAllAttributes && (key ==
"bridge" || key ==
"tunnel")) {
831 myCurrentEdge->setParameter(key,
"true");
835 && key !=
"maxspeed" && key !=
"junction" && key !=
"name" && key !=
"tracks" && key !=
"layer"
839 && key !=
"highspeed"
841 && key !=
"postal_code"
842 && key !=
"railway:preferred_direction"
843 && key !=
"railway:bidirectional"
844 && key !=
"railway:track_ref"
846 && key !=
"electrified"
847 && key !=
"public_transport") {
852 if ((key ==
"highway" && value !=
"platform") || key ==
"railway" || key ==
"waterway" || key ==
"cycleway"
853 || key ==
"busway" || key ==
"route" || key ==
"sidewalk" || key ==
"highspeed"
856 std::string singleTypeID = key +
"." + value;
857 myCurrentEdge->myCurrentIsRoad =
true;
859 if (key ==
"cycleway") {
863 if (value ==
"opposite_track") {
865 }
else if (value ==
"opposite_lane") {
870 if (key ==
"sidewalk") {
871 if (value ==
"no" || value ==
"none") {
872 myCurrentEdge->mySidewalkType =
WAY_NONE;
873 }
else if (value ==
"both") {
874 myCurrentEdge->mySidewalkType =
WAY_BOTH;
875 }
else if (value ==
"right") {
877 }
else if (value ==
"left") {
884 if (key ==
"busway") {
888 if (value ==
"opposite_track") {
890 }
else if (value ==
"opposite_lane") {
896 if (key ==
"highspeed") {
900 singleTypeID =
"railway.highspeed";
903 if (!myCurrentEdge->myHighWayType.empty() && singleTypeID !=
"railway.highspeed") {
904 if (myCurrentEdge->myHighWayType ==
"railway.highspeed") {
909 std::vector<std::string> types =
StringTokenizer(myCurrentEdge->myHighWayType,
911 types.push_back(singleTypeID);
914 myCurrentEdge->myHighWayType = singleTypeID;
916 }
else if (key ==
"lanes") {
922 std::vector<std::string> list = st.
getVector();
923 if (list.size() >= 2) {
924 int minLanes = std::numeric_limits<int>::max();
926 for (
auto& i : list) {
928 minLanes =
MIN2(minLanes, numLanes);
930 myCurrentEdge->myNoLanes = minLanes;
932 "Using minimum lane number from list (" + value +
") for edge '"
936 WRITE_WARNING(
"Value of key '" + key +
"' is not numeric ('" + value +
"') in edge '" +
937 toString(myCurrentEdge->id) +
"'.");
941 WRITE_WARNING(
"Value of key '" + key +
"' is not numeric ('" + value +
"') in edge '" +
942 toString(myCurrentEdge->id) +
"'.");
944 }
else if (key ==
"lanes:forward") {
948 WRITE_WARNING(
"Value of key '" + key +
"' is not numeric ('" + value +
"') in edge '" +
949 toString(myCurrentEdge->id) +
"'.");
951 }
else if (key ==
"lanes:backward") {
956 WRITE_WARNING(
"Value of key '" + key +
"' is not numeric ('" + value +
"') in edge '" +
957 toString(myCurrentEdge->id) +
"'.");
959 }
else if (key ==
"maxspeed") {
960 if (mySpeedMap.find(value) != mySpeedMap.end()) {
961 myCurrentEdge->myMaxSpeed = mySpeedMap[value];
963 double conversion = 1;
968 conversion = 1.609344;
973 WRITE_WARNING(
"Value of key '" + key +
"' is not numeric ('" + value +
"') in edge '" +
974 toString(myCurrentEdge->id) +
"'.");
977 }
else if (key ==
"junction") {
978 if ((value ==
"roundabout") && (myCurrentEdge->myIsOneWay.empty())) {
979 myCurrentEdge->myIsOneWay =
"yes";
981 }
else if (key ==
"oneway") {
982 myCurrentEdge->myIsOneWay = value;
983 }
else if (key ==
"name") {
984 myCurrentEdge->streetName = value;
985 }
else if (key ==
"ref") {
986 myCurrentEdge->ref = value;
987 myCurrentEdge->setParameter(
"ref", value);
988 }
else if (key ==
"layer") {
989 if (myAllAttributes) {
990 myCurrentEdge->setParameter(key, value);
995 WRITE_WARNING(
"Value of key '" + key +
"' is not numeric ('" + value +
"') in edge '" +
996 toString(myCurrentEdge->id) +
"'.");
998 }
else if (key ==
"tracks") {
1001 myCurrentEdge->myIsOneWay =
"true";
1003 WRITE_WARNING(
"Ignoring track count " + value +
" for edge '" +
toString(myCurrentEdge->id) +
"'.");
1006 WRITE_WARNING(
"Value of key '" + key +
"' is not numeric ('" + value +
"') in edge '" +
1007 toString(myCurrentEdge->id) +
"'.");
1009 }
else if (myAllAttributes && key ==
"postal_code") {
1010 myCurrentEdge->setParameter(key, value);
1011 }
else if (key ==
"railway:preferred_direction") {
1012 if (value ==
"both") {
1013 myCurrentEdge->myRailDirection =
WAY_BOTH;
1014 }
else if (value ==
"backward") {
1017 }
else if (key ==
"railway:bidirectional") {
1018 if (value ==
"regular") {
1019 myCurrentEdge->myRailDirection =
WAY_BOTH;
1021 }
else if (key ==
"electrified") {
1022 if (value !=
"no") {
1023 myCurrentEdge->myCurrentIsElectrified =
true;
1025 }
else if (key ==
"railway:track_ref") {
1026 myCurrentEdge->setParameter(key, value);
1027 }
else if (key ==
"public_transport" && value ==
"platform") {
1028 myCurrentEdge->myCurrentIsPlatform =
true;
1041 myParentElements.pop_back();
1042 if (element ==
SUMO_TAG_WAY && myCurrentEdge !=
nullptr) {
1043 if (myCurrentEdge->myCurrentIsRoad) {
1044 myEdgeMap[myCurrentEdge->id] = myCurrentEdge;
1045 }
else if (myCurrentEdge->myCurrentIsPlatform) {
1046 myPlatformShapesMap[myCurrentEdge->id] = myCurrentEdge;
1048 delete myCurrentEdge;
1050 myCurrentEdge =
nullptr;
1058 const std::map<long long int, NIOSMNode*>& osmNodes,
1059 const std::map<long long int, Edge*>& osmEdges,
NBPTStopCont* nbptStopCont,
1060 const std::map<long long int, Edge*>& platformShapes,
1066 myOSMEdges(osmEdges),
1068 myNBPTStopCont(nbptStopCont),
1069 myNBPTLineCont(nbptLineCont),
1079 myIsRestriction =
false;
1084 myRestrictionType = RESTRICTION_UNKNOWN;
1085 myPlatforms.clear();
1088 myIsStopArea =
false;
1096 myParentElements.push_back(element);
1100 myCurrentRelation = attrs.
get<
long long int>(
SUMO_ATTR_ID,
nullptr, ok);
1102 if (action ==
"delete" || !ok) {
1108 myNightService =
"";
1118 auto ref = attrs.
get<
long
1121 if (role ==
"via") {
1124 if (memberType ==
"way" && checkEdgeRef(ref)) {
1126 }
else if (memberType ==
"node") {
1131 "No node found for reference '" +
toString(ref) +
"' in relation '"
1136 }
else if (role ==
"from" && checkEdgeRef(ref)) {
1138 }
else if (role ==
"to" && checkEdgeRef(ref)) {
1140 }
else if (role ==
"stop") {
1141 myStops.push_back(ref);
1142 }
else if (role ==
"platform") {
1144 if (memberType ==
"way") {
1145 const std::map<
long long int,
1150 platform.
isWay =
true;
1152 myPlatforms.push_back(platform);
1154 }
else if (memberType ==
"node") {
1156 platform.
isWay =
false;
1158 myPlatforms.push_back(platform);
1161 }
else if (role.empty()) {
1163 if (memberType ==
"way") {
1164 myWays.push_back(ref);
1174 if (key ==
"type" || key ==
"restriction") {
1176 if (key ==
"type" && value ==
"restriction") {
1177 myIsRestriction =
true;
1180 if (key ==
"type" && value ==
"route") {
1184 if (key ==
"restriction") {
1187 if (value.substr(0, 5) ==
"only_") {
1188 myRestrictionType = RESTRICTION_ONLY;
1189 }
else if (value.substr(0, 3) ==
"no_") {
1190 myRestrictionType = RESTRICTION_NO;
1193 "Found unknown restriction type '" + value +
"' in relation '" +
toString(myCurrentRelation)
1198 }
else if (key ==
"public_transport") {
1200 if (value ==
"stop_area") {
1201 myIsStopArea =
true;
1203 }
else if (key ==
"route") {
1205 if (value ==
"train" || value ==
"subway" || value ==
"light_rail" || value ==
"monorail" || value ==
"tram" || value ==
"bus"
1206 || value ==
"trolleybus" || value ==
"arialway" || value ==
"ferry") {
1207 myPTRouteType = value;
1210 }
else if (key ==
"name") {
1212 }
else if (key ==
"ref") {
1214 }
else if (key ==
"interval" || key ==
"headway") {
1216 }
else if (key ==
"by_night") {
1224 if (myOSMEdges.find(ref) != myOSMEdges.end()) {
1229 "No way found for reference '" +
toString(ref) +
"' in relation '" +
toString(myCurrentRelation) +
"'");
1236 myParentElements.pop_back();
1238 if (myIsRestriction) {
1241 if (myRestrictionType == RESTRICTION_UNKNOWN) {
1242 WRITE_WARNING(
"Ignoring restriction relation '" +
toString(myCurrentRelation) +
"' with unknown type.");
1247 "Ignoring restriction relation '" +
toString(myCurrentRelation) +
"' with unknown from-way.");
1252 "Ignoring restriction relation '" +
toString(myCurrentRelation) +
"' with unknown to-way.");
1256 WRITE_WARNING(
"Ignoring restriction relation '" +
toString(myCurrentRelation) +
"' with unknown via.");
1259 if (ok && !applyRestriction()) {
1263 for (
long long ref : myStops) {
1273 if (ptStop ==
nullptr) {
1280 if (myPlatform.isWay) {
1284 WRITE_WARNINGF(
"Platform '%' in relation: '%' is given as polygon, which currently is not supported.", myPlatform.ref, myCurrentRelation);
1302 p.push_back(pNodePos);
1304 if (p.size() == 0) {
1306 "Referenced platform: '" +
toString(myPlatform.ref) +
"' in relation: '" +
toString(myCurrentRelation)
1307 +
"' is corrupt. Probably OSM file is incomplete.");
1324 NBPTPlatform platform(platformPos, myOptionsCont.getFloat(
1325 "osm.stop-output.length"));
1332 }
else if (myPTRouteType !=
"" && myIsRoute &&
OptionsCont::getOptions().isSet(
"ptline-output") && myStops.size() > 1) {
1335 for (
long long ref : myStops) {
1343 WRITE_WARNINGF(
"Done reading first coherent chunk of pt stops. Further stops in relation % are ignored", myCurrentRelation);
1351 if (ptStop ==
nullptr) {
1358 myNBPTStopCont->insert(ptStop);
1362 for (
long long& myWay : myWays) {
1363 auto entr = myOSMEdges.find(myWay);
1364 if (entr != myOSMEdges.end()) {
1365 Edge* edge = entr->second;
1372 WRITE_WARNINGF(
"PT line in relation % with no stops ignored. Probably OSM file is incomplete.", myCurrentRelation);
1376 if (myNBPTLineCont->getLines().count(ptLine->
getLineID()) == 0) {
1377 myNBPTLineCont->insert(ptLine);
1393 if (viaNode ==
nullptr) {
1399 if (from ==
nullptr) {
1400 WRITE_WARNING(
"from-edge of restriction relation could not be determined");
1403 if (to ==
nullptr) {
1404 WRITE_WARNING(
"to-edge of restriction relation could not be determined");
1407 if (myRestrictionType == RESTRICTION_ONLY) {
1414 WRITE_WARNING(
"direction of restriction relation could not be determined");
1422 const std::vector<NBEdge*>& candidates)
const {
1423 const std::string prefix =
toString(wayRef);
1424 const std::string backPrefix =
"-" + prefix;
1425 NBEdge* result =
nullptr;
1427 for (
auto candidate : candidates) {
1428 if ((candidate->getID().substr(0, prefix.size()) == prefix) ||
1429 (candidate->getID().substr(0, backPrefix.size()) == backPrefix)) {
1435 WRITE_WARNING(
"Ambigous way reference '" + prefix +
"' in restriction relation");
1448 std::map<NBNode*, std::vector<std::pair<double, double> > > layerForces;
1451 std::set<NBNode*> knownElevation;
1452 for (
auto& myEdge :
myEdges) {
1453 Edge* e = myEdge.second;
1457 if (node !=
nullptr) {
1458 knownElevation.insert(node);
1464 #ifdef DEBUG_LAYER_ELEVATION
1465 std::cout <<
"known elevations:\n";
1466 for (std::set<NBNode*>::iterator it = knownElevation.begin(); it != knownElevation.end(); ++it) {
1467 const std::vector<std::pair<double, double> >& primaryLayers = layerForces[*it];
1468 std::cout <<
" node=" << (*it)->
getID() <<
" ele=";
1469 for (std::vector<std::pair<double, double> >::const_iterator it_ele = primaryLayers.begin(); it_ele != primaryLayers.end(); ++it_ele) {
1470 std::cout << it_ele->first <<
" ";
1478 std::map<NBNode*, double> knownEleMax;
1479 for (
auto it : knownElevation) {
1480 double eleMax = -std::numeric_limits<double>::max();
1481 const std::vector<std::pair<double, double> >& primaryLayers = layerForces[it];
1482 for (
const auto& primaryLayer : primaryLayers) {
1483 eleMax =
MAX2(eleMax, primaryLayer.first);
1485 knownEleMax[it] = eleMax;
1488 bool changed =
true;
1491 for (
auto it = knownElevation.begin(); it != knownElevation.end(); ++it) {
1494 / gradeThreshold * 3,
1496 for (
auto& neighbor : neighbors) {
1497 if (knownElevation.count(neighbor.first) != 0) {
1498 const double grade = fabs(knownEleMax[*it] - knownEleMax[neighbor.first])
1500 #ifdef DEBUG_LAYER_ELEVATION
1501 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";
1503 if (grade > gradeThreshold * 50 / 3.6 / neighbor.second.second) {
1505 const double eleMax =
MAX2(knownEleMax[*it], knownEleMax[neighbor.first]);
1506 if (knownEleMax[*it] < eleMax) {
1507 knownEleMax[*it] = eleMax;
1509 knownEleMax[neighbor.first] = eleMax;
1519 std::set<NBNode*> unknownElevation;
1520 for (
auto it = knownElevation.begin(); it != knownElevation.end(); ++it) {
1521 const double eleMax = knownEleMax[*it];
1522 const double maxDist = fabs(eleMax) * 100 / layerElevation;
1523 std::map<NBNode*, std::pair<double, double> > neighbors =
getNeighboringNodes(*it, maxDist, knownElevation);
1524 for (
auto& neighbor : neighbors) {
1525 if (knownElevation.count(neighbor.first) == 0) {
1526 unknownElevation.insert(neighbor.first);
1527 layerForces[neighbor.first].emplace_back(eleMax, neighbor.second.first);
1533 for (
auto it = unknownElevation.begin(); it != unknownElevation.end(); ++it) {
1534 double eleMax = -std::numeric_limits<double>::max();
1535 const std::vector<std::pair<double, double> >& primaryLayers = layerForces[*it];
1536 for (
const auto& primaryLayer : primaryLayers) {
1537 eleMax =
MAX2(eleMax, primaryLayer.first);
1539 const double maxDist = fabs(eleMax) * 100 / layerElevation;
1540 std::map<NBNode*, std::pair<double, double> > neighbors =
getNeighboringNodes(*it, maxDist, knownElevation);
1541 for (
auto& neighbor : neighbors) {
1542 if (knownElevation.count(neighbor.first) == 0 && unknownElevation.count(neighbor.first) == 0) {
1543 layerForces[*it].emplace_back(0, neighbor.second.first);
1548 #ifdef DEBUG_LAYER_ELEVATION
1549 std::cout <<
"summation of forces\n";
1551 std::map<NBNode*, double> nodeElevation;
1552 for (
auto& layerForce : layerForces) {
1553 const std::vector<std::pair<double, double> >& forces = layerForce.second;
1554 if (knownElevation.count(layerForce.first) != 0) {
1562 #ifdef DEBUG_LAYER_ELEVATION
1563 std::cout <<
" node=" << it->first->getID() <<
" knownElevation=" << knownEleMax[it->first] <<
"\n";
1565 nodeElevation[layerForce.first] = knownEleMax[layerForce.first];
1566 }
else if (forces.size() == 1) {
1567 nodeElevation[layerForce.first] = forces.front().first;
1571 for (
const auto& force : forces) {
1572 distSum += force.second;
1574 double weightSum = 0;
1575 double elevation = 0;
1576 #ifdef DEBUG_LAYER_ELEVATION
1577 std::cout <<
" node=" << it->first->getID() <<
" distSum=" << distSum <<
"\n";
1579 for (
const auto& force : forces) {
1580 const double weight = (distSum - force.second) / distSum;
1581 weightSum += weight;
1582 elevation += force.first * weight;
1584 #ifdef DEBUG_LAYER_ELEVATION
1585 std::cout <<
" force=" << it_force->first <<
" dist=" << it_force->second <<
" weight=" << weight <<
" ele=" << elevation <<
"\n";
1588 nodeElevation[layerForce.first] = elevation / weightSum;
1591 #ifdef DEBUG_LAYER_ELEVATION
1592 std::cout <<
"final elevations:\n";
1593 for (std::map<NBNode*, double>::iterator it = nodeElevation.begin(); it != nodeElevation.end(); ++it) {
1594 std::cout <<
" node=" << (it->first)->getID() <<
" ele=" << it->second <<
"\n";
1598 for (
auto& it : nodeElevation) {
1605 for (
const auto& it : ec) {
1606 NBEdge* edge = it.second;
1608 const double length = geom.
length2D();
1609 const double zFrom = nodeElevation[edge->
getFromNode()];
1610 const double zTo = nodeElevation[edge->
getToNode()];
1615 for (
auto it_pos = geom.begin(); it_pos != geom.end(); ++it_pos) {
1616 if (it_pos != geom.begin()) {
1617 dist += (*it_pos).distanceTo2D(*(it_pos - 1));
1619 newGeom.push_back((*it_pos) +
Position(0, 0, zFrom + (zTo - zFrom) * dist / length));
1625 std::map<NBNode*, std::pair<double, double> >
1627 std::map<NBNode*, std::pair<double, double> > result;
1628 std::set<NBNode*> visited;
1629 std::vector<NBNode*> open;
1630 open.push_back(node);
1631 result[node] = std::make_pair(0, 0);
1632 while (!open.empty()) {
1635 if (visited.count(n) != 0) {
1640 for (
auto e : edges) {
1643 s = e->getFromNode();
1647 const double dist = result[n].first + e->getGeometry().length2D();
1648 const double speed =
MAX2(e->getSpeed(), result[n].second);
1649 if (result.count(s) == 0) {
1650 result[s] = std::make_pair(dist, speed);
1652 result[s] = std::make_pair(
MIN2(dist, result[s].first),
MAX2(speed, result[s].second));
1654 if (dist < maxDist && knownElevation.count(s) == 0) {
1666 if (tc.
knows(type)) {
1677 std::vector<std::string> types;
1679 std::string t = tok.
next();
1681 if (std::find(types.begin(), types.end(), t) == types.end()) {
1684 }
else if (tok.
size() > 1) {
1685 WRITE_WARNINGF(
"Discarding unknown compound '%' in type '%' (first occurence for edge '%').", t, type,
id);
1688 if (types.empty()) {
1689 WRITE_WARNINGF(
"Discarding unusable type '%' (first occurence for edge '%').", type,
id);
1694 if (tc.
knows(newType)) {
1702 double maxSpeed = 0;
1707 bool defaultIsOneWay =
true;
1709 bool discard =
true;
1710 for (
auto& type2 : types) {
1737 "Discarding compound type '" + newType +
"' (first occurence for edge '" +
id +
"').");
1742 WRITE_MESSAGE(
"Adding new type '" + type +
"' (first occurence for edge '" +
id +
"').");
1743 tc.
insert(newType, numLanes, maxSpeed, prio, permissions, width, defaultIsOneWay,
1744 sidewalkWidth, bikelaneWidth, 0, 0, 0);
1745 for (
auto& type3 : types) {
1760 std::vector<NIOSMNode*> nodes;
1761 std::vector<double> usablePositions;
1762 std::vector<int> usableIndex;
1767 if (node->
positionMeters != std::numeric_limits<double>::max()) {
1769 usableIndex.push_back(i);
1772 nodes.push_back(node);
1774 if (usablePositions.size() == 0) {
1777 bool forward =
true;
1778 if (usablePositions.size() == 1) {
1779 WRITE_WARNING(
"Ambiguous railway kilometrage direction for way '" +
id +
"' (assuming forward)");
1781 forward = usablePositions.front() < usablePositions.back();
1784 for (
int i = 1; i < (int)usablePositions.size(); i++) {
1785 if ((usablePositions[i - 1] < usablePositions[i]) != forward) {
1786 WRITE_WARNING(
"Inconsistent railway kilometrage direction for way '" +
id +
"': " +
toString(usablePositions) +
" (skipping)");
1790 if (nodes.size() > usablePositions.size()) {
1794 shape.push_back(
Position(node->lon, node->lat, 0));
1799 double sign = forward ? 1 : -1;
1801 for (
int i = usableIndex.front() - 1; i >= 0; i--) {
1802 nodes[i]->positionMeters = nodes[i + 1]->positionMeters - sign * shape[i].distanceTo2D(shape[i + 1]);
1805 for (
int i = usableIndex.front() + 1; i < (
int)nodes.size(); i++) {
1806 if (nodes[i]->positionMeters == std::numeric_limits<double>::max()) {
1807 nodes[i]->positionMeters = nodes[i - 1]->positionMeters + sign * shape[i].distanceTo2D(shape[i - 1]);
1835 return std::numeric_limits<double>::max();
1841 std::string stop = type;
1842 if (type ==
"train") {
1844 }
else if (type ==
"subway" || type ==
"light_rail") {
1847 }
else if (type ==
"bus") {
1849 }
else if (type ==
"tram") {