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:
Patrick Niklaus
2017-06-27 22:01:05 +00:00
committed by Patrick Niklaus
parent d52d530cbe
commit 44739f2dc3
39 changed files with 614 additions and 57 deletions
@@ -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);
+11 -2
View File
@@ -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;
+11 -4
View File
@@ -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);
+2
View File
@@ -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
+2
View File
@@ -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),
+22
View File
@@ -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
+4
View File
@@ -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;
+7 -4
View File
@@ -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 &current_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());
+9 -1
View File
@@ -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))
+16 -4
View File
@@ -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;
};
}
+21
View File
@@ -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;
+2
View File
@@ -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
+2
View 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,
+99
View File
@@ -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
View File
@@ -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
}
+7 -2
View File
@@ -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;