This PR adds more advanced coordinate extraction, analysing the road to detect offsets due to OSM way modelling. In addition it improves the handling of bearings. Right now OSM reports bearings simply based on the very first coordinate along a way. With this PR, we store the bearings for a turn correctly, making the bearings for turns correct.
134 lines
4.9 KiB
C++
134 lines
4.9 KiB
C++
#ifndef OSRM_EXTRACTOR_CLASSIFICATION_DATA_HPP_
|
|
#define OSRM_EXTRACTOR_CLASSIFICATION_DATA_HPP_
|
|
|
|
#include <cmath>
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
|
|
#include <osmium/osm.hpp>
|
|
|
|
namespace osrm
|
|
{
|
|
namespace extractor
|
|
{
|
|
namespace guidance
|
|
{
|
|
|
|
// Priorities are used to distinguish between how likely a turn is in comparison to a different
|
|
// road. The priorities here are used to distinguish between obvious turns (e.g. following a primary
|
|
// road next to a residential one is obvious). The decision what is obvious is described in the
|
|
// guidance constants.
|
|
namespace RoadPriorityClass
|
|
{
|
|
typedef std::uint8_t Enum;
|
|
// Top priority Road
|
|
const constexpr Enum MOTORWAY = 0;
|
|
// Second highest priority
|
|
const constexpr Enum TRUNK = 2;
|
|
// Main roads
|
|
const constexpr Enum PRIMARY = 4;
|
|
const constexpr Enum SECONDARY = 6;
|
|
const constexpr Enum TERTIARY = 8;
|
|
// Residential Categories
|
|
const constexpr Enum MAIN_RESIDENTIAL = 10;
|
|
const constexpr Enum SIDE_RESIDENTIAL = 11;
|
|
// Link Category
|
|
const constexpr Enum LINK_ROAD = 14;
|
|
// Bike Accessible
|
|
const constexpr Enum BIKE_PATH = 16;
|
|
// Walk Accessible
|
|
const constexpr Enum FOOT_PATH = 18;
|
|
// Link types are usually not considered in forks, unless amongst each other.
|
|
// a road simply offered for connectivity. Will be ignored in forks/other decisions. Always
|
|
// considered non-obvious to continue on
|
|
const constexpr Enum CONNECTIVITY = 31;
|
|
} // namespace Road Class
|
|
|
|
#pragma pack(push, 1)
|
|
class RoadClassification
|
|
{
|
|
// a class that behaves like a motorway (separated directions)
|
|
std::uint8_t motorway_class : 1;
|
|
// all types of link classes
|
|
std::uint8_t link_class : 1;
|
|
// a low priority class is a pure connectivity way. It can be ignored in multiple decisions
|
|
// (e.g. fork on a primary vs service will not happen)
|
|
std::uint8_t may_be_ignored : 1;
|
|
// the road priority is used as an indicator for forks. If the roads are of similar priority
|
|
// (difference <=1), we can see the road as a fork. Else one of the road classes is seen as
|
|
// obvious choice
|
|
RoadPriorityClass::Enum road_priority_class : 5;
|
|
// the number of lanes in the road
|
|
std::uint8_t number_of_lanes;
|
|
|
|
public:
|
|
// default construction
|
|
RoadClassification()
|
|
: motorway_class(0), link_class(0), may_be_ignored(1),
|
|
road_priority_class(RoadPriorityClass::CONNECTIVITY), number_of_lanes(0)
|
|
{
|
|
}
|
|
|
|
RoadClassification(bool motorway_class,
|
|
bool link_class,
|
|
bool may_be_ignored,
|
|
RoadPriorityClass::Enum road_priority_class,
|
|
std::uint8_t number_of_lanes)
|
|
: motorway_class(motorway_class), link_class(link_class), may_be_ignored(may_be_ignored),
|
|
road_priority_class(road_priority_class), number_of_lanes(number_of_lanes)
|
|
{
|
|
}
|
|
|
|
bool IsMotorwayClass() const { return (0 != motorway_class) && (0 == link_class); }
|
|
void SetMotorwayFlag(const bool new_value) { motorway_class = new_value; }
|
|
|
|
bool IsRampClass() const { return (0 != motorway_class) && (0 != link_class); }
|
|
|
|
bool IsLinkClass() const { return (0 != link_class); }
|
|
void SetLinkClass(const bool new_value) { link_class = new_value; }
|
|
|
|
bool IsLowPriorityRoadClass() const { return (0 != may_be_ignored); }
|
|
void SetLowPriorityFlag(const bool new_value) { may_be_ignored = new_value; }
|
|
|
|
std::uint8_t GetNumberOfLanes() const { return number_of_lanes; }
|
|
void SetNumberOfLanes(const std::uint8_t new_value) { number_of_lanes = new_value; }
|
|
|
|
std::uint32_t GetPriority() const { return static_cast<std::uint32_t>(road_priority_class); }
|
|
|
|
RoadPriorityClass::Enum GetClass() const { return road_priority_class; }
|
|
void SetClass(const RoadPriorityClass::Enum new_value) { road_priority_class = new_value; }
|
|
|
|
bool operator==(const RoadClassification &other) const
|
|
{
|
|
return motorway_class == other.motorway_class && link_class == other.link_class &&
|
|
may_be_ignored == other.may_be_ignored &&
|
|
road_priority_class == other.road_priority_class;
|
|
}
|
|
|
|
bool operator!=(const RoadClassification &other) const { return !(*this == other); }
|
|
|
|
std::string ToString() const
|
|
{
|
|
return std::string() + (motorway_class ? "motorway" : "normal") +
|
|
(link_class ? "_link" : "") + (may_be_ignored ? " ignorable " : " important ") +
|
|
std::to_string(road_priority_class);
|
|
}
|
|
};
|
|
#pragma pack(pop)
|
|
|
|
static_assert(
|
|
sizeof(RoadClassification) == 2,
|
|
"Road Classification should fit two bytes. Increasing this has a severe impact on memory.");
|
|
|
|
inline bool canBeSeenAsFork(const RoadClassification first, const RoadClassification second)
|
|
{
|
|
return std::abs(static_cast<int>(first.GetPriority()) -
|
|
static_cast<int>(second.GetPriority())) <= 1;
|
|
}
|
|
} // namespace guidance
|
|
} // namespace extractor
|
|
} // namespace osrm
|
|
|
|
#endif // OSRM_EXTRACTOR_CLASSIFICATION_DATA_HPP_
|