Enable just-before-contraction updates to edge weights. For small
datasets, this enables things like traffic-based updates in the shortest possible processing turnaround time.
This commit is contained in:
@@ -26,12 +26,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "edge_based_graph_factory.hpp"
|
||||
#include "../algorithms/coordinate_calculation.hpp"
|
||||
#include "../data_structures/percent.hpp"
|
||||
#include "../util/compute_angle.hpp"
|
||||
#include "../util/integer_range.hpp"
|
||||
#include "../util/lua_util.hpp"
|
||||
#include "../util/simple_logger.hpp"
|
||||
#include "../util/timing_util.hpp"
|
||||
#include "../util/osrm_exception.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
@@ -221,7 +223,11 @@ void EdgeBasedGraphFactory::FlushVectorToStream(
|
||||
}
|
||||
|
||||
void EdgeBasedGraphFactory::Run(const std::string &original_edge_data_filename,
|
||||
lua_State *lua_state)
|
||||
lua_State *lua_state,
|
||||
const std::string &edge_segment_lookup_filename,
|
||||
const std::string &edge_penalty_filename,
|
||||
const bool generate_edge_lookup
|
||||
)
|
||||
{
|
||||
TIMER_START(renumber);
|
||||
m_max_edge_id = RenumberEdges() - 1;
|
||||
@@ -232,7 +238,9 @@ void EdgeBasedGraphFactory::Run(const std::string &original_edge_data_filename,
|
||||
TIMER_STOP(generate_nodes);
|
||||
|
||||
TIMER_START(generate_edges);
|
||||
GenerateEdgeExpandedEdges(original_edge_data_filename, lua_state);
|
||||
GenerateEdgeExpandedEdges(original_edge_data_filename, lua_state,
|
||||
edge_segment_lookup_filename,edge_penalty_filename, generate_edge_lookup
|
||||
);
|
||||
TIMER_STOP(generate_edges);
|
||||
|
||||
SimpleLogger().Write() << "Timing statistics for edge-expanded graph:";
|
||||
@@ -317,7 +325,11 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes()
|
||||
|
||||
/// Actually it also generates OriginalEdgeData and serializes them...
|
||||
void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
const std::string &original_edge_data_filename, lua_State *lua_state)
|
||||
const std::string &original_edge_data_filename, lua_State *lua_state,
|
||||
const std::string &edge_segment_lookup_filename,
|
||||
const std::string &edge_fixed_penalties_filename,
|
||||
const bool generate_edge_lookup
|
||||
)
|
||||
{
|
||||
SimpleLogger().Write() << "generating edge-expanded edges";
|
||||
|
||||
@@ -325,6 +337,14 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
unsigned original_edges_counter = 0;
|
||||
|
||||
std::ofstream edge_data_file(original_edge_data_filename.c_str(), std::ios::binary);
|
||||
std::ofstream edge_segment_file;
|
||||
std::ofstream edge_penalty_file;
|
||||
|
||||
if (generate_edge_lookup)
|
||||
{
|
||||
edge_segment_file.open(edge_segment_lookup_filename.c_str(), std::ios::binary);
|
||||
edge_penalty_file.open(edge_fixed_penalties_filename.c_str(), std::ios::binary);
|
||||
}
|
||||
|
||||
// writes a dummy value that is updated later
|
||||
edge_data_file.write((char *)&original_edges_counter, sizeof(unsigned));
|
||||
@@ -437,7 +457,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
if (turn_instruction == TurnInstruction::UTurn)
|
||||
{
|
||||
distance += speed_profile.u_turn_penalty;
|
||||
}
|
||||
}
|
||||
|
||||
distance += turn_penalty;
|
||||
|
||||
const bool edge_is_compressed = m_compressed_edge_container.HasEntryForID(e1);
|
||||
@@ -464,6 +485,59 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
|
||||
m_edge_based_edge_list.emplace_back(edge_data1.edge_id, edge_data2.edge_id,
|
||||
m_edge_based_edge_list.size(), distance, true, false);
|
||||
|
||||
|
||||
// Here is where we write out the mapping between the edge-expanded edges, and
|
||||
// the node-based edges that are originally used to calculate the `distance`
|
||||
// for the edge-expanded edges. About 40 lines back, there is:
|
||||
//
|
||||
// unsigned distance = edge_data1.distance;
|
||||
//
|
||||
// This tells us that the weight for an edge-expanded-edge is based on the weight
|
||||
// of the *source* node-based edge. Therefore, we will look up the individual
|
||||
// segments of the source node-based edge, and write out a mapping between
|
||||
// those and the edge-based-edge ID.
|
||||
// External programs can then use this mapping to quickly perform
|
||||
// updates to the edge-expanded-edge based directly on its ID.
|
||||
if (generate_edge_lookup)
|
||||
{
|
||||
unsigned fixed_penalty = distance - edge_data1.distance;
|
||||
edge_penalty_file.write(reinterpret_cast<const char *>(&fixed_penalty), sizeof(fixed_penalty));
|
||||
if (edge_is_compressed)
|
||||
{
|
||||
const auto node_based_edges = m_compressed_edge_container.GetBucketReference(e1);
|
||||
NodeID previous = node_u;
|
||||
|
||||
const unsigned node_count = node_based_edges.size()+1;
|
||||
edge_segment_file.write(reinterpret_cast<const char *>(&node_count), sizeof(node_count));
|
||||
const QueryNode &first_node = m_node_info_list[previous];
|
||||
edge_segment_file.write(reinterpret_cast<const char *>(&first_node.node_id), sizeof(first_node.node_id));
|
||||
|
||||
for (auto target_node : node_based_edges)
|
||||
{
|
||||
const QueryNode &from = m_node_info_list[previous];
|
||||
const QueryNode &to = m_node_info_list[target_node.first];
|
||||
const double segment_length = coordinate_calculation::great_circle_distance(from.lat, from.lon, to.lat, to.lon);
|
||||
|
||||
edge_segment_file.write(reinterpret_cast<const char *>(&to.node_id), sizeof(to.node_id));
|
||||
edge_segment_file.write(reinterpret_cast<const char *>(&segment_length), sizeof(segment_length));
|
||||
edge_segment_file.write(reinterpret_cast<const char *>(&target_node.second), sizeof(target_node.second));
|
||||
previous = target_node.first;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
static const unsigned node_count = 2;
|
||||
const QueryNode from = m_node_info_list[node_u];
|
||||
const QueryNode to = m_node_info_list[node_v];
|
||||
const double segment_length = coordinate_calculation::great_circle_distance(from.lat, from.lon, to.lat, to.lon);
|
||||
edge_segment_file.write(reinterpret_cast<const char *>(&node_count), sizeof(node_count));
|
||||
edge_segment_file.write(reinterpret_cast<const char *>(&from.node_id), sizeof(from.node_id));
|
||||
edge_segment_file.write(reinterpret_cast<const char *>(&to.node_id), sizeof(to.node_id));
|
||||
edge_segment_file.write(reinterpret_cast<const char *>(&segment_length), sizeof(segment_length));
|
||||
edge_segment_file.write(reinterpret_cast<const char *>(&edge_data1.distance), sizeof(edge_data1.distance));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,11 @@ class EdgeBasedGraphFactory
|
||||
SpeedProfileProperties speed_profile);
|
||||
|
||||
void Run(const std::string &original_edge_data_filename,
|
||||
lua_State *lua_state);
|
||||
lua_State *lua_state,
|
||||
const std::string &edge_segment_lookup_filename,
|
||||
const std::string &edge_penalty_filename,
|
||||
const bool generate_edge_lookup
|
||||
);
|
||||
|
||||
void GetEdgeBasedEdges(DeallocatingVector<EdgeBasedEdge> &edges);
|
||||
|
||||
@@ -100,7 +104,11 @@ class EdgeBasedGraphFactory
|
||||
unsigned RenumberEdges();
|
||||
void GenerateEdgeExpandedNodes();
|
||||
void GenerateEdgeExpandedEdges(const std::string &original_edge_data_filename,
|
||||
lua_State *lua_state);
|
||||
lua_State *lua_state,
|
||||
const std::string &edge_segment_lookup_filename,
|
||||
const std::string &edge_fixed_penalties_filename,
|
||||
const bool generate_edge_lookup
|
||||
);
|
||||
|
||||
void InsertEdgeBasedNode(const NodeID u, const NodeID v);
|
||||
|
||||
|
||||
@@ -532,7 +532,11 @@ extractor::BuildEdgeExpandedGraph(std::vector<QueryNode> &internal_to_external_n
|
||||
|
||||
compressed_edge_container.SerializeInternalVector(config.geometry_output_path);
|
||||
|
||||
edge_based_graph_factory.Run(config.edge_output_path, lua_state);
|
||||
edge_based_graph_factory.Run(config.edge_output_path, lua_state,
|
||||
config.edge_segment_lookup_path,
|
||||
config.edge_penalty_path,
|
||||
config.generate_edge_lookup
|
||||
);
|
||||
lua_close(lua_state);
|
||||
|
||||
edge_based_graph_factory.GetEdgeBasedEdges(edge_based_edge_list);
|
||||
|
||||
@@ -61,7 +61,10 @@ ExtractorOptions::ParseArguments(int argc, char *argv[], ExtractorConfig &extrac
|
||||
"threads,t",
|
||||
boost::program_options::value<unsigned int>(&extractor_config.requested_num_threads)
|
||||
->default_value(tbb::task_scheduler_init::default_num_threads()),
|
||||
"Number of threads to use");
|
||||
"Number of threads to use")(
|
||||
"generate-edge-lookup",boost::program_options::value<bool>(
|
||||
&extractor_config.generate_edge_lookup)->implicit_value(true)->default_value(false),
|
||||
"Generate a lookup table for internal edge-expanded-edge IDs to OSM node pairs");
|
||||
|
||||
// hidden options, will be allowed both on command line and in config file, but will not be
|
||||
// shown to the user
|
||||
@@ -70,6 +73,7 @@ ExtractorOptions::ParseArguments(int argc, char *argv[], ExtractorConfig &extrac
|
||||
&extractor_config.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);
|
||||
@@ -149,6 +153,8 @@ void ExtractorOptions::GenerateOutputFilesNames(ExtractorConfig &extractor_confi
|
||||
extractor_config.node_output_path = input_path.string();
|
||||
extractor_config.rtree_nodes_output_path = input_path.string();
|
||||
extractor_config.rtree_leafs_output_path = input_path.string();
|
||||
extractor_config.edge_segment_lookup_path = input_path.string();
|
||||
extractor_config.edge_penalty_path = input_path.string();
|
||||
std::string::size_type pos = extractor_config.output_file_name.find(".osm.bz2");
|
||||
if (pos == std::string::npos)
|
||||
{
|
||||
@@ -177,6 +183,8 @@ void ExtractorOptions::GenerateOutputFilesNames(ExtractorConfig &extractor_confi
|
||||
extractor_config.edge_graph_output_path.append(".osrm.ebg");
|
||||
extractor_config.rtree_nodes_output_path.append(".osrm.ramIndex");
|
||||
extractor_config.rtree_leafs_output_path.append(".osrm.fileIndex");
|
||||
extractor_config.edge_segment_lookup_path.append(".osrm.edge_segment_lookup");
|
||||
extractor_config.edge_penalty_path.append(".osrm.edge_penalties");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -190,6 +198,8 @@ void ExtractorOptions::GenerateOutputFilesNames(ExtractorConfig &extractor_confi
|
||||
extractor_config.edge_graph_output_path.replace(pos, 5, ".osrm.ebg");
|
||||
extractor_config.rtree_nodes_output_path.replace(pos, 5, ".osrm.ramIndex");
|
||||
extractor_config.rtree_leafs_output_path.replace(pos, 5, ".osrm.fileIndex");
|
||||
extractor_config.edge_segment_lookup_path.replace(pos,5, ".osrm.edge_segment_lookup");
|
||||
extractor_config.edge_penalty_path.replace(pos,5, ".osrm.edge_penalties");
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -204,5 +214,7 @@ void ExtractorOptions::GenerateOutputFilesNames(ExtractorConfig &extractor_confi
|
||||
extractor_config.edge_graph_output_path.replace(pos, 8, ".osrm.ebg");
|
||||
extractor_config.rtree_nodes_output_path.replace(pos, 8, ".osrm.ramIndex");
|
||||
extractor_config.rtree_leafs_output_path.replace(pos, 8, ".osrm.fileIndex");
|
||||
extractor_config.edge_segment_lookup_path.replace(pos,8, ".osrm.edge_segment_lookup");
|
||||
extractor_config.edge_penalty_path.replace(pos,8, ".osrm.edge_penalties");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,10 @@ struct ExtractorConfig
|
||||
std::string rtree_leafs_output_path;
|
||||
|
||||
unsigned requested_num_threads;
|
||||
|
||||
bool generate_edge_lookup;
|
||||
std::string edge_penalty_path;
|
||||
std::string edge_segment_lookup_path;
|
||||
};
|
||||
|
||||
struct ExtractorOptions
|
||||
|
||||
Reference in New Issue
Block a user