write distances out in a seperate file for mld
This commit is contained in:
parent
9b7bb7b458
commit
1e2c40337c
@ -92,6 +92,7 @@ class EdgeBasedGraphFactory
|
|||||||
void GetStartPointMarkers(std::vector<bool> &node_is_startpoint);
|
void GetStartPointMarkers(std::vector<bool> &node_is_startpoint);
|
||||||
void GetEdgeBasedNodeWeights(std::vector<EdgeWeight> &output_node_weights);
|
void GetEdgeBasedNodeWeights(std::vector<EdgeWeight> &output_node_weights);
|
||||||
void GetEdgeBasedNodeDurations(std::vector<EdgeWeight> &output_node_durations);
|
void GetEdgeBasedNodeDurations(std::vector<EdgeWeight> &output_node_durations);
|
||||||
|
void GetEdgeBasedNodeDistances(std::vector<EdgeDistance> &output_node_distances);
|
||||||
std::uint32_t GetConnectivityChecksum() const;
|
std::uint32_t GetConnectivityChecksum() const;
|
||||||
|
|
||||||
std::uint64_t GetNumberOfEdgeBasedNodes() const;
|
std::uint64_t GetNumberOfEdgeBasedNodes() const;
|
||||||
@ -119,6 +120,7 @@ class EdgeBasedGraphFactory
|
|||||||
//! edge-based node
|
//! edge-based node
|
||||||
std::vector<EdgeWeight> m_edge_based_node_weights;
|
std::vector<EdgeWeight> m_edge_based_node_weights;
|
||||||
std::vector<EdgeDuration> m_edge_based_node_durations;
|
std::vector<EdgeDuration> m_edge_based_node_durations;
|
||||||
|
std::vector<EdgeDistance> m_edge_based_node_distances;
|
||||||
|
|
||||||
//! list of edge based nodes (compressed segments)
|
//! list of edge based nodes (compressed segments)
|
||||||
std::vector<EdgeBasedNodeSegment> m_edge_based_node_segments;
|
std::vector<EdgeBasedNodeSegment> m_edge_based_node_segments;
|
||||||
|
|||||||
@ -88,6 +88,7 @@ class Extractor
|
|||||||
std::vector<bool> &node_is_startpoint,
|
std::vector<bool> &node_is_startpoint,
|
||||||
std::vector<EdgeWeight> &edge_based_node_weights,
|
std::vector<EdgeWeight> &edge_based_node_weights,
|
||||||
std::vector<EdgeDuration> &edge_based_node_durations,
|
std::vector<EdgeDuration> &edge_based_node_durations,
|
||||||
|
std::vector<EdgeDistance> &edge_based_node_distances,
|
||||||
util::DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list,
|
util::DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list,
|
||||||
std::uint32_t &connectivity_checksum);
|
std::uint32_t &connectivity_checksum);
|
||||||
|
|
||||||
|
|||||||
@ -462,6 +462,34 @@ void readEdgeBasedNodeWeights(const boost::filesystem::path &path, NodeWeigtsVec
|
|||||||
storage::serialization::read(reader, "/extractor/edge_based_node_weights", weights);
|
storage::serialization::read(reader, "/extractor/edge_based_node_weights", weights);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename NodeWeigtsVectorT, typename NodeDurationsVectorT, typename NodeDistancesVectorT>
|
||||||
|
void readEdgeBasedNodeWeightsDurationsDistances(const boost::filesystem::path &path,
|
||||||
|
NodeWeigtsVectorT &weights,
|
||||||
|
NodeDurationsVectorT &durations,
|
||||||
|
NodeDistancesVectorT &distances)
|
||||||
|
{
|
||||||
|
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
||||||
|
storage::tar::FileReader reader{path, fingerprint};
|
||||||
|
|
||||||
|
storage::serialization::read(reader, "/extractor/edge_based_node_weights", weights);
|
||||||
|
storage::serialization::read(reader, "/extractor/edge_based_node_durations", durations);
|
||||||
|
storage::serialization::read(reader, "/extractor/edge_based_node_distances", distances);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename NodeWeigtsVectorT, typename NodeDurationsVectorT, typename NodeDistancesVectorT>
|
||||||
|
void writeEdgeBasedNodeWeightsDurationsDistances(const boost::filesystem::path &path,
|
||||||
|
const NodeWeigtsVectorT &weights,
|
||||||
|
const NodeDurationsVectorT &durations,
|
||||||
|
const NodeDistancesVectorT &distances)
|
||||||
|
{
|
||||||
|
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
|
||||||
|
storage::tar::FileWriter writer{path, fingerprint};
|
||||||
|
|
||||||
|
storage::serialization::write(writer, "/extractor/edge_based_node_weights", weights);
|
||||||
|
storage::serialization::write(writer, "/extractor/edge_based_node_durations", durations);
|
||||||
|
storage::serialization::write(writer, "/extractor/edge_based_node_distances", distances);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename NodeWeigtsVectorT, typename NodeDurationsVectorT>
|
template <typename NodeWeigtsVectorT, typename NodeDurationsVectorT>
|
||||||
void readEdgeBasedNodeWeightsDurations(const boost::filesystem::path &path,
|
void readEdgeBasedNodeWeightsDurations(const boost::filesystem::path &path,
|
||||||
NodeWeigtsVectorT &weights,
|
NodeWeigtsVectorT &weights,
|
||||||
|
|||||||
@ -27,6 +27,12 @@ class Updater
|
|||||||
std::vector<EdgeWeight> &node_weights,
|
std::vector<EdgeWeight> &node_weights,
|
||||||
std::vector<EdgeDuration> &node_durations, // TODO: to be deleted
|
std::vector<EdgeDuration> &node_durations, // TODO: to be deleted
|
||||||
std::uint32_t &connectivity_checksum) const;
|
std::uint32_t &connectivity_checksum) const;
|
||||||
|
EdgeID
|
||||||
|
LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &edge_based_edge_list,
|
||||||
|
std::vector<EdgeWeight> &node_weights,
|
||||||
|
std::vector<EdgeDuration> &node_durations, // TODO: to be deleted
|
||||||
|
std::vector<EdgeDistance> &node_distances, // TODO: to be deleted
|
||||||
|
std::uint32_t &connectivity_checksum) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UpdaterConfig config;
|
UpdaterConfig config;
|
||||||
|
|||||||
@ -76,13 +76,14 @@ auto LoadAndUpdateEdgeExpandedGraph(const CustomizationConfig &config,
|
|||||||
const partitioner::MultiLevelPartition &mlp,
|
const partitioner::MultiLevelPartition &mlp,
|
||||||
std::vector<EdgeWeight> &node_weights,
|
std::vector<EdgeWeight> &node_weights,
|
||||||
std::vector<EdgeDuration> &node_durations,
|
std::vector<EdgeDuration> &node_durations,
|
||||||
|
std::vector<EdgeDistance> &node_distances,
|
||||||
std::uint32_t &connectivity_checksum)
|
std::uint32_t &connectivity_checksum)
|
||||||
{
|
{
|
||||||
updater::Updater updater(config.updater_config);
|
updater::Updater updater(config.updater_config);
|
||||||
|
|
||||||
std::vector<extractor::EdgeBasedEdge> edge_based_edge_list;
|
std::vector<extractor::EdgeBasedEdge> edge_based_edge_list;
|
||||||
EdgeID num_nodes = updater.LoadAndUpdateEdgeExpandedGraph(
|
EdgeID num_nodes = updater.LoadAndUpdateEdgeExpandedGraph(
|
||||||
edge_based_edge_list, node_weights, node_durations, connectivity_checksum);
|
edge_based_edge_list, node_weights, node_durations, node_distances, connectivity_checksum);
|
||||||
|
|
||||||
auto directed = partitioner::splitBidirectionalEdges(edge_based_edge_list);
|
auto directed = partitioner::splitBidirectionalEdges(edge_based_edge_list);
|
||||||
|
|
||||||
@ -129,7 +130,7 @@ int Customizer::Run(const CustomizationConfig &config)
|
|||||||
node_distances; // TODO: is this and the above still to be removed later? dont think so
|
node_distances; // TODO: is this and the above still to be removed later? dont think so
|
||||||
std::uint32_t connectivity_checksum = 0;
|
std::uint32_t connectivity_checksum = 0;
|
||||||
auto graph = LoadAndUpdateEdgeExpandedGraph(
|
auto graph = LoadAndUpdateEdgeExpandedGraph(
|
||||||
config, mlp, node_weights, node_durations, connectivity_checksum);
|
config, mlp, node_weights, node_durations, node_distances, connectivity_checksum);
|
||||||
BOOST_ASSERT(graph.GetNumberOfNodes() == node_weights.size());
|
BOOST_ASSERT(graph.GetNumberOfNodes() == node_weights.size());
|
||||||
std::for_each(node_weights.begin(), node_weights.end(), [](auto &w) { w &= 0x7fffffff; });
|
std::for_each(node_weights.begin(), node_weights.end(), [](auto &w) { w &= 0x7fffffff; });
|
||||||
util::Log() << "Loaded edge based graph: " << graph.GetNumberOfEdges() << " edges, "
|
util::Log() << "Loaded edge based graph: " << graph.GetNumberOfEdges() << " edges, "
|
||||||
|
|||||||
@ -114,6 +114,13 @@ void EdgeBasedGraphFactory::GetEdgeBasedNodeDurations(
|
|||||||
swap(m_edge_based_node_durations, output_node_durations);
|
swap(m_edge_based_node_durations, output_node_durations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EdgeBasedGraphFactory::GetEdgeBasedNodeDistances(
|
||||||
|
std::vector<EdgeDistance> &output_node_distances)
|
||||||
|
{
|
||||||
|
using std::swap; // Koenig swap
|
||||||
|
swap(m_edge_based_node_distances, output_node_distances);
|
||||||
|
}
|
||||||
|
|
||||||
std::uint32_t EdgeBasedGraphFactory::GetConnectivityChecksum() const
|
std::uint32_t EdgeBasedGraphFactory::GetConnectivityChecksum() const
|
||||||
{
|
{
|
||||||
return m_connectivity_checksum;
|
return m_connectivity_checksum;
|
||||||
@ -293,6 +300,7 @@ unsigned EdgeBasedGraphFactory::LabelEdgeBasedNodes()
|
|||||||
// (edge-based nodes)
|
// (edge-based nodes)
|
||||||
m_edge_based_node_weights.reserve(4 * m_node_based_graph.GetNumberOfNodes());
|
m_edge_based_node_weights.reserve(4 * m_node_based_graph.GetNumberOfNodes());
|
||||||
m_edge_based_node_durations.reserve(4 * m_node_based_graph.GetNumberOfNodes());
|
m_edge_based_node_durations.reserve(4 * m_node_based_graph.GetNumberOfNodes());
|
||||||
|
m_edge_based_node_distances.reserve(4 * m_node_based_graph.GetNumberOfNodes());
|
||||||
nbe_to_ebn_mapping.resize(m_node_based_graph.GetEdgeCapacity(), SPECIAL_NODEID);
|
nbe_to_ebn_mapping.resize(m_node_based_graph.GetEdgeCapacity(), SPECIAL_NODEID);
|
||||||
|
|
||||||
// renumber edge based node of outgoing edges
|
// renumber edge based node of outgoing edges
|
||||||
@ -310,6 +318,7 @@ unsigned EdgeBasedGraphFactory::LabelEdgeBasedNodes()
|
|||||||
|
|
||||||
m_edge_based_node_weights.push_back(edge_data.weight);
|
m_edge_based_node_weights.push_back(edge_data.weight);
|
||||||
m_edge_based_node_durations.push_back(edge_data.duration);
|
m_edge_based_node_durations.push_back(edge_data.duration);
|
||||||
|
m_edge_based_node_distances.push_back(edge_data.distance);
|
||||||
|
|
||||||
BOOST_ASSERT(numbered_edges_count < m_node_based_graph.GetNumberOfEdges());
|
BOOST_ASSERT(numbered_edges_count < m_node_based_graph.GetNumberOfEdges());
|
||||||
nbe_to_ebn_mapping[current_edge] = numbered_edges_count;
|
nbe_to_ebn_mapping[current_edge] = numbered_edges_count;
|
||||||
@ -407,6 +416,8 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedNodes(const WayRestrictionMap &way_re
|
|||||||
m_edge_based_node_weights.push_back(ebn_weight);
|
m_edge_based_node_weights.push_back(ebn_weight);
|
||||||
m_edge_based_node_durations.push_back(
|
m_edge_based_node_durations.push_back(
|
||||||
m_edge_based_node_durations[nbe_to_ebn_mapping[eid]]);
|
m_edge_based_node_durations[nbe_to_ebn_mapping[eid]]);
|
||||||
|
m_edge_based_node_distances.push_back(
|
||||||
|
m_edge_based_node_distances[nbe_to_ebn_mapping[eid]]);
|
||||||
|
|
||||||
edge_based_node_id++;
|
edge_based_node_id++;
|
||||||
progress.PrintStatus(progress_counter++);
|
progress.PrintStatus(progress_counter++);
|
||||||
@ -416,6 +427,7 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedNodes(const WayRestrictionMap &way_re
|
|||||||
BOOST_ASSERT(m_edge_based_node_segments.size() == m_edge_based_node_is_startpoint.size());
|
BOOST_ASSERT(m_edge_based_node_segments.size() == m_edge_based_node_is_startpoint.size());
|
||||||
BOOST_ASSERT(m_number_of_edge_based_nodes == m_edge_based_node_weights.size());
|
BOOST_ASSERT(m_number_of_edge_based_nodes == m_edge_based_node_weights.size());
|
||||||
BOOST_ASSERT(m_number_of_edge_based_nodes == m_edge_based_node_durations.size());
|
BOOST_ASSERT(m_number_of_edge_based_nodes == m_edge_based_node_durations.size());
|
||||||
|
BOOST_ASSERT(m_number_of_edge_based_nodes == m_edge_based_node_distances.size());
|
||||||
|
|
||||||
util::Log() << "Generated " << m_number_of_edge_based_nodes << " nodes ("
|
util::Log() << "Generated " << m_number_of_edge_based_nodes << " nodes ("
|
||||||
<< way_restriction_map.NumberOfDuplicatedNodes()
|
<< way_restriction_map.NumberOfDuplicatedNodes()
|
||||||
|
|||||||
@ -242,6 +242,7 @@ int Extractor::run(ScriptingEnvironment &scripting_environment)
|
|||||||
std::vector<bool> node_is_startpoint;
|
std::vector<bool> node_is_startpoint;
|
||||||
std::vector<EdgeWeight> edge_based_node_weights;
|
std::vector<EdgeWeight> edge_based_node_weights;
|
||||||
std::vector<EdgeDuration> edge_based_node_durations;
|
std::vector<EdgeDuration> edge_based_node_durations;
|
||||||
|
std::vector<EdgeDistance> edge_based_node_distances;
|
||||||
std::uint32_t ebg_connectivity_checksum = 0;
|
std::uint32_t ebg_connectivity_checksum = 0;
|
||||||
|
|
||||||
// Create a node-based graph from the OSRM file
|
// Create a node-based graph from the OSRM file
|
||||||
@ -322,6 +323,7 @@ int Extractor::run(ScriptingEnvironment &scripting_environment)
|
|||||||
node_is_startpoint,
|
node_is_startpoint,
|
||||||
edge_based_node_weights,
|
edge_based_node_weights,
|
||||||
edge_based_node_durations,
|
edge_based_node_durations,
|
||||||
|
edge_based_node_distances,
|
||||||
edge_based_edge_list,
|
edge_based_edge_list,
|
||||||
ebg_connectivity_checksum);
|
ebg_connectivity_checksum);
|
||||||
|
|
||||||
@ -345,8 +347,10 @@ int Extractor::run(ScriptingEnvironment &scripting_environment)
|
|||||||
|
|
||||||
util::Log() << "Saving edge-based node weights to file.";
|
util::Log() << "Saving edge-based node weights to file.";
|
||||||
TIMER_START(timer_write_node_weights);
|
TIMER_START(timer_write_node_weights);
|
||||||
extractor::files::writeEdgeBasedNodeWeightsDurations(
|
extractor::files::writeEdgeBasedNodeWeightsDurationsDistances(config.GetPath(".osrm.enw"),
|
||||||
config.GetPath(".osrm.enw"), edge_based_node_weights, edge_based_node_durations);
|
edge_based_node_weights,
|
||||||
|
edge_based_node_durations,
|
||||||
|
edge_based_node_distances);
|
||||||
TIMER_STOP(timer_write_node_weights);
|
TIMER_STOP(timer_write_node_weights);
|
||||||
util::Log() << "Done writing. (" << TIMER_SEC(timer_write_node_weights) << ")";
|
util::Log() << "Done writing. (" << TIMER_SEC(timer_write_node_weights) << ")";
|
||||||
|
|
||||||
@ -736,6 +740,7 @@ EdgeID Extractor::BuildEdgeExpandedGraph(
|
|||||||
std::vector<bool> &node_is_startpoint,
|
std::vector<bool> &node_is_startpoint,
|
||||||
std::vector<EdgeWeight> &edge_based_node_weights,
|
std::vector<EdgeWeight> &edge_based_node_weights,
|
||||||
std::vector<EdgeDuration> &edge_based_node_durations,
|
std::vector<EdgeDuration> &edge_based_node_durations,
|
||||||
|
std::vector<EdgeDistance> &edge_based_node_distances,
|
||||||
util::DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list,
|
util::DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list,
|
||||||
std::uint32_t &connectivity_checksum)
|
std::uint32_t &connectivity_checksum)
|
||||||
{
|
{
|
||||||
@ -786,6 +791,7 @@ EdgeID Extractor::BuildEdgeExpandedGraph(
|
|||||||
edge_based_graph_factory.GetStartPointMarkers(node_is_startpoint);
|
edge_based_graph_factory.GetStartPointMarkers(node_is_startpoint);
|
||||||
edge_based_graph_factory.GetEdgeBasedNodeWeights(edge_based_node_weights);
|
edge_based_graph_factory.GetEdgeBasedNodeWeights(edge_based_node_weights);
|
||||||
edge_based_graph_factory.GetEdgeBasedNodeDurations(edge_based_node_durations);
|
edge_based_graph_factory.GetEdgeBasedNodeDurations(edge_based_node_durations);
|
||||||
|
edge_based_graph_factory.GetEdgeBasedNodeDistances(edge_based_node_distances);
|
||||||
connectivity_checksum = edge_based_graph_factory.GetConnectivityChecksum();
|
connectivity_checksum = edge_based_graph_factory.GetConnectivityChecksum();
|
||||||
|
|
||||||
return number_of_edge_based_nodes;
|
return number_of_edge_based_nodes;
|
||||||
|
|||||||
@ -147,12 +147,14 @@ int Partitioner::Run(const PartitionerConfig &config)
|
|||||||
{
|
{
|
||||||
std::vector<EdgeWeight> node_weights;
|
std::vector<EdgeWeight> node_weights;
|
||||||
std::vector<EdgeDuration> node_durations;
|
std::vector<EdgeDuration> node_durations;
|
||||||
extractor::files::readEdgeBasedNodeWeightsDurations(
|
std::vector<EdgeDuration> node_distances;
|
||||||
config.GetPath(".osrm.enw"), node_weights, node_durations);
|
extractor::files::readEdgeBasedNodeWeightsDurationsDistances(
|
||||||
|
config.GetPath(".osrm.enw"), node_weights, node_durations, node_distances);
|
||||||
util::inplacePermutation(node_weights.begin(), node_weights.end(), permutation);
|
util::inplacePermutation(node_weights.begin(), node_weights.end(), permutation);
|
||||||
util::inplacePermutation(node_durations.begin(), node_durations.end(), permutation);
|
util::inplacePermutation(node_durations.begin(), node_durations.end(), permutation);
|
||||||
extractor::files::writeEdgeBasedNodeWeightsDurations(
|
util::inplacePermutation(node_distances.begin(), node_distances.end(), permutation);
|
||||||
config.GetPath(".osrm.enw"), node_weights, node_durations);
|
extractor::files::writeEdgeBasedNodeWeightsDurationsDistances(
|
||||||
|
config.GetPath(".osrm.enw"), node_weights, node_durations, node_distances);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const auto &filename = config.GetPath(".osrm.maneuver_overrides");
|
const auto &filename = config.GetPath(".osrm.maneuver_overrides");
|
||||||
|
|||||||
@ -541,6 +541,7 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &e
|
|||||||
std::vector<EdgeDuration> &node_durations,
|
std::vector<EdgeDuration> &node_durations,
|
||||||
std::uint32_t &connectivity_checksum) const
|
std::uint32_t &connectivity_checksum) const
|
||||||
{
|
{
|
||||||
|
|
||||||
TIMER_START(load_edges);
|
TIMER_START(load_edges);
|
||||||
|
|
||||||
EdgeID number_of_edge_based_nodes = 0;
|
EdgeID number_of_edge_based_nodes = 0;
|
||||||
@ -812,6 +813,299 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &e
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(NDEBUG)
|
||||||
|
if (config.turn_penalty_lookup_paths.empty())
|
||||||
|
{ // don't check weights consistency with turn updates that can break assertion
|
||||||
|
// condition with turn weight penalties negative updates
|
||||||
|
checkWeightsConsistency(config, edge_based_edge_list);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
saveDatasourcesNames(config);
|
||||||
|
|
||||||
|
TIMER_STOP(load_edges);
|
||||||
|
util::Log() << "Done reading edges in " << TIMER_MSEC(load_edges) << "ms.";
|
||||||
|
return number_of_edge_based_nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
EdgeID
|
||||||
|
Updater::LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &edge_based_edge_list,
|
||||||
|
std::vector<EdgeWeight> &node_weights,
|
||||||
|
std::vector<EdgeDuration> &node_durations,
|
||||||
|
std::vector<EdgeDistance> &node_distances,
|
||||||
|
std::uint32_t &connectivity_checksum) const
|
||||||
|
{
|
||||||
|
TIMER_START(load_edges);
|
||||||
|
|
||||||
|
EdgeID number_of_edge_based_nodes = 0;
|
||||||
|
std::vector<util::Coordinate> coordinates;
|
||||||
|
extractor::PackedOSMIDs osm_node_ids;
|
||||||
|
|
||||||
|
extractor::files::readEdgeBasedNodeWeightsDurationsDistances(
|
||||||
|
config.GetPath(".osrm.enw"), node_weights, node_durations, node_distances);
|
||||||
|
|
||||||
|
extractor::files::readEdgeBasedGraph(config.GetPath(".osrm.ebg"),
|
||||||
|
number_of_edge_based_nodes,
|
||||||
|
edge_based_edge_list,
|
||||||
|
connectivity_checksum);
|
||||||
|
extractor::files::readNodes(config.GetPath(".osrm.nbg_nodes"), coordinates, osm_node_ids);
|
||||||
|
|
||||||
|
const bool update_conditional_turns =
|
||||||
|
!config.GetPath(".osrm.restrictions").empty() && config.valid_now;
|
||||||
|
const bool update_edge_weights = !config.segment_speed_lookup_paths.empty();
|
||||||
|
const bool update_turn_penalties = !config.turn_penalty_lookup_paths.empty();
|
||||||
|
|
||||||
|
if (!update_edge_weights && !update_turn_penalties && !update_conditional_turns)
|
||||||
|
{
|
||||||
|
saveDatasourcesNames(config);
|
||||||
|
return number_of_edge_based_nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
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" +
|
||||||
|
SOURCE_REF);
|
||||||
|
|
||||||
|
extractor::EdgeBasedNodeDataContainer node_data;
|
||||||
|
extractor::SegmentDataContainer segment_data;
|
||||||
|
extractor::ProfileProperties profile_properties;
|
||||||
|
std::vector<TurnPenalty> turn_weight_penalties;
|
||||||
|
std::vector<TurnPenalty> turn_duration_penalties;
|
||||||
|
if (update_edge_weights || update_turn_penalties || update_conditional_turns)
|
||||||
|
{
|
||||||
|
tbb::parallel_invoke(
|
||||||
|
[&] {
|
||||||
|
extractor::files::readSegmentData(config.GetPath(".osrm.geometry"), segment_data);
|
||||||
|
},
|
||||||
|
[&] { extractor::files::readNodeData(config.GetPath(".osrm.ebg_nodes"), node_data); },
|
||||||
|
|
||||||
|
[&] {
|
||||||
|
extractor::files::readTurnWeightPenalty(
|
||||||
|
config.GetPath(".osrm.turn_weight_penalties"), turn_weight_penalties);
|
||||||
|
},
|
||||||
|
[&] {
|
||||||
|
extractor::files::readTurnDurationPenalty(
|
||||||
|
config.GetPath(".osrm.turn_duration_penalties"), turn_duration_penalties);
|
||||||
|
},
|
||||||
|
[&] {
|
||||||
|
extractor::files::readProfileProperties(config.GetPath(".osrm.properties"),
|
||||||
|
profile_properties);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<extractor::ConditionalTurnPenalty> conditional_turns;
|
||||||
|
if (update_conditional_turns)
|
||||||
|
{
|
||||||
|
extractor::files::readConditionalRestrictions(config.GetPath(".osrm.restrictions"),
|
||||||
|
conditional_turns);
|
||||||
|
}
|
||||||
|
|
||||||
|
tbb::concurrent_vector<GeometryID> updated_segments;
|
||||||
|
if (update_edge_weights)
|
||||||
|
{
|
||||||
|
auto segment_speed_lookup = csv::readSegmentValues(config.segment_speed_lookup_paths);
|
||||||
|
|
||||||
|
TIMER_START(segment);
|
||||||
|
updated_segments = updateSegmentData(config,
|
||||||
|
profile_properties,
|
||||||
|
segment_speed_lookup,
|
||||||
|
segment_data,
|
||||||
|
coordinates,
|
||||||
|
osm_node_ids);
|
||||||
|
// Now save out the updated compressed geometries
|
||||||
|
extractor::files::writeSegmentData(config.GetPath(".osrm.geometry"), segment_data);
|
||||||
|
TIMER_STOP(segment);
|
||||||
|
util::Log() << "Updating segment data took " << TIMER_MSEC(segment) << "ms.";
|
||||||
|
}
|
||||||
|
|
||||||
|
auto turn_penalty_lookup = csv::readTurnValues(config.turn_penalty_lookup_paths);
|
||||||
|
if (update_turn_penalties)
|
||||||
|
{
|
||||||
|
auto updated_turn_penalties = updateTurnPenalties(config,
|
||||||
|
profile_properties,
|
||||||
|
turn_penalty_lookup,
|
||||||
|
turn_weight_penalties,
|
||||||
|
turn_duration_penalties,
|
||||||
|
osm_node_ids);
|
||||||
|
const auto offset = updated_segments.size();
|
||||||
|
updated_segments.resize(offset + updated_turn_penalties.size());
|
||||||
|
// we need to re-compute all edges that have updated turn penalties.
|
||||||
|
// this marks it for re-computation
|
||||||
|
std::transform(updated_turn_penalties.begin(),
|
||||||
|
updated_turn_penalties.end(),
|
||||||
|
updated_segments.begin() + offset,
|
||||||
|
[&node_data, &edge_based_edge_list](const std::uint64_t turn_id) {
|
||||||
|
const auto node_id = edge_based_edge_list[turn_id].source;
|
||||||
|
return node_data.GetGeometryID(node_id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (update_conditional_turns)
|
||||||
|
{
|
||||||
|
// initialize instance of class that handles time zone resolution
|
||||||
|
if (config.valid_now <= 0)
|
||||||
|
{
|
||||||
|
util::Log(logERROR) << "Given UTC time is invalid: " << config.valid_now;
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
const Timezoner time_zone_handler = Timezoner(config.tz_file_path, config.valid_now);
|
||||||
|
|
||||||
|
auto updated_turn_penalties =
|
||||||
|
updateConditionalTurns(turn_weight_penalties, conditional_turns, time_zone_handler);
|
||||||
|
const auto offset = updated_segments.size();
|
||||||
|
updated_segments.resize(offset + updated_turn_penalties.size());
|
||||||
|
// we need to re-compute all edges that have updated turn penalties.
|
||||||
|
// this marks it for re-computation
|
||||||
|
std::transform(updated_turn_penalties.begin(),
|
||||||
|
updated_turn_penalties.end(),
|
||||||
|
updated_segments.begin() + offset,
|
||||||
|
[&node_data, &edge_based_edge_list](const std::uint64_t turn_id) {
|
||||||
|
const auto node_id = edge_based_edge_list[turn_id].source;
|
||||||
|
return node_data.GetGeometryID(node_id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
tbb::parallel_sort(updated_segments.begin(),
|
||||||
|
updated_segments.end(),
|
||||||
|
[](const GeometryID lhs, const GeometryID rhs) {
|
||||||
|
return std::tie(lhs.id, lhs.forward) < std::tie(rhs.id, rhs.forward);
|
||||||
|
});
|
||||||
|
|
||||||
|
using WeightAndDuration = std::tuple<EdgeWeight, EdgeWeight>;
|
||||||
|
const auto compute_new_weight_and_duration =
|
||||||
|
[&](const GeometryID geometry_id) -> WeightAndDuration {
|
||||||
|
EdgeWeight new_weight = 0;
|
||||||
|
EdgeWeight new_duration = 0;
|
||||||
|
if (geometry_id.forward)
|
||||||
|
{
|
||||||
|
const auto weights = segment_data.GetForwardWeights(geometry_id.id);
|
||||||
|
for (const auto weight : weights)
|
||||||
|
{
|
||||||
|
if (weight == INVALID_SEGMENT_WEIGHT)
|
||||||
|
{
|
||||||
|
new_weight = INVALID_EDGE_WEIGHT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
new_weight += weight;
|
||||||
|
}
|
||||||
|
const auto durations = segment_data.GetForwardDurations(geometry_id.id);
|
||||||
|
new_duration = std::accumulate(durations.begin(), durations.end(), EdgeWeight{0});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto weights = segment_data.GetReverseWeights(geometry_id.id);
|
||||||
|
for (const auto weight : weights)
|
||||||
|
{
|
||||||
|
if (weight == INVALID_SEGMENT_WEIGHT)
|
||||||
|
{
|
||||||
|
new_weight = INVALID_EDGE_WEIGHT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
new_weight += weight;
|
||||||
|
}
|
||||||
|
const auto durations = segment_data.GetReverseDurations(geometry_id.id);
|
||||||
|
new_duration = std::accumulate(durations.begin(), durations.end(), EdgeWeight{0});
|
||||||
|
}
|
||||||
|
return std::make_tuple(new_weight, new_duration);
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<WeightAndDuration> accumulated_segment_data(updated_segments.size());
|
||||||
|
tbb::parallel_for(tbb::blocked_range<std::size_t>(0, updated_segments.size()),
|
||||||
|
[&](const auto &range) {
|
||||||
|
for (auto index = range.begin(); index < range.end(); ++index)
|
||||||
|
{
|
||||||
|
accumulated_segment_data[index] =
|
||||||
|
compute_new_weight_and_duration(updated_segments[index]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const auto update_edge = [&](extractor::EdgeBasedEdge &edge) {
|
||||||
|
const auto node_id = edge.source;
|
||||||
|
const auto geometry_id = node_data.GetGeometryID(node_id);
|
||||||
|
auto updated_iter = std::lower_bound(updated_segments.begin(),
|
||||||
|
updated_segments.end(),
|
||||||
|
geometry_id,
|
||||||
|
[](const GeometryID lhs, const GeometryID rhs) {
|
||||||
|
return std::tie(lhs.id, lhs.forward) <
|
||||||
|
std::tie(rhs.id, rhs.forward);
|
||||||
|
});
|
||||||
|
if (updated_iter != updated_segments.end() && updated_iter->id == geometry_id.id &&
|
||||||
|
updated_iter->forward == geometry_id.forward)
|
||||||
|
{
|
||||||
|
// Find a segment with zero speed and simultaneously compute the new edge
|
||||||
|
// weight
|
||||||
|
EdgeWeight new_weight;
|
||||||
|
EdgeWeight new_duration;
|
||||||
|
std::tie(new_weight, new_duration) =
|
||||||
|
accumulated_segment_data[updated_iter - updated_segments.begin()];
|
||||||
|
|
||||||
|
// Update the node-weight cache. This is the weight of the edge-based-node
|
||||||
|
// only, it doesn't include the turn. We may visit the same node multiple times,
|
||||||
|
// but we should always assign the same value here.
|
||||||
|
BOOST_ASSERT(edge.source < node_weights.size());
|
||||||
|
node_weights[edge.source] =
|
||||||
|
node_weights[edge.source] & 0x80000000 ? new_weight | 0x80000000 : new_weight;
|
||||||
|
node_durations[edge.source] = new_duration;
|
||||||
|
|
||||||
|
// We found a zero-speed edge, so we'll skip this whole edge-based-edge
|
||||||
|
// which
|
||||||
|
// effectively removes it from the routing network.
|
||||||
|
if (new_weight == INVALID_EDGE_WEIGHT)
|
||||||
|
{
|
||||||
|
edge.data.weight = INVALID_EDGE_WEIGHT;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the turn penalty and update to the new value if required
|
||||||
|
auto turn_weight_penalty = turn_weight_penalties[edge.data.turn_id];
|
||||||
|
auto turn_duration_penalty = turn_duration_penalties[edge.data.turn_id];
|
||||||
|
const auto num_nodes = segment_data.GetForwardGeometry(geometry_id.id).size();
|
||||||
|
const auto weight_min_value = static_cast<EdgeWeight>(num_nodes);
|
||||||
|
if (turn_weight_penalty + new_weight < weight_min_value)
|
||||||
|
{
|
||||||
|
if (turn_weight_penalty < 0)
|
||||||
|
{
|
||||||
|
util::Log(logWARNING) << "turn penalty " << turn_weight_penalty
|
||||||
|
<< " is too negative: clamping turn weight to "
|
||||||
|
<< weight_min_value;
|
||||||
|
turn_weight_penalty = weight_min_value - new_weight;
|
||||||
|
turn_weight_penalties[edge.data.turn_id] = turn_weight_penalty;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new_weight = weight_min_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update edge weight
|
||||||
|
edge.data.weight = new_weight + turn_weight_penalty;
|
||||||
|
edge.data.duration = new_duration + turn_duration_penalty;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (updated_segments.size() > 0)
|
||||||
|
{
|
||||||
|
tbb::parallel_for(tbb::blocked_range<std::size_t>(0, edge_based_edge_list.size()),
|
||||||
|
[&](const auto &range) {
|
||||||
|
for (auto index = range.begin(); index < range.end(); ++index)
|
||||||
|
{
|
||||||
|
update_edge(edge_based_edge_list[index]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (update_turn_penalties || update_conditional_turns)
|
||||||
|
{
|
||||||
|
tbb::parallel_invoke(
|
||||||
|
[&] {
|
||||||
|
extractor::files::writeTurnWeightPenalty(
|
||||||
|
config.GetPath(".osrm.turn_weight_penalties"), turn_weight_penalties);
|
||||||
|
},
|
||||||
|
[&] {
|
||||||
|
extractor::files::writeTurnDurationPenalty(
|
||||||
|
config.GetPath(".osrm.turn_duration_penalties"), turn_duration_penalties);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#if !defined(NDEBUG)
|
#if !defined(NDEBUG)
|
||||||
if (config.turn_penalty_lookup_paths.empty())
|
if (config.turn_penalty_lookup_paths.empty())
|
||||||
{ // don't check weights consistency with turn updates that can break assertion
|
{ // don't check weights consistency with turn updates that can break assertion
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user