Implement Turn Lane Api

This commit is contained in:
Moritz Kobitzsch
2016-06-15 14:38:24 +02:00
parent ec0a1a4ab1
commit 5d91b759d1
59 changed files with 1274 additions and 439 deletions
+1
View File
@@ -12,6 +12,7 @@
#include "engine/guidance/assemble_overview.hpp"
#include "engine/guidance/assemble_route.hpp"
#include "engine/guidance/assemble_steps.hpp"
#include "engine/guidance/lane_processing.hpp"
#include "engine/guidance/post_processing.hpp"
#include "engine/internal_route_result.hpp"
@@ -138,6 +138,10 @@ class BaseDataFacade
const int bearing,
const int bearing_range) const = 0;
virtual bool hasLaneData(const EdgeID id) const = 0;
virtual util::guidance::LaneTupelIdPair GetLaneData(const EdgeID id) const = 0;
virtual std::string GetTurnStringForID(const LaneStringID lane_string_id) const = 0;
virtual unsigned GetCheckSum() const = 0;
virtual bool IsCoreNode(const NodeID id) const = 0;
@@ -16,6 +16,7 @@
#include "storage/storage_config.hpp"
#include "engine/geospatial_query.hpp"
#include "util/graph_loader.hpp"
#include "util/guidance/turn_lanes.hpp"
#include "util/io.hpp"
#include "util/packed_vector.hpp"
#include "util/range_table.hpp"
@@ -78,8 +79,11 @@ class InternalDataFacade final : public BaseDataFacade
util::ShM<NodeID, false>::vector m_via_node_list;
util::ShM<unsigned, false>::vector m_name_ID_list;
util::ShM<extractor::guidance::TurnInstruction, false>::vector m_turn_instruction_list;
util::ShM<LaneDataID, false>::vector m_lane_data_id;
util::ShM<util::guidance::LaneTupelIdPair, false>::vector m_lane_tupel_id_pairs;
util::ShM<extractor::TravelMode, false>::vector m_travel_mode_list;
util::ShM<char, false>::vector m_names_char_list;
util::ShM<char, false>::vector m_lanes_char_list;
util::ShM<unsigned, false>::vector m_geometry_indices;
util::ShM<extractor::CompressedEdgeContainer::CompressedEdge, false>::vector m_geometry_list;
util::ShM<bool, false>::vector m_is_core_node;
@@ -93,6 +97,7 @@ class InternalDataFacade final : public BaseDataFacade
boost::filesystem::path ram_index_path;
boost::filesystem::path file_index_path;
util::RangeTable<16, false> m_name_table;
util::RangeTable<16, false> m_lane_string_table;
// bearing classes by node based node
util::ShM<BearingClassID, false>::vector m_bearing_class_id_table;
@@ -118,6 +123,20 @@ class InternalDataFacade final : public BaseDataFacade
sizeof(m_profile_properties));
}
void LoadLaneTupelIdPairs(const boost::filesystem::path &lane_data_path)
{
boost::filesystem::ifstream in_stream(lane_data_path);
if (!in_stream)
{
throw util::exception("Could not open " + lane_data_path.string() + " for reading.");
}
std::uint64_t size;
in_stream.read(reinterpret_cast<char *>(&size), sizeof(size));
m_lane_tupel_id_pairs.resize(size);
in_stream.read(reinterpret_cast<char *>(&m_lane_tupel_id_pairs[0]),
sizeof(m_lane_tupel_id_pairs) * size);
}
void LoadTimestamp(const boost::filesystem::path &timestamp_path)
{
util::SimpleLogger().Write() << "Loading Timestamp";
@@ -173,6 +192,7 @@ class InternalDataFacade final : public BaseDataFacade
m_via_node_list.resize(number_of_edges);
m_name_ID_list.resize(number_of_edges);
m_turn_instruction_list.resize(number_of_edges);
m_lane_data_id.resize(number_of_edges);
m_travel_mode_list.resize(number_of_edges);
m_entry_class_id_list.resize(number_of_edges);
@@ -184,6 +204,7 @@ class InternalDataFacade final : public BaseDataFacade
m_via_node_list[i] = current_edge_data.via_node;
m_name_ID_list[i] = current_edge_data.name_id;
m_turn_instruction_list[i] = current_edge_data.turn_instruction;
m_lane_data_id[i] = current_edge_data.lane_data_id;
m_travel_mode_list[i] = current_edge_data.travel_mode;
m_entry_class_id_list[i] = current_edge_data.entry_classid;
}
@@ -284,6 +305,20 @@ class InternalDataFacade final : public BaseDataFacade
new InternalGeospatialQuery(*m_static_rtree, m_coordinate_list, *this));
}
void LoadLaneStrings(const boost::filesystem::path &lane_string_file)
{
boost::filesystem::ifstream lane_stream(lane_string_file, std::ios::binary);
lane_stream >> m_lane_string_table;
unsigned number_of_chars = 0;
lane_stream.read((char *)&number_of_chars, sizeof(unsigned));
m_lanes_char_list.resize(number_of_chars + 1); //+1 gives sentinel element
if( number_of_chars )
lane_stream.read((char *)&m_lanes_char_list[0], number_of_chars * sizeof(char));
m_lanes_char_list[number_of_chars] = '\0';
}
void LoadStreetNames(const boost::filesystem::path &names_file)
{
boost::filesystem::ifstream name_stream(names_file, std::ios::binary);
@@ -386,11 +421,17 @@ class InternalDataFacade final : public BaseDataFacade
util::SimpleLogger().Write() << "loading street names";
LoadStreetNames(config.names_data_path);
util::SimpleLogger().Write() << "loading lane tags";
LoadLaneStrings(config.turn_lane_string_path);
util::SimpleLogger().Write() << "loading rtree";
LoadRTree();
util::SimpleLogger().Write() << "loading intersection class data";
LoadIntersectionClasses(config.intersection_class_path);
util::SimpleLogger().Write() << "Loading Lane Data Pairs";
LoadLaneTupelIdPairs(config.turn_lane_data_path);
}
// search graph access
@@ -741,6 +782,37 @@ class InternalDataFacade final : public BaseDataFacade
{
return m_entry_class_table.at(entry_class_id);
}
bool hasLaneData(const EdgeID id) const override final
{
return m_lane_data_id[id] != INVALID_LANE_DATAID;
}
util::guidance::LaneTupelIdPair GetLaneData(const EdgeID id) const override final
{
BOOST_ASSERT(hasLaneData(id));
return m_lane_tupel_id_pairs[m_lane_data_id[id]];
}
std::string GetTurnStringForID(const LaneStringID lane_string_id) const override final
{
if (INVALID_LANE_STRINGID == lane_string_id)
{
return "";
}
auto range = m_lane_string_table.GetRange(lane_string_id);
std::string result;
result.reserve(range.size());
if (range.begin() != range.end())
{
result.resize(range.back() - range.front() + 1);
std::copy(m_lanes_char_list.begin() + range.front(),
m_lanes_char_list.begin() + range.back() + 1,
result.begin());
}
return result;
}
};
}
}
@@ -12,6 +12,7 @@
#include "extractor/profile_properties.hpp"
#include "util/guidance/bearing_class.hpp"
#include "util/guidance/entry_class.hpp"
#include "util/guidance/turn_lanes.hpp"
#include "engine/geospatial_query.hpp"
#include "util/make_unique.hpp"
@@ -79,10 +80,14 @@ class SharedDataFacade final : public BaseDataFacade
util::PackedVector<OSMNodeID, true> m_osmnodeid_list;
util::ShM<NodeID, true>::vector m_via_node_list;
util::ShM<unsigned, true>::vector m_name_ID_list;
util::ShM<LaneDataID, true>::vector m_lane_data_id;
util::ShM<extractor::guidance::TurnInstruction, true>::vector m_turn_instruction_list;
util::ShM<extractor::TravelMode, true>::vector m_travel_mode_list;
util::ShM<char, true>::vector m_names_char_list;
util::ShM<char, true>::vector m_turn_string_char_list;
util::ShM<unsigned, true>::vector m_name_begin_indices;
util::ShM<char, true>::vector m_lane_string_char_list;
util::ShM<unsigned, true>::vector m_lane_string_begin_indices;
util::ShM<unsigned, true>::vector m_geometry_indices;
util::ShM<extractor::CompressedEdgeContainer::CompressedEdge, true>::vector m_geometry_list;
util::ShM<bool, true>::vector m_is_core_node;
@@ -91,12 +96,14 @@ class SharedDataFacade final : public BaseDataFacade
util::ShM<char, true>::vector m_datasource_name_data;
util::ShM<std::size_t, true>::vector m_datasource_name_offsets;
util::ShM<std::size_t, true>::vector m_datasource_name_lengths;
util::ShM<util::guidance::LaneTupelIdPair, true>::vector m_lane_tupel_id_pairs;
std::unique_ptr<SharedRTree> m_static_rtree;
std::unique_ptr<SharedGeospatialQuery> m_geospatial_query;
boost::filesystem::path file_index_path;
std::shared_ptr<util::RangeTable<16, true>> m_name_table;
std::shared_ptr<util::RangeTable<16, true>> m_turn_string_table;
// bearing classes by node based node
util::ShM<BearingClassID, true>::vector m_bearing_class_id_table;
@@ -186,6 +193,19 @@ class SharedDataFacade final : public BaseDataFacade
travel_mode_list_ptr, data_layout->num_entries[storage::SharedDataLayout::TRAVEL_MODE]);
m_travel_mode_list = std::move(travel_mode_list);
auto lane_data_id_ptr = data_layout->GetBlockPtr<LaneDataID>(
shared_memory, storage::SharedDataLayout::LANE_DATA_ID);
util::ShM<LaneDataID, true>::vector lane_data_id(
lane_data_id_ptr, data_layout->num_entries[storage::SharedDataLayout::LANE_DATA_ID]);
m_lane_data_id = std::move(lane_data_id);
auto lane_tupel_id_pair_ptr = data_layout->GetBlockPtr<util::guidance::LaneTupelIdPair>(
shared_memory, storage::SharedDataLayout::TURN_LANE_DATA);
util::ShM<util::guidance::LaneTupelIdPair, true>::vector lane_tupel_id_pair(
lane_tupel_id_pair_ptr,
data_layout->num_entries[storage::SharedDataLayout::TURN_LANE_DATA]);
m_lane_tupel_id_pairs = std::move(lane_tupel_id_pair);
auto turn_instruction_list_ptr =
data_layout->GetBlockPtr<extractor::guidance::TurnInstruction>(
shared_memory, storage::SharedDataLayout::TURN_INSTRUCTION);
@@ -238,6 +258,29 @@ class SharedDataFacade final : public BaseDataFacade
m_names_char_list = std::move(names_char_list);
}
void LoadTurnLaneStrings()
{
auto offsets_ptr = data_layout->GetBlockPtr<unsigned>(
shared_memory, storage::SharedDataLayout::TURN_STRING_OFFSETS);
auto blocks_ptr = data_layout->GetBlockPtr<IndexBlock>(
shared_memory, storage::SharedDataLayout::TURN_STRING_BLOCKS);
util::ShM<unsigned, true>::vector turn_string_offsets(
offsets_ptr, data_layout->num_entries[storage::SharedDataLayout::TURN_STRING_OFFSETS]);
util::ShM<IndexBlock, true>::vector turn_string_blocks(
blocks_ptr, data_layout->num_entries[storage::SharedDataLayout::TURN_STRING_BLOCKS]);
auto turn_strings_list_ptr = data_layout->GetBlockPtr<char>(
shared_memory, storage::SharedDataLayout::TURN_STRING_CHAR_LIST);
util::ShM<char, true>::vector turn_strings_char_list(
turn_strings_list_ptr,
data_layout->num_entries[storage::SharedDataLayout::TURN_STRING_CHAR_LIST]);
m_turn_string_table = util::make_unique<util::RangeTable<16, true>>(
turn_string_offsets,
turn_string_blocks,
static_cast<unsigned>(turn_strings_char_list.size()));
m_turn_string_char_list = std::move(turn_strings_char_list);
}
void LoadCoreInformation()
{
if (data_layout->num_entries[storage::SharedDataLayout::CORE_MARKER] <= 0)
@@ -416,6 +459,7 @@ class SharedDataFacade final : public BaseDataFacade
LoadTimestamp();
LoadViaNodeList();
LoadNames();
LoadTurnLaneStrings();
LoadCoreInformation();
LoadProfileProperties();
LoadRTree();
@@ -783,6 +827,37 @@ class SharedDataFacade final : public BaseDataFacade
{
return m_entry_class_table.at(entry_class_id);
}
bool hasLaneData(const EdgeID id) const override final
{
return INVALID_LANE_DATAID != m_lane_data_id.at(id);
}
util::guidance::LaneTupelIdPair GetLaneData(const EdgeID id) const override final
{
BOOST_ASSERT(hasLaneData(id));
return m_lane_tupel_id_pairs.at(m_lane_data_id.at(id));
}
std::string GetTurnStringForID(const LaneStringID lane_string_id) const override final
{
if (INVALID_LANE_STRINGID == lane_string_id)
{
return "";
}
auto range = m_turn_string_table->GetRange(lane_string_id);
std::string result;
result.reserve(range.size());
if (range.begin() != range.end())
{
result.resize(range.back() - range.front() + 1);
std::copy(m_turn_string_char_list.begin() + range.front(),
m_turn_string_char_list.begin() + range.back() + 1,
result.begin());
}
return result;
}
};
}
}
+15 -3
View File
@@ -15,6 +15,7 @@
#include "util/coordinate_calculation.hpp"
#include "util/guidance/entry_class.hpp"
#include "util/guidance/toolkit.hpp"
#include "util/guidance/turn_lanes.hpp"
#include "util/typedefs.hpp"
#include <boost/optional.hpp>
@@ -70,7 +71,9 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
bearings.second,
extractor::guidance::TurnInstruction::NO_TURN(),
WaypointType::Depart,
0};
0,
util::guidance::LaneTupel(),
""};
Intersection intersection{source_node.location,
std::vector<short>({bearings.second}),
std::vector<bool>({true}),
@@ -147,7 +150,11 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
bearings.second,
path_point.turn_instruction,
WaypointType::None,
0};
0,
path_point.lane_data.first,
(path_point.lane_data.second != INVALID_LANE_STRINGID
? facade.GetTurnStringForID(path_point.lane_data.second)
: "")};
segment_index++;
segment_duration = 0;
}
@@ -202,7 +209,9 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
bearings.second,
extractor::guidance::TurnInstruction::NO_TURN(),
WaypointType::Arrive,
0};
0,
util::guidance::LaneTupel(),
""};
intersection = {
target_node.location,
std::vector<short>({static_cast<short>(util::bearing::reverseBearing(bearings.first))}),
@@ -233,6 +242,9 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
BOOST_ASSERT(steps.back().intersections.front().bearings.size() == 1);
BOOST_ASSERT(steps.back().intersections.front().entry.size() == 1);
BOOST_ASSERT(steps.back().maneuver.waypoint_type == WaypointType::Arrive);
BOOST_ASSERT(steps.back().maneuver.lanes.lanes_in_turn == 0);
BOOST_ASSERT(steps.back().maneuver.lanes.first_lane_from_the_right == INVALID_LANEID);
BOOST_ASSERT(steps.back().maneuver.turn_lane_string == "");
return steps;
}
@@ -0,0 +1,24 @@
#ifndef OSRM_ENGINE_GUIDANCE_LANE_PROCESSING_HPP_
#define OSRM_ENGINE_GUIDANCE_LANE_PROCESSING_HPP_
#include <vector>
#include "engine/guidance/route_step.hpp"
namespace osrm
{
namespace engine
{
namespace guidance
{
// Constrains lanes for multi-hop situations where lane changes depend on earlier ones.
// Instead of forcing users to change lanes rapidly in a short amount of time,
// we anticipate lane changes emitting only matching lanes early on.
std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps);
} // namespace guidance
} // namespace engine
} // namespace osrm
#endif /* OSRM_ENGINE_GUIDANCE_LANE_PROCESSING_HPP_ */
@@ -43,11 +43,6 @@ std::vector<RouteStep> buildIntersections(std::vector<RouteStep> steps);
// remove steps invalidated by post-processing
std::vector<RouteStep> removeNoTurnInstructions(std::vector<RouteStep> steps);
// Constrains lanes for multi-hop situations where lane changes depend on earlier ones.
// Instead of forcing users to change lanes rapidly in a short amount of time,
// we anticipate lane changes emitting only matching lanes early on.
std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps);
// postProcess will break the connection between the leg geometry
// for which a segment is supposed to represent exactly the coordinates
// between routing maneuvers and the route steps itself.
+9 -1
View File
@@ -3,8 +3,10 @@
#include "extractor/guidance/turn_instruction.hpp"
#include "util/coordinate.hpp"
#include "util/guidance/turn_lanes.hpp"
#include <cstdint>
#include <string>
#include <vector>
namespace osrm
@@ -27,8 +29,12 @@ struct StepManeuver
short bearing_before;
short bearing_after;
extractor::guidance::TurnInstruction instruction;
WaypointType waypoint_type;
unsigned exit;
util::guidance::LaneTupel lanes;
std::string turn_lane_string;
};
inline StepManeuver getInvalidStepManeuver()
@@ -38,7 +44,9 @@ inline StepManeuver getInvalidStepManeuver()
0,
extractor::guidance::TurnInstruction::NO_TURN(),
WaypointType::None,
0};
0,
util::guidance::LaneTupel(),
""};
}
} // namespace guidance
+4 -2
View File
@@ -4,9 +4,9 @@
#include "extractor/guidance/turn_instruction.hpp"
#include "extractor/travel_mode.hpp"
#include "engine/phantom_node.hpp"
#include "util/typedefs.hpp"
#include "osrm/coordinate.hpp"
#include "util/guidance/turn_lanes.hpp"
#include "util/typedefs.hpp"
#include <vector>
@@ -27,6 +27,8 @@ struct PathData
EdgeWeight duration_until_turn;
// instruction to execute at the turn
extractor::guidance::TurnInstruction turn_instruction;
// turn lane data
util::guidance::LaneTupelIdPair lane_data;
// travel mode of the street that leads to the turn
extractor::TravelMode travel_mode : 4;
// entry class of the turn, indicating possibility of turns
@@ -327,10 +327,14 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
name_index,
weight_vector[i],
extractor::guidance::TurnInstruction::NO_TURN(),
{{0, INVALID_LANEID}, INVALID_LANE_STRINGID},
travel_mode,
INVALID_ENTRY_CLASSID});
}
BOOST_ASSERT(unpacked_path.size() > 0);
if (facade->hasLaneData(ed.id))
unpacked_path.back().lane_data = facade->GetLaneData(ed.id);
unpacked_path.back().entry_classid = facade->GetEntryClassID(ed.id);
unpacked_path.back().turn_instruction = turn_instruction;
unpacked_path.back().duration_until_turn += (ed.distance - total_weight);
@@ -389,6 +393,7 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
phantom_node_pair.target_phantom.name_id,
weight_vector[i],
extractor::guidance::TurnInstruction::NO_TURN(),
{{0, INVALID_LANEID}, INVALID_LANE_STRINGID},
target_traversed_in_reverse ? phantom_node_pair.target_phantom.backward_travel_mode
: phantom_node_pair.target_phantom.forward_travel_mode,
INVALID_ENTRY_CLASSID});
@@ -59,6 +59,7 @@ class EdgeBasedGraphFactory
const util::NameTable &turn_lanes);
void Run(const std::string &original_edge_data_filename,
const std::string &turn_lane_data_filename,
lua_State *lua_state,
const std::string &edge_segment_lookup_filename,
const std::string &edge_penalty_filename,
@@ -124,6 +125,7 @@ class EdgeBasedGraphFactory
unsigned RenumberEdges();
void GenerateEdgeExpandedNodes();
void GenerateEdgeExpandedEdges(const std::string &original_edge_data_filename,
const std::string &turn_lane_data_filename,
lua_State *lua_state,
const std::string &edge_segment_lookup_filename,
const std::string &edge_fixed_penalties_filename,
+1 -1
View File
@@ -2,8 +2,8 @@
#define EXTRACTION_WAY_HPP
#include "extractor/travel_mode.hpp"
#include "util/typedefs.hpp"
#include "util/guidance/turn_lanes.hpp"
#include "util/typedefs.hpp"
#include <string>
#include <vector>
+4 -2
View File
@@ -61,7 +61,8 @@ struct ExtractorConfig
output_file_name = basepath + ".osrm";
restriction_file_name = basepath + ".osrm.restrictions";
names_file_name = basepath + ".osrm.names";
turn_lane_file_name = basepath + ".osrm.tld";
turn_lane_strings_file_name = basepath + ".osrm.tls";
turn_lane_data_file_name = basepath + ".osrm.tld";
timestamp_file_name = basepath + ".osrm.timestamp";
geometry_output_path = basepath + ".osrm.geometry";
node_output_path = basepath + ".osrm.nodes";
@@ -83,7 +84,8 @@ struct ExtractorConfig
std::string output_file_name;
std::string restriction_file_name;
std::string names_file_name;
std::string turn_lane_file_name;
std::string turn_lane_data_file_name;
std::string turn_lane_strings_file_name;
std::string timestamp_file_name;
std::string geometry_output_path;
std::string edge_output_path;
+1 -1
View File
@@ -35,7 +35,7 @@ inline void printTurnAssignmentData(const NodeID at,
for (const auto &road)
std::cout << "\t" << toString(road) << "\n";
//flushes as well
// flushes as well
print(turn_lane_data);
}
@@ -22,6 +22,7 @@ struct TurnOperation final
EdgeID eid;
double angle;
TurnInstruction instruction;
LaneDataID lane_data_id;
};
// A Connected Road is the internal representation of a potential turn. Internally, we require
@@ -5,9 +5,9 @@
#include "extractor/guidance/intersection.hpp"
#include "extractor/query_node.hpp"
#include "extractor/restriction_map.hpp"
#include "util/name_table.hpp"
#include "util/node_based_graph.hpp"
#include "util/typedefs.hpp"
#include "util/name_table.hpp"
#include <unordered_set>
#include <vector>
+7
View File
@@ -5,6 +5,8 @@
#include "util/coordinate.hpp"
#include "util/coordinate_calculation.hpp"
#include "util/guidance/toolkit.hpp"
#include "util/guidance/turn_lanes.hpp"
#include "util/typedefs.hpp"
#include "extractor/compressed_edge_container.hpp"
#include "extractor/query_node.hpp"
@@ -20,10 +22,12 @@
#include <cstdint>
#include <map>
#include <string>
#include <unordered_map>
#include <utility>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/functional/hash.hpp>
namespace osrm
{
@@ -32,6 +36,9 @@ namespace extractor
namespace guidance
{
using util::guidance::LaneTupelIdPair;
using LaneDataIdMap = std::unordered_map<LaneTupelIdPair, LaneDataID, boost::hash<LaneTupelIdPair>>;
using util::guidance::angularDeviation;
namespace detail
+1 -1
View File
@@ -51,7 +51,7 @@ class TurnAnalysis
std::vector<TurnOperation>
transformIntersectionIntoTurns(const Intersection &intersection) const;
const IntersectionGenerator& getGenerator() const;
const IntersectionGenerator &getGenerator() const;
private:
const util::NodeBasedDynamicGraph &node_based_graph;
@@ -77,16 +77,14 @@ struct TurnInstruction
{
using LaneTupel = util::guidance::LaneTupel;
TurnInstruction(const TurnType::Enum type = TurnType::Invalid,
const DirectionModifier::Enum direction_modifier = DirectionModifier::Straight,
const LaneTupel lane_tupel = {0, INVALID_LANEID})
: type(type), direction_modifier(direction_modifier), lane_tupel(lane_tupel)
const DirectionModifier::Enum direction_modifier = DirectionModifier::UTurn)
: type(type), direction_modifier(direction_modifier)
{
}
TurnType::Enum type : 5;
DirectionModifier::Enum direction_modifier : 3;
// the lane tupel that is used for the turn
LaneTupel lane_tupel;
static TurnInstruction INVALID() { return {TurnType::Invalid, DirectionModifier::UTurn}; }
@@ -147,18 +145,16 @@ struct TurnInstruction
}
};
static_assert(sizeof(TurnInstruction) == 3, "TurnInstruction does not fit three byte");
static_assert(sizeof(TurnInstruction) == 1, "TurnInstruction does not fit a byte");
inline bool operator!=(const TurnInstruction lhs, const TurnInstruction rhs)
{
return lhs.type != rhs.type || lhs.direction_modifier != rhs.direction_modifier ||
lhs.lane_tupel != rhs.lane_tupel;
return lhs.type != rhs.type || lhs.direction_modifier != rhs.direction_modifier;
}
inline bool operator==(const TurnInstruction lhs, const TurnInstruction rhs)
{
return lhs.type == rhs.type && lhs.direction_modifier == rhs.direction_modifier &&
lhs.lane_tupel == rhs.lane_tupel;
return lhs.type == rhs.type && lhs.direction_modifier == rhs.direction_modifier;
}
} // namespace guidance
@@ -2,6 +2,7 @@
#define OSRM_EXTRACTOR_GUIDANCE_TURN_LANE_HANDLER_HPP_
#include "extractor/guidance/intersection.hpp"
#include "extractor/guidance/toolkit.hpp"
#include "extractor/guidance/turn_analysis.hpp"
#include "extractor/guidance/turn_lane_data.hpp"
#include "extractor/query_node.hpp"
@@ -13,7 +14,6 @@
#include <map>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
@@ -38,13 +38,12 @@ class TurnLaneHandler
const std::vector<QueryNode> &node_info_list,
const TurnAnalysis &turn_analysis);
Intersection
assignTurnLanes(const NodeID at, const EdgeID via_edge, Intersection intersection) const;
Intersection assignTurnLanes(const NodeID at,
const EdgeID via_edge,
Intersection intersection,
LaneDataIdMap &id_map) const;
private:
using LaneTupel = util::guidance::LaneTupel;
std::unordered_map<LaneTupel, std::uint16_t> lane_tupels;
// we need to be able to look at previous intersections to, in some cases, find the correct turn
// lanes for a turn
const util::NodeBasedDynamicGraph &node_based_graph;
@@ -58,7 +57,9 @@ class TurnLaneHandler
// in case of a simple intersection, assign the lane entries
Intersection simpleMatchTuplesToTurns(Intersection intersection,
const LaneDataVector &lane_data) const;
const LaneDataVector &lane_data,
const LaneStringID lane_string_id,
LaneDataIdMap &id_map) const;
// partition lane data into lane data relevant at current turn and at next turn
std::pair<TurnLaneHandler::LaneDataVector, TurnLaneHandler::LaneDataVector> partitionLaneData(
@@ -68,7 +69,8 @@ class TurnLaneHandler
// intersection whose turns might be related to this current intersection
Intersection handleTurnAtPreviousIntersection(const NodeID at,
const EdgeID via_edge,
Intersection intersection) const;
Intersection intersection,
LaneDataIdMap &id_map) const;
};
} // namespace lanes
@@ -2,12 +2,15 @@
#define OSRM_EXTRACTOR_GUIDANCE_TURN_LANE_MATCHER_HPP_
#include "extractor/guidance/intersection.hpp"
#include "extractor/guidance/toolkit.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include "extractor/guidance/turn_lane_data.hpp"
#include "util/guidance/turn_lanes.hpp"
#include "util/node_based_graph.hpp"
#include <unordered_map>
namespace osrm
{
namespace extractor
@@ -44,7 +47,9 @@ bool canMatchTrivially(const Intersection &intersection, const LaneDataVector &l
// perform a trivial match on the turn lanes
Intersection triviallyMatchLanesToTurns(Intersection intersection,
const LaneDataVector &lane_data,
const util::NodeBasedDynamicGraph &node_based_graph);
const util::NodeBasedDynamicGraph &node_based_graph,
const LaneStringID lane_string_id,
LaneDataIdMap &lane_data_to_id);
} // namespace lanes
} // namespace guidance
+2 -2
View File
@@ -90,8 +90,8 @@ inline NodeBasedEdge::NodeBasedEdge(NodeID source,
guidance::RoadClassificationData road_classification)
: source(source), target(target), name_id(name_id), weight(weight), forward(forward),
backward(backward), roundabout(roundabout), access_restricted(access_restricted),
startpoint(startpoint), is_split(is_split), travel_mode(travel_mode), lane_string_id(lane_string_id),
road_classification(std::move(road_classification))
startpoint(startpoint), is_split(is_split), travel_mode(travel_mode),
lane_string_id(lane_string_id), road_classification(std::move(road_classification))
{
}
+7 -2
View File
@@ -17,18 +17,19 @@ struct OriginalEdgeData
{
explicit OriginalEdgeData(NodeID via_node,
unsigned name_id,
LaneDataID lane_data_id,
guidance::TurnInstruction turn_instruction,
EntryClassID entry_classid,
TravelMode travel_mode)
: via_node(via_node), name_id(name_id), entry_classid(entry_classid),
turn_instruction(turn_instruction), travel_mode(travel_mode)
lane_data_id(lane_data_id), turn_instruction(turn_instruction), travel_mode(travel_mode)
{
}
OriginalEdgeData()
: via_node(std::numeric_limits<unsigned>::max()),
name_id(std::numeric_limits<unsigned>::max()), entry_classid(INVALID_ENTRY_CLASSID),
turn_instruction(guidance::TurnInstruction::INVALID()),
lane_data_id(INVALID_LANE_DATAID), turn_instruction(guidance::TurnInstruction::INVALID()),
travel_mode(TRAVEL_MODE_INACCESSIBLE)
{
}
@@ -36,9 +37,13 @@ struct OriginalEdgeData
NodeID via_node;
unsigned name_id;
EntryClassID entry_classid;
LaneDataID lane_data_id;
guidance::TurnInstruction turn_instruction;
TravelMode travel_mode;
};
static_assert(sizeof(OriginalEdgeData) == 16,
"Increasing the size of OriginalEdgeData increases memory consumption");
}
}
+45 -3
View File
@@ -16,6 +16,41 @@ namespace storage
// Added at the start and end of each block as sanity check
const constexpr char CANARY[4] = {'O', 'S', 'R', 'M'};
const constexpr char *block_id_to_name[] = {"NAME_OFFSETS",
"NAME_BLOCKS",
"NAME_CHAR_LIST",
"NAME_ID_LIST",
"VIA_NODE_LIST",
"GRAPH_NODE_LIST",
"GRAPH_EDGE_LIST",
"COORDINATE_LIST",
"OSM_NODE_ID_LIST",
"TURN_INSTRUCTION",
"TRAVEL_MODE",
"ENTRY_CLASSID",
"R_SEARCH_TREE",
"GEOMETRIES_INDEX",
"GEOMETRIES_LIST",
"HSGR_CHECKSUM",
"TIMESTAMP",
"FILE_INDEX_PATH",
"CORE_MARKER",
"DATASOURCES_LIST",
"DATASOURCE_NAME_DATA",
"DATASOURCE_NAME_OFFSETS",
"DATASOURCE_NAME_LENGTHS",
"PROPERTIES",
"BEARING_CLASSID",
"BEARING_OFFSETS",
"BEARING_BLOCKS",
"BEARING_VALUES",
"ENTRY_CLASS",
"LANE_DATA_ID",
"TURN_LANE_DATA",
"TURN_STRING_OFFSETS",
"TURN_STRING_BLOCKS",
"TURN_STRING_CHAR_LIST"};
struct SharedDataLayout
{
enum BlockID
@@ -30,8 +65,8 @@ struct SharedDataLayout
COORDINATE_LIST,
OSM_NODE_ID_LIST,
TURN_INSTRUCTION,
ENTRY_CLASSID,
TRAVEL_MODE,
ENTRY_CLASSID,
R_SEARCH_TREE,
GEOMETRIES_INDEX,
GEOMETRIES_LIST,
@@ -49,6 +84,11 @@ struct SharedDataLayout
BEARING_BLOCKS,
BEARING_VALUES,
ENTRY_CLASS,
LANE_DATA_ID,
TURN_LANE_DATA,
TURN_STRING_OFFSETS,
TURN_STRING_BLOCKS,
TURN_STRING_CHAR_LIST,
NUM_BLOCKS
};
@@ -113,11 +153,13 @@ struct SharedDataLayout
bool end_canary_alive = std::equal(CANARY, CANARY + sizeof(CANARY), end_canary_ptr);
if (!start_canary_alive)
{
throw util::exception("Start canary of block corrupted.");
throw util::exception(std::string("Start canary of block corrupted. (") +
block_id_to_name[bid] + ")");
}
if (!end_canary_alive)
{
throw util::exception("End canary of block corrupted.");
throw util::exception(std::string("End canary of block corrupted. (") +
block_id_to_name[bid] + ")");
}
}
+2
View File
@@ -65,6 +65,8 @@ struct StorageConfig final
boost::filesystem::path names_data_path;
boost::filesystem::path properties_path;
boost::filesystem::path intersection_class_path;
boost::filesystem::path turn_lane_data_path;
boost::filesystem::path turn_lane_string_path;
};
}
}
+8 -11
View File
@@ -65,21 +65,18 @@ class LaneTupel
LaneID lanes_in_turn;
LaneID first_lane_from_the_right;
friend std::size_t std::hash<LaneTupel>::operator()(const LaneTupel &) const;
friend std::size_t hash_value(const LaneTupel &tup)
{
std::size_t seed{0};
boost::hash_combine(seed, tup.lanes_in_turn);
boost::hash_combine(seed, tup.first_lane_from_the_right);
return seed;
}
};
using LaneTupelIdPair = std::pair<util::guidance::LaneTupel, LaneStringID>;
} // namespace guidance
} // namespace util
} // namespace osrm
// make Bearing Class hasbable
namespace std
{
inline size_t hash<::osrm::util::guidance::LaneTupel>::
operator()(const ::osrm::util::guidance::LaneTupel &lane_tupel) const
{
return boost::hash_value(*reinterpret_cast<const std::uint16_t *>(&lane_tupel));
}
} // namespace std
#endif /* OSRM_UTIL_GUIDANCE_TURN_LANES_HPP */
+2 -1
View File
@@ -20,7 +20,8 @@ struct NodeBasedEdgeData
NodeBasedEdgeData()
: distance(INVALID_EDGE_WEIGHT), edge_id(SPECIAL_NODEID),
name_id(std::numeric_limits<unsigned>::max()), access_restricted(false), reversed(false),
roundabout(false), travel_mode(TRAVEL_MODE_INACCESSIBLE), lane_string_id(INVALID_LANE_STRINGID)
roundabout(false), travel_mode(TRAVEL_MODE_INACCESSIBLE),
lane_string_id(INVALID_LANE_STRINGID)
{
}
+3 -1
View File
@@ -60,9 +60,11 @@ using NameID = std::uint32_t;
using EdgeWeight = std::int32_t;
using LaneStringID = std::uint16_t;
static const LaneStringID INVALID_LANE_STRINGID = std::numeric_limits<LaneStringID>::max();
using LaneID = std::uint8_t;
static const LaneID INVALID_LANEID = std::numeric_limits<LaneID>::max();
static const LaneStringID INVALID_LANE_STRINGID = std::numeric_limits<LaneStringID>::max();
using LaneDataID = std::uint16_t;
static const LaneDataID INVALID_LANE_DATAID = std::numeric_limits<LaneStringID>::max();
using BearingClassID = std::uint32_t;
static const BearingClassID INVALID_BEARING_CLASSID = std::numeric_limits<BearingClassID>::max();