Allow users to specify a class for each way
This adds the ability to mark ways with a user-defined class in the profile. This class information will be included in the response as property of the RouteStep object.
This commit is contained in:
committed by
Patrick Niklaus
parent
d52d530cbe
commit
44739f2dc3
@@ -318,7 +318,7 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
void InitializeEdgeBasedNodeDataInformationPointers(storage::DataLayout &layout,
|
||||
char *memory_ptr)
|
||||
{
|
||||
auto via_geometry_list_ptr =
|
||||
const auto via_geometry_list_ptr =
|
||||
layout.GetBlockPtr<GeometryID>(memory_ptr, storage::DataLayout::GEOMETRY_ID_LIST);
|
||||
util::vector_view<GeometryID> geometry_ids(
|
||||
via_geometry_list_ptr, layout.num_entries[storage::DataLayout::GEOMETRY_ID_LIST]);
|
||||
@@ -338,10 +338,16 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
util::vector_view<extractor::TravelMode> travel_modes(
|
||||
travel_mode_list_ptr, layout.num_entries[storage::DataLayout::TRAVEL_MODE_LIST]);
|
||||
|
||||
const auto classes_list_ptr =
|
||||
layout.GetBlockPtr<extractor::ClassData>(memory_ptr, storage::DataLayout::CLASSES_LIST);
|
||||
util::vector_view<extractor::ClassData> classes(
|
||||
classes_list_ptr, layout.num_entries[storage::DataLayout::CLASSES_LIST]);
|
||||
|
||||
edge_based_node_data = extractor::EdgeBasedNodeDataView(std::move(geometry_ids),
|
||||
std::move(name_ids),
|
||||
std::move(component_ids),
|
||||
std::move(travel_modes));
|
||||
std::move(travel_modes),
|
||||
std::move(classes));
|
||||
}
|
||||
|
||||
void InitializeEdgeInformationPointers(storage::DataLayout &layout, char *memory_ptr)
|
||||
@@ -783,6 +789,22 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
return edge_based_node_data.GetTravelMode(id);
|
||||
}
|
||||
|
||||
extractor::ClassData GetClassData(const NodeID id) const override final
|
||||
{
|
||||
return edge_based_node_data.GetClassData(id);
|
||||
}
|
||||
|
||||
std::vector<std::string> GetClasses(const extractor::ClassData class_data) const override final
|
||||
{
|
||||
auto indexes = extractor::getClassIndexes(class_data);
|
||||
std::vector<std::string> classes(indexes.size());
|
||||
std::transform(indexes.begin(), indexes.end(), classes.begin(), [this](const auto index) {
|
||||
return m_profile_properties->GetClassName(index);
|
||||
});
|
||||
|
||||
return classes;
|
||||
}
|
||||
|
||||
NameID GetNameIndex(const NodeID id) const override final
|
||||
{
|
||||
return edge_based_node_data.GetNameID(id);
|
||||
|
||||
@@ -3,14 +3,19 @@
|
||||
|
||||
// Exposes all data access interfaces to the algorithms via base class ptr
|
||||
|
||||
#include "engine/approach.hpp"
|
||||
#include "engine/phantom_node.hpp"
|
||||
|
||||
#include "contractor/query_edge.hpp"
|
||||
|
||||
#include "extractor/class_data.hpp"
|
||||
#include "extractor/edge_based_node_segment.hpp"
|
||||
#include "extractor/external_memory_node.hpp"
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "extractor/original_edge_data.hpp"
|
||||
#include "engine/approach.hpp"
|
||||
#include "engine/phantom_node.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
|
||||
#include "util/exception.hpp"
|
||||
#include "util/guidance/bearing_class.hpp"
|
||||
#include "util/guidance/entry_class.hpp"
|
||||
@@ -87,6 +92,10 @@ class BaseDataFacade
|
||||
|
||||
virtual extractor::TravelMode GetTravelMode(const NodeID id) const = 0;
|
||||
|
||||
virtual extractor::ClassData GetClassData(const NodeID id) const = 0;
|
||||
|
||||
virtual std::vector<std::string> GetClasses(const extractor::ClassData class_data) const = 0;
|
||||
|
||||
virtual std::vector<RTreeLeaf> GetEdgesInBox(const util::Coordinate south_west,
|
||||
const util::Coordinate north_east) const = 0;
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
: source_node.forward_segment_id.id;
|
||||
const auto source_name_id = facade.GetNameIndex(source_node_id);
|
||||
const auto source_mode = facade.GetTravelMode(source_node_id);
|
||||
auto source_classes = facade.GetClasses(facade.GetClassData(source_node_id));
|
||||
|
||||
const EdgeWeight target_duration =
|
||||
target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration;
|
||||
@@ -62,6 +63,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
: target_node.forward_segment_id.id;
|
||||
const auto target_name_id = facade.GetNameIndex(target_node_id);
|
||||
const auto target_mode = facade.GetTravelMode(target_node_id);
|
||||
auto target_classes = facade.GetClasses(facade.GetClassData(target_node_id));
|
||||
|
||||
const auto number_of_segments = leg_geometry.GetNumberOfSegments();
|
||||
|
||||
@@ -116,6 +118,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
const auto destinations = facade.GetDestinationsForID(step_name_id);
|
||||
const auto exits = facade.GetExitsForID(step_name_id);
|
||||
const auto distance = leg_geometry.segment_distances[segment_index];
|
||||
auto classes = facade.GetClasses(path_point.classes);
|
||||
|
||||
steps.push_back(RouteStep{step_name_id,
|
||||
name.to_string(),
|
||||
@@ -132,7 +135,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
maneuver,
|
||||
leg_geometry.FrontIndex(segment_index),
|
||||
leg_geometry.BackIndex(segment_index) + 1,
|
||||
{intersection}});
|
||||
{intersection},
|
||||
std::move(classes)});
|
||||
|
||||
if (leg_data_index + 1 < leg_data.size())
|
||||
{
|
||||
@@ -208,7 +212,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
maneuver,
|
||||
leg_geometry.FrontIndex(segment_index),
|
||||
leg_geometry.BackIndex(segment_index) + 1,
|
||||
{intersection}});
|
||||
{intersection},
|
||||
std::move(target_classes)});
|
||||
}
|
||||
// In this case the source + target are on the same edge segment
|
||||
else
|
||||
@@ -250,7 +255,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
std::move(maneuver),
|
||||
leg_geometry.FrontIndex(segment_index),
|
||||
leg_geometry.BackIndex(segment_index) + 1,
|
||||
{intersection}});
|
||||
{intersection},
|
||||
std::move(source_classes)});
|
||||
}
|
||||
|
||||
BOOST_ASSERT(segment_index == number_of_segments - 1);
|
||||
@@ -289,7 +295,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
std::move(maneuver),
|
||||
leg_geometry.locations.size() - 1,
|
||||
leg_geometry.locations.size(),
|
||||
{intersection}});
|
||||
{intersection},
|
||||
std::move(target_classes)});
|
||||
|
||||
BOOST_ASSERT(steps.front().intersections.size() == 1);
|
||||
BOOST_ASSERT(steps.front().intersections.front().bearings.size() == 1);
|
||||
|
||||
@@ -74,6 +74,7 @@ struct RouteStep
|
||||
std::size_t geometry_begin;
|
||||
std::size_t geometry_end;
|
||||
std::vector<IntermediateIntersection> intersections;
|
||||
std::vector<std::string> classes;
|
||||
|
||||
// remove all information from the route step, marking it as invalid (used to indicate empty
|
||||
// steps to be removed).
|
||||
@@ -127,6 +128,7 @@ inline void RouteStep::Invalidate()
|
||||
geometry_end = 0;
|
||||
intersections.clear();
|
||||
intersections.push_back(getInvalidIntersection());
|
||||
classes.clear();
|
||||
}
|
||||
|
||||
// Elongate by another step in front
|
||||
|
||||
@@ -33,6 +33,8 @@ struct PathData
|
||||
util::guidance::LaneTupleIdPair lane_data;
|
||||
// travel mode of the street that leads to the turn
|
||||
extractor::TravelMode travel_mode : 4;
|
||||
// user defined classed of the street that leads to the turn
|
||||
extractor::ClassData classes;
|
||||
// entry class of the turn, indicating possibility of turns
|
||||
util::guidance::EntryClass entry_class;
|
||||
|
||||
|
||||
@@ -140,6 +140,7 @@ void annotatePath(const FacadeT &facade,
|
||||
const auto name_index = facade.GetNameIndex(node_id);
|
||||
const auto turn_instruction = facade.GetTurnInstructionForEdgeID(turn_id);
|
||||
const extractor::TravelMode travel_mode = facade.GetTravelMode(node_id);
|
||||
const auto classes = facade.GetClassData(node_id);
|
||||
|
||||
const auto geometry_index = facade.GetGeometryIndex(node_id);
|
||||
std::vector<NodeID> id_vector;
|
||||
@@ -186,6 +187,7 @@ void annotatePath(const FacadeT &facade,
|
||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
{{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID},
|
||||
travel_mode,
|
||||
classes,
|
||||
EMPTY_ENTRY_CLASS,
|
||||
datasource_vector[segment_idx],
|
||||
util::guidance::TurnBearing(0),
|
||||
@@ -261,6 +263,7 @@ void annotatePath(const FacadeT &facade,
|
||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
{{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID},
|
||||
facade.GetTravelMode(target_node_id),
|
||||
facade.GetClassData(target_node_id),
|
||||
EMPTY_ENTRY_CLASS,
|
||||
datasource_vector[segment_idx],
|
||||
util::guidance::TurnBearing(0),
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef OSRM_EXTRACTOR_CLASSES_DATA_HPP
|
||||
#define OSRM_EXTRACTOR_CLASSES_DATA_HPP
|
||||
|
||||
#include "util/bit_range.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
|
||||
using ClassData = std::uint8_t;
|
||||
static const std::uint8_t MAX_CLASS_INDEX = 8 - 1;
|
||||
|
||||
inline bool isSubset(const ClassData lhs, const ClassData rhs) { return (lhs & rhs) == lhs; }
|
||||
|
||||
inline auto getClassIndexes(const ClassData data) { return util::makeBitRange<ClassData>(data); }
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -85,6 +85,10 @@ struct ExtractionWay
|
||||
}
|
||||
const char *GetTurnLanesBackward() const { return turn_lanes_backward.c_str(); }
|
||||
|
||||
// markers for determining user-defined classes for each way
|
||||
std::unordered_map<std::string, bool> forward_classes;
|
||||
std::unordered_map<std::string, bool> backward_classes;
|
||||
|
||||
// speed in km/h
|
||||
double forward_speed;
|
||||
double backward_speed;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef EXTRACTOR_CALLBACKS_HPP
|
||||
#define EXTRACTOR_CALLBACKS_HPP
|
||||
|
||||
#include "extractor/class_data.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
@@ -61,13 +62,18 @@ class ExtractorCallbacks
|
||||
using MapKey = std::tuple<std::string, std::string, std::string, std::string, std::string>;
|
||||
using MapVal = unsigned;
|
||||
std::unordered_map<MapKey, MapVal> string_map;
|
||||
guidance::LaneDescriptionMap lane_description_map;
|
||||
ExtractionContainers &external_memory;
|
||||
std::unordered_map<std::string, ClassData> &classes_map;
|
||||
guidance::LaneDescriptionMap &lane_description_map;
|
||||
bool fallback_to_duration;
|
||||
bool force_split_edges;
|
||||
|
||||
public:
|
||||
using ClassesMap = std::unordered_map<std::string, ClassData>;
|
||||
|
||||
explicit ExtractorCallbacks(ExtractionContainers &extraction_containers,
|
||||
std::unordered_map<std::string, ClassData> &classes_map,
|
||||
guidance::LaneDescriptionMap &lane_description_map,
|
||||
const ProfileProperties &properties);
|
||||
|
||||
ExtractorCallbacks(const ExtractorCallbacks &) = delete;
|
||||
@@ -81,9 +87,6 @@ class ExtractorCallbacks
|
||||
|
||||
// warning: caller needs to take care of synchronization!
|
||||
void ProcessWay(const osmium::Way ¤t_way, const ExtractionWay &result_way);
|
||||
|
||||
// destroys the internal laneDescriptionMap
|
||||
guidance::LaneDescriptionMap &&moveOutLaneDescriptionMap();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ struct InternalExtractorEdge
|
||||
false, // local access only
|
||||
false, // split edge
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
0,
|
||||
guidance::TurnLaneType::empty,
|
||||
guidance::RoadClassification()),
|
||||
weight_data(), duration_data()
|
||||
@@ -91,6 +92,7 @@ struct InternalExtractorEdge
|
||||
bool restricted,
|
||||
bool is_split,
|
||||
TravelMode travel_mode,
|
||||
ClassData classes,
|
||||
LaneDescriptionID lane_description,
|
||||
guidance::RoadClassification road_classification,
|
||||
util::Coordinate source_coordinate)
|
||||
@@ -107,6 +109,7 @@ struct InternalExtractorEdge
|
||||
restricted,
|
||||
is_split,
|
||||
travel_mode,
|
||||
classes,
|
||||
lane_description,
|
||||
std::move(road_classification)),
|
||||
weight_data(std::move(weight_data)), duration_data(std::move(duration_data)),
|
||||
@@ -139,6 +142,7 @@ struct InternalExtractorEdge
|
||||
false, // local access only
|
||||
false, // split edge
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
0,
|
||||
INVALID_LANE_DESCRIPTIONID,
|
||||
guidance::RoadClassification(),
|
||||
util::Coordinate());
|
||||
@@ -158,6 +162,7 @@ struct InternalExtractorEdge
|
||||
false, // local access only
|
||||
false, // split edge
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
0,
|
||||
INVALID_LANE_DESCRIPTIONID,
|
||||
guidance::RoadClassification(),
|
||||
util::Coordinate());
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef NODE_BASED_EDGE_HPP
|
||||
#define NODE_BASED_EDGE_HPP
|
||||
|
||||
#include "extractor/class_data.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
@@ -28,6 +29,7 @@ struct NodeBasedEdge
|
||||
bool restricted,
|
||||
bool is_split,
|
||||
TravelMode travel_mode,
|
||||
ClassData classes,
|
||||
const LaneDescriptionID lane_description_id,
|
||||
guidance::RoadClassification road_classification);
|
||||
|
||||
@@ -46,6 +48,7 @@ struct NodeBasedEdge
|
||||
std::uint8_t restricted : 1; // 1
|
||||
std::uint8_t is_split : 1; // 1
|
||||
TravelMode travel_mode : 4; // 4
|
||||
ClassData classes; // 8 1
|
||||
LaneDescriptionID lane_description_id; // 16 2
|
||||
guidance::RoadClassification road_classification; // 16 2
|
||||
};
|
||||
@@ -65,6 +68,7 @@ struct NodeBasedEdgeWithOSM : NodeBasedEdge
|
||||
bool restricted,
|
||||
bool is_split,
|
||||
TravelMode travel_mode,
|
||||
ClassData classes,
|
||||
const LaneDescriptionID lane_description_id,
|
||||
guidance::RoadClassification road_classification);
|
||||
|
||||
@@ -95,12 +99,14 @@ inline NodeBasedEdge::NodeBasedEdge(NodeID source,
|
||||
bool restricted,
|
||||
bool is_split,
|
||||
TravelMode travel_mode,
|
||||
ClassData classes,
|
||||
const LaneDescriptionID lane_description_id,
|
||||
guidance::RoadClassification road_classification)
|
||||
: source(source), target(target), name_id(name_id), weight(weight), duration(duration),
|
||||
forward(forward), backward(backward), roundabout(roundabout), circular(circular),
|
||||
startpoint(startpoint), restricted(restricted), is_split(is_split), travel_mode(travel_mode),
|
||||
lane_description_id(lane_description_id), road_classification(std::move(road_classification))
|
||||
classes(classes), lane_description_id(lane_description_id),
|
||||
road_classification(std::move(road_classification))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -134,6 +140,7 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(OSMNodeID source,
|
||||
bool restricted,
|
||||
bool is_split,
|
||||
TravelMode travel_mode,
|
||||
ClassData classes,
|
||||
const LaneDescriptionID lane_description_id,
|
||||
guidance::RoadClassification road_classification)
|
||||
: NodeBasedEdge(SPECIAL_NODEID,
|
||||
@@ -149,6 +156,7 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(OSMNodeID source,
|
||||
restricted,
|
||||
is_split,
|
||||
travel_mode,
|
||||
classes,
|
||||
lane_description_id,
|
||||
std::move(road_classification)),
|
||||
osm_source_id(std::move(source)), osm_target_id(std::move(target))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef OSRM_EXTRACTOR_NODE_DATA_CONTAINER_HPP
|
||||
#define OSRM_EXTRACTOR_NODE_DATA_CONTAINER_HPP
|
||||
|
||||
#include "extractor/class_data.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
|
||||
#include "storage/io_fwd.hpp"
|
||||
@@ -41,16 +42,18 @@ template <storage::Ownership Ownership> class EdgeBasedNodeDataContainerImpl
|
||||
EdgeBasedNodeDataContainerImpl() = default;
|
||||
|
||||
EdgeBasedNodeDataContainerImpl(std::size_t size)
|
||||
: geometry_ids(size), name_ids(size), component_ids(size), travel_modes(size)
|
||||
: geometry_ids(size), name_ids(size), component_ids(size), travel_modes(size), classes(size)
|
||||
{
|
||||
}
|
||||
|
||||
EdgeBasedNodeDataContainerImpl(Vector<GeometryID> geometry_ids,
|
||||
Vector<NameID> name_ids,
|
||||
Vector<ComponentID> component_ids,
|
||||
Vector<TravelMode> travel_modes)
|
||||
Vector<TravelMode> travel_modes,
|
||||
Vector<ClassData> classes)
|
||||
: geometry_ids(std::move(geometry_ids)), name_ids(std::move(name_ids)),
|
||||
component_ids(std::move(component_ids)), travel_modes(std::move(travel_modes))
|
||||
component_ids(std::move(component_ids)), travel_modes(std::move(travel_modes)),
|
||||
classes(std::move(classes))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -62,13 +65,20 @@ template <storage::Ownership Ownership> class EdgeBasedNodeDataContainerImpl
|
||||
|
||||
ComponentID GetComponentID(const NodeID node_id) const { return component_ids[node_id]; }
|
||||
|
||||
ClassData GetClassData(const NodeID node_id) const { return classes[node_id]; }
|
||||
|
||||
// Used by EdgeBasedGraphFactory to fill data structure
|
||||
template <typename = std::enable_if<Ownership == storage::Ownership::Container>>
|
||||
void SetData(NodeID node_id, GeometryID geometry_id, NameID name_id, TravelMode travel_mode)
|
||||
void SetData(NodeID node_id,
|
||||
GeometryID geometry_id,
|
||||
NameID name_id,
|
||||
TravelMode travel_mode,
|
||||
ClassData class_data)
|
||||
{
|
||||
geometry_ids[node_id] = geometry_id;
|
||||
name_ids[node_id] = name_id;
|
||||
travel_modes[node_id] = travel_mode;
|
||||
classes[node_id] = class_data;
|
||||
}
|
||||
|
||||
// Used by EdgeBasedGraphFactory to fill data structure
|
||||
@@ -91,6 +101,7 @@ template <storage::Ownership Ownership> class EdgeBasedNodeDataContainerImpl
|
||||
util::inplacePermutation(name_ids.begin(), name_ids.end(), permutation);
|
||||
util::inplacePermutation(component_ids.begin(), component_ids.end(), permutation);
|
||||
util::inplacePermutation(travel_modes.begin(), travel_modes.end(), permutation);
|
||||
util::inplacePermutation(classes.begin(), classes.end(), permutation);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -98,6 +109,7 @@ template <storage::Ownership Ownership> class EdgeBasedNodeDataContainerImpl
|
||||
Vector<NameID> name_ids;
|
||||
Vector<ComponentID> component_ids;
|
||||
Vector<TravelMode> travel_modes;
|
||||
Vector<ClassData> classes;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef PROFILE_PROPERTIES_HPP
|
||||
#define PROFILE_PROPERTIES_HPP
|
||||
|
||||
#include "extractor/class_data.hpp"
|
||||
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
@@ -17,6 +19,7 @@ const constexpr auto DEFAULT_MAX_SPEED = 180 / 3.6; // 180kmph -> m/s
|
||||
struct ProfileProperties
|
||||
{
|
||||
static constexpr int MAX_WEIGHT_NAME_LENGTH = 255;
|
||||
static constexpr int MAX_CLASS_NAME_LENGTH = 255;
|
||||
|
||||
ProfileProperties()
|
||||
: traffic_signal_penalty(0), u_turn_penalty(0),
|
||||
@@ -66,6 +69,22 @@ struct ProfileProperties
|
||||
return std::string(weight_name);
|
||||
}
|
||||
|
||||
void SetClassName(std::size_t index, const std::string &name)
|
||||
{
|
||||
char *name_ptr = class_names[index];
|
||||
auto count = std::min<std::size_t>(name.length(), MAX_CLASS_NAME_LENGTH) + 1;
|
||||
std::copy_n(name.c_str(), count, name_ptr);
|
||||
// Make sure this is always zero terminated
|
||||
BOOST_ASSERT(class_names[index][count - 1] == '\0');
|
||||
BOOST_ASSERT(class_names[index][MAX_CLASS_NAME_LENGTH] == '\0');
|
||||
}
|
||||
|
||||
std::string GetClassName(std::size_t index) const
|
||||
{
|
||||
BOOST_ASSERT(index <= MAX_CLASS_INDEX);
|
||||
return std::string(class_names[index]);
|
||||
}
|
||||
|
||||
double GetWeightMultiplier() const { return std::pow(10., weight_precision); }
|
||||
|
||||
double GetMaxTurnWeight() const
|
||||
@@ -86,6 +105,8 @@ struct ProfileProperties
|
||||
bool fallback_to_duration;
|
||||
//! stores the name of the weight (e.g. 'duration', 'distance', 'safety')
|
||||
char weight_name[MAX_WEIGHT_NAME_LENGTH + 1];
|
||||
//! stores the names of each class
|
||||
std::array<char[MAX_CLASS_NAME_LENGTH + 1], MAX_CLASS_INDEX + 1> class_names;
|
||||
unsigned weight_precision = 1;
|
||||
bool force_split_edges = false;
|
||||
|
||||
|
||||
@@ -121,6 +121,7 @@ inline void read(storage::io::FileReader &reader,
|
||||
storage::serialization::read(reader, node_data_container.name_ids);
|
||||
storage::serialization::read(reader, node_data_container.component_ids);
|
||||
storage::serialization::read(reader, node_data_container.travel_modes);
|
||||
storage::serialization::read(reader, node_data_container.classes);
|
||||
}
|
||||
|
||||
template <storage::Ownership Ownership>
|
||||
@@ -131,6 +132,7 @@ inline void write(storage::io::FileWriter &writer,
|
||||
storage::serialization::write(writer, node_data_container.name_ids);
|
||||
storage::serialization::write(writer, node_data_container.component_ids);
|
||||
storage::serialization::write(writer, node_data_container.travel_modes);
|
||||
storage::serialization::write(writer, node_data_container.classes);
|
||||
}
|
||||
|
||||
// read/write for conditional turn restrictions file
|
||||
|
||||
@@ -23,6 +23,7 @@ const constexpr char *block_id_to_name[] = {"NAME_CHAR_DATA",
|
||||
"NAME_ID_LIST",
|
||||
"COMPONENT_ID_LIST",
|
||||
"TRAVEL_MODE_LIST",
|
||||
"CLASSES_LIST",
|
||||
"CH_GRAPH_NODE_LIST",
|
||||
"CH_GRAPH_EDGE_LIST",
|
||||
"COORDINATE_LIST",
|
||||
@@ -79,6 +80,7 @@ struct DataLayout
|
||||
NAME_ID_LIST,
|
||||
COMPONENT_ID_LIST,
|
||||
TRAVEL_MODE_LIST,
|
||||
CLASSES_LIST,
|
||||
CH_GRAPH_NODE_LIST,
|
||||
CH_GRAPH_EDGE_LIST,
|
||||
COORDINATE_LIST,
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
#ifndef OSRM_UTIL_BIT_RANGE_HPP
|
||||
#define OSRM_UTIL_BIT_RANGE_HPP
|
||||
|
||||
#include "util/msb.hpp"
|
||||
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <typename T> std::size_t countOnes(T value)
|
||||
{
|
||||
static_assert(std::is_unsigned<T>::value, "Only unsigned types allowed");
|
||||
std::size_t number_of_ones = 0;
|
||||
while (value > 0)
|
||||
{
|
||||
auto index = msb(value);
|
||||
value = value & ~(T{1} << index);
|
||||
number_of_ones++;
|
||||
}
|
||||
return number_of_ones;
|
||||
}
|
||||
|
||||
#if (defined(__clang__) || defined(__GNUC__) || defined(__GNUG__))
|
||||
inline std::size_t countOnes(std::uint8_t value)
|
||||
{
|
||||
return __builtin_popcount(std::uint32_t{value});
|
||||
}
|
||||
inline std::size_t countOnes(std::uint16_t value)
|
||||
{
|
||||
return __builtin_popcount(std::uint32_t{value});
|
||||
}
|
||||
inline std::size_t countOnes(unsigned int value) { return __builtin_popcount(value); }
|
||||
inline std::size_t countOnes(unsigned long value) { return __builtin_popcountl(value); }
|
||||
inline std::size_t countOnes(unsigned long long value) { return __builtin_popcountll(value); }
|
||||
#endif
|
||||
}
|
||||
|
||||
// Investigate if we can replace this with
|
||||
// http://www.boost.org/doc/libs/1_64_0/libs/dynamic_bitset/dynamic_bitset.html
|
||||
template <typename DataT>
|
||||
class BitIterator : public boost::iterator_facade<BitIterator<DataT>,
|
||||
const std::size_t,
|
||||
boost::forward_traversal_tag,
|
||||
const std::size_t>
|
||||
{
|
||||
typedef boost::iterator_facade<BitIterator<DataT>,
|
||||
const std::size_t,
|
||||
boost::forward_traversal_tag,
|
||||
const std::size_t>
|
||||
base_t;
|
||||
|
||||
public:
|
||||
typedef typename base_t::value_type value_type;
|
||||
typedef typename base_t::difference_type difference_type;
|
||||
typedef typename base_t::reference reference;
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
|
||||
explicit BitIterator() : m_value(0) {}
|
||||
explicit BitIterator(const DataT x) : m_value(std::move(x)) {}
|
||||
|
||||
private:
|
||||
void increment()
|
||||
{
|
||||
auto index = msb(m_value);
|
||||
m_value = m_value & ~(DataT{1} << index);
|
||||
}
|
||||
|
||||
difference_type distance_to(const BitIterator &other) const
|
||||
{
|
||||
return detail::countOnes(m_value) - detail::countOnes(other.m_value);
|
||||
}
|
||||
|
||||
bool equal(const BitIterator &other) const { return m_value == other.m_value; }
|
||||
|
||||
reference dereference() const
|
||||
{
|
||||
BOOST_ASSERT(m_value > 0);
|
||||
return msb(m_value);
|
||||
}
|
||||
|
||||
friend class ::boost::iterator_core_access;
|
||||
DataT m_value;
|
||||
};
|
||||
|
||||
// Returns range over all 1 bits of value
|
||||
template <typename T> auto makeBitRange(const T value)
|
||||
{
|
||||
return boost::make_iterator_range(BitIterator<T>{value}, BitIterator<T>{});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+14
-5
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <climits>
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
|
||||
@@ -26,16 +27,24 @@ template <typename T> std::size_t msb(T value)
|
||||
return msb - 1;
|
||||
}
|
||||
|
||||
#if (defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)) && __x86_64__
|
||||
inline std::size_t msb(std::uint64_t v)
|
||||
#if (defined(__clang__) || defined(__GNUC__) || defined(__GNUG__))
|
||||
inline std::size_t msb(unsigned long long v)
|
||||
{
|
||||
BOOST_ASSERT(v > 0);
|
||||
return 63UL - __builtin_clzl(v);
|
||||
constexpr auto MSB_INDEX = CHAR_BIT * sizeof(unsigned long long) - 1;
|
||||
return MSB_INDEX - __builtin_clzll(v);
|
||||
}
|
||||
inline std::size_t msb(std::uint32_t v)
|
||||
inline std::size_t msb(unsigned long v)
|
||||
{
|
||||
BOOST_ASSERT(v > 0);
|
||||
return 31UL - __builtin_clz(v);
|
||||
constexpr auto MSB_INDEX = CHAR_BIT * sizeof(unsigned long) - 1;
|
||||
return MSB_INDEX - __builtin_clzl(v);
|
||||
}
|
||||
inline std::size_t msb(unsigned int v)
|
||||
{
|
||||
BOOST_ASSERT(v > 0);
|
||||
constexpr auto MSB_INDEX = CHAR_BIT * sizeof(unsigned int) - 1;
|
||||
return MSB_INDEX - __builtin_clz(v);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef NODE_BASED_GRAPH_HPP
|
||||
#define NODE_BASED_GRAPH_HPP
|
||||
|
||||
#include "extractor/class_data.hpp"
|
||||
#include "extractor/guidance/road_classification.hpp"
|
||||
#include "extractor/node_based_edge.hpp"
|
||||
#include "util/dynamic_graph.hpp"
|
||||
@@ -35,10 +36,12 @@ struct NodeBasedEdgeData
|
||||
bool startpoint,
|
||||
bool restricted,
|
||||
extractor::TravelMode travel_mode,
|
||||
extractor::ClassData classes,
|
||||
const LaneDescriptionID lane_description_id)
|
||||
: weight(weight), duration(duration), edge_id(edge_id), name_id(name_id),
|
||||
reversed(reversed), roundabout(roundabout), circular(circular), startpoint(startpoint),
|
||||
restricted(restricted), travel_mode(travel_mode), lane_description_id(lane_description_id)
|
||||
restricted(restricted), travel_mode(travel_mode), classes(classes),
|
||||
lane_description_id(lane_description_id)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -52,6 +55,7 @@ struct NodeBasedEdgeData
|
||||
bool startpoint : 1;
|
||||
bool restricted : 1;
|
||||
extractor::TravelMode travel_mode : 4;
|
||||
extractor::ClassData classes;
|
||||
LaneDescriptionID lane_description_id;
|
||||
extractor::guidance::RoadClassification road_classification;
|
||||
|
||||
@@ -59,7 +63,7 @@ struct NodeBasedEdgeData
|
||||
{
|
||||
return (reversed == other.reversed) && (roundabout == other.roundabout) &&
|
||||
(circular == other.circular) && (startpoint == other.startpoint) &&
|
||||
(travel_mode == other.travel_mode) &&
|
||||
(travel_mode == other.travel_mode) && (classes == other.classes) &&
|
||||
(road_classification == other.road_classification) &&
|
||||
(restricted == other.restricted);
|
||||
}
|
||||
@@ -89,6 +93,7 @@ NodeBasedDynamicGraphFromEdges(NodeID number_of_nodes,
|
||||
output_edge.data.circular = input_edge.circular;
|
||||
output_edge.data.name_id = input_edge.name_id;
|
||||
output_edge.data.travel_mode = input_edge.travel_mode;
|
||||
output_edge.data.classes = input_edge.classes;
|
||||
output_edge.data.startpoint = input_edge.startpoint;
|
||||
output_edge.data.restricted = input_edge.restricted;
|
||||
output_edge.data.road_classification = input_edge.road_classification;
|
||||
|
||||
Reference in New Issue
Block a user