diff --git a/CMakeLists.txt b/CMakeLists.txt index 62030dfd9..d4d66f368 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,10 +38,10 @@ set(ExtractorSources extractor.cpp ${ExtractorGlob} Util/GitDescription.cpp) add_executable(osrm-extract ${ExtractorSources} ) file(GLOB PrepareGlob Contractor/*.cpp) -set(PrepareSources createHierarchy.cpp ${PrepareGlob}) +set(PrepareSources createHierarchy.cpp ${PrepareGlob} Util/GitDescription.cpp) add_executable(osrm-prepare ${PrepareSources} ) -add_executable(osrm-routed routed.cpp ) +add_executable(osrm-routed routed.cpp Util/GitDescription.cpp) set_target_properties(osrm-routed PROPERTIES COMPILE_FLAGS -DROUTED) file(GLOB DescriptorGlob Descriptors/*.cpp) diff --git a/Library/OSRM.cpp b/Library/OSRM.cpp index 79f6b869f..3c56ac6cd 100644 --- a/Library/OSRM.cpp +++ b/Library/OSRM.cpp @@ -19,76 +19,11 @@ or see http://www.gnu.org/licenses/agpl.txt. */ #include "OSRM.h" +#include -OSRM::OSRM(const char * server_ini_path) { - if( !testDataFile(server_ini_path) ){ - std::string error_message = std::string(server_ini_path) + " not found"; - throw OSRMException(error_message.c_str()); - } - - IniFile serverConfig(server_ini_path); - - boost::filesystem::path base_path = - boost::filesystem::absolute(server_ini_path).parent_path(); - - if ( !serverConfig.Holds("hsgrData")) { - throw OSRMException("no ram index file name in server ini"); - } - if ( !serverConfig.Holds("ramIndex") ) { - throw OSRMException("no mem index file name in server ini"); - } - if ( !serverConfig.Holds("fileIndex") ) { - throw OSRMException("no nodes file name in server ini"); - } - if ( !serverConfig.Holds("nodesData") ) { - throw OSRMException("no nodes file name in server ini"); - } - if ( !serverConfig.Holds("edgesData") ) { - throw OSRMException("no edges file name in server ini"); - } - - boost::filesystem::path hsgr_path = boost::filesystem::absolute( - serverConfig.GetParameter("hsgrData"), - base_path - ); - - boost::filesystem::path ram_index_path = boost::filesystem::absolute( - serverConfig.GetParameter("ramIndex"), - base_path - ); - - boost::filesystem::path file_index_path = boost::filesystem::absolute( - serverConfig.GetParameter("fileIndex"), - base_path - ); - - boost::filesystem::path node_data_path = boost::filesystem::absolute( - serverConfig.GetParameter("nodesData"), - base_path - ); - boost::filesystem::path edge_data_path = boost::filesystem::absolute( - serverConfig.GetParameter("edgesData"), - base_path - ); - boost::filesystem::path name_data_path = boost::filesystem::absolute( - serverConfig.GetParameter("namesData"), - base_path - ); - boost::filesystem::path timestamp_path = boost::filesystem::absolute( - serverConfig.GetParameter("timestamp"), - base_path - ); - - objects = new QueryObjectsStorage( - hsgr_path.string(), - ram_index_path.string(), - file_index_path.string(), - node_data_path.string(), - edge_data_path.string(), - name_data_path.string(), - timestamp_path.string() - ); +OSRM::OSRM(boost::unordered_map& paths) { + objects = new QueryObjectsStorage( paths ); RegisterPlugin(new HelloWorldPlugin()); RegisterPlugin(new LocatePlugin(objects)); RegisterPlugin(new NearestPlugin(objects)); diff --git a/Library/OSRM.h b/Library/OSRM.h index bb3caa7d9..515bfd3ed 100644 --- a/Library/OSRM.h +++ b/Library/OSRM.h @@ -30,9 +30,9 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "../Plugins/TimestampPlugin.h" #include "../Plugins/ViaRoutePlugin.h" #include "../Server/DataStructures/RouteParameters.h" -#include "../Util/IniFile.h" #include "../Util/InputFileUtil.h" #include "../Util/OSRMException.h" +#include "../Util/ProgramOptions.h" #include "../Util/SimpleLogger.h" #include "../Server/BasicDatastructures.h" @@ -47,7 +47,7 @@ class OSRM : boost::noncopyable { typedef boost::unordered_map PluginMap; QueryObjectsStorage * objects; public: - OSRM(const char * server_ini_path); + OSRM(boost::unordered_map& paths); ~OSRM(); void RunQuery(RouteParameters & route_parameters, http::Reply & reply); private: diff --git a/Rakefile b/Rakefile index ed0b48bab..21e95cfb2 100644 --- a/Rakefile +++ b/Rakefile @@ -59,23 +59,6 @@ def wait_for_shutdown name raise "*** Could not terminate #{name}." end -def write_server_ini osm_file - s=<<-EOF - Threads = 1 - IP = 0.0.0.0 - Port = #{OSRM_PORT} - - hsgrData=#{osm_file}.osrm.hsgr - nodesData=#{osm_file}.osrm.nodes - edgesData=#{osm_file}.osrm.edges - ramIndex=#{osm_file}.osrm.ramIndex - fileIndex=#{osm_file}.osrm.fileIndex - namesData=#{osm_file}.osrm.names - timestamp=#{osm_file}.osrm.timestamp - EOF - File.open( 'server.ini', 'w') {|f| f.write( s ) } -end - desc "Rebuild and run tests." task :default => [:build] @@ -93,17 +76,10 @@ end desc "Setup config files." task :setup do - Dir.mkdir "#{DATA_FOLDER}" unless File.exist? "#{DATA_FOLDER}" - ['server.ini','extractor.ini','contractor.ini'].each do |file| - unless File.exist? "#{DATA_FOLDER}/#{file}" - puts "Copying #{file} template to #{DATA_FOLDER}/#{file}" - FileUtils.cp file, "#{DATA_FOLDER}/#{file}" - end - end end desc "Download OSM data." -task :download => :setup do +task :download do Dir.mkdir "#{DATA_FOLDER}" unless File.exist? "#{DATA_FOLDER}" puts "Downloading..." puts "curl http://download.geofabrik.de/europe/#{osm_data_country}-latest.osm.pbf -o #{DATA_FOLDER}/#{osm_data_country}.osm.pbf" @@ -122,26 +98,20 @@ task :crop do end desc "Reprocess OSM data." -task :process => :setup do - Dir.chdir DATA_FOLDER do - raise "Error while extracting data." unless system "../#{BUILD_FOLDER}/osrm-extract #{osm_data_area_name}.osm.pbf --profile #{PROFILES_FOLDER}/#{PROFILE}.lua" - puts - raise "Error while preparing data." unless system "../#{BUILD_FOLDER}/osrm-prepare #{osm_data_area_name}.osrm #{osm_data_area_name}.osrm.restrictions #{PROFILES_FOLDER}/#{PROFILE}.lua" - puts - end +task :process => [:extract,:prepare] do end desc "Extract OSM data." -task :extract => :setup do +task :extract do Dir.chdir DATA_FOLDER do raise "Error while extracting data." unless system "../#{BUILD_FOLDER}/osrm-extract #{osm_data_area_name}.osm.pbf --profile ../profiles/#{PROFILE}.lua" end end desc "Prepare OSM data." -task :prepare => :setup do +task :prepare do Dir.chdir DATA_FOLDER do - raise "Error while preparing data." unless system "../#{BUILD_FOLDER}/osrm-prepare #{osm_data_area_name}.osrm #{osm_data_area_name}.osrm.restrictions ../profiles/#{PROFILE}.lua" + raise "Error while preparing data." unless system "../#{BUILD_FOLDER}/osrm-prepare #{osm_data_area_name}.osrm --profile ../profiles/#{PROFILE}.lua" end end @@ -158,19 +128,17 @@ task :test do end desc "Run the routing server in the terminal. Press Ctrl-C to stop." -task :run => :setup do +task :run do Dir.chdir DATA_FOLDER do - write_server_ini osm_data_area_name - system "../#{BUILD_FOLDER}/osrm-routed" + system "../#{BUILD_FOLDER}/osrm-routed #{osm_data_area_name}.osrm --port #{OSRM_PORT}" end end desc "Launch the routing server in the background. Use rake:down to stop it." -task :up => :setup do +task :up do Dir.chdir DATA_FOLDER do abort("Already up.") if up? - write_server_ini osm_data_area_name - pipe = IO.popen("../#{BUILD_FOLDER}/osrm-routed 1>>osrm-routed.log 2>>osrm-routed.log") + pipe = IO.popen("../#{BUILD_FOLDER}/osrm-routed #{osm_data_area_name}.osrm --port #{OSRM_PORT} 1>>osrm-routed.log 2>>osrm-routed.log") timeout = 5 (timeout*10).times do begin diff --git a/Server/DataStructures/QueryObjectsStorage.cpp b/Server/DataStructures/QueryObjectsStorage.cpp index e0ec72e40..d7c22ef47 100644 --- a/Server/DataStructures/QueryObjectsStorage.cpp +++ b/Server/DataStructures/QueryObjectsStorage.cpp @@ -21,31 +21,23 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "QueryObjectsStorage.h" -QueryObjectsStorage::QueryObjectsStorage( - const std::string & hsgr_path, - const std::string & ram_index_path, - const std::string & file_index_path, - const std::string & nodes_path, - const std::string & edges_path, - const std::string & names_path, - const std::string & timestamp_path -) { - if( hsgr_path.empty() ) { +QueryObjectsStorage::QueryObjectsStorage(boost::unordered_map& paths) { + if( paths["hsgr"].empty() ) { throw OSRMException("no hsgr file given in ini file"); } - if( ram_index_path.empty() ) { + if( paths["ramIndex"].empty() ) { throw OSRMException("no ram index file given in ini file"); } - if( file_index_path.empty() ) { + if( paths["fileIndex"].empty() ) { throw OSRMException("no mem index file given in ini file"); } - if( nodes_path.empty() ) { + if( paths["nodes"].empty() ) { throw OSRMException("no nodes file given in ini file"); } - if( edges_path.empty() ) { + if( paths["edges"].empty() ) { throw OSRMException("no edges file given in ini file"); } - if( names_path.empty() ) { + if( paths["names"].empty() ) { throw OSRMException("no names file given in ini file"); } @@ -54,7 +46,7 @@ QueryObjectsStorage::QueryObjectsStorage( std::vector< QueryGraph::_StrNode> node_list; std::vector< QueryGraph::_StrEdge> edge_list; const int number_of_nodes = readHSGRFromStream( - hsgr_path, + paths["hsgr"].c_str(), node_list, edge_list, &check_sum @@ -65,11 +57,11 @@ QueryObjectsStorage::QueryObjectsStorage( assert(0 == node_list.size()); assert(0 == edge_list.size()); - if(timestamp_path.length()) { + if(!paths["timestamp"].empty()) { SimpleLogger().Write() << "Loading Timestamp"; - std::ifstream timestampInStream(timestamp_path.c_str()); + std::ifstream timestampInStream(paths["timestamp"].c_str()); if(!timestampInStream) { - SimpleLogger().Write(logWARNING) << timestamp_path << " not found"; + SimpleLogger().Write(logWARNING) << paths["timestamp"].c_str() << " not found"; } getline(timestampInStream, timestamp); @@ -85,26 +77,25 @@ QueryObjectsStorage::QueryObjectsStorage( SimpleLogger().Write() << "Loading auxiliary information"; //Init nearest neighbor data structure nodeHelpDesk = new NodeInformationHelpDesk( - ram_index_path, - file_index_path, - nodes_path, - edges_path, + paths["ramIndex"].c_str(), + paths["fileIndex"].c_str(), + paths["nodes"].c_str(), + paths["edges"].c_str(), number_of_nodes, check_sum ); //deserialize street name list SimpleLogger().Write() << "Loading names index"; - boost::filesystem::path names_file(names_path); - if ( !boost::filesystem::exists( names_file ) ) { + if ( !boost::filesystem::exists( paths["names"] ) ) { throw OSRMException("names file does not exist"); } - if ( 0 == boost::filesystem::file_size( names_file ) ) { + if ( 0 == boost::filesystem::file_size( paths["names"] ) ) { throw OSRMException("names file is empty"); } - boost::filesystem::ifstream name_stream(names_file, std::ios::binary); + boost::filesystem::ifstream name_stream(paths["names"], std::ios::binary); unsigned size = 0; name_stream.read((char *)&size, sizeof(unsigned)); BOOST_ASSERT_MSG(0 != size, "name file broken"); diff --git a/Server/DataStructures/QueryObjectsStorage.h b/Server/DataStructures/QueryObjectsStorage.h index fd5419283..a2d3a58c1 100644 --- a/Server/DataStructures/QueryObjectsStorage.h +++ b/Server/DataStructures/QueryObjectsStorage.h @@ -50,16 +50,7 @@ struct QueryObjectsStorage { void GetName(const unsigned name_id, std::string & result) const; - QueryObjectsStorage( - const std::string & hsgrPath, - const std::string & ramIndexPath, - const std::string & fileIndexPath, - const std::string & nodesPath, - const std::string & edgesPath, - const std::string & namesPath, - const std::string & timestampPath - ); - + QueryObjectsStorage(boost::unordered_map& paths); ~QueryObjectsStorage(); }; diff --git a/Server/ServerFactory.h b/Server/ServerFactory.h index 60502e257..209fe4391 100644 --- a/Server/ServerFactory.h +++ b/Server/ServerFactory.h @@ -22,46 +22,23 @@ or see http://www.gnu.org/licenses/agpl.txt. #define SERVERFACTORY_H_ #include "Server.h" -#include "../Util/IniFile.h" #include "../Util/SimpleLogger.h" #include "../Util/StringUtil.h" #include #include +#include struct ServerFactory : boost::noncopyable { - static Server * CreateServer( IniFile & serverConfig ) { - int threads = omp_get_num_procs(); - if( serverConfig.GetParameter("IP").empty() ) { - serverConfig.SetParameter("IP", "0.0.0.0"); - } - - if( serverConfig.GetParameter("Port").empty() ) { - serverConfig.SetParameter("Port", "5000"); - } - - if( - stringToInt(serverConfig.GetParameter("Threads")) >= 1 && - stringToInt(serverConfig.GetParameter("Threads")) <= threads - ) { - threads = stringToInt( serverConfig.GetParameter("Threads") ); - } + static Server * CreateServer(std::string& ip_address, int ip_port, int threads) { SimpleLogger().Write() << "http 1.1 compression handled by zlib version " << zlibVersion(); - Server * server = new Server( - serverConfig.GetParameter("IP"), - serverConfig.GetParameter("Port"), - threads - ); - return server; - } - - static Server * CreateServer(const char * iniFile) { - IniFile serverConfig(iniFile); - return CreateServer(serverConfig); + std::stringstream port_stream; + port_stream << ip_port; + return new Server( ip_address, port_stream.str(), std::min( omp_get_num_procs(), threads) ); } }; diff --git a/Tools/componentAnalysis.cpp b/Tools/componentAnalysis.cpp index 74d7104d2..a3154a184 100644 --- a/Tools/componentAnalysis.cpp +++ b/Tools/componentAnalysis.cpp @@ -26,7 +26,6 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "../DataStructures/QueryEdge.h" #include "../DataStructures/TurnInstructions.h" #include "../Util/GraphLoader.h" -#include "../Util/IniFile.h" #include "../Util/InputFileUtil.h" #include "../Util/OSRMException.h" #include "../Util/SimpleLogger.h" diff --git a/Util/ProgramOptions.h b/Util/ProgramOptions.h index cd2180b29..a1e2d4c46 100644 --- a/Util/ProgramOptions.h +++ b/Util/ProgramOptions.h @@ -21,6 +21,9 @@ or see http://www.gnu.org/licenses/agpl.txt. Custom validators for use with boost::program_options. */ +#ifndef PROGAM_OPTIONS_H +#define PROGAM_OPTIONS_H + #include "OSRMException.h" #include @@ -53,3 +56,5 @@ namespace boost { } } } + +#endif /* PROGRAM_OPTIONS_H */ diff --git a/contractor.ini b/contractor.ini deleted file mode 100644 index 4da33c7ef..000000000 --- a/contractor.ini +++ /dev/null @@ -1 +0,0 @@ -Threads = 4 diff --git a/createHierarchy.cpp b/createHierarchy.cpp index a3c6ceb20..13088effa 100644 --- a/createHierarchy.cpp +++ b/createHierarchy.cpp @@ -26,12 +26,13 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "DataStructures/QueryEdge.h" #include "DataStructures/StaticGraph.h" #include "DataStructures/StaticRTree.h" -#include "Util/IniFile.h" +#include "Util/GitDescription.h" #include "Util/GraphLoader.h" #include "Util/InputFileUtil.h" #include "Util/LuaUtil.h" #include "Util/OpenMPWrapper.h" #include "Util/OSRMException.h" +#include "Util/ProgramOptions.h" #include "Util/SimpleLogger.h" #include "Util/StringUtil.h" #include "typedefs.h" @@ -50,7 +51,6 @@ or see http://www.gnu.org/licenses/agpl.txt. typedef QueryEdge::EdgeData EdgeData; typedef DynamicGraph::InputEdge InputEdge; typedef StaticGraph::InputEdge StaticEdge; -typedef IniFile ContractorConfiguration; std::vector internalToExternalNodeMapping; std::vector inputRestrictions; @@ -61,30 +61,95 @@ std::vector edgeList; int main (int argc, char *argv[]) { try { LogPolicy::GetInstance().Unmute(); - if(argc < 3) { - SimpleLogger().Write(logWARNING) << - "usage: \n" << - argv[0] << " []"; + double startupTime = get_timestamp(); + boost::filesystem::path config_file_path, input_path, restrictions_path, profile_path; + int requested_num_threads; + + // declare a group of options that will be allowed only on command line + boost::program_options::options_description generic_options("Options"); + generic_options.add_options() + ("version,v", "Show version") + ("help,h", "Show this help message") + ("config,c", boost::program_options::value(&config_file_path)->default_value("contractor.ini"), + "Path to a configuration file."); + + // declare a group of options that will be allowed both on command line and in config file + boost::program_options::options_description config_options("Configuration"); + config_options.add_options() + ("restrictions,r", boost::program_options::value(&restrictions_path), + "Restrictions file in .osrm.restrictions format") + ("profile,p", boost::program_options::value(&profile_path)->default_value("profile.lua"), + "Path to LUA routing profile") + ("threads,t", boost::program_options::value(&requested_num_threads)->default_value(10), + "Number of threads to use"); + + // hidden options, will be allowed both on command line and in config file, but will not be shown to the user + boost::program_options::options_description hidden_options("Hidden options"); + hidden_options.add_options() + ("input,i", boost::program_options::value(&input_path), + "Input file in .osm, .osm.bz2 or .osm.pbf format"); + + // positional option + boost::program_options::positional_options_description positional_options; + positional_options.add("input", 1); + + // combine above options for parsing + boost::program_options::options_description cmdline_options; + cmdline_options.add(generic_options).add(config_options).add(hidden_options); + + boost::program_options::options_description config_file_options; + config_file_options.add(config_options).add(hidden_options); + + boost::program_options::options_description visible_options("Usage: " + boost::filesystem::basename(argv[0]) + " [options]"); + visible_options.add(generic_options).add(config_options); + + // parse command line options + boost::program_options::variables_map option_variables; + boost::program_options::store(boost::program_options::command_line_parser(argc, argv). + options(cmdline_options).positional(positional_options).run(), option_variables); + + if(option_variables.count("version")) { + SimpleLogger().Write() << g_GIT_DESCRIPTION; + return 0; + } + + if(option_variables.count("help")) { + SimpleLogger().Write() << std::endl << visible_options; + return 0; + } + + boost::program_options::notify(option_variables); + + // parse config file + if(boost::filesystem::is_regular_file(config_file_path)) { + std::ifstream ifs(config_file_path.c_str()); + SimpleLogger().Write() << "Reading options from: " << config_file_path.filename().string(); + boost::program_options::store(parse_config_file(ifs, config_file_options), option_variables); + boost::program_options::notify(option_variables); + } + + if(!option_variables.count("restrictions")) { + restrictions_path = std::string( input_path.c_str()) + ".restrictions"; + } + + if(!option_variables.count("input")) { + SimpleLogger().Write(logWARNING) << "No input file specified"; return -1; } - double startupTime = get_timestamp(); - unsigned number_of_threads = omp_get_num_procs(); - if(testDataFile("contractor.ini")) { - ContractorConfiguration contractorConfig("contractor.ini"); - unsigned rawNumber = stringToInt(contractorConfig.GetParameter("Threads")); - if(rawNumber != 0 && rawNumber <= number_of_threads) - number_of_threads = rawNumber; + if(1 > requested_num_threads) { + SimpleLogger().Write(logWARNING) << "Number of threads must be 1 or larger"; + return -1; } - omp_set_num_threads(number_of_threads); - LogPolicy::GetInstance().Unmute(); - SimpleLogger().Write() << "Using restrictions from file: " << argv[2]; - std::ifstream restrictionsInstream(argv[2], std::ios::binary); - if(!restrictionsInstream.good()) { - std::cerr << - "Could not access files" << std::endl; - } + SimpleLogger().Write() << "Input file: " << input_path.filename().string(); + SimpleLogger().Write() << "Restrictions file: " << restrictions_path.filename().string(); + SimpleLogger().Write() << "Profile: " << profile_path.filename().string(); + SimpleLogger().Write() << "Threads: " << requested_num_threads; + + omp_set_num_threads( std::min( omp_get_num_procs(), requested_num_threads) ); + LogPolicy::GetInstance().Unmute(); + std::ifstream restrictionsInstream( restrictions_path.c_str(), std::ios::binary); TurnRestriction restriction; UUID uuid_loaded, uuid_orig; unsigned usableRestrictionsCounter(0); @@ -107,21 +172,15 @@ int main (int argc, char *argv[]) { restrictionsInstream.close(); std::ifstream in; - in.open (argv[1], std::ifstream::in | std::ifstream::binary); - if (!in.is_open()) { - throw OSRMException("Cannot open osrm input file"); - } + in.open (input_path.c_str(), std::ifstream::in | std::ifstream::binary); - std::string nodeOut(argv[1]); nodeOut += ".nodes"; - std::string edgeOut(argv[1]); edgeOut += ".edges"; - std::string graphOut(argv[1]); graphOut += ".hsgr"; - std::string rtree_nodes_path(argv[1]); rtree_nodes_path += ".ramIndex"; - std::string rtree_leafs_path(argv[1]); rtree_leafs_path += ".fileIndex"; + std::string nodeOut(input_path.c_str()); nodeOut += ".nodes"; + std::string edgeOut(input_path.c_str()); edgeOut += ".edges"; + std::string graphOut(input_path.c_str()); graphOut += ".hsgr"; + std::string rtree_nodes_path(input_path.c_str()); rtree_nodes_path += ".ramIndex"; + std::string rtree_leafs_path(input_path.c_str()); rtree_leafs_path += ".fileIndex"; /*** Setup Scripting Environment ***/ - if(!testDataFile( (argc > 3 ? argv[3] : "profile.lua") )) { - throw OSRMException("Cannot open profile.lua "); - } // Create a new lua state lua_State *myLuaState = luaL_newstate(); @@ -133,14 +192,10 @@ int main (int argc, char *argv[]) { luaL_openlibs(myLuaState); //adjust lua load path - luaAddScriptFolderToLoadPath( myLuaState, (argc > 3 ? argv[3] : "profile.lua") ); + luaAddScriptFolderToLoadPath( myLuaState, profile_path.c_str() ); // Now call our function in a lua script - SimpleLogger().Write() << - "Parsing speedprofile from " << - (argc > 3 ? argv[3] : "profile.lua"); - - if(0 != luaL_dofile(myLuaState, (argc > 3 ? argv[3] : "profile.lua") )) { + if(0 != luaL_dofile(myLuaState, profile_path.c_str() )) { std::cerr << lua_tostring(myLuaState,-1) << " occured in scripting block" << @@ -338,6 +393,12 @@ int main (int argc, char *argv[]) { //cleanedEdgeList.clear(); _nodes.clear(); SimpleLogger().Write() << "finished preprocessing"; + } catch(boost::program_options::too_many_positional_options_error& e) { + SimpleLogger().Write(logWARNING) << "Only one file can be specified"; + return -1; + } catch(boost::program_options::error& e) { + SimpleLogger().Write(logWARNING) << e.what(); + return -1; } catch ( const std::exception &e ) { SimpleLogger().Write(logWARNING) << "Exception occured: " << e.what() << std::endl; diff --git a/extractor.cpp b/extractor.cpp index 4a380e18b..81f86695c 100644 --- a/extractor.cpp +++ b/extractor.cpp @@ -197,11 +197,9 @@ int main (int argc, char *argv[]) { "extraction finished after " << get_timestamp() - startup_time << "s"; - SimpleLogger().Write() << "\nRun:\n./osrm-prepare " << - output_file_name << - " " << - restrictionsFileName << - std::endl; + SimpleLogger().Write() << "To prepare the data for routing, run: " + << "osrm-prepare " << output_file_name << std::endl; + } catch(boost::program_options::too_many_positional_options_error& e) { SimpleLogger().Write(logWARNING) << "Only one input file can be specified"; return -1; diff --git a/features/step_definitions/locate.rb b/features/step_definitions/locate.rb index 26f8fdd36..3b1d5d7da 100644 --- a/features/step_definitions/locate.rb +++ b/features/step_definitions/locate.rb @@ -1,7 +1,7 @@ When /^I request locate I should get$/ do |table| reprocess actual = [] - OSRMLauncher.new do + OSRMLauncher.new("#{@osm_file}.osrm") do table.hashes.each_with_index do |row,ri| in_node = find_node_by_name row['in'] raise "*** unknown in-node '#{row['in']}" unless in_node diff --git a/features/step_definitions/nearest.rb b/features/step_definitions/nearest.rb index 6c0af7a0f..352f6bc89 100644 --- a/features/step_definitions/nearest.rb +++ b/features/step_definitions/nearest.rb @@ -1,7 +1,7 @@ When /^I request nearest I should get$/ do |table| reprocess actual = [] - OSRMLauncher.new do + OSRMLauncher.new("#{@osm_file}.osrm") do table.hashes.each_with_index do |row,ri| in_node = find_node_by_name row['in'] raise "*** unknown in-node '#{row['in']}" unless in_node diff --git a/features/step_definitions/requests.rb b/features/step_definitions/requests.rb index d965b1aa0..fb1f9f8b7 100644 --- a/features/step_definitions/requests.rb +++ b/features/step_definitions/requests.rb @@ -1,6 +1,6 @@ When /^I request \/(.*)$/ do |path| reprocess - OSRMLauncher.new do + OSRMLauncher.new("#{@osm_file}.osrm") do @response = request_path path end end diff --git a/features/step_definitions/routability.rb b/features/step_definitions/routability.rb index d01d2234f..6c5148b14 100644 --- a/features/step_definitions/routability.rb +++ b/features/step_definitions/routability.rb @@ -5,7 +5,7 @@ Then /^routability should be$/ do |table| if table.headers&["forw","backw","bothw"] == [] raise "*** routability tabel must contain either 'forw', 'backw' or 'bothw' column" end - OSRMLauncher.new do + OSRMLauncher.new("#{@osm_file}.osrm") do table.hashes.each_with_index do |row,i| got = row.dup attempts = [] diff --git a/features/step_definitions/routing.rb b/features/step_definitions/routing.rb index 349fa9243..ead847166 100644 --- a/features/step_definitions/routing.rb +++ b/features/step_definitions/routing.rb @@ -1,7 +1,7 @@ When /^I route I should get$/ do |table| reprocess actual = [] - OSRMLauncher.new do + OSRMLauncher.new("#{@osm_file}.osrm") do table.hashes.each_with_index do |row,ri| waypoints = [] if row['from'] and row['to'] diff --git a/features/support/config.rb b/features/support/config.rb index 9c4cb0fd7..e61c9fc74 100644 --- a/features/support/config.rb +++ b/features/support/config.rb @@ -10,21 +10,3 @@ end def set_profile profile @profile = profile end - -def write_server_ini - s=<<-EOF - Threads = 1 - IP = 0.0.0.0 - Port = #{OSRM_PORT} - - hsgrData=#{@osm_file}.osrm.hsgr - nodesData=#{@osm_file}.osrm.nodes - edgesData=#{@osm_file}.osrm.edges - ramIndex=#{@osm_file}.osrm.ramIndex - fileIndex=#{@osm_file}.osrm.fileIndex - namesData=#{@osm_file}.osrm.names - timestamp=#{@osm_file}.osrm.timestamp - EOF - File.open( 'server.ini', 'w') {|f| f.write( s ) } -end - diff --git a/features/support/data.rb b/features/support/data.rb index 6af83d96c..b11e460f7 100644 --- a/features/support/data.rb +++ b/features/support/data.rb @@ -263,13 +263,12 @@ def reprocess unless prepared? log_preprocess_info log "== Preparing #{@osm_file}.osm...", :preprocess - unless system "#{BIN_PATH}/osrm-prepare #{@osm_file}.osrm #{@osm_file}.osrm.restrictions 1>>#{PREPROCESS_LOG_FILE} 2>>#{PREPROCESS_LOG_FILE} #{PROFILES_PATH}/#{@profile}.lua" + unless system "#{BIN_PATH}/osrm-prepare #{@osm_file}.osrm --profile #{PROFILES_PATH}/#{@profile}.lua 1>>#{PREPROCESS_LOG_FILE} 2>>#{PREPROCESS_LOG_FILE}" log "*** Exited with code #{$?.exitstatus}.", :preprocess raise PrepareError.new $?.exitstatus, "osrm-prepare exited with code #{$?.exitstatus}." end log '', :preprocess end log_preprocess_done - write_server_ini end end diff --git a/features/support/file.rb b/features/support/file.rb index 602f07e48..03d4ce939 100644 --- a/features/support/file.rb +++ b/features/support/file.rb @@ -18,5 +18,7 @@ class File tail_of_file = chunks.join('') ary = tail_of_file.split(/\n/) lines_to_return = ary[ ary.size - n, ary.size - 1 ] + rescue + ["Cannot read log file!"] end end \ No newline at end of file diff --git a/features/support/launch.rb b/features/support/launch.rb index 9e95e5259..02e236665 100644 --- a/features/support/launch.rb +++ b/features/support/launch.rb @@ -6,7 +6,8 @@ SHUTDOWN_TIMEOUT = 2 OSRM_ROUTED_LOG_FILE = 'osrm-routed.log' class OSRMLauncher - def initialize &block + def initialize input_file, &block + @input_file = input_file Dir.chdir TEST_FOLDER do begin launch @@ -48,7 +49,7 @@ class OSRMLauncher def osrm_up return if osrm_up? - @pid = Process.spawn(["#{BIN_PATH}/osrm-routed",''],:out=>OSRM_ROUTED_LOG_FILE, :err=>OSRM_ROUTED_LOG_FILE) + @pid = Process.spawn("#{BIN_PATH}/osrm-routed #{@input_file} --port #{OSRM_PORT}",:out=>OSRM_ROUTED_LOG_FILE, :err=>OSRM_ROUTED_LOG_FILE) end def osrm_down diff --git a/routed.cpp b/routed.cpp index de6ad1472..6eb97b94a 100644 --- a/routed.cpp +++ b/routed.cpp @@ -23,9 +23,10 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "Server/ServerFactory.h" -#include "Util/IniFile.h" +#include "Util/GitDescription.h" #include "Util/InputFileUtil.h" #include "Util/OpenMPWrapper.h" +#include "Util/ProgramOptions.h" #include "Util/SimpleLogger.h" #include "Util/UUID.h" @@ -73,8 +74,140 @@ int main (int argc, char * argv[]) { installCrashHandler(argv[0]); #endif + + boost::unordered_map paths; + std::string ip_address; + int ip_port, requested_num_threads; + + // declare a group of options that will be allowed only on command line + boost::program_options::options_description generic_options("Options"); + generic_options.add_options() + ("version,v", "Show version") + ("help,h", "Show this help message") + ("config,c", boost::program_options::value(&paths["config"])->default_value("server.ini"), + "Path to a configuration file."); + + // declare a group of options that will be allowed both on command line and in config file + boost::program_options::options_description config_options("Configuration"); + config_options.add_options() + ("hsgr", boost::program_options::value(&paths["hsgr"]), + "HSGR file") + ("nodes", boost::program_options::value(&paths["nodes"]), + "Nodes file") + ("edges", boost::program_options::value(&paths["edges"]), + "Edges file") + ("ram-index", boost::program_options::value(&paths["ramIndex"]), + "RAM index file") + ("file-index", boost::program_options::value(&paths["fileIndex"]), + "File index file") + ("names", boost::program_options::value(&paths["names"]), + "Names file") + ("timestamp", boost::program_options::value(&paths["timestamp"]), + "Timestamp file") + ("ip,i", boost::program_options::value(&ip_address)->default_value("0.0.0.0"), + "IP address") + ("port,p", boost::program_options::value(&ip_port)->default_value(5000), + "IP Port") + ("threads,t", boost::program_options::value(&requested_num_threads)->default_value(10), + "Number of threads to use"); + + // hidden options, will be allowed both on command line and in config file, but will not be shown to the user + boost::program_options::options_description hidden_options("Hidden options"); + hidden_options.add_options() + ("input,i", boost::program_options::value(&paths["input"]), + "Input file in .osrm format"); + + // positional option + boost::program_options::positional_options_description positional_options; + positional_options.add("input", 1); + + // combine above options for parsing + boost::program_options::options_description cmdline_options; + cmdline_options.add(generic_options).add(config_options).add(hidden_options); + + boost::program_options::options_description config_file_options; + config_file_options.add(config_options).add(hidden_options); + + boost::program_options::options_description visible_options(boost::filesystem::basename(argv[0]) + " []"); + visible_options.add(generic_options).add(config_options); + + // parse command line options + boost::program_options::variables_map option_variables; + boost::program_options::store(boost::program_options::command_line_parser(argc, argv). + options(cmdline_options).positional(positional_options).run(), option_variables); + + if(option_variables.count("version")) { + SimpleLogger().Write() << g_GIT_DESCRIPTION; + return 0; + } + + if(option_variables.count("help")) { + SimpleLogger().Write() << visible_options; + return 0; + } + + boost::program_options::notify(option_variables); + + // parse config file + if(boost::filesystem::is_regular_file(paths["config"])) { + std::ifstream ifs(paths["config"].c_str()); + SimpleLogger().Write() << "Reading options from: " << paths["config"].c_str(); + boost::program_options::store(parse_config_file(ifs, config_file_options), option_variables); + boost::program_options::notify(option_variables); + } + + if(!option_variables.count("hsgr")) { + paths["hsgr"] = std::string( paths["input"].c_str()) + ".hsgr"; + } + + if(!option_variables.count("nodes")) { + paths["nodes"] = std::string( paths["input"].c_str()) + ".nodes"; + } + + if(!option_variables.count("edges")) { + paths["edges"] = std::string( paths["input"].c_str()) + ".edges"; + } + + if(!option_variables.count("ram")) { + paths["ramIndex"] = std::string( paths["input"].c_str()) + ".ramIndex"; + } + + if(!option_variables.count("index")) { + paths["fileIndex"] = std::string( paths["input"].c_str()) + ".fileIndex"; + } + + if(!option_variables.count("names")) { + paths["names"] = std::string( paths["input"].c_str()) + ".names"; + } + + if(!option_variables.count("timestamp")) { + paths["timestamp"] = std::string( paths["input"].c_str()) + ".timestamp"; + } + + if(!option_variables.count("input")) { + SimpleLogger().Write(logWARNING) << "No input file specified"; + return -1; + } + + if(1 > requested_num_threads) { + SimpleLogger().Write(logWARNING) << "Number of threads must be 1 or larger"; + return -1; + } + SimpleLogger().Write() << - "starting up engines, compiled at " << __DATE__ << ", " __TIME__; + "starting up engines, " << g_GIT_DESCRIPTION << ", compiled at " << __DATE__ << ", " __TIME__; + + SimpleLogger().Write() << "Input file:\t" << paths["input"].c_str(); + SimpleLogger().Write() << "HSGR file:\t" << paths["hsgr"].c_str(); + SimpleLogger().Write() << "Nodes file:\t" << paths["nodes"].c_str(); + SimpleLogger().Write() << "Edges file:\t" << paths["edges"].c_str(); + SimpleLogger().Write() << "RAM file:\t" << paths["ramIndex"].c_str(); + SimpleLogger().Write() << "Index file:\t" << paths["fileIndex"].c_str(); + SimpleLogger().Write() << "Names file:\t" << paths["names"].c_str(); + SimpleLogger().Write() << "Timestamp file:\t" << paths["timestamp"].c_str(); + SimpleLogger().Write() << "Threads:\t" << requested_num_threads; + SimpleLogger().Write() << "IP address:\t" << ip_address; + SimpleLogger().Write() << "IP port:\t" << ip_port; #ifndef _WIN32 int sig = 0; @@ -84,10 +217,8 @@ int main (int argc, char * argv[]) { pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask); #endif - IniFile serverConfig((argc > 1 ? argv[1] : "server.ini")); - OSRM routing_machine((argc > 1 ? argv[1] : "server.ini")); - - Server * s = ServerFactory::CreateServer(serverConfig); + OSRM routing_machine(paths); + Server * s = ServerFactory::CreateServer(ip_address,ip_port,requested_num_threads); s->GetRequestHandlerPtr().RegisterRoutingMachine(&routing_machine); boost::thread t(boost::bind(&Server::Run, s)); diff --git a/server.ini b/server.ini deleted file mode 100644 index e8138257e..000000000 --- a/server.ini +++ /dev/null @@ -1,11 +0,0 @@ -Threads = 8 -IP = 0.0.0.0 -Port = 5000 - -hsgrData=/Users/dennisluxen/Downloads/berlin-latest.osrm.hsgr -nodesData=/Users/dennisluxen/Downloads/berlin-latest.osrm.nodes -edgesData=/Users/dennisluxen/Downloads/berlin-latest.osrm.edges -ramIndex=/Users/dennisluxen/Downloads/berlin-latest.osrm.ramIndex -fileIndex=/Users/dennisluxen/Downloads/berlin-latest.osrm.fileIndex -namesData=/Users/dennisluxen/Downloads/berlin-latest.osrm.names -timestamp=/Users/dennisluxen/Downloads/berlin-latest.osrm.timestamp diff --git a/test/contractor.ini b/test/contractor.ini deleted file mode 100644 index 4da33c7ef..000000000 --- a/test/contractor.ini +++ /dev/null @@ -1 +0,0 @@ -Threads = 4