diff --git a/DataStructures/ExtractorCallBacks.h b/DataStructures/ExtractorCallBacks.h index 9d3c0eeb0..2ec397f0a 100644 --- a/DataStructures/ExtractorCallBacks.h +++ b/DataStructures/ExtractorCallBacks.h @@ -101,7 +101,7 @@ public: std::string oneway( w.keyVals.Find("oneway")); std::string junction( w.keyVals.Find("junction") ); std::string route( w.keyVals.Find("route") ); - double maxspeed( atoi(w.keyVals.Find("maxspeed").c_str()) ); + 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") ); @@ -119,12 +119,17 @@ public: } //Is the highway tag listed as usable way? - if(0 < settings[highway]) { + if(0 < settings[highway] || "yes" == accessTag || "designated" == accessTag) { - if(0 < maxspeed) - w.speed = maxspeed; - else - w.speed = settings[highway]; + 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? @@ -157,11 +162,16 @@ public: 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 = 1; + w.type = settings.GetHighwayTypeID(highway); //Get the unique identifier for the street name const StringMap::const_iterator strit = stringMap->find(w.name); 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..eaa92d1e0 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,11 +346,11 @@ 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--") 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){ diff --git a/Rakefile b/Rakefile index e28fec545..61c6bfbd1 100644 --- a/Rakefile +++ b/Rakefile @@ -1,37 +1,50 @@ sandbox = "sandbox" #where to locate builds, server configs and test data osm_data = "amager" #name of OSM data file -desc "Recompile, reprocess OSM data and run server" -task :default => [:compile, :process, :run] +desc "Rebuild, reprocess OSM data and run server" +task :default => [:build, "data:process", :run] -desc "Compile" -task :compile do - system "scons" +desc "Build with Scons" +task :build do + raise "Error while building." unless system "scons" end file "#{sandbox}/amager.osm.pbf" => "amager.osm.pbf" do |t| - system "cp #{t.prerequisites.join} #{t.name}" + raise unless system "cp #{t.prerequisites.join} #{t.name}" end -desc "Reprocess OSM test data" -task :process => ["#{sandbox}/amager.osm.pbf", :setup] do - prev = Dir.pwd - cd sandbox #we must be in the sandbox folder to use the speedprofile.ini in that folder - system "./osrm-extract amager.osm.pbf" - system "./osrm-prepare amager.osrm amager.osrm.restrictions" - cd prev +namespace :data do + desc "Process OSM test data" + task :process => ["#{sandbox}/amager.osm.pbf", :setup] do + prev = Dir.pwd + cd sandbox #we must be in the sandbox folder to use the speedprofile.ini in that folder + raise "Error while extracting data." unless system "./osrm-extract amager.osm.pbf" + raise "Error while preparing data." unless system "./osrm-prepare amager.osrm amager.osrm.restrictions" + cd prev + end + + desc "Download fresh OSM for the test data" + task :download => :setup do + start = Time.now + country = 'denmark' + bbox = 'top=55.6655 left=12.5589 bottom=55.6462 right=12.5963' + area = 'amager' + + raise "Error while downloading data." unless system "curl http://download.geofabrik.de/osm/europe/#{country}.osm.pbf -o #{sandbox}/#{country}.osm.pbf" + raise "Error while cropping data." unless system "osmosis --read-pbf file=#{sandbox}/#{country}.osm.pbf --bounding-box #{bbox} --write-pbf file=#{sandbox}/#{area}.osm.pbf omitmetadata=true" + end end desc "Setup server files" task :setup => ["#{sandbox}/speedprofile.ini", "#{sandbox}/extractor.ini", "#{sandbox}/server.ini"] file "#{sandbox}/speedprofile.ini" => "speedprofile.ini" do |t| - system "cp #{t.prerequisites.join} #{t.name}" + raise unless system "cp #{t.prerequisites.join} #{t.name}" end file "#{sandbox}/extractor.ini" => "extractor.ini" do |t| - system "cp #{t.prerequisites.join} #{t.name}" + raise unless system "cp #{t.prerequisites.join} #{t.name}" end file "#{sandbox}/server.ini" => "server.ini" do |t| @@ -49,7 +62,7 @@ task :run => :setup do system "osrm-routed" end -desc "Run all test" +desc "Run test" task :test do puts "Test would go here..." end \ No newline at end of file diff --git a/SConstruct b/SConstruct index 21022ac5b..a6a6423b3 100644 --- a/SConstruct +++ b/SConstruct @@ -74,15 +74,20 @@ else: if sys.platform == 'darwin': #Mac OS X env.Append(CPPPATH = ['/usr/include/libxml2'] ) #comes with os x - #assume stxxl and boost are installed via homebrew. - #call out to brew to get the folder locations + #assume dependencies are installed with homebrew, and call out get folder locations import subprocess stxxl_prefix = subprocess.check_output(["brew", "--prefix", "libstxxl"]).strip() - boost_prefix = subprocess.check_output(["brew", "--prefix", "boost"]).strip() env.Append(CPPPATH = [stxxl_prefix+"/include"] ) env.Append(LIBPATH = [stxxl_prefix+"/lib"] ) + + boost_prefix = subprocess.check_output(["brew", "--prefix", "boost"]).strip() env.Append(CPPPATH = [boost_prefix+"/include"] ) env.Append(LIBPATH = [boost_prefix+"/lib"] ) + + #libxml2_prefix = subprocess.check_output(["brew", "--prefix", "libxml2"]).strip() + #env.Append(CPPPATH = [libxml2_prefix+"/include"] ) + #env.Append(LIBPATH = [libxml2_prefix+"/lib"] ) + elif sys.platform.startswith("freebsd"): env.ParseConfig('pkg-config --cflags --libs protobuf') env.Append(CPPPATH = ['/usr/local/include', '/usr/local/include/libxml2']) @@ -105,9 +110,11 @@ else: env.Append(CPPPATH = ['/usr/include', '/usr/include/include', '/usr/include/libxml2/']) -if not conf.CheckHeader('omp.h'): - print "Compiler does not support OpenMP. Exiting" - Exit(-1) +if sys.platform != 'darwin': + if not conf.CheckHeader('omp.h'): + print "Compiler does not support OpenMP. Exiting" + Exit(-1) + if not conf.CheckLibWithHeader('xml2', 'libxml/xmlreader.h', 'CXX'): print "libxml2 library or header not found. Exiting" Exit(-1) diff --git a/amager.osm.pbf b/amager.osm.pbf index bfcb5b654..2d0dfd4bb 100644 Binary files a/amager.osm.pbf and b/amager.osm.pbf differ diff --git a/extractor.cpp b/extractor.cpp index a709016da..2ba0a35a3 100644 --- a/extractor.cpp +++ b/extractor.cpp @@ -102,7 +102,7 @@ int main (int argc, char *argv[]) { boost::property_tree::ptree pt; try { INFO("Loading speed profiles") - boost::property_tree::ini_parser::read_ini("speedprofile.ini", pt); + boost::property_tree::ini_parser::read_ini("speedprofile.ini", pt); INFO("Found the following speed profiles: "); int profileCounter(0); BOOST_FOREACH(boost::property_tree::ptree::value_type &v, pt.get_child("")) { @@ -134,11 +134,20 @@ int main (int argc, char *argv[]) { if(name == "accessTag") { settings.accessTag = value; continue; + } else { + if(name == "excludeFromGrid") { + settings.excludeFromGrid = value; + } else { + if(name == "defaultSpeed") { + settings.defaultSpeed = atoi(value.c_str()); + settings.speedProfile["default"] = std::make_pair(settings.defaultSpeed, settings.speedProfile.size() ); + } + } } } } + settings.speedProfile[name] = std::make_pair(std::atoi(value.c_str()), settings.speedProfile.size() ); } - settings.speedProfile[name] = atoi(value.c_str()); } } catch(std::exception& e) { ERR("caught: " << e.what() ); @@ -189,7 +198,7 @@ int main (int argc, char *argv[]) { cout << "[extractor] parsing finished after " << get_timestamp() - time << " seconds" << endl; time = get_timestamp(); - boost::uint64_t memory_to_use = static_cast(amountOfRAM) * 1024 * 1024 * 1024; + boost::uint64_t memory_to_use = static_cast(amountOfRAM) * 1024 * 1024 * 1024; cout << "[extractor] Sorting used nodes ... " << flush; stxxl::sort(externalMemory.usedNodeIDs.begin(), externalMemory.usedNodeIDs.end(), Cmp(), memory_to_use); @@ -221,11 +230,11 @@ int main (int argc, char *argv[]) { while(wayStartAndEndEdgeIT != externalMemory.wayStartEndVector.end() && restrictionsIT != externalMemory.restrictionsVector.end()) { if(wayStartAndEndEdgeIT->wayID < restrictionsIT->fromWay){ - ++wayStartAndEndEdgeIT; + ++wayStartAndEndEdgeIT; continue; } if(wayStartAndEndEdgeIT->wayID > restrictionsIT->fromWay) { - ++restrictionsIT; + ++restrictionsIT; continue; } assert(wayStartAndEndEdgeIT->wayID == restrictionsIT->fromWay); @@ -257,11 +266,11 @@ int main (int argc, char *argv[]) { wayStartAndEndEdgeIT = externalMemory.wayStartEndVector.begin(); while(wayStartAndEndEdgeIT != externalMemory.wayStartEndVector.end() && restrictionsIT != externalMemory.restrictionsVector.end()) { if(wayStartAndEndEdgeIT->wayID < restrictionsIT->toWay){ - ++wayStartAndEndEdgeIT; + ++wayStartAndEndEdgeIT; continue; } if(wayStartAndEndEdgeIT->wayID > restrictionsIT->toWay) { - ++restrictionsIT; + ++restrictionsIT; continue; } NodeID viaNode = restrictionsIT->restriction.viaNode; @@ -276,9 +285,7 @@ int main (int argc, char *argv[]) { } if(UINT_MAX != restrictionsIT->restriction.fromNode && UINT_MAX != restrictionsIT->restriction.toNode) { - ++usableRestrictionsCounter; - } else { - INFO("Restriction from: " << restrictionsIT->restriction.fromNode << ", to: " << restrictionsIT->restriction.toNode); + ++usableRestrictionsCounter; } ++restrictionsIT; } @@ -346,7 +353,7 @@ int main (int argc, char *argv[]) { STXXLEdgeVector::iterator edgeIT = externalMemory.allEdges.begin(); while(edgeIT != externalMemory.allEdges.end() && nodesIT != externalMemory.allNodes.end()) { if(edgeIT->start < nodesIT->id){ - ++edgeIT; + ++edgeIT; continue; } if(edgeIT->start > nodesIT->id) { @@ -374,11 +381,11 @@ int main (int argc, char *argv[]) { edgeIT = externalMemory.allEdges.begin(); while(edgeIT != externalMemory.allEdges.end() && nodesIT != externalMemory.allNodes.end()) { if(edgeIT->target < nodesIT->id){ - ++edgeIT; + ++edgeIT; continue; } if(edgeIT->target > nodesIT->id) { - ++nodesIT; + ++nodesIT; continue; } if(edgeIT->target == nodesIT->id) {