105 importer.
load(oc, nb);
117 delete myEdge.second;
121 delete myPlatformShape.second;
128 if (!oc.
isSet(
"osm-files")) {
136 for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
139 WRITE_ERROR(
"Could not open osm-file '" + *file +
"'.");
151 for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
160 if (!oc.
getBool(
"osm.skip-duplicates-check")) {
163 std::set<const Edge*, CompareEdges> dupsFinder;
165 if (dupsFinder.count(it->second) > 0) {
170 dupsFinder.insert(it->second);
181 std::map<long long int, int> nodeUsage;
183 for (std::map<long long int, Edge*>::const_iterator i =
myEdges.begin(); i !=
myEdges.end(); ++i) {
184 Edge* e = (*i).second;
186 for (std::vector<long long int>::const_iterator j = e->
myCurrentNodes.begin();
189 if (nodeUsage.find(*j) == nodeUsage.end()) {
192 nodeUsage[*j] = nodeUsage[*j] + 1;
196 for (std::map<long long int, NIOSMNode*>::const_iterator nodesIt =
myOSMNodes.begin();
199 if (nodesIt->second->tlsControlled || nodesIt->second->railwaySignal ) {
202 nodeUsage[nodesIt->first] += 1;
212 Edge* e = myEdge.second;
226 std::vector<long long int> passed;
228 passed.push_back(*j);
231 running =
insertEdge(e, running, currentFrom, currentTo, passed, nb);
232 currentFrom = currentTo;
234 passed.push_back(*j);
240 insertEdge(e, running, currentFrom, last, passed, nb);
243 const double layerElevation = oc.
getFloat(
"osm.layer-elevation");
244 if (layerElevation > 0) {
257 for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
269 if (node ==
nullptr) {
294 if (!tlsc.
insert(tlDef)) {
309 const std::vector<long long int>& passed,
NBNetBuilder& nb) {
318 if (from ==
nullptr || to ==
nullptr) {
319 WRITE_ERROR(
"Discarding edge '" +
id +
"' because the nodes could not be built.");
328 assert(passed.size() >= 2);
329 if (passed.size() == 2) {
330 WRITE_WARNING(
"Discarding edge '" +
id +
"' which connects two identical nodes without geometry.");
334 int intermediateIndex = (int) passed.size() / 2;
336 std::vector<long long int> part1(passed.begin(), passed.begin() + intermediateIndex + 1);
337 std::vector<long long int> part2(passed.begin() + intermediateIndex, passed.end());
338 index =
insertEdge(e, index, from, intermediate, part1, nb);
339 return insertEdge(e, index, intermediate, to, part2, nb);
341 const int newIndex = index + 1;
345 double distanceStart =
myOSMNodes[passed.front()]->positionMeters;
346 double distanceEnd =
myOSMNodes[passed.back()]->positionMeters;
347 const bool useDistance = distanceStart != std::numeric_limits<double>::max() && distanceEnd != std::numeric_limits<double>::max();
350 if (distanceStart < distanceEnd) {
359 for (
long long i : passed) {
363 if (existingPtStop !=
nullptr) {
377 shape.push_back(pos);
380 WRITE_ERROR(
"Unable to project coordinates for edge '" +
id +
"'.");
400 double forwardWidth = tc.
getWidth(type);
401 double backwardWidth = tc.
getWidth(type);
405 bool addForward =
true;
406 bool addBackward =
true;
423 if (addForward && !addBackward) {
425 }
else if (!addForward && addBackward) {
433 numLanesForward = (int) std::ceil(e->
myNoLanes / 2.0);
435 numLanesBackward = e->
myNoLanes - numLanesForward;
438 numLanesForward =
MAX2(1, numLanesForward);
439 numLanesBackward =
MAX2(1, numLanesBackward);
442 WRITE_WARNING(
"Skipping edge '" +
id +
"' because it has zero lanes.");
456 if (!addForward && (cyclewayType &
WAY_FORWARD) != 0) {
464 if (!addBackward && (cyclewayType &
WAY_BACKWARD) != 0) {
468 numLanesBackward = 1;
476 if (!addForward && (sidewalkType &
WAY_FORWARD) != 0) {
484 if (!addBackward && (sidewalkType &
WAY_BACKWARD) != 0) {
488 numLanesBackward = 1;
502 numLanesBackward = 1;
511 const std::string reverseID =
"-" + id;
514 assert(numLanesForward > 0);
539 assert(numLanesBackward > 0);
560 throw ProcessError(
"Could not add edge '-" +
id +
"'.");
595 std::set<NIOSMNode*, CompareNodes>& uniqueNodes,
602 myIsInValidNodeTag(false),
604 myUniqueNodes(uniqueNodes),
605 myImportElevation(oc.getBool(
"osm.elevation")),
616 if (myHierarchyLevel != 2) {
621 +
"', level='" +
toString(myHierarchyLevel) +
"').");
624 const long long int id = attrs.
get<
long long int>(
SUMO_ATTR_ID,
nullptr, ok);
626 if (action ==
"delete" || !ok) {
630 if (myToFill.find(
id) == myToFill.end()) {
654 auto* toAdd =
new NIOSMNode(
id, tlon, tlat);
655 myIsInValidNodeTag =
true;
662 toAdd = *similarNode;
665 myToFill[id] = toAdd;
669 if (myHierarchyLevel != 3) {
670 WRITE_ERROR(
"Tag element on wrong XML hierarchy level.");
676 if (key ==
"highway" || key ==
"ele" || key ==
"crossing" || key ==
"railway" || key ==
"public_transport"
677 || key ==
"name" || key ==
"train" || key ==
"bus" || key ==
"tram" || key ==
"light_rail" || key ==
"subway" || key ==
"station" || key ==
"noexit"
682 if (key ==
"highway" && value.find(
"traffic_signal") != std::string::npos) {
683 myToFill[myLastNodeID]->tlsControlled =
true;
684 }
else if (key ==
"crossing" && value.find(
"traffic_signals") != std::string::npos) {
685 myToFill[myLastNodeID]->tlsControlled =
true;
686 }
else if ((key ==
"noexit" && value ==
"yes")
687 || (key ==
"railway" && value ==
"buffer_stop")) {
688 myToFill[myLastNodeID]->railwayBufferStop =
true;
689 }
else if (key ==
"railway" && value.find(
"crossing") != std::string::npos) {
690 myToFill[myLastNodeID]->railwayCrossing =
true;
692 value ==
"block" || value ==
"entry" || value ==
"exit" || value ==
"intermediate")) {
693 myToFill[myLastNodeID]->railwaySignal =
true;
694 }
else if (
StringUtils::startsWith(key,
"railway:position") && value.size() > myToFill[myLastNodeID]->position.size()) {
696 myToFill[myLastNodeID]->position = value;
697 }
else if ((key ==
"public_transport" && value ==
"stop_position") ||
698 (key ==
"highway" && value ==
"bus_stop")) {
699 myToFill[myLastNodeID]->ptStopPosition =
true;
700 if (myToFill[myLastNodeID]->ptStopLength == 0) {
702 myToFill[myLastNodeID]->ptStopLength = myOptionsCont.getFloat(
"osm.stop-output.length");
704 }
else if (key ==
"name") {
705 myToFill[myLastNodeID]->name = value;
706 }
else if (key ==
"train") {
707 myToFill[myLastNodeID]->permissions =
SVC_RAIL;
708 myToFill[myLastNodeID]->ptStopLength = myOptionsCont.getFloat(
"osm.stop-output.length.train");
709 }
else if (key ==
"subway" || key ==
"light_rail"
710 || (key ==
"station" && (value ==
"subway" || value ==
"light_rail"))) {
712 myToFill[myLastNodeID]->ptStopLength = myOptionsCont.getFloat(
"osm.stop-output.length.train");
713 }
else if (key ==
"bus") {
714 myToFill[myLastNodeID]->permissions =
SVC_BUS;
715 myToFill[myLastNodeID]->ptStopLength = myOptionsCont.getFloat(
"osm.stop-output.length.bus");
716 }
else if (key ==
"tram") {
717 myToFill[myLastNodeID]->permissions =
SVC_TRAM;
718 myToFill[myLastNodeID]->ptStopLength = myOptionsCont.getFloat(
"osm.stop-output.length.tram");
719 }
else if (myImportElevation && key ==
"ele") {
723 WRITE_WARNING(
"Value of key '" + key +
"' is not numeric ('" + value +
"') in node '" +
735 myIsInValidNodeTag =
false;
744 const std::map<long long int, NIOSMNode*>& osmNodes,
745 std::map<long long int, Edge*>& toFill, std::map<long long int, Edge*>& platformShapes):
749 myPlatformShapesMap(platformShapes) {
766 myParentElements.push_back(element);
770 const long long int id = attrs.
get<
long long int>(
SUMO_ATTR_ID,
nullptr, ok);
772 if (action ==
"delete" || !ok) {
773 myCurrentEdge =
nullptr;
776 myCurrentEdge =
new Edge(
id);
779 if (element ==
SUMO_TAG_ND && myCurrentEdge !=
nullptr) {
789 ref = node->second->id;
790 if (myCurrentEdge->myCurrentNodes.empty() ||
791 myCurrentEdge->myCurrentNodes.back() != ref) {
792 myCurrentEdge->myCurrentNodes.push_back(ref);
798 if (element ==
SUMO_TAG_TAG && myParentElements.size() > 2
799 && myParentElements[myParentElements.size() - 2] ==
SUMO_TAG_WAY) {
800 if (myCurrentEdge ==
nullptr) {
807 const std::string cyclewaySpec = key.substr(9);
809 if (cyclewaySpec ==
"right") {
810 myCurrentEdge->myCyclewayType = (
WayType)(myCurrentEdge->myCyclewayType |
WAY_FORWARD);
811 }
else if (cyclewaySpec ==
"left") {
813 }
else if (cyclewaySpec ==
"both") {
814 myCurrentEdge->myCyclewayType = (
WayType)(myCurrentEdge->myCyclewayType |
WAY_BOTH);
818 if ((myCurrentEdge->myCyclewayType &
WAY_BOTH) != 0) {
820 myCurrentEdge->myCyclewayType = (
WayType)(myCurrentEdge->myCyclewayType & ~
WAY_UNKNOWN);
824 const std::string buswaySpec = key.substr(7);
826 if (buswaySpec ==
"right") {
828 }
else if (buswaySpec ==
"left") {
830 }
else if (buswaySpec ==
"both") {
831 myCurrentEdge->myBuswayType = (
WayType)(myCurrentEdge->myBuswayType |
WAY_BOTH);
836 if (myAllAttributes && (key ==
"bridge" || key ==
"tunnel")) {
837 myCurrentEdge->setParameter(key,
"true");
841 && key !=
"maxspeed" && key !=
"junction" && key !=
"name" && key !=
"tracks" && key !=
"layer"
845 && key !=
"highspeed"
847 && key !=
"postal_code"
848 && key !=
"railway:preferred_direction"
849 && key !=
"railway:bidirectional"
850 && key !=
"railway:track_ref"
852 && key !=
"electrified"
853 && key !=
"public_transport") {
858 if ((key ==
"highway" && value !=
"platform") || key ==
"railway" || key ==
"waterway" || key ==
"cycleway"
859 || key ==
"busway" || key ==
"route" || key ==
"sidewalk" || key ==
"highspeed"
862 std::string singleTypeID = key +
"." + value;
863 myCurrentEdge->myCurrentIsRoad =
true;
865 if (key ==
"cycleway") {
869 if (value ==
"opposite_track") {
871 }
else if (value ==
"opposite_lane") {
876 if (key ==
"sidewalk") {
877 if (value ==
"no" || value ==
"none") {
878 myCurrentEdge->mySidewalkType =
WAY_NONE;
879 }
else if (value ==
"both") {
880 myCurrentEdge->mySidewalkType =
WAY_BOTH;
881 }
else if (value ==
"right") {
883 }
else if (value ==
"left") {
890 if (key ==
"busway") {
894 if (value ==
"opposite_track") {
896 }
else if (value ==
"opposite_lane") {
902 if (key ==
"highspeed") {
906 singleTypeID =
"railway.highspeed";
909 if (!myCurrentEdge->myHighWayType.empty() && singleTypeID !=
"railway.highspeed") {
910 if (myCurrentEdge->myHighWayType ==
"railway.highspeed") {
915 std::vector<std::string> types =
StringTokenizer(myCurrentEdge->myHighWayType,
917 types.push_back(singleTypeID);
920 myCurrentEdge->myHighWayType = singleTypeID;
922 }
else if (key ==
"lanes") {
928 std::vector<std::string> list = st.
getVector();
929 if (list.size() >= 2) {
930 int minLanes = std::numeric_limits<int>::max();
932 for (
auto& i : list) {
934 minLanes =
MIN2(minLanes, numLanes);
936 myCurrentEdge->myNoLanes = minLanes;
938 "Using minimum lane number from list (" + value +
") for edge '"
942 WRITE_WARNING(
"Value of key '" + key +
"' is not numeric ('" + value +
"') in edge '" +
943 toString(myCurrentEdge->id) +
"'.");
947 WRITE_WARNING(
"Value of key '" + key +
"' is not numeric ('" + value +
"') in edge '" +
948 toString(myCurrentEdge->id) +
"'.");
950 }
else if (key ==
"lanes:forward") {
954 WRITE_WARNING(
"Value of key '" + key +
"' is not numeric ('" + value +
"') in edge '" +
955 toString(myCurrentEdge->id) +
"'.");
957 }
else if (key ==
"lanes:backward") {
962 WRITE_WARNING(
"Value of key '" + key +
"' is not numeric ('" + value +
"') in edge '" +
963 toString(myCurrentEdge->id) +
"'.");
965 }
else if (key ==
"maxspeed") {
966 if (mySpeedMap.find(value) != mySpeedMap.end()) {
967 myCurrentEdge->myMaxSpeed = mySpeedMap[value];
969 double conversion = 1;
974 conversion = 1.609344;
979 WRITE_WARNING(
"Value of key '" + key +
"' is not numeric ('" + value +
"') in edge '" +
980 toString(myCurrentEdge->id) +
"'.");
983 }
else if (key ==
"junction") {
984 if ((value ==
"roundabout") && (myCurrentEdge->myIsOneWay.empty())) {
985 myCurrentEdge->myIsOneWay =
"yes";
987 }
else if (key ==
"oneway") {
988 myCurrentEdge->myIsOneWay = value;
989 }
else if (key ==
"name") {
990 myCurrentEdge->streetName = value;
991 }
else if (key ==
"ref") {
992 myCurrentEdge->ref = value;
993 }
else if (key ==
"layer") {
994 if (myAllAttributes) {
995 myCurrentEdge->setParameter(key, value);
1000 WRITE_WARNING(
"Value of key '" + key +
"' is not numeric ('" + value +
"') in edge '" +
1001 toString(myCurrentEdge->id) +
"'.");
1003 }
else if (key ==
"tracks") {
1006 myCurrentEdge->myIsOneWay =
"false";
1008 myCurrentEdge->myIsOneWay =
"true";
1011 WRITE_WARNING(
"Value of key '" + key +
"' is not numeric ('" + value +
"') in edge '" +
1012 toString(myCurrentEdge->id) +
"'.");
1014 }
else if (myAllAttributes && key ==
"postal_code") {
1015 myCurrentEdge->setParameter(key, value);
1016 }
else if (key ==
"railway:preferred_direction") {
1017 if (value ==
"both") {
1018 myCurrentEdge->myRailDirection =
WAY_BOTH;
1019 }
else if (value ==
"backward") {
1022 }
else if (key ==
"railway:bidirectional") {
1023 if (value ==
"regular") {
1024 myCurrentEdge->myRailDirection =
WAY_BOTH;
1026 }
else if (key ==
"electrified") {
1027 if (value !=
"no") {
1028 myCurrentEdge->myCurrentIsElectrified =
true;
1030 }
else if (key ==
"railway:track_ref") {
1031 myCurrentEdge->setParameter(key, value);
1032 }
else if (key ==
"public_transport" && value ==
"platform") {
1033 myCurrentEdge->myCurrentIsPlatform =
true;
1046 myParentElements.pop_back();
1047 if (element ==
SUMO_TAG_WAY && myCurrentEdge !=
nullptr) {
1048 if (myCurrentEdge->myCurrentIsRoad) {
1049 myEdgeMap[myCurrentEdge->id] = myCurrentEdge;
1050 }
else if (myCurrentEdge->myCurrentIsPlatform) {
1051 myPlatformShapesMap[myCurrentEdge->id] = myCurrentEdge;
1053 delete myCurrentEdge;
1055 myCurrentEdge =
nullptr;
1063 const std::map<long long int, NIOSMNode*>& osmNodes,
1064 const std::map<long long int, Edge*>& osmEdges,
NBPTStopCont* nbptStopCont,
1065 const std::map<long long int, Edge*>& platformShapes,
1071 myOSMEdges(osmEdges),
1073 myNBPTStopCont(nbptStopCont),
1074 myNBPTLineCont(nbptLineCont),
1084 myIsRestriction =
false;
1089 myRestrictionType = RESTRICTION_UNKNOWN;
1090 myPlatforms.clear();
1093 myIsStopArea =
false;
1101 myParentElements.push_back(element);
1105 myCurrentRelation = attrs.
get<
long long int>(
SUMO_ATTR_ID,
nullptr, ok);
1107 if (action ==
"delete" || !ok) {
1113 myNightService =
"";
1123 auto ref = attrs.
get<
long
1126 if (role ==
"via") {
1129 if (memberType ==
"way" && checkEdgeRef(ref)) {
1131 }
else if (memberType ==
"node") {
1136 "No node found for reference '" +
toString(ref) +
"' in relation '"
1141 }
else if (role ==
"from" && checkEdgeRef(ref)) {
1143 }
else if (role ==
"to" && checkEdgeRef(ref)) {
1145 }
else if (role ==
"stop") {
1146 myStops.push_back(ref);
1147 }
else if (role ==
"platform") {
1149 if (memberType ==
"way") {
1150 const std::map<
long long int,
1155 platform.
isWay =
true;
1157 myPlatforms.push_back(platform);
1159 }
else if (memberType ==
"node") {
1161 platform.
isWay =
false;
1163 myPlatforms.push_back(platform);
1166 }
else if (role.empty()) {
1168 if (memberType ==
"way") {
1169 myWays.push_back(ref);
1179 if (key ==
"type" || key ==
"restriction") {
1181 if (key ==
"type" && value ==
"restriction") {
1182 myIsRestriction =
true;
1185 if (key ==
"type" && value ==
"route") {
1189 if (key ==
"restriction") {
1192 if (value.substr(0, 5) ==
"only_") {
1193 myRestrictionType = RESTRICTION_ONLY;
1194 }
else if (value.substr(0, 3) ==
"no_") {
1195 myRestrictionType = RESTRICTION_NO;
1198 "Found unknown restriction type '" + value +
"' in relation '" +
toString(myCurrentRelation)
1203 }
else if (key ==
"public_transport") {
1205 if (value ==
"stop_area") {
1206 myIsStopArea =
true;
1208 }
else if (key ==
"route") {
1210 if (value ==
"train" || value ==
"subway" || value ==
"light_rail" || value ==
"monorail" || value ==
"tram" || value ==
"bus"
1211 || value ==
"trolleybus" || value ==
"arialway" || value ==
"ferry") {
1212 myPTRouteType = value;
1215 }
else if (key ==
"name") {
1217 }
else if (key ==
"ref") {
1219 }
else if (key ==
"interval" || key ==
"headway") {
1221 }
else if (key ==
"by_night") {
1229 if (myOSMEdges.find(ref) != myOSMEdges.end()) {
1234 "No way found for reference '" +
toString(ref) +
"' in relation '" +
toString(myCurrentRelation) +
"'");
1241 myParentElements.pop_back();
1243 if (myIsRestriction) {
1246 if (myRestrictionType == RESTRICTION_UNKNOWN) {
1247 WRITE_WARNING(
"Ignoring restriction relation '" +
toString(myCurrentRelation) +
"' with unknown type.");
1252 "Ignoring restriction relation '" +
toString(myCurrentRelation) +
"' with unknown from-way.");
1257 "Ignoring restriction relation '" +
toString(myCurrentRelation) +
"' with unknown to-way.");
1261 WRITE_WARNING(
"Ignoring restriction relation '" +
toString(myCurrentRelation) +
"' with unknown via.");
1264 if (ok && !applyRestriction()) {
1268 for (
long long ref : myStops) {
1278 if (ptStop ==
nullptr) {
1285 if (myPlatform.isWay) {
1288 if (edge->myCurrentNodes[0] == *(edge->myCurrentNodes.end() - 1)) {
1290 +
"' is given as polygon, which currently is not supported.");
1295 for (
auto nodeRef : edge->myCurrentNodes) {
1308 p.push_back(pNodePos);
1310 if (p.size() == 0) {
1312 "Referenced platform: '" +
toString(myPlatform.ref) +
"' in relation: '" +
toString(myCurrentRelation)
1313 +
"' is corrupt. Probably OSM file is incomplete.");
1330 NBPTPlatform platform(platformPos, myOptionsCont.getFloat(
1331 "osm.stop-output.length"));
1339 NBPTLine* ptLine =
new NBPTLine(
toString(myCurrentRelation), myName, myPTRouteType, myRef, myInterval, myNightService);
1341 for (
long long ref : myStops) {
1349 WRITE_WARNING(
"Done reading first coherent chunk of pt stops. Further stops in relation " +
toString(myCurrentRelation) +
" are ignored");
1357 if (ptStop ==
nullptr) {
1364 WRITE_WARNING(
"Done reading first coherent chunk of pt stops. Further stops in relation " +
toString(myCurrentRelation) +
" are ignored");
1371 for (
long long& myWay : myWays) {
1372 auto entr = myOSMEdges.find(myWay);
1373 if (entr != myOSMEdges.end()) {
1374 Edge* edge = entr->second;
1381 WRITE_WARNING(
"PT line in relation " +
toString(myCurrentRelation) +
" with no stops ignored. Probably OSM file is incomplete.");
1385 if (myNBPTLineCont->getLines().count(ptLine->
getLineID()) == 0) {
1386 myNBPTLineCont->insert(ptLine);
1402 if (viaNode ==
nullptr) {
1408 if (from ==
nullptr) {
1409 WRITE_WARNING(
"from-edge of restriction relation could not be determined");
1412 if (to ==
nullptr) {
1413 WRITE_WARNING(
"to-edge of restriction relation could not be determined");
1416 if (myRestrictionType == RESTRICTION_ONLY) {
1423 WRITE_WARNING(
"direction of restriction relation could not be determined");
1431 const std::vector<NBEdge*>& candidates)
const {
1432 const std::string prefix =
toString(wayRef);
1433 const std::string backPrefix =
"-" + prefix;
1434 NBEdge* result =
nullptr;
1436 for (
auto candidate : candidates) {
1437 if ((candidate->getID().substr(0, prefix.size()) == prefix) ||
1438 (candidate->getID().substr(0, backPrefix.size()) == backPrefix)) {
1444 WRITE_WARNING(
"Ambigous way reference '" + prefix +
"' in restriction relation");
1457 std::map<NBNode*, std::vector<std::pair<double, double> > > layerForces;
1460 std::set<NBNode*> knownElevation;
1461 for (
auto& myEdge :
myEdges) {
1462 Edge* e = myEdge.second;
1466 if (node !=
nullptr) {
1467 knownElevation.insert(node);
1473 #ifdef DEBUG_LAYER_ELEVATION
1474 std::cout <<
"known elevations:\n";
1475 for (std::set<NBNode*>::iterator it = knownElevation.begin(); it != knownElevation.end(); ++it) {
1476 const std::vector<std::pair<double, double> >& primaryLayers = layerForces[*it];
1477 std::cout <<
" node=" << (*it)->
getID() <<
" ele=";
1478 for (std::vector<std::pair<double, double> >::const_iterator it_ele = primaryLayers.begin(); it_ele != primaryLayers.end(); ++it_ele) {
1479 std::cout << it_ele->first <<
" ";
1487 std::map<NBNode*, double> knownEleMax;
1488 for (
auto it : knownElevation) {
1489 double eleMax = -std::numeric_limits<double>::max();
1490 const std::vector<std::pair<double, double> >& primaryLayers = layerForces[it];
1491 for (
const auto& primaryLayer : primaryLayers) {
1492 eleMax =
MAX2(eleMax, primaryLayer.first);
1494 knownEleMax[it] = eleMax;
1497 bool changed =
true;
1500 for (
auto it = knownElevation.begin(); it != knownElevation.end(); ++it) {
1503 / gradeThreshold * 3,
1505 for (
auto& neighbor : neighbors) {
1506 if (knownElevation.count(neighbor.first) != 0) {
1507 const double grade = fabs(knownEleMax[*it] - knownEleMax[neighbor.first])
1509 #ifdef DEBUG_LAYER_ELEVATION
1510 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";
1512 if (grade > gradeThreshold * 50 / 3.6 / neighbor.second.second) {
1514 const double eleMax =
MAX2(knownEleMax[*it], knownEleMax[neighbor.first]);
1515 if (knownEleMax[*it] < eleMax) {
1516 knownEleMax[*it] = eleMax;
1518 knownEleMax[neighbor.first] = eleMax;
1528 std::set<NBNode*> unknownElevation;
1529 for (
auto it = knownElevation.begin(); it != knownElevation.end(); ++it) {
1530 const double eleMax = knownEleMax[*it];
1531 const double maxDist = fabs(eleMax) * 100 / layerElevation;
1532 std::map<NBNode*, std::pair<double, double> > neighbors =
getNeighboringNodes(*it, maxDist, knownElevation);
1533 for (
auto& neighbor : neighbors) {
1534 if (knownElevation.count(neighbor.first) == 0) {
1535 unknownElevation.insert(neighbor.first);
1536 layerForces[neighbor.first].emplace_back(eleMax, neighbor.second.first);
1542 for (
auto it = unknownElevation.begin(); it != unknownElevation.end(); ++it) {
1543 double eleMax = -std::numeric_limits<double>::max();
1544 const std::vector<std::pair<double, double> >& primaryLayers = layerForces[*it];
1545 for (
const auto& primaryLayer : primaryLayers) {
1546 eleMax =
MAX2(eleMax, primaryLayer.first);
1548 const double maxDist = fabs(eleMax) * 100 / layerElevation;
1549 std::map<NBNode*, std::pair<double, double> > neighbors =
getNeighboringNodes(*it, maxDist, knownElevation);
1550 for (
auto& neighbor : neighbors) {
1551 if (knownElevation.count(neighbor.first) == 0 && unknownElevation.count(neighbor.first) == 0) {
1552 layerForces[*it].emplace_back(0, neighbor.second.first);
1557 #ifdef DEBUG_LAYER_ELEVATION
1558 std::cout <<
"summation of forces\n";
1560 std::map<NBNode*, double> nodeElevation;
1561 for (
auto& layerForce : layerForces) {
1562 const std::vector<std::pair<double, double> >& forces = layerForce.second;
1563 if (knownElevation.count(layerForce.first) != 0) {
1571 #ifdef DEBUG_LAYER_ELEVATION
1572 std::cout <<
" node=" << it->first->getID() <<
" knownElevation=" << knownEleMax[it->first] <<
"\n";
1574 nodeElevation[layerForce.first] = knownEleMax[layerForce.first];
1575 }
else if (forces.size() == 1) {
1576 nodeElevation[layerForce.first] = forces.front().first;
1580 for (
const auto& force : forces) {
1581 distSum += force.second;
1583 double weightSum = 0;
1584 double elevation = 0;
1585 #ifdef DEBUG_LAYER_ELEVATION
1586 std::cout <<
" node=" << it->first->getID() <<
" distSum=" << distSum <<
"\n";
1588 for (
const auto& force : forces) {
1589 const double weight = (distSum - force.second) / distSum;
1590 weightSum += weight;
1591 elevation += force.first * weight;
1593 #ifdef DEBUG_LAYER_ELEVATION
1594 std::cout <<
" force=" << it_force->first <<
" dist=" << it_force->second <<
" weight=" << weight <<
" ele=" << elevation <<
"\n";
1597 nodeElevation[layerForce.first] = elevation / weightSum;
1600 #ifdef DEBUG_LAYER_ELEVATION
1601 std::cout <<
"final elevations:\n";
1602 for (std::map<NBNode*, double>::iterator it = nodeElevation.begin(); it != nodeElevation.end(); ++it) {
1603 std::cout <<
" node=" << (it->first)->getID() <<
" ele=" << it->second <<
"\n";;
1607 for (
auto& it : nodeElevation) {
1614 for (
const auto& it : ec) {
1615 NBEdge* edge = it.second;
1617 const double length = geom.
length2D();
1618 const double zFrom = nodeElevation[edge->
getFromNode()];
1619 const double zTo = nodeElevation[edge->
getToNode()];
1624 for (
auto it_pos = geom.begin(); it_pos != geom.end(); ++it_pos) {
1625 if (it_pos != geom.begin()) {
1626 dist += (*it_pos).distanceTo2D(*(it_pos - 1));
1628 newGeom.push_back((*it_pos) +
Position(0, 0, zFrom + (zTo - zFrom) * dist / length));
1634 std::map<NBNode*, std::pair<double, double> >
1636 std::map<NBNode*, std::pair<double, double> > result;
1637 std::set<NBNode*> visited;
1638 std::vector<NBNode*> open;
1639 open.push_back(node);
1640 result[node] = std::make_pair(0, 0);
1641 while (!open.empty()) {
1644 if (visited.count(n) != 0) {
1649 for (
auto e : edges) {
1652 s = e->getFromNode();
1656 const double dist = result[n].first + e->getGeometry().length2D();
1657 const double speed =
MAX2(e->getSpeed(), result[n].second);
1658 if (result.count(s) == 0) {
1659 result[s] = std::make_pair(dist, speed);
1661 result[s] = std::make_pair(
MIN2(dist, result[s].first),
MAX2(speed, result[s].second));
1663 if (dist < maxDist && knownElevation.count(s) == 0) {
1675 if (tc.
knows(type)) {
1686 std::vector<std::string> types;
1688 std::string t = tok.
next();
1690 if (std::find(types.begin(), types.end(), t) == types.end()) {
1693 }
else if (tok.
size() > 1) {
1695 "Discarding unknown compound '" + t +
"' in type '" + type +
"' (first occurence for edge '"
1700 if (types.empty()) {
1701 WRITE_WARNING(
"Discarding unusable type '" + type +
"' (first occurence for edge '" +
id +
"').");
1706 if (tc.
knows(newType)) {
1714 double maxSpeed = 0;
1719 bool defaultIsOneWay =
false;
1721 bool discard =
true;
1722 for (
auto& type2 : types) {
1749 "Discarding compound type '" + newType +
"' (first occurence for edge '" +
id +
"').");
1754 WRITE_MESSAGE(
"Adding new type '" + type +
"' (first occurence for edge '" +
id +
"').");
1755 tc.
insert(newType, numLanes, maxSpeed, prio, permissions, width, defaultIsOneWay,
1756 sidewalkWidth, bikelaneWidth, 0, 0, 0);
1757 for (
auto& type3 : types) {
1772 std::vector<NIOSMNode*> nodes;
1773 std::vector<double> usablePositions;
1774 std::vector<int> usableIndex;
1779 if (node->
positionMeters != std::numeric_limits<double>::max()) {
1781 usableIndex.push_back(i);
1784 nodes.push_back(node);
1786 if (usablePositions.size() == 0) {
1789 bool forward =
true;
1790 if (usablePositions.size() == 1) {
1791 WRITE_WARNING(
"Ambiguous railway kilometrage direction for way '" +
id +
"' (assuming forward)");
1793 forward = usablePositions.front() < usablePositions.back();
1796 for (
int i = 1; i < (int)usablePositions.size(); i++) {
1797 if ((usablePositions[i - 1] < usablePositions[i]) != forward) {
1798 WRITE_WARNING(
"Inconsistent railway kilometrage direction for way '" +
id +
"': " +
toString(usablePositions) +
" (skipping)");
1802 if (nodes.size() > usablePositions.size()) {
1806 shape.push_back(
Position(node->lon, node->lat, 0));
1811 double sign = forward ? 1 : -1;
1813 for (
int i = usableIndex.front() - 1; i >= 0; i--) {
1814 nodes[i]->positionMeters = nodes[i + 1]->positionMeters - sign * shape[i].distanceTo2D(shape[i + 1]);
1817 for (
int i = usableIndex.front() + 1; i < (int)nodes.size(); i++) {
1818 if (nodes[i]->positionMeters == std::numeric_limits<double>::max()) {
1819 nodes[i]->positionMeters = nodes[i - 1]->positionMeters + sign * shape[i].distanceTo2D(shape[i - 1]);
1847 return std::numeric_limits<double>::max();