Enables the use of multiple segment-speed-files on the osrm-contract

command line, and exposes the file name used for each edge in the debug
tiles.
This commit is contained in:
Daniel Patterson
2016-03-14 23:03:19 -07:00
committed by Patrick Niklaus
parent 80f008684d
commit 11b356e55f
15 changed files with 442 additions and 54 deletions
+87 -27
View File
@@ -71,8 +71,9 @@ int Contractor::Run()
std::size_t max_edge_id = LoadEdgeExpandedGraph(
config.edge_based_graph_path, edge_based_edge_list, config.edge_segment_lookup_path,
config.edge_penalty_path, config.segment_speed_lookup_path, config.node_based_graph_path,
config.geometry_path, config.rtree_leaf_path);
config.edge_penalty_path, config.segment_speed_lookup_paths, config.node_based_graph_path,
config.geometry_path, config.datasource_names_path, config.datasource_indexes_path,
config.rtree_leaf_path);
// Contracting the edge-expanded graph
@@ -127,15 +128,17 @@ std::size_t Contractor::LoadEdgeExpandedGraph(
util::DeallocatingVector<extractor::EdgeBasedEdge> &edge_based_edge_list,
const std::string &edge_segment_lookup_filename,
const std::string &edge_penalty_filename,
const std::string &segment_speed_filename,
const std::vector<std::string> &segment_speed_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)
{
util::SimpleLogger().Write() << "Opening " << edge_based_graph_filename;
boost::filesystem::ifstream input_stream(edge_based_graph_filename, std::ios::binary);
const bool update_edge_weights = segment_speed_filename != "";
const bool update_edge_weights = !segment_speed_filenames.empty();
boost::filesystem::ifstream edge_segment_input_stream;
boost::filesystem::ifstream edge_fixed_penalties_input_stream;
@@ -167,22 +170,36 @@ std::size_t Contractor::LoadEdgeExpandedGraph(
util::SimpleLogger().Write() << "Reading " << number_of_edges
<< " edges from the edge based graph";
std::unordered_map<std::pair<OSMNodeID, OSMNodeID>, unsigned> segment_speed_lookup;
std::unordered_map<std::pair<OSMNodeID, OSMNodeID>, std::pair<unsigned, uint8_t>>
segment_speed_lookup;
if (update_edge_weights)
{
util::SimpleLogger().Write()
<< "Segment speed data supplied, will update edge weights from "
<< segment_speed_filename;
io::CSVReader<3> csv_in(segment_speed_filename);
csv_in.set_header("from_node", "to_node", "speed");
uint64_t from_node_id{};
uint64_t to_node_id{};
unsigned speed{};
while (csv_in.read_row(from_node_id, to_node_id, speed))
uint8_t file_id = 1;
for (auto segment_speed_filename : segment_speed_filenames)
{
segment_speed_lookup[std::make_pair(OSMNodeID(from_node_id), OSMNodeID(to_node_id))] =
speed;
util::SimpleLogger().Write()
<< "Segment speed data supplied, will update edge weights from "
<< segment_speed_filename;
io::CSVReader<3> csv_in(segment_speed_filename);
csv_in.set_header("from_node", "to_node", "speed");
uint64_t from_node_id{};
uint64_t to_node_id{};
unsigned speed{};
while (csv_in.read_row(from_node_id, to_node_id, speed))
{
segment_speed_lookup[std::make_pair(OSMNodeID(from_node_id),
OSMNodeID(to_node_id))] =
std::make_pair(speed, file_id);
}
++file_id;
// Check for overflow
if (file_id == 0)
{
throw util::exception(
"Sorry, there's a limit of 254 segment speed files, you supplied too many");
}
}
std::vector<extractor::QueryNode> internal_to_external_node_map;
@@ -241,6 +258,14 @@ std::size_t Contractor::LoadEdgeExpandedGraph(
}
}
// This is a list of the "data source id" for every segment in the compressed
// geometry container. We assume that everything so far has come from the
// profile (data source 0). Here, we replace the 0's with the index of the
// CSV file that supplied the value that gets used for that segment, then
// we write out this list so that it can be returned by the debugging
// vector tiles later on.
std::vector<uint8_t> m_geometry_datasource(m_geometry_list.size(), 0);
// Now, we iterate over all the segments stored in the StaticRTree, updating
// the packed geometry weights in the `.geometries` file (note: we do not
// update the RTree itself, we just use the leaf nodes to iterate over all segments)
@@ -297,12 +322,16 @@ std::size_t Contractor::LoadEdgeExpandedGraph(
segment_speed_lookup.find(std::make_pair(u->node_id, v->node_id));
if (forward_speed_iter != segment_speed_lookup.end())
{
int new_segment_weight = std::max(
1, static_cast<int>(std::floor(
(segment_length * 10.) / (forward_speed_iter->second / 3.6) +
.5)));
int new_segment_weight =
std::max(1, static_cast<int>(std::floor(
(segment_length * 10.) /
(forward_speed_iter->second.first / 3.6) +
.5)));
m_geometry_list[forward_begin + leaf_object.fwd_segment_position]
.weight = new_segment_weight;
m_geometry_datasource[forward_begin +
leaf_object.fwd_segment_position] =
forward_speed_iter->second.second;
}
}
if (leaf_object.reverse_packed_geometry_id != SPECIAL_EDGEID)
@@ -338,12 +367,15 @@ std::size_t Contractor::LoadEdgeExpandedGraph(
segment_speed_lookup.find(std::make_pair(u->node_id, v->node_id));
if (reverse_speed_iter != segment_speed_lookup.end())
{
int new_segment_weight = std::max(
1, static_cast<int>(std::floor(
(segment_length * 10.) / (reverse_speed_iter->second / 3.6) +
.5)));
int new_segment_weight =
std::max(1, static_cast<int>(std::floor(
(segment_length * 10.) /
(reverse_speed_iter->second.first / 3.6) +
.5)));
m_geometry_list[reverse_begin + rev_segment_position].weight =
new_segment_weight;
m_geometry_datasource[reverse_begin + rev_segment_position] =
reverse_speed_iter->second.second;
}
}
}
@@ -370,6 +402,34 @@ std::size_t Contractor::LoadEdgeExpandedGraph(
number_of_compressed_geometries *
sizeof(extractor::CompressedEdgeContainer::CompressedEdge));
}
{
std::ofstream datasource_stream(datasource_indexes_filename, std::ios::binary);
if (!datasource_stream)
{
throw util::exception("Failed to open " + datasource_indexes_filename +
" for writing");
}
auto number_of_datasource_entries = m_geometry_datasource.size();
datasource_stream.write(reinterpret_cast<const char *>(&number_of_datasource_entries),
sizeof(number_of_datasource_entries));
datasource_stream.write(reinterpret_cast<char *>(&(m_geometry_datasource[0])),
number_of_datasource_entries * sizeof(uint8_t));
}
{
std::ofstream datasource_stream(datasource_names_filename, std::ios::binary);
if (!datasource_stream)
{
throw util::exception("Failed to open " + datasource_names_filename +
" for writing");
}
datasource_stream << "lua profile" << std::endl;
for (auto const &name : segment_speed_filenames)
{
datasource_stream << name << std::endl;
}
}
}
// TODO: can we read this in bulk? util::DeallocatingVector isn't necessarily
@@ -413,9 +473,9 @@ std::size_t Contractor::LoadEdgeExpandedGraph(
// This sets the segment weight using the same formula as the
// EdgeBasedGraphFactory for consistency. The *why* of this formula
// is lost in the annals of time.
int new_segment_weight =
std::max(1, static_cast<int>(std::floor(
(segment_length * 10.) / (speed_iter->second / 3.6) + .5)));
int new_segment_weight = std::max(
1, static_cast<int>(std::floor(
(segment_length * 10.) / (speed_iter->second.first / 3.6) + .5)));
new_weight += new_segment_weight;
}
else