Skip to content

Commit

Permalink
introduce concept of "no level" = wildcard (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
felixguendling authored Oct 27, 2024
1 parent dc598c3 commit 2c9bf3d
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 8 deletions.
5 changes: 5 additions & 0 deletions include/osr/routing/profiles/foot.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,11 @@ struct foot {
return std::nullopt;
}

if (from_level == kNoLevel || way_prop.from_level() == kNoLevel) {
return way_prop.to_level() == kGroundLevel ? way_prop.from_level()
: way_prop.to_level();
}

if (way_prop.is_steps()) {
if (way_prop.from_level() == from_level) {
return way_prop.to_level();
Expand Down
23 changes: 15 additions & 8 deletions include/osr/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,35 +136,42 @@ constexpr direction to_direction(std::string_view s) {
// level
using level_t = cista::strong<std::uint8_t, struct level_>;

constexpr auto const kMinLevel = -4.0F;
// would be -4.0 as float but represented as NaN
constexpr auto const kNoLevel = level_t{0U};
constexpr auto const kMinLevel = -3.75F;
constexpr auto const kMaxLevel = 3.75F;

constexpr level_t to_level(float const f) {
return level_t{static_cast<std::uint8_t>((f - kMinLevel) / 0.25F)};
return level_t{static_cast<std::uint8_t>((f - kMinLevel) / 0.25F) + 1U};
}

constexpr float to_float(level_t const l) {
return l == level_t::invalid() ? 0.0F : (kMinLevel + (to_idx(l) / 4.0F));
switch (to_idx(l)) {
case 0U: return std::numeric_limits<float>::signaling_NaN();
case to_idx(level_t::invalid()): return 0.0F;
default: return (kMinLevel + ((to_idx(l) - 1U) / 4.0F));
}
}

constexpr auto const kLevelBits = cista::constexpr_trailing_zeros(
cista::next_power_of_two(to_idx(to_level(kMaxLevel))));

constexpr auto const kGroundLevel = to_level(0.0F);

using level_bits_t = std::uint32_t;

constexpr std::tuple<level_t, level_t, bool> get_levels(
bool const has_level, level_bits_t const levels) noexcept {
if (!has_level) {
return {level_t{to_level(0.F)}, level_t{to_level(0.F)}, false};
return {kNoLevel, kNoLevel, false};
}
auto from = level_t::invalid(), to = level_t::invalid();
auto from = kNoLevel, to = kNoLevel;
utl::for_each_set_bit(levels, [&](auto&& bit) {
from == level_t::invalid() //
from == kNoLevel //
? from = level_t{bit}
: to = level_t{bit};
});
return {from, to == level_t::invalid() ? from : to,
std::popcount(levels) > 2};
return {from, to == kNoLevel ? from : to, std::popcount(levels) > 2};
}

static_assert(kLevelBits == 5U);
Expand Down

0 comments on commit 2c9bf3d

Please sign in to comment.