Allow specifing a weight for routing that is independent of duration
This commit is contained in:
committed by
Patrick Niklaus
parent
e463733138
commit
279f8aabfb
+172
-80
@@ -74,7 +74,9 @@ struct Segment final
|
||||
|
||||
struct SpeedSource final
|
||||
{
|
||||
SpeedSource() : speed(0), weight(INVALID_EDGE_WEIGHT) {}
|
||||
unsigned speed;
|
||||
EdgeWeight weight;
|
||||
std::uint8_t source;
|
||||
};
|
||||
|
||||
@@ -86,7 +88,7 @@ struct Turn final
|
||||
: from(from), via(via), to(to)
|
||||
{
|
||||
}
|
||||
Turn(const osrm::extractor::lookup::PenaltyBlock &turn)
|
||||
Turn(const osrm::extractor::lookup::TurnIndexBlock &turn)
|
||||
: from(static_cast<std::uint64_t>(turn.from_id)),
|
||||
via(static_cast<std::uint64_t>(turn.via_id)), to(static_cast<std::uint64_t>(turn.to_id))
|
||||
{
|
||||
@@ -103,7 +105,9 @@ struct Turn final
|
||||
|
||||
struct PenaltySource final
|
||||
{
|
||||
double penalty;
|
||||
PenaltySource() : duration(0.), weight(std::numeric_limits<double>::quiet_NaN()) {}
|
||||
double duration;
|
||||
double weight;
|
||||
std::uint8_t source;
|
||||
};
|
||||
|
||||
@@ -115,11 +119,15 @@ template <typename T> inline bool is_aligned(const void *pointer)
|
||||
} // anon ns
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(Segment, (decltype(Segment::from), from)(decltype(Segment::to), to))
|
||||
BOOST_FUSION_ADAPT_STRUCT(SpeedSource, (decltype(SpeedSource::speed), speed))
|
||||
BOOST_FUSION_ADAPT_STRUCT(SpeedSource,
|
||||
(decltype(SpeedSource::speed), speed)(decltype(SpeedSource::weight),
|
||||
weight))
|
||||
BOOST_FUSION_ADAPT_STRUCT(Turn,
|
||||
(decltype(Turn::from), from)(decltype(Turn::via), via)(decltype(Turn::to),
|
||||
to))
|
||||
BOOST_FUSION_ADAPT_STRUCT(PenaltySource, (decltype(PenaltySource::penalty), penalty))
|
||||
BOOST_FUSION_ADAPT_STRUCT(PenaltySource,
|
||||
(decltype(PenaltySource::duration),
|
||||
duration)(decltype(PenaltySource::weight), weight))
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
@@ -240,29 +248,37 @@ inline EdgeWeight ConvertToDuration(double distance_in_meters, double speed_in_k
|
||||
BOOST_ASSERT(speed_in_kmh > 0);
|
||||
const double speed_in_ms = speed_in_kmh / 3.6;
|
||||
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
|
||||
EdgeWeight GetNewWeight(const SpeedSource &value,
|
||||
const double &segment_length,
|
||||
const std::vector<std::string> &segment_speed_filenames,
|
||||
const EdgeWeight old_weight,
|
||||
const double log_edge_updates_factor,
|
||||
const OSMNodeID &from,
|
||||
const OSMNodeID &to)
|
||||
void GetNewWeight(const SpeedSource &value,
|
||||
const double &segment_length,
|
||||
const std::vector<std::string> &segment_speed_filenames,
|
||||
const EdgeWeight current_duration,
|
||||
const double log_edge_updates_factor,
|
||||
const OSMNodeID from,
|
||||
const OSMNodeID to,
|
||||
EdgeWeight &new_segment_weight,
|
||||
EdgeWeight &new_segment_duration)
|
||||
{
|
||||
const auto new_segment_weight =
|
||||
// Update the edge duration as distance/speed
|
||||
new_segment_duration =
|
||||
(value.speed > 0) ? ConvertToDuration(segment_length, value.speed) : INVALID_EDGE_WEIGHT;
|
||||
// the check here is enabled by the `--edge-weight-updates-over-factor` flag it logs
|
||||
// a warning if the new weight exceeds a heuristic of what a reasonable weight update is
|
||||
if (log_edge_updates_factor > 0 && old_weight != 0)
|
||||
|
||||
// Update the edge weight or fallback to the new edge duration
|
||||
new_segment_weight =
|
||||
(value.weight == INVALID_EDGE_WEIGHT) ? new_segment_duration : value.weight;
|
||||
|
||||
// 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 (log_edge_updates_factor > 0 && current_duration != 0)
|
||||
{
|
||||
auto new_secs = new_segment_weight / 10.0;
|
||||
auto old_secs = old_weight / 10.0;
|
||||
auto approx_original_speed = (segment_length / old_secs) * 3.6;
|
||||
if (old_weight >= (new_segment_weight * log_edge_updates_factor))
|
||||
if (current_duration >= (new_segment_duration * log_edge_updates_factor))
|
||||
{
|
||||
auto new_secs = new_segment_duration / 10.;
|
||||
auto old_secs = current_duration / 10.;
|
||||
auto approx_original_speed = (segment_length / old_secs) * 3.6;
|
||||
auto speed_file = segment_speed_filenames.at(value.source - 1);
|
||||
util::Log(logWARNING) << "[weight updates] Edge weight update from " << old_secs
|
||||
<< "s to " << new_secs << "s New speed: " << value.speed
|
||||
@@ -273,21 +289,10 @@ EdgeWeight GetNewWeight(const SpeedSource &value,
|
||||
<< speed_file;
|
||||
}
|
||||
}
|
||||
|
||||
return new_segment_weight;
|
||||
}
|
||||
|
||||
int Contractor::Run()
|
||||
{
|
||||
#ifdef WIN32
|
||||
#pragma message("Memory consumption on Windows can be higher due to different bit packing")
|
||||
#else
|
||||
static_assert(sizeof(extractor::NodeBasedEdge) == 24,
|
||||
"changing extractor::NodeBasedEdge type has influence on memory consumption!");
|
||||
static_assert(sizeof(extractor::EdgeBasedEdge) == 16,
|
||||
"changing EdgeBasedEdge type has influence on memory consumption!");
|
||||
#endif
|
||||
|
||||
if (config.core_factor > 1.0 || config.core_factor < 0)
|
||||
{
|
||||
throw util::exception("Core factor must be between 0.0 to 1.0 (inclusive)" + SOURCE_REF);
|
||||
@@ -314,7 +319,9 @@ int Contractor::Run()
|
||||
edge_based_edge_list,
|
||||
node_weights,
|
||||
config.edge_segment_lookup_path,
|
||||
config.edge_penalty_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,
|
||||
@@ -377,7 +384,9 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
|
||||
std::vector<extractor::EdgeBasedEdge> &edge_based_edge_list,
|
||||
std::vector<EdgeWeight> &node_weights,
|
||||
const std::string &edge_segment_lookup_filename,
|
||||
const std::string &edge_penalty_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,
|
||||
@@ -393,15 +402,14 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
|
||||
|
||||
util::Log() << "Opening " << edge_based_graph_filename;
|
||||
|
||||
auto mmap_file = [](const std::string &filename) {
|
||||
auto mmap_file = [](const std::string &filename, boost::interprocess::mode_t mode) {
|
||||
using boost::interprocess::file_mapping;
|
||||
using boost::interprocess::mapped_region;
|
||||
using boost::interprocess::read_only;
|
||||
|
||||
try
|
||||
{
|
||||
const file_mapping mapping{filename.c_str(), read_only};
|
||||
mapped_region region{mapping, read_only};
|
||||
const file_mapping mapping{filename.c_str(), mode};
|
||||
mapped_region region{mapping, mode};
|
||||
region.advise(mapped_region::advice_sequential);
|
||||
return region;
|
||||
}
|
||||
@@ -412,15 +420,16 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
|
||||
}
|
||||
};
|
||||
|
||||
const auto edge_based_graph_region = mmap_file(edge_based_graph_filename);
|
||||
const auto edge_based_graph_region =
|
||||
mmap_file(edge_based_graph_filename, boost::interprocess::read_only);
|
||||
|
||||
const bool update_edge_weights = !segment_speed_filenames.empty();
|
||||
const bool update_turn_penalties = !turn_penalty_filenames.empty();
|
||||
|
||||
const auto edge_penalty_region = [&] {
|
||||
const auto turn_penalties_index_region = [&] {
|
||||
if (update_edge_weights || update_turn_penalties)
|
||||
{
|
||||
return mmap_file(edge_penalty_filename);
|
||||
return mmap_file(turn_penalties_index_filename, boost::interprocess::read_only);
|
||||
}
|
||||
return boost::interprocess::mapped_region();
|
||||
}();
|
||||
@@ -428,7 +437,7 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
|
||||
const auto edge_segment_region = [&] {
|
||||
if (update_edge_weights || update_turn_penalties)
|
||||
{
|
||||
return mmap_file(edge_segment_lookup_filename);
|
||||
return mmap_file(edge_segment_lookup_filename, boost::interprocess::read_only);
|
||||
}
|
||||
return boost::interprocess::mapped_region();
|
||||
}();
|
||||
@@ -474,12 +483,13 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
|
||||
util::Log() << "Reading " << graph_header.number_of_edges << " edges from the edge based graph";
|
||||
|
||||
auto segment_speed_lookup = CSVFilesParser<Segment, SpeedSource>(
|
||||
1, qi::ulong_long >> ',' >> qi::ulong_long, qi::uint_)(segment_speed_filenames);
|
||||
1, qi::ulong_long >> ',' >> qi::ulong_long, qi::uint_ >> -(',' >> qi::uint_))(
|
||||
segment_speed_filenames);
|
||||
|
||||
auto turn_penalty_lookup = CSVFilesParser<Turn, PenaltySource>(
|
||||
1 + segment_speed_filenames.size(),
|
||||
qi::ulong_long >> ',' >> qi::ulong_long >> ',' >> qi::ulong_long,
|
||||
qi::double_)(turn_penalty_filenames);
|
||||
qi::double_ >> -(',' >> qi::double_))(turn_penalty_filenames);
|
||||
|
||||
// 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
|
||||
@@ -490,9 +500,11 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
|
||||
std::vector<NodeID> geometry_node_list;
|
||||
std::vector<EdgeWeight> geometry_fwd_weight_list;
|
||||
std::vector<EdgeWeight> geometry_rev_weight_list;
|
||||
std::vector<EdgeWeight> geometry_fwd_duration_list;
|
||||
std::vector<EdgeWeight> geometry_rev_duration_list;
|
||||
|
||||
const auto maybe_load_internal_to_external_node_map = [&] {
|
||||
if (!(update_edge_weights || update_turn_penalties))
|
||||
if (!update_edge_weights)
|
||||
return;
|
||||
|
||||
storage::io::FileReader nodes_file(nodes_filename,
|
||||
@@ -503,7 +515,7 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
|
||||
};
|
||||
|
||||
const auto maybe_load_geometries = [&] {
|
||||
if (!(update_edge_weights || update_turn_penalties))
|
||||
if (!update_edge_weights)
|
||||
return;
|
||||
|
||||
storage::io::FileReader geometry_file(geometry_filename,
|
||||
@@ -518,6 +530,8 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
|
||||
geometry_node_list.resize(number_of_compressed_geometries);
|
||||
geometry_fwd_weight_list.resize(number_of_compressed_geometries);
|
||||
geometry_rev_weight_list.resize(number_of_compressed_geometries);
|
||||
geometry_fwd_duration_list.resize(number_of_compressed_geometries);
|
||||
geometry_rev_duration_list.resize(number_of_compressed_geometries);
|
||||
|
||||
if (number_of_compressed_geometries > 0)
|
||||
{
|
||||
@@ -526,13 +540,17 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
|
||||
number_of_compressed_geometries);
|
||||
geometry_file.ReadInto(geometry_rev_weight_list.data(),
|
||||
number_of_compressed_geometries);
|
||||
geometry_file.ReadInto(geometry_fwd_duration_list.data(),
|
||||
number_of_compressed_geometries);
|
||||
geometry_file.ReadInto(geometry_rev_duration_list.data(),
|
||||
number_of_compressed_geometries);
|
||||
}
|
||||
};
|
||||
|
||||
// Folds all our actions into independently concurrently executing lambdas
|
||||
tbb::parallel_invoke(maybe_load_internal_to_external_node_map, maybe_load_geometries);
|
||||
|
||||
if (update_edge_weights || update_turn_penalties)
|
||||
if (update_edge_weights)
|
||||
{
|
||||
// Here, we have to update the compressed geometry weights
|
||||
// First, we need the external-to-internal node lookup table
|
||||
@@ -552,7 +570,7 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
|
||||
|
||||
using boost::interprocess::mapped_region;
|
||||
|
||||
auto region = mmap_file(rtree_leaf_filename.c_str());
|
||||
auto region = mmap_file(rtree_leaf_filename.c_str(), boost::interprocess::read_only);
|
||||
region.advise(mapped_region::advice_willneed);
|
||||
BOOST_ASSERT(is_aligned<LeafNode>(region.get_address()));
|
||||
|
||||
@@ -589,32 +607,38 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
|
||||
auto fwd_source = LUA_SOURCE, rev_source = LUA_SOURCE;
|
||||
if (auto value = segment_speed_lookup({u.node_id, v.node_id}))
|
||||
{
|
||||
const auto current_fwd_weight = geometry_fwd_weight_list[u_index];
|
||||
const auto new_segment_weight = GetNewWeight(*value,
|
||||
segment_length,
|
||||
segment_speed_filenames,
|
||||
current_fwd_weight,
|
||||
log_edge_updates_factor,
|
||||
u.node_id,
|
||||
v.node_id);
|
||||
EdgeWeight new_segment_weight, new_segment_duration;
|
||||
GetNewWeight(*value,
|
||||
segment_length,
|
||||
segment_speed_filenames,
|
||||
geometry_fwd_duration_list[u_index],
|
||||
log_edge_updates_factor,
|
||||
u.node_id,
|
||||
v.node_id,
|
||||
new_segment_weight,
|
||||
new_segment_duration);
|
||||
|
||||
geometry_fwd_weight_list[v_index] = new_segment_weight;
|
||||
geometry_fwd_duration_list[v_index] = new_segment_duration;
|
||||
geometry_datasource[v_index] = value->source;
|
||||
fwd_source = value->source;
|
||||
}
|
||||
|
||||
if (auto value = segment_speed_lookup({v.node_id, u.node_id}))
|
||||
{
|
||||
const auto current_rev_weight = geometry_rev_weight_list[u_index];
|
||||
const auto new_segment_weight = GetNewWeight(*value,
|
||||
segment_length,
|
||||
segment_speed_filenames,
|
||||
current_rev_weight,
|
||||
log_edge_updates_factor,
|
||||
v.node_id,
|
||||
u.node_id);
|
||||
EdgeWeight new_segment_weight, new_segment_duration;
|
||||
GetNewWeight(*value,
|
||||
segment_length,
|
||||
segment_speed_filenames,
|
||||
geometry_rev_duration_list[u_index],
|
||||
log_edge_updates_factor,
|
||||
v.node_id,
|
||||
u.node_id,
|
||||
new_segment_weight,
|
||||
new_segment_duration);
|
||||
|
||||
geometry_rev_weight_list[u_index] = new_segment_weight;
|
||||
geometry_rev_duration_list[u_index] = new_segment_duration;
|
||||
geometry_datasource[u_index] = value->source;
|
||||
rev_source = value->source;
|
||||
}
|
||||
@@ -652,7 +676,7 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
|
||||
}
|
||||
|
||||
const auto maybe_save_geometries = [&] {
|
||||
if (!(update_edge_weights || update_turn_penalties))
|
||||
if (!update_edge_weights)
|
||||
return;
|
||||
|
||||
// Now save out the updated compressed geometries
|
||||
@@ -675,6 +699,10 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
|
||||
number_of_compressed_geometries * sizeof(EdgeWeight));
|
||||
geometry_stream.write(reinterpret_cast<char *>(&(geometry_rev_weight_list[0])),
|
||||
number_of_compressed_geometries * sizeof(EdgeWeight));
|
||||
geometry_stream.write(reinterpret_cast<char *>(&(geometry_fwd_duration_list[0])),
|
||||
number_of_compressed_geometries * sizeof(EdgeWeight));
|
||||
geometry_stream.write(reinterpret_cast<char *>(&(geometry_rev_duration_list[0])),
|
||||
number_of_compressed_geometries * sizeof(EdgeWeight));
|
||||
};
|
||||
|
||||
const auto save_datasource_indexes = [&] {
|
||||
@@ -716,17 +744,47 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
|
||||
|
||||
tbb::parallel_invoke(maybe_save_geometries, save_datasource_indexes, save_datastore_names);
|
||||
|
||||
auto turn_penalty_blocks_ptr = reinterpret_cast<const extractor::lookup::PenaltyBlock *>(
|
||||
edge_penalty_region.get_address());
|
||||
BOOST_ASSERT(is_aligned<extractor::lookup::PenaltyBlock>(turn_penalty_blocks_ptr));
|
||||
std::vector<TurnPenalty> turn_weight_penalties;
|
||||
std::vector<TurnPenalty> turn_duration_penalties;
|
||||
|
||||
auto edge_based_edge_ptr = reinterpret_cast<extractor::EdgeBasedEdge *>(
|
||||
const auto maybe_load_turn_weight_penalties = [&] {
|
||||
if (!update_edge_weights && !update_turn_penalties)
|
||||
return;
|
||||
using storage::io::FileReader;
|
||||
FileReader file(turn_weight_penalties_filename, FileReader::HasNoFingerprint);
|
||||
file.DeserializeVector(turn_weight_penalties);
|
||||
};
|
||||
|
||||
const auto maybe_load_turn_duration_penalties = [&] {
|
||||
if (!update_turn_penalties)
|
||||
return;
|
||||
using storage::io::FileReader;
|
||||
FileReader file(turn_duration_penalties_filename, FileReader::HasNoFingerprint);
|
||||
file.DeserializeVector(turn_duration_penalties);
|
||||
};
|
||||
|
||||
tbb::parallel_invoke(maybe_load_turn_weight_penalties, maybe_load_turn_duration_penalties);
|
||||
|
||||
if (update_turn_penalties && turn_duration_penalties.empty())
|
||||
{ // Copy-on-write for duration penalties as turn weight penalties
|
||||
turn_duration_penalties = turn_weight_penalties;
|
||||
}
|
||||
|
||||
// Mapped file pointer for turn indices
|
||||
const extractor::lookup::TurnIndexBlock *turn_index_blocks =
|
||||
reinterpret_cast<const extractor::lookup::TurnIndexBlock *>(
|
||||
turn_penalties_index_region.get_address());
|
||||
BOOST_ASSERT(is_aligned<extractor::lookup::TurnIndexBlock>(turn_index_blocks));
|
||||
|
||||
// Mapped file pointers for edge-based graph edges
|
||||
auto edge_based_edge_ptr = reinterpret_cast<const extractor::EdgeBasedEdge *>(
|
||||
reinterpret_cast<char *>(edge_based_graph_region.get_address()) +
|
||||
sizeof(EdgeBasedGraphHeader));
|
||||
BOOST_ASSERT(is_aligned<extractor::EdgeBasedEdge>(edge_based_edge_ptr));
|
||||
|
||||
auto edge_segment_byte_ptr = reinterpret_cast<const char *>(edge_segment_region.get_address());
|
||||
|
||||
bool fallback_to_duration = true;
|
||||
for (std::uint64_t edge_index = 0; edge_index < graph_header.number_of_edges; ++edge_index)
|
||||
{
|
||||
// Make a copy of the data from the memory map
|
||||
@@ -759,7 +817,10 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
|
||||
if (value->speed == 0)
|
||||
return true;
|
||||
|
||||
segment_weight = ConvertToDuration(segment.segment_length, value->speed);
|
||||
segment_weight =
|
||||
value->weight == INVALID_EDGE_WEIGHT
|
||||
? ConvertToDuration(segment.segment_length, value->speed)
|
||||
: value->weight;
|
||||
}
|
||||
|
||||
// Update the edge weight and the next OSM node ID
|
||||
@@ -779,30 +840,61 @@ Contractor::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
|
||||
continue;
|
||||
|
||||
// Get the turn penalty and update to the new value if required
|
||||
const auto &turn_block = turn_penalty_blocks_ptr[edge_index];
|
||||
EdgeWeight new_turn_penalty = turn_block.fixed_penalty;
|
||||
if (auto value = turn_penalty_lookup(turn_block))
|
||||
const auto &turn_index = turn_index_blocks[edge_index];
|
||||
auto turn_weight_penalty = turn_weight_penalties[edge_index];
|
||||
if (auto value = turn_penalty_lookup(turn_index))
|
||||
{
|
||||
new_turn_penalty = static_cast<EdgeWeight>(value->penalty * 10);
|
||||
auto turn_duration_penalty =
|
||||
boost::numeric_cast<TurnPenalty>(std::round(value->duration * 10.));
|
||||
turn_weight_penalty =
|
||||
std::isfinite(value->weight)
|
||||
? boost::numeric_cast<TurnPenalty>(std::round(value->weight * 10))
|
||||
: turn_duration_penalty;
|
||||
|
||||
if (new_weight + new_turn_penalty < 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)
|
||||
{
|
||||
util::Log(logWARNING)
|
||||
<< "turn penalty " << value->penalty << " for turn " << turn_block.from_id
|
||||
<< "," << turn_block.via_id << "," << turn_block.to_id
|
||||
<< " is too negative: clamping turn weight to " << header->num_osm_nodes;
|
||||
util::Log(logWARNING) << "turn penalty " << turn_weight_penalty << " for turn "
|
||||
<< turn_index.from_id << ", " << turn_index.via_id << ", "
|
||||
<< turn_index.to_id
|
||||
<< " is too negative: clamping turn weight to "
|
||||
<< weight_min_value;
|
||||
|
||||
new_turn_penalty = header->num_osm_nodes - new_weight;
|
||||
turn_weight_penalty = weight_min_value - new_weight;
|
||||
}
|
||||
|
||||
turn_duration_penalties[edge_index] = turn_duration_penalty;
|
||||
turn_weight_penalties[edge_index] = turn_weight_penalty;
|
||||
|
||||
// Is fallback of duration to weight values allowed
|
||||
fallback_to_duration &= (turn_duration_penalty == turn_weight_penalty);
|
||||
}
|
||||
|
||||
// Update edge weight
|
||||
inbuffer.weight = new_weight + new_turn_penalty;
|
||||
inbuffer.weight = new_weight + turn_weight_penalty;
|
||||
}
|
||||
|
||||
edge_based_edge_list.emplace_back(std::move(inbuffer));
|
||||
}
|
||||
|
||||
if (update_turn_penalties)
|
||||
{
|
||||
if (fallback_to_duration)
|
||||
{ // Turn duration penalties are identical to turn weight penalties
|
||||
// Save empty data vector, so turn weight penalties will be used by data facade.
|
||||
turn_duration_penalties.clear();
|
||||
}
|
||||
|
||||
const auto save_penalties = [](const auto &filename, const auto &data) -> void {
|
||||
storage::io::FileWriter file(filename, storage::io::FileWriter::HasNoFingerprint);
|
||||
file.SerializeVector(data);
|
||||
};
|
||||
|
||||
tbb::parallel_invoke(
|
||||
[&] { save_penalties(turn_weight_penalties_filename, turn_weight_penalties); },
|
||||
[&] { save_penalties(turn_duration_penalties_filename, turn_duration_penalties); });
|
||||
}
|
||||
|
||||
util::Log() << "Done reading edges";
|
||||
return graph_header.max_edge_id;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user