initial version of intersection classification

This commit is contained in:
Moritz Kobitzsch
2016-04-26 13:27:40 +02:00
committed by Patrick Niklaus
parent 6aa97048df
commit ba074b0116
33 changed files with 1065 additions and 262 deletions
+47
View File
@@ -4,6 +4,10 @@
#include "engine/polyline_compressor.hpp"
#include "util/integer_range.hpp"
#include "util/guidance/bearing_class.hpp"
#include "util/guidance/entry_class.hpp"
#include "util/guidance/toolkit.hpp"
#include <boost/assert.hpp>
#include <boost/optional.hpp>
@@ -93,6 +97,47 @@ util::json::Array coordinateToLonLat(const util::Coordinate coordinate)
return array;
}
util::json::Object getConnection(const bool entry_allowed, const double bearing)
{
util::json::Object result;
result.values["entry_allowed"] = entry_allowed ? "true" : "false";
result.values["bearing"] = bearing;
return result;
}
util::json::Array getConnections(const util::guidance::EntryClass entry_class,
const util::guidance::BearingClass bearing_class)
{
util::json::Array result;
const auto bearings = bearing_class.getAvailableBearings();
for (size_t connection = 0; connection < bearings.size(); ++connection)
{
result.values.push_back(
getConnection(entry_class.allowsEntry(connection), bearings[connection]));
}
return result;
}
util::json::Object getIntersection(const guidance::StepManeuver maneuver)
{
util::json::Object result;
// bearings are oriented in the direction of driving. For the in-bearing, we actually need to
// find the bearing from the view of the intersection. This means we have to rotate the bearing
// by 180 degree.
const auto rotated_bearing_before = (maneuver.bearing_before >= 180.0)
? (maneuver.bearing_before - 180.0)
: (maneuver.bearing_before + 180.0);
result.values["from_bearing"] =
getMatchingDiscreteBearing(false, rotated_bearing_before, maneuver.entry_class,
maneuver.bearing_class.getAvailableBearings());
result.values["to_bearing"] =
getMatchingDiscreteBearing(true, maneuver.bearing_after, maneuver.entry_class,
maneuver.bearing_class.getAvailableBearings());
result.values["connections"] = getConnections(maneuver.entry_class, maneuver.bearing_class);
return result;
}
// FIXME this actually needs to be configurable from the profiles
std::string modeToString(const extractor::TravelMode mode)
{
@@ -150,6 +195,7 @@ util::json::Object makeStepManeuver(const guidance::StepManeuver &maneuver)
if (maneuver.waypoint_type == guidance::WaypointType::None)
{
step_maneuver.values["type"] = detail::instructionTypeToString(maneuver.instruction.type);
step_maneuver.values["intersection"] = detail::getIntersection(maneuver);
}
else
step_maneuver.values["type"] = detail::waypointTypeToString(maneuver.waypoint_type);
@@ -169,6 +215,7 @@ util::json::Object makeStepManeuver(const guidance::StepManeuver &maneuver)
// actually compute the correct locations of the intersections
if (!maneuver.intersections.empty() && maneuver.exit == 0)
step_maneuver.values["exit"] = maneuver.intersections.size();
return step_maneuver;
}
+17 -19
View File
@@ -37,20 +37,23 @@ StepManeuver stepManeuverFromGeometry(extractor::guidance::TurnInstruction instr
pre_turn_bearing =
util::coordinate_calculation::bearing(pre_turn_coordinate, turn_coordinate);
}
return StepManeuver{
std::move(turn_coordinate),
pre_turn_bearing,
post_turn_bearing,
std::move(instruction),
waypoint_type,
INVALID_EXIT_NR,
{} // no intermediate intersections
};
return StepManeuver{std::move(turn_coordinate),
pre_turn_bearing,
post_turn_bearing,
std::move(instruction),
waypoint_type,
INVALID_EXIT_NR,
// BearingClass,EntryClass, and Intermediate intersections are unknown yet
{},
{},
{}};
}
StepManeuver stepManeuverFromGeometry(extractor::guidance::TurnInstruction instruction,
const LegGeometry &leg_geometry,
const std::size_t segment_index)
const std::size_t segment_index,
util::guidance::EntryClass entry_class,
util::guidance::BearingClass bearing_class)
{
auto turn_index = leg_geometry.BackIndex(segment_index);
BOOST_ASSERT(turn_index > 0);
@@ -66,15 +69,10 @@ StepManeuver stepManeuverFromGeometry(extractor::guidance::TurnInstruction instr
const double post_turn_bearing =
util::coordinate_calculation::bearing(turn_coordinate, post_turn_coordinate);
return StepManeuver{
std::move(turn_coordinate),
pre_turn_bearing,
post_turn_bearing,
std::move(instruction),
WaypointType::None,
INVALID_EXIT_NR,
{} // no intermediate intersections
};
// add a step without intermediate intersections
return StepManeuver{std::move(turn_coordinate), pre_turn_bearing, post_turn_bearing,
std::move(instruction), WaypointType::None, INVALID_EXIT_NR,
std::move(entry_class), std::move(bearing_class), {}};
}
} // ns detail
} // ns engine
+2 -1
View File
@@ -444,7 +444,8 @@ std::vector<RouteStep> postProcess(std::vector<RouteStep> steps)
auto addIntersection = [](RouteStep into, const RouteStep &last_step,
const RouteStep &intersection) {
into.maneuver.intersections.push_back(
{last_step.duration, last_step.distance, intersection.maneuver.location});
{last_step.duration, last_step.distance, intersection.maneuver.location,
intersection.maneuver.entry_class, intersection.maneuver.bearing_class});
return forwardInto(std::move(into), intersection);
};
+76 -1
View File
@@ -11,6 +11,7 @@
#include "extractor/suffix_table.hpp"
#include "extractor/guidance/toolkit.hpp"
#include "extractor/guidance/turn_analysis.hpp"
#include <boost/assert.hpp>
#include <boost/numeric/conversion/cast.hpp>
@@ -22,6 +23,7 @@
#include <limits>
#include <sstream>
#include <string>
#include <unordered_map>
namespace osrm
{
@@ -326,6 +328,10 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
guidance::TurnAnalysis turn_analysis(*m_node_based_graph, m_node_info_list, *m_restriction_map,
m_barrier_nodes, m_compressed_edge_container, name_table,
street_name_suffix_table);
bearing_class_by_node_based_node.resize(m_node_based_graph->GetNumberOfNodes(),
std::numeric_limits<std::uint32_t>::max());
for (const auto node_u : util::irange(0u, m_node_based_graph->GetNumberOfNodes()))
{
progress.PrintStatus(node_u);
@@ -340,6 +346,40 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
auto possible_turns = turn_analysis.getTurns(node_u, edge_from_u);
const NodeID node_v = m_node_based_graph->GetTarget(edge_from_u);
// the entry class depends on the turn, so we have to classify the interesction for
// every edge
const auto turn_classification = classifyIntersection(
node_v, turn_analysis.getIntersection(node_u, edge_from_u), *m_node_based_graph,
m_compressed_edge_container, m_node_info_list);
const auto entry_class_id = [&](const util::guidance::EntryClass entry_class) {
if (0 == entry_class_hash.count(entry_class))
{
const auto id = static_cast<std::uint16_t>(entry_class_hash.size());
entry_class_hash[entry_class] = id;
return id;
}
else
{
return entry_class_hash.find(entry_class)->second;
}
}(turn_classification.first);
const auto bearing_class_id = [&](const util::guidance::BearingClass bearing_class) {
if (0 == bearing_class_hash.count(bearing_class))
{
const auto id = static_cast<std::uint32_t>(bearing_class_hash.size());
bearing_class_hash[bearing_class] = id;
return id;
}
else
{
return bearing_class_hash.find(bearing_class)->second;
}
}(turn_classification.second);
bearing_class_by_node_based_node[node_v] = bearing_class_id;
for (const auto turn : possible_turns)
{
const double turn_angle = turn.angle;
@@ -373,7 +413,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
BOOST_ASSERT(m_compressed_edge_container.HasEntryForID(edge_from_u));
original_edge_data_vector.emplace_back(
m_compressed_edge_container.GetPositionForID(edge_from_u), edge_data1.name_id,
turn_instruction, edge_data1.travel_mode);
turn_instruction, entry_class_id, edge_data1.travel_mode);
++original_edges_counter;
@@ -469,6 +509,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
}
}
util::SimpleLogger().Write() << "Created " << entry_class_hash.size() << " entry classes and "
<< bearing_class_hash.size() << " Bearing Classes";
FlushVectorToStream(edge_data_file, original_edge_data_vector);
// Finally jump back to the empty space at the beginning and write length prefix
@@ -493,6 +536,38 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
<< " turns over barriers";
}
std::vector<util::guidance::BearingClass> EdgeBasedGraphFactory::GetBearingClasses() const
{
std::vector<util::guidance::BearingClass> result(bearing_class_hash.size());
for (const auto &pair : bearing_class_hash)
{
BOOST_ASSERT(pair.second < result.size());
result[pair.second] = pair.first;
}
return result;
}
const std::vector<BearingClassID> &EdgeBasedGraphFactory::GetBearingClassIds() const
{
return bearing_class_by_node_based_node;
}
std::vector<BearingClassID> &EdgeBasedGraphFactory::GetBearingClassIds()
{
return bearing_class_by_node_based_node;
}
std::vector<util::guidance::EntryClass> EdgeBasedGraphFactory::GetEntryClasses() const
{
std::vector<util::guidance::EntryClass> result(entry_class_hash.size());
for (const auto &pair : entry_class_hash)
{
BOOST_ASSERT(pair.second < result.size());
result[pair.second] = pair.first;
}
return result;
}
int EdgeBasedGraphFactory::GetTurnPenalty(double angle, lua_State *lua_state) const
{
BOOST_ASSERT(lua_state != nullptr);
+54 -16
View File
@@ -9,20 +9,18 @@
#include "extractor/scripting_environment.hpp"
#include "extractor/raster_source.hpp"
#include "util/graph_loader.hpp"
#include "util/io.hpp"
#include "util/lua_util.hpp"
#include "util/make_unique.hpp"
#include "util/name_table.hpp"
#include "util/simple_logger.hpp"
#include "util/timing_util.hpp"
#include "util/lua_util.hpp"
#include "util/graph_loader.hpp"
#include "util/name_table.hpp"
#include "util/typedefs.hpp"
#include "util/static_graph.hpp"
#include "util/static_rtree.hpp"
#include "extractor/compressed_edge_container.hpp"
#include "extractor/restriction_map.hpp"
#include "util/static_graph.hpp"
#include "util/static_rtree.hpp"
#include "extractor/tarjan_scc.hpp"
@@ -41,14 +39,14 @@
#include <algorithm>
#include <atomic>
#include <bitset>
#include <chrono>
#include <chrono>
#include <fstream>
#include <iostream>
#include <thread>
#include <unordered_map>
#include <vector>
#include <bitset>
#include <chrono>
namespace osrm
{
@@ -159,8 +157,7 @@ int Extractor::run()
// parse OSM entities in parallel, store in resulting vectors
tbb::parallel_for(
tbb::blocked_range<std::size_t>(0, osm_elements.size()),
[&](const tbb::blocked_range<std::size_t> &range)
{
[&](const tbb::blocked_range<std::size_t> &range) {
ExtractionNode result_node;
ExtractionWay result_way;
auto &local_context = scripting_environment.GetContex();
@@ -269,10 +266,10 @@ int Extractor::run()
std::vector<bool> node_is_startpoint;
std::vector<EdgeWeight> edge_based_node_weights;
std::vector<QueryNode> internal_to_external_node_map;
auto graph_size = BuildEdgeExpandedGraph(main_context.state, main_context.properties,
internal_to_external_node_map,
edge_based_node_list, node_is_startpoint,
edge_based_node_weights, edge_based_edge_list);
auto graph_size = BuildEdgeExpandedGraph(
main_context.state, main_context.properties, internal_to_external_node_map,
edge_based_node_list, node_is_startpoint, edge_based_node_weights, edge_based_edge_list,
config.intersection_class_data_output_path);
auto number_of_node_based_nodes = graph_size.first;
auto max_edge_id = graph_size.second;
@@ -474,7 +471,8 @@ Extractor::BuildEdgeExpandedGraph(lua_State *lua_state,
std::vector<EdgeBasedNode> &node_based_edge_list,
std::vector<bool> &node_is_startpoint,
std::vector<EdgeWeight> &edge_based_node_weights,
util::DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list)
util::DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list,
const std::string &intersection_class_output_file)
{
std::unordered_set<NodeID> barrier_nodes;
std::unordered_set<NodeID> traffic_lights;
@@ -508,6 +506,11 @@ Extractor::BuildEdgeExpandedGraph(lua_State *lua_state,
auto max_edge_id = edge_based_graph_factory.GetHighestEdgeID();
const std::size_t number_of_node_based_nodes = node_based_graph->GetNumberOfNodes();
WriteIntersectionClassificationData(
intersection_class_output_file, edge_based_graph_factory.GetBearingClassIds(),
edge_based_graph_factory.GetBearingClasses(), edge_based_graph_factory.GetEntryClasses());
return std::make_pair(number_of_node_based_nodes, max_edge_id);
}
@@ -601,5 +604,40 @@ void Extractor::WriteEdgeBasedGraph(
util::SimpleLogger().Write() << "Processed " << number_of_used_edges << " edges";
}
void Extractor::WriteIntersectionClassificationData(
const std::string &output_file_name,
const std::vector<BearingClassID> &node_based_intersection_classes,
const std::vector<util::guidance::BearingClass> &bearing_classes,
const std::vector<util::guidance::EntryClass> &entry_classes) const
{
std::ofstream file_out_stream(output_file_name.c_str(), std::ios::binary);
if (!file_out_stream)
{
util::SimpleLogger().Write(logWARNING) << "Failed to open " << output_file_name
<< " for writing";
return;
}
util::SimpleLogger().Write() << "Writing Intersection Classification Data";
TIMER_START(write_edges);
util::writeFingerprint(file_out_stream);
util::serializeVector(file_out_stream, node_based_intersection_classes);
static_assert(std::is_trivially_copyable<util::guidance::BearingClass>::value,
"BearingClass Serialization requires trivial copyable bearing classes");
util::serializeVector(file_out_stream, bearing_classes);
static_assert(std::is_trivially_copyable<util::guidance::EntryClass>::value,
"EntryClass Serialization requires trivial copyable entry classes");
util::serializeVector(file_out_stream, entry_classes);
TIMER_STOP(write_edges);
util::SimpleLogger().Write() << "ok, after " << TIMER_SEC(write_edges) << "s for "
<< node_based_intersection_classes.size() << " Indices into "
<< bearing_classes.size() << " bearing classes and "
<< entry_classes.size() << " entry classes";
}
}
}
+7
View File
@@ -9,8 +9,10 @@
#include <cstddef>
#include <iomanip>
#include <limits>
#include <map>
#include <set>
#include <unordered_set>
#include <unordered_map>
using osrm::util::guidance::getTurnDirection;
@@ -79,6 +81,11 @@ std::vector<TurnOperation> TurnAnalysis::getTurns(const NodeID from_nid, const E
return turns;
}
Intersection TurnAnalysis::getIntersection(const NodeID from_nid, const EdgeID via_eid) const
{
return intersection_generator(from_nid, via_eid);
}
// Sets basic turn types as fallback for otherwise unhandled turns
Intersection
TurnAnalysis::setTurnTypes(const NodeID from_nid, const EdgeID, Intersection intersection) const
@@ -0,0 +1,97 @@
#include "extractor/guidance/turn_classification.hpp"
#include "util/simple_logger.hpp"
namespace osrm
{
namespace extractor
{
namespace guidance
{
struct TurnPossibility
{
TurnPossibility(bool entry_allowed, double bearing)
: entry_allowed(entry_allowed), bearing(std::move(bearing))
{
}
TurnPossibility() : entry_allowed(false), bearing(0) {}
bool entry_allowed;
double bearing;
};
std::pair<util::guidance::EntryClass, util::guidance::BearingClass>
classifyIntersection(NodeID nid,
const Intersection &intersection,
const util::NodeBasedDynamicGraph &node_based_graph,
const extractor::CompressedEdgeContainer &compressed_geometries,
const std::vector<extractor::QueryNode> &query_nodes)
{
std::vector<TurnPossibility> turns;
const auto node_coordinate = util::Coordinate(query_nodes[nid].lon, query_nodes[nid].lat);
// generate a list of all turn angles between a base edge, the node and a current edge
for (const auto &road : intersection)
{
const auto eid = road.turn.eid;
const auto edge_coordinate = getRepresentativeCoordinate(
nid, node_based_graph.GetTarget(eid), eid, false, compressed_geometries, query_nodes);
const double bearing =
util::coordinate_calculation::bearing(node_coordinate, edge_coordinate);
turns.push_back({road.entry_allowed, bearing});
}
if (turns.empty())
return {};
std::sort(turns.begin(), turns.end(),
[](const TurnPossibility left, const TurnPossibility right) {
return left.bearing < right.bearing;
});
util::guidance::EntryClass entry_class;
util::guidance::BearingClass bearing_class;
std::size_t turn_index = 0;
for (std::size_t i = 0; i < turns.size(); ++i)
{
if (turns[i].entry_allowed)
entry_class.activate(turn_index);
if (bearing_class.addContinuous(turns[i].bearing))
++turn_index;
}
if (turn_index != turns.size())
{
util::SimpleLogger().Write(logDEBUG)
<< "Failed to provide full turn list for intersection: " << turn_index << " roads of "
<< turns.size() << " mapped.";
for (auto turn : turns)
std::cout << " " << (int)turn.bearing << " ("
<< (int)util::guidance::BearingClass::discreteBearingID(turn.bearing) << ")";
std::cout << std::endl;
for (const auto &road : intersection)
{
const auto eid = road.turn.eid;
const auto edge_coordinate =
getRepresentativeCoordinate(nid, node_based_graph.GetTarget(eid), eid, false,
compressed_geometries, query_nodes);
const double bearing =
util::coordinate_calculation::bearing(node_coordinate, edge_coordinate);
std::cout << " " << bearing;
}
std::cout << std::endl;
}
return std::make_pair(entry_class, bearing_class);
}
} // namespace guidance
} // namespace extractor
} // namespace osrm
+82 -37
View File
@@ -1,24 +1,25 @@
#include "extractor/original_edge_data.hpp"
#include "util/range_table.hpp"
#include "contractor/query_edge.hpp"
#include "extractor/query_node.hpp"
#include "extractor/profile_properties.hpp"
#include "engine/datafacade/datafacade_base.hpp"
#include "extractor/compressed_edge_container.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include "extractor/original_edge_data.hpp"
#include "extractor/profile_properties.hpp"
#include "extractor/query_node.hpp"
#include "extractor/travel_mode.hpp"
#include "storage/shared_barriers.hpp"
#include "storage/shared_datatype.hpp"
#include "storage/shared_memory.hpp"
#include "storage/storage.hpp"
#include "util/coordinate.hpp"
#include "util/exception.hpp"
#include "util/fingerprint.hpp"
#include "util/io.hpp"
#include "util/range_table.hpp"
#include "util/shared_memory_vector_wrapper.hpp"
#include "util/simple_logger.hpp"
#include "util/static_graph.hpp"
#include "util/static_rtree.hpp"
#include "engine/datafacade/datafacade_base.hpp"
#include "extractor/travel_mode.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include "storage/storage.hpp"
#include "storage/shared_datatype.hpp"
#include "storage/shared_barriers.hpp"
#include "storage/shared_memory.hpp"
#include "util/fingerprint.hpp"
#include "util/exception.hpp"
#include "util/simple_logger.hpp"
#include "util/typedefs.hpp"
#include "util/coordinate.hpp"
#ifdef __linux__
#include <sys/mman.h>
@@ -49,8 +50,7 @@ void deleteRegion(const SharedDataType region)
{
if (SharedMemory::RegionExists(region) && !SharedMemory::Remove(region))
{
const std::string name = [&]
{
const std::string name = [&] {
switch (region)
{
case CURRENT_REGIONS:
@@ -105,20 +105,14 @@ int Storage::Run()
// determine segment to use
bool segment2_in_use = SharedMemory::RegionExists(LAYOUT_2);
const storage::SharedDataType layout_region = [&]
{
const storage::SharedDataType layout_region = [&] {
return segment2_in_use ? LAYOUT_1 : LAYOUT_2;
}();
const storage::SharedDataType data_region = [&]
{
return segment2_in_use ? DATA_1 : DATA_2;
}();
const storage::SharedDataType previous_layout_region = [&]
{
const storage::SharedDataType data_region = [&] { return segment2_in_use ? DATA_1 : DATA_2; }();
const storage::SharedDataType previous_layout_region = [&] {
return segment2_in_use ? LAYOUT_2 : LAYOUT_1;
}();
const storage::SharedDataType previous_data_region = [&]
{
const storage::SharedDataType previous_data_region = [&] {
return segment2_in_use ? DATA_2 : DATA_1;
}();
@@ -136,7 +130,8 @@ int Storage::Run()
boost::filesystem::ifstream name_stream(config.names_data_path, std::ios::binary);
if (!name_stream)
{
throw util::exception("Could not open " + config.names_data_path.string() + " for reading.");
throw util::exception("Could not open " + config.names_data_path.string() +
" for reading.");
}
unsigned name_blocks = 0;
name_stream.read((char *)&name_blocks, sizeof(unsigned));
@@ -154,7 +149,8 @@ int Storage::Run()
boost::filesystem::ifstream edges_input_stream(config.edges_data_path, std::ios::binary);
if (!edges_input_stream)
{
throw util::exception("Could not open " + config.edges_data_path.string() + " for reading.");
throw util::exception("Could not open " + config.edges_data_path.string() +
" for reading.");
}
unsigned number_of_original_edges = 0;
edges_input_stream.read((char *)&number_of_original_edges, sizeof(unsigned));
@@ -168,6 +164,8 @@ int Storage::Run()
number_of_original_edges);
shared_layout_ptr->SetBlockSize<extractor::guidance::TurnInstruction>(
SharedDataLayout::TURN_INSTRUCTION, number_of_original_edges);
shared_layout_ptr->SetBlockSize<EntryClassID>(SharedDataLayout::ENTRY_CLASSID,
number_of_original_edges);
boost::filesystem::ifstream hsgr_input_stream(config.hsgr_data_path, std::ios::binary);
if (!hsgr_input_stream)
@@ -250,7 +248,8 @@ int Storage::Run()
boost::filesystem::ifstream geometry_input_stream(config.geometries_path, std::ios::binary);
if (!geometry_input_stream)
{
throw util::exception("Could not open " + config.geometries_path.string() + " for reading.");
throw util::exception("Could not open " + config.geometries_path.string() +
" for reading.");
}
unsigned number_of_geometries_indices = 0;
unsigned number_of_compressed_geometries = 0;
@@ -270,7 +269,8 @@ int Storage::Run()
std::ios::binary);
if (!geometry_datasource_input_stream)
{
throw util::exception("Could not open " + config.datasource_indexes_path.string() + " for reading.");
throw util::exception("Could not open " + config.datasource_indexes_path.string() +
" for reading.");
}
std::size_t number_of_compressed_datasources = 0;
if (geometry_datasource_input_stream)
@@ -287,7 +287,8 @@ int Storage::Run()
std::ios::binary);
if (!datasource_names_input_stream)
{
throw util::exception("Could not open " + config.datasource_names_path.string() + " for reading.");
throw util::exception("Could not open " + config.datasource_names_path.string() +
" for reading.");
}
std::vector<char> m_datasource_name_data;
std::vector<std::size_t> m_datasource_name_offsets;
@@ -331,7 +332,8 @@ int Storage::Run()
file_index_path_ptr +
shared_layout_ptr->GetBlockSize(SharedDataLayout::FILE_INDEX_PATH),
0);
std::copy(absolute_file_index_path.string().begin(), absolute_file_index_path.string().end(), file_index_path_ptr);
std::copy(absolute_file_index_path.string().begin(), absolute_file_index_path.string().end(),
file_index_path_ptr);
// Loading street names
unsigned *name_offsets_ptr = shared_layout_ptr->GetBlockPtr<unsigned, true>(
@@ -382,6 +384,9 @@ int Storage::Run()
shared_layout_ptr->GetBlockPtr<extractor::guidance::TurnInstruction, true>(
shared_memory_ptr, SharedDataLayout::TURN_INSTRUCTION);
EntryClassID *entry_class_id_ptr = shared_layout_ptr->GetBlockPtr<EntryClassID, true>(
shared_memory_ptr, SharedDataLayout::ENTRY_CLASSID);
extractor::OriginalEdgeData current_edge_data;
for (unsigned i = 0; i < number_of_original_edges; ++i)
{
@@ -390,6 +395,7 @@ int Storage::Run()
name_id_ptr[i] = current_edge_data.name_id;
travel_mode_ptr[i] = current_edge_data.travel_mode;
turn_instructions_ptr[i] = current_edge_data.turn_instruction;
entry_class_id_ptr[i] = current_edge_data.entry_classid;
}
edges_input_stream.close();
@@ -503,8 +509,7 @@ int Storage::Run()
{
const unsigned bucket = i / 32;
const unsigned offset = i % 32;
const unsigned value = [&]
{
const unsigned value = [&] {
unsigned return_value = 0;
if (0 != offset)
{
@@ -539,13 +544,16 @@ int Storage::Run()
hsgr_input_stream.close();
// load profile properties
auto profile_properties_ptr = shared_layout_ptr->GetBlockPtr<extractor::ProfileProperties, true>(shared_memory_ptr, SharedDataLayout::PROPERTIES);
auto profile_properties_ptr =
shared_layout_ptr->GetBlockPtr<extractor::ProfileProperties, true>(
shared_memory_ptr, SharedDataLayout::PROPERTIES);
boost::filesystem::ifstream profile_properties_stream(config.properties_path);
if (!profile_properties_stream)
{
util::exception("Could not open " + config.properties_path.string() + " for reading!");
}
profile_properties_stream.read(reinterpret_cast<char*>(profile_properties_ptr), sizeof(extractor::ProfileProperties));
profile_properties_stream.read(reinterpret_cast<char *>(profile_properties_ptr),
sizeof(extractor::ProfileProperties));
// acquire lock
SharedMemory *data_type_memory =
@@ -562,6 +570,43 @@ int Storage::Run()
barrier.no_running_queries_condition.wait(query_lock);
}
// load intersection classes
{
boost::filesystem::ifstream intersection_stream(config.intersection_class_path,
std::ios::binary);
if (!util::readAndCheckFingerprint(intersection_stream))
{
util::SimpleLogger().Write(logWARNING)
<< "Fingerprint does not match or reading failed";
}
std::vector<BearingClassID> bearing_class_id_table;
util::deserializeVector(intersection_stream, bearing_class_id_table);
shared_layout_ptr->SetBlockSize<BearingClassID>(SharedDataLayout::BEARING_CLASSID,
bearing_class_id_table.size());
auto bearing_id_ptr = shared_layout_ptr->GetBlockPtr<BearingClassID, true>(
shared_memory_ptr, SharedDataLayout::BEARING_CLASSID);
std::copy(bearing_class_id_table.begin(), bearing_class_id_table.end(), bearing_id_ptr);
auto bearing_class_ptr =
shared_layout_ptr->GetBlockPtr<util::guidance::BearingClass, true>(
shared_memory_ptr, SharedDataLayout::BEARING_CLASS);
std::vector<util::guidance::BearingClass> bearing_class_table;
util::deserializeVector(intersection_stream, bearing_class_table);
shared_layout_ptr->SetBlockSize<util::guidance::BearingClass>(
SharedDataLayout::BEARING_CLASS, bearing_class_table.size());
std::copy(bearing_class_table.begin(), bearing_class_table.end(), bearing_class_ptr);
auto entry_class_ptr =
shared_layout_ptr->GetBlockPtr<util::guidance::EntryClass, true>(
shared_memory_ptr, SharedDataLayout::ENTRY_CLASS);
std::vector<util::guidance::EntryClass> entry_class_table;
util::deserializeVector(intersection_stream, entry_class_table);
shared_layout_ptr->SetBlockSize<util::guidance::EntryClass>(
SharedDataLayout::ENTRY_CLASS, entry_class_table.size());
std::copy(entry_class_table.begin(), entry_class_table.end(), entry_class_ptr);
}
data_timestamp_ptr->layout = layout_region;
data_timestamp_ptr->data = data_region;
data_timestamp_ptr->timestamp += 1;
+4 -3
View File
@@ -14,8 +14,8 @@ StorageConfig::StorageConfig(const boost::filesystem::path &base)
geometries_path{base.string() + ".geometry"}, timestamp_path{base.string() + ".timestamp"},
datasource_names_path{base.string() + ".datasource_names"},
datasource_indexes_path{base.string() + ".datasource_indexes"},
names_data_path{base.string() + ".names"},
properties_path{base.string() + ".properties"}
names_data_path{base.string() + ".names"}, properties_path{base.string() + ".properties"},
intersection_class_path{base.string() + ".icd"}
{
}
@@ -32,7 +32,8 @@ bool StorageConfig::IsValid() const
boost::filesystem::is_regular_file(datasource_names_path) &&
boost::filesystem::is_regular_file(datasource_indexes_path) &&
boost::filesystem::is_regular_file(names_data_path) &&
boost::filesystem::is_regular_file(properties_path);
boost::filesystem::is_regular_file(properties_path) &&
boost::filesystem::is_regular_file(intersection_class_path);
}
}
}
+68
View File
@@ -0,0 +1,68 @@
#include "extractor/guidance/discrete_angle.hpp"
#include "util/guidance/bearing_class.hpp"
#include <boost/assert.hpp>
namespace osrm
{
namespace util
{
namespace guidance
{
static_assert(
360 / BearingClass::discrete_angle_step_size <= 8 * sizeof(BearingClass::FlagBaseType),
"The number of expressable bearings does not fit into the datatype used for storage.");
std::uint8_t BearingClass::discreteBearingID(double angle)
{
BOOST_ASSERT(angle >= 0. && angle <= 360.);
// shift angle by half the step size to have the class be located around the center
angle = (angle + 0.5 * BearingClass::discrete_angle_step_size);
if (angle > 360)
angle -= 360;
return std::uint8_t(angle / BearingClass::discrete_angle_step_size);
}
BearingClass::BearingClass() : available_bearings_mask(0) {}
bool BearingClass::operator==(const BearingClass &other) const
{
return other.available_bearings_mask == available_bearings_mask;
}
bool BearingClass::operator<(const BearingClass &other) const
{
return available_bearings_mask < other.available_bearings_mask;
}
bool BearingClass::addContinuous(const double angle)
{
return addDiscreteID(discreteBearingID(angle));
}
bool BearingClass::addDiscreteID(const std::uint8_t discrete_id)
{
const auto mask = (1 << discrete_id);
const auto is_new = (0 == (available_bearings_mask & mask));
available_bearings_mask |= mask;
return is_new;
}
std::vector<double> BearingClass::getAvailableBearings() const
{
std::vector<double> result;
// account for some basic inaccuracries of double
for (std::size_t discrete_id = 0; discrete_id * discrete_angle_step_size <= 361; ++discrete_id)
{
// ervery set bit indicates a bearing
if (available_bearings_mask & (1 << discrete_id))
result.push_back(discrete_id * discrete_angle_step_size);
}
return result;
}
} // namespace guidance
} // namespace extractor
} // namespace osrm
+38
View File
@@ -0,0 +1,38 @@
#include "util/guidance/entry_class.hpp"
#include <boost/assert.hpp>
namespace osrm
{
namespace util
{
namespace guidance
{
EntryClass::EntryClass() : enabled_entries_flags(0) {}
void EntryClass::activate(std::uint32_t index)
{
BOOST_ASSERT(index < 8 * sizeof(FlagBaseType));
enabled_entries_flags |= (1 << index);
}
bool EntryClass::allowsEntry(std::uint32_t index) const
{
BOOST_ASSERT(index < 8 * sizeof(FlagBaseType));
return 0 != (enabled_entries_flags & (1 << index));
}
bool EntryClass::operator==(const EntryClass &other) const
{
return enabled_entries_flags == other.enabled_entries_flags;
}
bool EntryClass::operator<(const EntryClass &other) const
{
return enabled_entries_flags < other.enabled_entries_flags;
}
} // namespace guidance
} // namespace extractor
} // namespace osrm