Added weight multipliers for speed and turn updates

This commit is contained in:
Michael Krasnyk 2017-01-17 09:24:52 +01:00 committed by Patrick Niklaus
parent 279f8aabfb
commit c059d15cb9
12 changed files with 117 additions and 124 deletions

View File

@ -51,12 +51,12 @@ Feature: Traffic - speeds
Given the contract extra arguments "--segment-speed-file {speeds_file}" Given the contract extra arguments "--segment-speed-file {speeds_file}"
Given the speed file Given the speed file
""" """
1,2,1,200207 1,2,1,20020.7
2,1,1,200207 2,1,1,20020.7
2,3,27,7415 2,3,27,741.5
3,2,27,7415 3,2,27,741.5
1,4,27,12757 1,4,27,1275.7
4,1,27,12757 4,1,27,1275.7
""" """
And I route I should get And I route I should get
| from | to | route | speed | weights | | from | to | route | speed | weights |
@ -70,25 +70,33 @@ Feature: Traffic - speeds
Scenario: Weighting based on speed file weights, ETA based on file durations Scenario: Weighting based on speed file weights, ETA based on file durations
Given the contract extra arguments "--segment-speed-file {speeds_file}" Given the profile file "testbot" extended with
"""
api_version = 1
properties.traffic_signal_penalty = 0
properties.u_turn_penalty = 0
properties.weight_precision = 3
"""
And the contract extra arguments "--segment-speed-file {speeds_file}"
Given the speed file Given the speed file
""" """
1,2,1,200207 1,2,1,20020.789
2,1,1,200207 2,1,1,20020.123
2,3,27,7415 2,3,27,741.56789
3,2,27,7415 3,2,27,741.3
1,4,1,344450 1,4,1,34445.12
4,1,1,344450 4,1,1,34445.3
""" """
And I route I should get And I route I should get
| from | to | route | speed | weights | | from | to | route | speed | weights |
| a | b | ab,ab | 1 km/h | 20020.7,0 | | a | b | ab,ab | 1 km/h | 20020.789,0 |
| a | c | ab,bc,bc | 2 km/h | 20020.7,741.5,0 | | a | c | ab,bc,bc | 2 km/h | 20020.789,741.568,0 |
| b | c | bc,bc | 27 km/h | 741.5,0 | | b | c | bc,bc | 27 km/h | 741.568,0 |
| a | d | ab,eb,de,de | 2 km/h | 20020.7,378.2,400.4,0 | | a | d | ab,eb,de,de | 2 km/h | 20020.789,378.169,400.415,0 |
| d | c | dc,dc | 36 km/h | 956.8,0 | | d | c | dc,dc | 36 km/h | 956.805,0 |
| g | b | ab,ab | 1 km/h | 10010.4,0 | | g | b | ab,ab | 1 km/h | 10010.392,0 |
| a | g | ab,ab | 1 km/h | 10010.3,0 | | a | g | ab,ab | 1 km/h | 10010.397,0 |
| g | a | ab,ab | 1 km/h | 10010.064,0 |
Scenario: Speeds that isolate a single node (a) Scenario: Speeds that isolate a single node (a)

View File

@ -78,21 +78,9 @@ class Contractor
private: private:
ContractorConfig config; ContractorConfig config;
EdgeID LoadEdgeExpandedGraph(const std::string &edge_based_graph_path, EdgeID LoadEdgeExpandedGraph(const ContractorConfig &config,
std::vector<extractor::EdgeBasedEdge> &edge_based_edge_list, std::vector<extractor::EdgeBasedEdge> &edge_based_edge_list,
std::vector<EdgeWeight> &node_weights, std::vector<EdgeWeight> &node_weights);
const std::string &edge_segment_lookup_path,
const std::string &turn_weight_penalties_path,
const std::string &turn_duration_penalties_path,
const std::string &turn_penalties_index_path,
const std::vector<std::string> &segment_speed_path,
const std::vector<std::string> &turn_penalty_path,
const std::string &nodes_filename,
const std::string &geometry_filename,
const std::string &datasource_names_filename,
const std::string &datasource_indexes_filename,
const std::string &rtree_leaf_filename,
const double log_edge_updates_factor);
}; };
} }
} }

View File

@ -39,7 +39,7 @@ namespace contractor
struct ContractorConfig struct ContractorConfig
{ {
ContractorConfig() : requested_num_threads(0) {} ContractorConfig() : requested_num_threads(0), weight_multiplier(10.) {}
// Infer the output names from the path of the .osrm file // Infer the output names from the path of the .osrm file
void UseDefaultOutputNames() void UseDefaultOutputNames()
@ -57,6 +57,7 @@ struct ContractorConfig
rtree_leaf_path = osrm_input_path.string() + ".fileIndex"; rtree_leaf_path = osrm_input_path.string() + ".fileIndex";
datasource_names_path = osrm_input_path.string() + ".datasource_names"; datasource_names_path = osrm_input_path.string() + ".datasource_names";
datasource_indexes_path = osrm_input_path.string() + ".datasource_indexes"; datasource_indexes_path = osrm_input_path.string() + ".datasource_indexes";
profile_properties_path = osrm_input_path.string() + ".properties";
} }
boost::filesystem::path config_file_path; boost::filesystem::path config_file_path;
@ -78,6 +79,7 @@ struct ContractorConfig
unsigned requested_num_threads; unsigned requested_num_threads;
double log_edge_updates_factor; double log_edge_updates_factor;
double weight_multiplier;
// A percentage of vertices that will be contracted for the hierarchy. // A percentage of vertices that will be contracted for the hierarchy.
// Offers a trade-off between preprocessing and query time. // Offers a trade-off between preprocessing and query time.
@ -89,6 +91,7 @@ struct ContractorConfig
std::vector<std::string> turn_penalty_lookup_paths; std::vector<std::string> turn_penalty_lookup_paths;
std::string datasource_indexes_path; std::string datasource_indexes_path;
std::string datasource_names_path; std::string datasource_names_path;
std::string profile_properties_path;
}; };
} }
} }

View File

@ -996,6 +996,11 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
return m_profile_properties->weight_precision; return m_profile_properties->weight_precision;
} }
double GetWeightMultiplier() const override final
{
return m_profile_properties->GetWeightMultiplier();
}
BearingClassID GetBearingClassID(const NodeID id) const override final BearingClassID GetBearingClassID(const NodeID id) const override final
{ {
return m_bearing_class_id_table.at(id); return m_bearing_class_id_table.at(id);

View File

@ -189,6 +189,8 @@ class BaseDataFacade
virtual unsigned GetWeightPrecision() const = 0; virtual unsigned GetWeightPrecision() const = 0;
virtual double GetWeightMultiplier() const = 0;
virtual BearingClassID GetBearingClassID(const NodeID id) const = 0; virtual BearingClassID GetBearingClassID(const NodeID id) const = 0;
virtual util::guidance::TurnBearing PreTurnBearing(const EdgeID eid) const = 0; virtual util::guidance::TurnBearing PreTurnBearing(const EdgeID eid) const = 0;

View File

@ -41,7 +41,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
const bool source_traversed_in_reverse, const bool source_traversed_in_reverse,
const bool target_traversed_in_reverse) const bool target_traversed_in_reverse)
{ {
const double weight_multiplier = std::pow(10., facade.GetWeightPrecision()); const double weight_multiplier = facade.GetWeightMultiplier();
const double constexpr ZERO_DURATION = 0., ZERO_DISTANCE = 0., ZERO_WEIGHT = 0; const double constexpr ZERO_DURATION = 0., ZERO_DISTANCE = 0., ZERO_WEIGHT = 0;
const constexpr char *NO_ROTARY_NAME = ""; const constexpr char *NO_ROTARY_NAME = "";

View File

@ -67,6 +67,8 @@ struct ProfileProperties
return std::string(weight_name); return std::string(weight_name);
} }
double GetWeightMultiplier() const { return std::pow(10., weight_precision); }
//! penalty to cross a traffic light in deci-seconds //! penalty to cross a traffic light in deci-seconds
std::int32_t traffic_signal_penalty; std::int32_t traffic_signal_penalty;
//! penalty to do a uturn in deci-seconds //! penalty to do a uturn in deci-seconds

View File

@ -74,9 +74,9 @@ struct Segment final
struct SpeedSource final struct SpeedSource final
{ {
SpeedSource() : speed(0), weight(INVALID_EDGE_WEIGHT) {} SpeedSource() : speed(0), weight(std::numeric_limits<double>::quiet_NaN()) {}
unsigned speed; unsigned speed;
EdgeWeight weight; double weight;
std::uint8_t source; std::uint8_t source;
}; };
@ -245,41 +245,42 @@ template <typename Key, typename Value> struct CSVFilesParser
// Returns duration in deci-seconds // Returns duration in deci-seconds
inline EdgeWeight ConvertToDuration(double distance_in_meters, double speed_in_kmh) inline EdgeWeight ConvertToDuration(double distance_in_meters, double speed_in_kmh)
{ {
BOOST_ASSERT(speed_in_kmh > 0); if (speed_in_kmh <= 0.)
return INVALID_EDGE_WEIGHT;
const double speed_in_ms = speed_in_kmh / 3.6; const double speed_in_ms = speed_in_kmh / 3.6;
const double duration = distance_in_meters / speed_in_ms; const double duration = distance_in_meters / speed_in_ms;
return std::max<EdgeWeight>(1, static_cast<EdgeWeight>(std::round(duration * 10.))); return std::max<EdgeWeight>(1, static_cast<EdgeWeight>(std::round(duration * 10.)));
} }
// Returns updated edge weight // Returns updated edge weight
void GetNewWeight(const SpeedSource &value, void GetNewWeight(const ContractorConfig &config,
const SpeedSource &value,
const double &segment_length, const double &segment_length,
const std::vector<std::string> &segment_speed_filenames,
const EdgeWeight current_duration, const EdgeWeight current_duration,
const double log_edge_updates_factor,
const OSMNodeID from, const OSMNodeID from,
const OSMNodeID to, const OSMNodeID to,
EdgeWeight &new_segment_weight, EdgeWeight &new_segment_weight,
EdgeWeight &new_segment_duration) EdgeWeight &new_segment_duration)
{ {
// Update the edge duration as distance/speed // Update the edge duration as distance/speed
new_segment_duration = new_segment_duration = ConvertToDuration(segment_length, value.speed);
(value.speed > 0) ? ConvertToDuration(segment_length, value.speed) : INVALID_EDGE_WEIGHT;
// Update the edge weight or fallback to the new edge duration // Update the edge weight or fallback to the new edge duration
new_segment_weight = new_segment_weight = std::isfinite(value.weight)
(value.weight == INVALID_EDGE_WEIGHT) ? new_segment_duration : value.weight; ? std::round(value.weight * config.weight_multiplier)
: new_segment_duration;
// The check here is enabled by the `--edge-weight-updates-over-factor` flag it logs a warning // The check here is enabled by the `--edge-weight-updates-over-factor` flag it logs a warning
// if the new duration exceeds a heuristic of what a reasonable duration update is // if the new duration exceeds a heuristic of what a reasonable duration update is
if (log_edge_updates_factor > 0 && current_duration != 0) if (config.log_edge_updates_factor > 0 && current_duration != 0)
{ {
if (current_duration >= (new_segment_duration * log_edge_updates_factor)) if (current_duration >= (new_segment_duration * config.log_edge_updates_factor))
{ {
auto new_secs = new_segment_duration / 10.; auto new_secs = new_segment_duration / 10.;
auto old_secs = current_duration / 10.; auto old_secs = current_duration / 10.;
auto approx_original_speed = (segment_length / old_secs) * 3.6; auto approx_original_speed = (segment_length / old_secs) * 3.6;
auto speed_file = segment_speed_filenames.at(value.source - 1); auto speed_file = config.segment_speed_lookup_paths.at(value.source - 1);
util::Log(logWARNING) << "[weight updates] Edge weight update from " << old_secs util::Log(logWARNING) << "[weight updates] Edge weight update from " << old_secs
<< "s to " << new_secs << "s New speed: " << value.speed << "s to " << new_secs << "s New speed: " << value.speed
<< " kph" << " kph"
@ -315,21 +316,7 @@ int Contractor::Run()
std::vector<extractor::EdgeBasedEdge> edge_based_edge_list; std::vector<extractor::EdgeBasedEdge> edge_based_edge_list;
EdgeID max_edge_id = LoadEdgeExpandedGraph(config.edge_based_graph_path, EdgeID max_edge_id = LoadEdgeExpandedGraph(config, edge_based_edge_list, node_weights);
edge_based_edge_list,
node_weights,
config.edge_segment_lookup_path,
config.turn_weight_penalties_path,
config.turn_duration_penalties_path,
config.turn_penalties_index_path,
config.segment_speed_lookup_paths,
config.turn_penalty_lookup_paths,
config.node_based_graph_path,
config.geometry_path,
config.datasource_names_path,
config.datasource_indexes_path,
config.rtree_leaf_path,
config.log_edge_updates_factor);
// Contracting the edge-expanded graph // Contracting the edge-expanded graph
@ -380,27 +367,15 @@ int Contractor::Run()
} }
EdgeID EdgeID
Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename, Contractor::LoadEdgeExpandedGraph(const ContractorConfig &config,
std::vector<extractor::EdgeBasedEdge> &edge_based_edge_list, std::vector<extractor::EdgeBasedEdge> &edge_based_edge_list,
std::vector<EdgeWeight> &node_weights, std::vector<EdgeWeight> &node_weights)
const std::string &edge_segment_lookup_filename,
const std::string &turn_weight_penalties_filename,
const std::string &turn_duration_penalties_filename,
const std::string &turn_penalties_index_filename,
const std::vector<std::string> &segment_speed_filenames,
const std::vector<std::string> &turn_penalty_filenames,
const std::string &nodes_filename,
const std::string &geometry_filename,
const std::string &datasource_names_filename,
const std::string &datasource_indexes_filename,
const std::string &rtree_leaf_filename,
const double log_edge_updates_factor)
{ {
if (segment_speed_filenames.size() > 255 || turn_penalty_filenames.size() > 255) if (config.segment_speed_lookup_paths.size() + config.turn_penalty_lookup_paths.size() > 255)
throw util::exception("Limit of 255 segment speed and turn penalty files each reached" + throw util::exception("Limit of 255 segment speed and turn penalty files each reached" +
SOURCE_REF); SOURCE_REF);
util::Log() << "Opening " << edge_based_graph_filename; util::Log() << "Opening " << config.edge_based_graph_path;
auto mmap_file = [](const std::string &filename, boost::interprocess::mode_t mode) { auto mmap_file = [](const std::string &filename, boost::interprocess::mode_t mode) {
using boost::interprocess::file_mapping; using boost::interprocess::file_mapping;
@ -421,15 +396,15 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
}; };
const auto edge_based_graph_region = const auto edge_based_graph_region =
mmap_file(edge_based_graph_filename, boost::interprocess::read_only); mmap_file(config.edge_based_graph_path, boost::interprocess::read_only);
const bool update_edge_weights = !segment_speed_filenames.empty(); const bool update_edge_weights = !config.segment_speed_lookup_paths.empty();
const bool update_turn_penalties = !turn_penalty_filenames.empty(); const bool update_turn_penalties = !config.turn_penalty_lookup_paths.empty();
const auto turn_penalties_index_region = [&] { const auto turn_penalties_index_region = [&] {
if (update_edge_weights || update_turn_penalties) if (update_edge_weights || update_turn_penalties)
{ {
return mmap_file(turn_penalties_index_filename, boost::interprocess::read_only); return mmap_file(config.turn_penalties_index_path, boost::interprocess::read_only);
} }
return boost::interprocess::mapped_region(); return boost::interprocess::mapped_region();
}(); }();
@ -437,7 +412,7 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
const auto edge_segment_region = [&] { const auto edge_segment_region = [&] {
if (update_edge_weights || update_turn_penalties) if (update_edge_weights || update_turn_penalties)
{ {
return mmap_file(edge_segment_lookup_filename, boost::interprocess::read_only); return mmap_file(config.edge_segment_lookup_path, boost::interprocess::read_only);
} }
return boost::interprocess::mapped_region(); return boost::interprocess::mapped_region();
}(); }();
@ -462,13 +437,13 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
const util::FingerPrint expected_fingerprint = util::FingerPrint::GetValid(); const util::FingerPrint expected_fingerprint = util::FingerPrint::GetValid();
if (!graph_header.fingerprint.IsValid()) if (!graph_header.fingerprint.IsValid())
{ {
util::Log(logERROR) << edge_based_graph_filename << " does not have a valid fingerprint"; util::Log(logERROR) << config.edge_based_graph_path << " does not have a valid fingerprint";
throw util::exception("Invalid fingerprint"); throw util::exception("Invalid fingerprint");
} }
if (!expected_fingerprint.IsDataCompatible(graph_header.fingerprint)) if (!expected_fingerprint.IsDataCompatible(graph_header.fingerprint))
{ {
util::Log(logERROR) << edge_based_graph_filename util::Log(logERROR) << config.edge_based_graph_path
<< " is not compatible with this version of OSRM."; << " is not compatible with this version of OSRM.";
util::Log(logERROR) << "It was prepared with OSRM " util::Log(logERROR) << "It was prepared with OSRM "
<< graph_header.fingerprint.GetMajorVersion() << "." << graph_header.fingerprint.GetMajorVersion() << "."
@ -483,13 +458,13 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
util::Log() << "Reading " << graph_header.number_of_edges << " edges from the edge based graph"; util::Log() << "Reading " << graph_header.number_of_edges << " edges from the edge based graph";
auto segment_speed_lookup = CSVFilesParser<Segment, SpeedSource>( auto segment_speed_lookup = CSVFilesParser<Segment, SpeedSource>(
1, qi::ulong_long >> ',' >> qi::ulong_long, qi::uint_ >> -(',' >> qi::uint_))( 1, qi::ulong_long >> ',' >> qi::ulong_long, qi::uint_ >> -(',' >> qi::double_))(
segment_speed_filenames); config.segment_speed_lookup_paths);
auto turn_penalty_lookup = CSVFilesParser<Turn, PenaltySource>( auto turn_penalty_lookup = CSVFilesParser<Turn, PenaltySource>(
1 + segment_speed_filenames.size(), 1 + config.segment_speed_lookup_paths.size(),
qi::ulong_long >> ',' >> qi::ulong_long >> ',' >> qi::ulong_long, qi::ulong_long >> ',' >> qi::ulong_long >> ',' >> qi::ulong_long,
qi::double_ >> -(',' >> qi::double_))(turn_penalty_filenames); qi::double_ >> -(',' >> qi::double_))(config.turn_penalty_lookup_paths);
// If we update the edge weights, this file will hold the datasource information for each // If we update the edge weights, this file will hold the datasource information for each
// segment; the other files will also be conditionally filled concurrently if we make an update // segment; the other files will also be conditionally filled concurrently if we make an update
@ -507,18 +482,17 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
if (!update_edge_weights) if (!update_edge_weights)
return; return;
storage::io::FileReader nodes_file(nodes_filename, storage::io::FileReader nodes_file(config.node_based_graph_path,
storage::io::FileReader::HasNoFingerprint); storage::io::FileReader::HasNoFingerprint);
nodes_file.DeserializeVector(internal_to_external_node_map); nodes_file.DeserializeVector(internal_to_external_node_map);
}; };
const auto maybe_load_geometries = [&] { const auto maybe_load_geometries = [&] {
if (!update_edge_weights) if (!update_edge_weights)
return; return;
storage::io::FileReader geometry_file(geometry_filename, storage::io::FileReader geometry_file(config.geometry_path,
storage::io::FileReader::HasNoFingerprint); storage::io::FileReader::HasNoFingerprint);
const auto number_of_indices = geometry_file.ReadElementCount32(); const auto number_of_indices = geometry_file.ReadElementCount32();
geometry_indices.resize(number_of_indices); geometry_indices.resize(number_of_indices);
@ -570,7 +544,7 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
using boost::interprocess::mapped_region; using boost::interprocess::mapped_region;
auto region = mmap_file(rtree_leaf_filename.c_str(), boost::interprocess::read_only); auto region = mmap_file(config.rtree_leaf_path.c_str(), boost::interprocess::read_only);
region.advise(mapped_region::advice_willneed); region.advise(mapped_region::advice_willneed);
BOOST_ASSERT(is_aligned<LeafNode>(region.get_address())); BOOST_ASSERT(is_aligned<LeafNode>(region.get_address()));
@ -581,7 +555,7 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
// vector to count used speeds for logging // vector to count used speeds for logging
// size offset by one since index 0 is used for speeds not from external file // size offset by one since index 0 is used for speeds not from external file
using counters_type = std::vector<std::size_t>; using counters_type = std::vector<std::size_t>;
std::size_t num_counters = segment_speed_filenames.size() + 1; std::size_t num_counters = config.segment_speed_lookup_paths.size() + 1;
tbb::enumerable_thread_specific<counters_type> segment_speeds_counters( tbb::enumerable_thread_specific<counters_type> segment_speeds_counters(
counters_type(num_counters, 0)); counters_type(num_counters, 0));
const constexpr auto LUA_SOURCE = 0; const constexpr auto LUA_SOURCE = 0;
@ -608,11 +582,10 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
if (auto value = segment_speed_lookup({u.node_id, v.node_id})) if (auto value = segment_speed_lookup({u.node_id, v.node_id}))
{ {
EdgeWeight new_segment_weight, new_segment_duration; EdgeWeight new_segment_weight, new_segment_duration;
GetNewWeight(*value, GetNewWeight(config,
*value,
segment_length, segment_length,
segment_speed_filenames,
geometry_fwd_duration_list[u_index], geometry_fwd_duration_list[u_index],
log_edge_updates_factor,
u.node_id, u.node_id,
v.node_id, v.node_id,
new_segment_weight, new_segment_weight,
@ -627,11 +600,10 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
if (auto value = segment_speed_lookup({v.node_id, u.node_id})) if (auto value = segment_speed_lookup({v.node_id, u.node_id}))
{ {
EdgeWeight new_segment_weight, new_segment_duration; EdgeWeight new_segment_weight, new_segment_duration;
GetNewWeight(*value, GetNewWeight(config,
*value,
segment_length, segment_length,
segment_speed_filenames,
geometry_rev_duration_list[u_index], geometry_rev_duration_list[u_index],
log_edge_updates_factor,
v.node_id, v.node_id,
u.node_id, u.node_id,
new_segment_weight, new_segment_weight,
@ -670,7 +642,7 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
// segments_speeds_counters has 0 as LUA, segment_speed_filenames not, thus we need // segments_speeds_counters has 0 as LUA, segment_speed_filenames not, thus we need
// to susbstract 1 to avoid off-by-one error // to susbstract 1 to avoid off-by-one error
util::Log() << "Used " << merged_counters[i] << " speeds from " util::Log() << "Used " << merged_counters[i] << " speeds from "
<< segment_speed_filenames[i - 1]; << config.segment_speed_lookup_paths[i - 1];
} }
} }
} }
@ -680,10 +652,10 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
return; return;
// Now save out the updated compressed geometries // Now save out the updated compressed geometries
std::ofstream geometry_stream(geometry_filename, std::ios::binary); std::ofstream geometry_stream(config.geometry_path, std::ios::binary);
if (!geometry_stream) if (!geometry_stream)
{ {
const std::string message{"Failed to open " + geometry_filename + " for writing"}; const std::string message{"Failed to open " + config.geometry_path + " for writing"};
throw util::exception(message + SOURCE_REF); throw util::exception(message + SOURCE_REF);
} }
const unsigned number_of_indices = geometry_indices.size(); const unsigned number_of_indices = geometry_indices.size();
@ -706,10 +678,10 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
}; };
const auto save_datasource_indexes = [&] { const auto save_datasource_indexes = [&] {
std::ofstream datasource_stream(datasource_indexes_filename, std::ios::binary); std::ofstream datasource_stream(config.datasource_indexes_path, std::ios::binary);
if (!datasource_stream) if (!datasource_stream)
{ {
const std::string message{"Failed to open " + datasource_indexes_filename + const std::string message{"Failed to open " + config.datasource_indexes_path +
" for writing"}; " for writing"};
throw util::exception(message + SOURCE_REF); throw util::exception(message + SOURCE_REF);
} }
@ -724,10 +696,10 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
}; };
const auto save_datastore_names = [&] { const auto save_datastore_names = [&] {
std::ofstream datasource_stream(datasource_names_filename, std::ios::binary); std::ofstream datasource_stream(config.datasource_names_path, std::ios::binary);
if (!datasource_stream) if (!datasource_stream)
{ {
const std::string message{"Failed to open " + datasource_names_filename + const std::string message{"Failed to open " + config.datasource_names_path +
" for writing"}; " for writing"};
throw util::exception(message + SOURCE_REF); throw util::exception(message + SOURCE_REF);
} }
@ -736,7 +708,7 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
// Only write the filename, without path or extension. // Only write the filename, without path or extension.
// This prevents information leakage, and keeps names short // This prevents information leakage, and keeps names short
// for rendering in the debug tiles. // for rendering in the debug tiles.
for (auto const &name : segment_speed_filenames) for (auto const &name : config.segment_speed_lookup_paths)
{ {
datasource_stream << boost::filesystem::path(name).stem().string() << std::endl; datasource_stream << boost::filesystem::path(name).stem().string() << std::endl;
} }
@ -751,7 +723,7 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
if (!update_edge_weights && !update_turn_penalties) if (!update_edge_weights && !update_turn_penalties)
return; return;
using storage::io::FileReader; using storage::io::FileReader;
FileReader file(turn_weight_penalties_filename, FileReader::HasNoFingerprint); FileReader file(config.turn_weight_penalties_path, FileReader::HasNoFingerprint);
file.DeserializeVector(turn_weight_penalties); file.DeserializeVector(turn_weight_penalties);
}; };
@ -759,7 +731,7 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
if (!update_turn_penalties) if (!update_turn_penalties)
return; return;
using storage::io::FileReader; using storage::io::FileReader;
FileReader file(turn_duration_penalties_filename, FileReader::HasNoFingerprint); FileReader file(config.turn_duration_penalties_path, FileReader::HasNoFingerprint);
file.DeserializeVector(turn_duration_penalties); file.DeserializeVector(turn_duration_penalties);
}; };
@ -818,9 +790,9 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
return true; return true;
segment_weight = segment_weight =
value->weight == INVALID_EDGE_WEIGHT std::isfinite(value->weight)
? ConvertToDuration(segment.segment_length, value->speed) ? std::round(value->weight * config.weight_multiplier)
: value->weight; : ConvertToDuration(segment.segment_length, value->speed);
} }
// Update the edge weight and the next OSM node ID // Update the edge weight and the next OSM node ID
@ -846,10 +818,10 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
{ {
auto turn_duration_penalty = auto turn_duration_penalty =
boost::numeric_cast<TurnPenalty>(std::round(value->duration * 10.)); boost::numeric_cast<TurnPenalty>(std::round(value->duration * 10.));
turn_weight_penalty = turn_weight_penalty = std::isfinite(value->weight)
std::isfinite(value->weight) ? boost::numeric_cast<TurnPenalty>(std::round(
? boost::numeric_cast<TurnPenalty>(std::round(value->weight * 10)) value->weight * config.weight_multiplier))
: turn_duration_penalty; : turn_duration_penalty;
const auto weight_min_value = static_cast<EdgeWeight>(header->num_osm_nodes); const auto weight_min_value = static_cast<EdgeWeight>(header->num_osm_nodes);
if (turn_weight_penalty + new_weight < weight_min_value) if (turn_weight_penalty + new_weight < weight_min_value)
@ -891,8 +863,8 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
}; };
tbb::parallel_invoke( tbb::parallel_invoke(
[&] { save_penalties(turn_weight_penalties_filename, turn_weight_penalties); }, [&] { save_penalties(config.turn_weight_penalties_path, turn_weight_penalties); },
[&] { save_penalties(turn_duration_penalties_filename, turn_duration_penalties); }); [&] { save_penalties(config.turn_duration_penalties_path, turn_duration_penalties); });
} }
util::Log() << "Done reading edges"; util::Log() << "Done reading edges";

View File

@ -371,7 +371,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
std::vector<TurnPenalty> turn_duration_penalties; std::vector<TurnPenalty> turn_duration_penalties;
const auto weight_multiplier = const auto weight_multiplier =
std::pow(10, scripting_environment.GetProfileProperties().weight_precision); scripting_environment.GetProfileProperties().GetWeightMultiplier();
{ {
util::UnbufferedLog log; util::UnbufferedLog log;

View File

@ -392,7 +392,7 @@ void ExtractionContainers::PrepareEdges(ScriptingEnvironment &scripting_environm
const auto all_nodes_list_end_ = all_nodes_list.end(); const auto all_nodes_list_end_ = all_nodes_list.end();
const auto weight_multiplier = const auto weight_multiplier =
std::pow(10, scripting_environment.GetProfileProperties().weight_precision); scripting_environment.GetProfileProperties().GetWeightMultiplier();
while (edge_iterator != all_edges_list_end_ && node_iterator != all_nodes_list_end_) while (edge_iterator != all_edges_list_end_ && node_iterator != all_nodes_list_end_)
{ {

View File

@ -1,5 +1,7 @@
#include "contractor/contractor.hpp" #include "contractor/contractor.hpp"
#include "contractor/contractor_config.hpp" #include "contractor/contractor_config.hpp"
#include "extractor/profile_properties.hpp"
#include "storage/io.hpp"
#include "util/log.hpp" #include "util/log.hpp"
#include "util/version.hpp" #include "util/version.hpp"
@ -162,6 +164,16 @@ int main(int argc, char *argv[]) try
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (boost::filesystem::is_regular_file(contractor_config.osrm_input_path))
{
// Propagate profile properties to contractor configuration structure
extractor::ProfileProperties profile_properties;
storage::io::FileReader profile_properties_file(contractor_config.profile_properties_path,
storage::io::FileReader::HasNoFingerprint);
profile_properties_file.ReadInto<extractor::ProfileProperties>(&profile_properties, 1);
contractor_config.weight_multiplier = profile_properties.GetWeightMultiplier();
}
util::Log() << "Input file: " << contractor_config.osrm_input_path.filename().string(); util::Log() << "Input file: " << contractor_config.osrm_input_path.filename().string();
util::Log() << "Threads: " << contractor_config.requested_num_threads; util::Log() << "Threads: " << contractor_config.requested_num_threads;

View File

@ -226,6 +226,7 @@ class MockDataFacade final : public engine::datafacade::BaseDataFacade
double GetMapMatchingMaxSpeed() const override { return 180 / 3.6; } double GetMapMatchingMaxSpeed() const override { return 180 / 3.6; }
const char *GetWeightName() const override final { return "duration"; } const char *GetWeightName() const override final { return "duration"; }
unsigned GetWeightPrecision() const override final { return 1; } unsigned GetWeightPrecision() const override final { return 1; }
double GetWeightMultiplier() const override final { return 10.; }
BearingClassID GetBearingClassID(const NodeID /*id*/) const override { return 0; } BearingClassID GetBearingClassID(const NodeID /*id*/) const override { return 0; }
EntryClassID GetEntryClassID(const EdgeID /*id*/) const override { return 0; } EntryClassID GetEntryClassID(const EdgeID /*id*/) const override { return 0; }