diff --git a/DataStructures/ExtractorCallBacks.h b/DataStructures/ExtractorCallBacks.h index 3ca24974d..127673cea 100644 --- a/DataStructures/ExtractorCallBacks.h +++ b/DataStructures/ExtractorCallBacks.h @@ -93,78 +93,84 @@ public: /** warning: caller needs to take care of synchronization! */ inline bool wayFunction(_Way &w) { - - std::string accessClass( w.keyVals.Find(settings.accessTag) ); - std::string access( w.keyVals.Find("access") ); - std::string highway( w.keyVals.Find("highway") ); - - //class tag like bicycle=yes/no overrides everything else - if("yes" == accessClass || "permissive" == accessClass || "designated" == accessClass || "official" == accessClass) - w.access = true; - else if("no" == accessClass) - w.access = false; - else { - std::string route( w.keyVals.Find("route") ); - std::string man_made( w.keyVals.Find("man_made") ); - //speedprofile allows routing on this type of way/route/man_made? - if(settings[highway] > 0 || settings[route] > 0 || settings[man_made] > 0) { - if(0 < access.size()) { //fastest way to check for non-empty string - if( access == "yes" || access == "permissive" || access == "designated" || access == "public" ) - w.access = true; - else - w.access = false; - } - } - else - w.access = false; - } - - if ( w.access == true && (1 < w.path.size()) ) { - std::string name( w.keyVals.Find("name") ); - std::string ref( w.keyVals.Find("ref")); - std::string oneway( w.keyVals.Find("oneway")); - std::string onewayClass( w.keyVals.Find("oneway:"+accessClass)); - std::string junction( w.keyVals.Find("junction") ); - double maxspeed( atoi(w.keyVals.Find("maxspeed").c_str()) ); - std::string barrier( w.keyVals.Find("barrier") ); - - //name - if ( 0 < ref.length() ) - w.name = ref; - else if ( 0 < name.length() ) - w.name = name; - - //roundabout - if(junction == "roundabout") - w.roundabout = true; - - //speed - if(0 < maxspeed && (maxspeed < settings[highway]) ) - w.speed = maxspeed; - else - w.speed = settings[highway]; - - //TODO: type is not set, perhaps use a bimap'ed speed profile to do set the type correctly? - w.type = 1; - //oneway - if( settings.obeyOneways ) { - //TODO: handle cycleway=opposite_* - if( oneway == "no" || oneway == "0" || oneway == "false" || - onewayClass == "no" || onewayClass == "0" || onewayClass == "false") - w.direction = _Way::bidirectional; - else if( oneway == "yes" || oneway == "1" || oneway == "true" || - onewayClass == "yes" || onewayClass == "1" || onewayClass == "true" || - junction == "roundabout" || highway == "motorway_link" || highway == "motorway" ) - w.direction = _Way::oneway; - else if( oneway == "-1") { - w.direction = _Way::opposite; - std::reverse( w.path.begin(), w.path.end() ); - } - else - w.direction = _Way::bidirectional; - } - + //Get the properties of the way. + std::string highway( w.keyVals.Find("highway") ); + std::string name( w.keyVals.Find("name") ); + std::string ref( w.keyVals.Find("ref")); + std::string oneway( w.keyVals.Find("oneway")); + std::string junction( w.keyVals.Find("junction") ); + std::string route( w.keyVals.Find("route") ); + int maxspeed( atoi(w.keyVals.Find("maxspeed").c_str()) ); + std::string access( w.keyVals.Find("access") ); + std::string accessTag( w.keyVals.Find(settings.accessTag) ); + std::string man_made( w.keyVals.Find("man_made") ); + std::string barrier( w.keyVals.Find("barrier") ); + + //Save the name of the way if it has one, ref has precedence over name tag. + if ( 0 < ref.length() ) + w.name = ref; + else + if ( 0 < name.length() ) + w.name = name; + + if(junction == "roundabout") { + w.roundabout = true; + } + + //Is the highway tag listed as usable way? + if(0 < settings[highway] || "yes" == accessTag || "designated" == accessTag) { + + if(0 < settings[highway]) { + if(0 < maxspeed) + w.speed = std::min(maxspeed, settings[highway]); + else + w.speed = settings[highway]; + } else { + w.speed = settings.defaultSpeed; + highway = "default"; + } + w.useful = true; + + //Okay, do we have access to that way? + if(0 < access.size()) { //fastest way to check for non-empty string + //If access is forbidden, we don't want to route there. + if(access == "private" || access == "no" || access == "agricultural" || access == "forestry" || access == "delivery") { //Todo: this is still hard coded + w.access = false; + } + } + + if("no" == accessTag) { + return true; + } + + //Let's process oneway property, if speed profile obeys to it + if(oneway != "no" && oneway != "false" && oneway != "0" && settings.obeyOneways) { + //if oneway tag is in forward direction or if actually roundabout + if(junction == "roundabout" || oneway == "yes" || oneway == "true" || oneway == "1") { + w.direction = _Way::oneway; + } else { + if( oneway == "-1") + w.direction = _Way::opposite; + } + } + } else { + //Is the route tag listed as usable way in the profile? + if(settings[route] > 0 || settings[man_made] > 0) { + w.useful = true; + w.speed = settings[route]; + w.direction = _Way::bidirectional; + if(0 < settings[route]) + highway = route; + else if (0 < settings[man_made]) { + highway = man_made; + } + } + } + if ( w.useful && w.access && (1 < w.path.size()) ) { //Only true if the way is specified by the speed profile + //TODO: type is not set, perhaps use a bimap'ed speed profile to do set the type correctly? + w.type = settings.GetHighwayTypeID(highway); + //Get the unique identifier for the street name const StringMap::const_iterator strit = stringMap->find(w.name); if(strit == stringMap->end()) { @@ -175,7 +181,7 @@ public: w.nameID = strit->second; } - if(-1 == w.speed) { + if(-1 == w.speed){ WARN("found way with bogus speed, id: " << w.id); return true; } @@ -184,6 +190,10 @@ public: return true; } + if ( w.direction == _Way::opposite ){ + std::reverse( w.path.begin(), w.path.end() ); + } + for(vector< NodeID >::size_type n = 0; n < w.path.size()-1; ++n) { externalMemory->allEdges.push_back(_Edge(w.path[n], w.path[n+1], w.type, w.direction, w.speed, w.nameID, w.roundabout)); externalMemory->usedNodeIDs.push_back(w.path[n]); @@ -193,9 +203,8 @@ public: //The following information is needed to identify start and end segments of restrictions externalMemory->wayStartEndVector.push_back(_WayIDStartAndEndEdge(w.id, w.path[0], w.path[1], w.path[w.path.size()-2], w.path[w.path.size()-1])); } - return true; } }; -#endif /* EXTRACTORCALLBACKS_H_ */ +#endif /* EXTRACTORCALLBACKS_H_ */ \ No newline at end of file diff --git a/DataStructures/ExtractorStructs.h b/DataStructures/ExtractorStructs.h index 864b05761..5abfd67cd 100644 --- a/DataStructures/ExtractorStructs.h +++ b/DataStructures/ExtractorStructs.h @@ -35,7 +35,8 @@ struct _PathData { short turnInstruction; }; -typedef boost::unordered_map StringMap; +typedef boost::unordered_map StringMap; +typedef boost::unordered_map > StringToIntPairMap; struct _Node : NodeInfo{ _Node(int _lat, int _lon, unsigned int _id) : NodeInfo(_lat, _lon, _id) {} @@ -254,19 +255,28 @@ struct CmpWayByID : public std::binary_function<_WayIDStartAndEndEdge, _WayIDSta }; struct Settings { - Settings() : obeyPollards(true), obeyOneways(true), useRestrictions(true), accessTag("motorcar") {} - StringMap speedProfile; - int operator[](const string & param) const { + Settings() : obeyPollards(true), obeyOneways(true), useRestrictions(true), accessTag("motorcar"), defaultSpeed(30), excludeFromGrid("ferry") {} + StringToIntPairMap speedProfile; + int operator[](const std::string & param) const { if(speedProfile.find(param) == speedProfile.end()) return 0; else - return speedProfile.at(param); + return speedProfile.at(param).first; + } + int GetHighwayTypeID(const std::string & param) const { + if(speedProfile.find(param) == speedProfile.end()) { + DEBUG("There is a bug with highway \"" << param << "\""); + return -1; + } else { + return speedProfile.at(param).second; + } } bool obeyPollards; bool obeyOneways; bool useRestrictions; - string accessTag; - + std::string accessTag; + int defaultSpeed; + std::string excludeFromGrid; }; struct Cmp : public std::binary_function { diff --git a/DataStructures/NNGrid.h b/DataStructures/NNGrid.h index 93cdfb4b2..a446e20b7 100644 --- a/DataStructures/NNGrid.h +++ b/DataStructures/NNGrid.h @@ -304,18 +304,22 @@ public: _GridEdge smallestEdge; _Coordinate tmp, newEndpoint; - double dist = (numeric_limits::max)(); + double dist = numeric_limits::max(); BOOST_FOREACH(_GridEdge candidate, candidates) { double r = 0.; double tmpDist = ComputeDistance(startCoord, candidate.startCoord, candidate.targetCoord, tmp, &r); if(DoubleEpsilonCompare(dist, tmpDist) && 1 == std::abs((int)candidate.edgeBasedNode-(int)resultNode.edgeBasedNode)) { resultNode.weight2 = candidate.weight; +// INFO("b) " << candidate.edgeBasedNode << ", dist: " << tmpDist); if(candidate.edgeBasedNode < resultNode.edgeBasedNode) { resultNode.edgeBasedNode = candidate.edgeBasedNode; std::swap(resultNode.weight1, resultNode.weight2); } +// } else if(std::fabs(dist - tmpDist) < 1) { +// INFO("b) ignored " << candidate.edgeBasedNode << " at distance " << tmpDist); } if(tmpDist < dist && !DoubleEpsilonCompare(dist, tmpDist)) { +// INFO("a) " << candidate.edgeBasedNode << ", dist: " << tmpDist); resultNode.Reset(); resultNode.edgeBasedNode = candidate.edgeBasedNode; resultNode.nodeBasedEdgeNameID = candidate.nameID; @@ -326,6 +330,8 @@ public: foundNode = true; smallestEdge = candidate; newEndpoint = tmp; +// } else if(tmpDist < dist) { +// INFO("a) ignored " << candidate.edgeBasedNode << " at distance " << std::fabs(dist - tmpDist)); } } @@ -340,13 +346,13 @@ public: double ratio = std::min(1., LengthOfVector(smallestEdge.startCoord, newEndpoint)/LengthOfVector(smallestEdge.startCoord, smallestEdge.targetCoord) ); assert(ratio >= 0 && ratio <=1); - // INFO("Old weight1: " << resultNode.weight1 << ", old weight2: " << resultNode.weight2); +// INFO("Old weight1: " << resultNode.weight1 << ", old weight2: " << resultNode.weight2); resultNode.weight1 *= ratio; if(INT_MAX != resultNode.weight2) { resultNode.weight2 *= (1-ratio); - // INFO("New weight1: " << resultNode.weight1 << ", new weight2: " << resultNode.weight2); +// INFO("New weight1: " << resultNode.weight1 << ", new weight2: " << resultNode.weight2); } -// INFO("bidirected: " << (resultNode.isBidirected() ? "yes" : "no") << "\n--") +// INFO("selected node: " << resultNode.edgeBasedNode << ", bidirected: " << (resultNode.isBidirected() ? "yes" : "no") << "\n--") return foundNode; } diff --git a/DataStructures/SearchEngine.h b/DataStructures/SearchEngine.h index c26eff91d..942927e90 100644 --- a/DataStructures/SearchEngine.h +++ b/DataStructures/SearchEngine.h @@ -91,14 +91,18 @@ public: //insert start and/or target node of start edge _forwardHeap->Insert(phantomNodes.startPhantom.edgeBasedNode, -phantomNodes.startPhantom.weight1, phantomNodes.startPhantom.edgeBasedNode); +// INFO("a) forw insert " << phantomNodes.startPhantom.edgeBasedNode << ", weight: " << -phantomNodes.startPhantom.weight1); if(phantomNodes.startPhantom.isBidirected() ) { - _forwardHeap->Insert(phantomNodes.startPhantom.edgeBasedNode+1, -phantomNodes.startPhantom.weight2, phantomNodes.startPhantom.edgeBasedNode+1); +// INFO("b) forw insert " << phantomNodes.startPhantom.edgeBasedNode+1 << ", weight: " << -phantomNodes.startPhantom.weight2); + _forwardHeap->Insert(phantomNodes.startPhantom.edgeBasedNode+1, -phantomNodes.startPhantom.weight2, phantomNodes.startPhantom.edgeBasedNode+1); } //insert start and/or target node of target edge id - _backwardHeap->Insert(phantomNodes.targetPhantom.edgeBasedNode, -phantomNodes.targetPhantom.weight1, phantomNodes.targetPhantom.edgeBasedNode); + _backwardHeap->Insert(phantomNodes.targetPhantom.edgeBasedNode, -phantomNodes.targetPhantom.weight2, phantomNodes.targetPhantom.edgeBasedNode); +// INFO("c) back insert " << phantomNodes.targetPhantom.edgeBasedNode << ", weight: " << -phantomNodes.targetPhantom.weight2); if(phantomNodes.targetPhantom.isBidirected() ) { - _backwardHeap->Insert(phantomNodes.targetPhantom.edgeBasedNode+1, -phantomNodes.targetPhantom.weight2, phantomNodes.targetPhantom.edgeBasedNode+1); - } + _backwardHeap->Insert(phantomNodes.targetPhantom.edgeBasedNode+1, -phantomNodes.targetPhantom.weight1, phantomNodes.targetPhantom.edgeBasedNode+1); +// INFO("d) back insert " << phantomNodes.targetPhantom.edgeBasedNode+1 << ", weight: " << -phantomNodes.targetPhantom.weight1); + } while(_forwardHeap->Size() + _backwardHeap->Size() > 0){ if(_forwardHeap->Size() > 0){