Skip to content

Commit

Permalink
fix level changes: propagate kNoLevel
Browse files Browse the repository at this point in the history
  • Loading branch information
felixguendling committed Nov 2, 2024
1 parent 54f21fe commit 0bcf6ce
Show file tree
Hide file tree
Showing 15 changed files with 411 additions and 740 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ configure_file(
file(GLOB_RECURSE osr-test-files test/*cc)
add_executable(osr-test ${osr-test-files})
target_include_directories(osr-test PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/generated)
target_link_libraries(osr-test gtest osr)
target_link_libraries(osr-test gtest osr boost-json)

# --- MIMALLOC ---
if (OSR_MIMALLOC)
Expand Down
12 changes: 6 additions & 6 deletions exe/backend/src/http_server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ web_server::string_res_t json_response(
location parse_location(json::value const& v) {
auto const& obj = v.as_object();
return {obj.at("lat").as_double(), obj.at("lng").as_double(),
obj.contains("level") ? to_level(obj.at("level").to_number<float>())
obj.contains("level") ? level_t{obj.at("level").to_number<float>()}
: kNoLevel};
}

Expand Down Expand Up @@ -132,7 +132,7 @@ struct http_server::impl {
{"type", "Feature"},
{
"properties",
{{"level", to_float(s.from_level_)},
{{"level", s.from_level_.to_float()},
{"osm_way_id",
s.way_ == way_idx_t::invalid()
? 0U
Expand Down Expand Up @@ -162,7 +162,7 @@ struct http_server::impl {
}
});
auto levels_sorted =
utl::to_vec(levels, [](level_t const l) { return to_float(l); });
utl::to_vec(levels, [](level_t const l) { return l.to_float(); });
utl::sort(levels_sorted, [](auto&& a, auto&& b) { return a > b; });
cb(json_response(req,
json::serialize(utl::all(levels_sorted) //
Expand All @@ -184,10 +184,10 @@ struct http_server::impl {

switch (profile) {
case search_profile::kFoot:
send_graph_response<foot<false>>(req, cb, gj);
send_graph_response<foot<false, elevator_tracking>>(req, cb, gj);
break;
case search_profile::kWheelchair:
send_graph_response<foot<true>>(req, cb, gj);
send_graph_response<foot<true, elevator_tracking>>(req, cb, gj);
break;
case search_profile::kBike: send_graph_response<bike>(req, cb, gj); break;
case search_profile::kCar: send_graph_response<car>(req, cb, gj); break;
Expand Down Expand Up @@ -229,7 +229,7 @@ struct http_server::impl {

auto const query = boost::json::parse(req.body()).as_object();
auto const level = query.contains("level")
? to_level(query.at("level").to_number<float>())
? level_t{query.at("level").to_number<float>()}
: kNoLevel;
auto const waypoints = query.at("waypoints").as_array();
auto const min = point::from_latlng(
Expand Down
5 changes: 4 additions & 1 deletion include/osr/extract/tags.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,16 @@ struct tags {
is_platform_ = true;
}
break;
case cista::hash("layer"):
// not correct but layer seems to be used like level in some places :/
[[fallthrough]];
case cista::hash("level"): {
has_level_ = true;
auto s = utl::cstr{t.value()};
while (s) {
auto l = 0.0F;
utl::parse_arg(s, l);
auto const lvl = to_level(std::clamp(l, kMinLevel, kMaxLevel));
auto const lvl = level_t{std::clamp(l, kMinLevel, kMaxLevel)};
level_bits_ |= (1U << to_idx(lvl));
if (s) {
++s;
Expand Down
12 changes: 6 additions & 6 deletions include/osr/geojson.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ struct geojson_writer {
{"properties",
{{"type", is_way(r) ? "way" : "node"},
{"platform_idx", to_idx(i)},
{"level", to_float(platforms_->get_level(w_, i))},
{"level", platforms_->get_level(w_, i).to_float()},
{"names", platform_names(*platforms_, i)}}},
{"geometry", geometry}});
}
Expand Down Expand Up @@ -94,8 +94,8 @@ struct geojson_writer {
{"oneway_car", p.is_oneway_car()},
{"oneway_bike", p.is_oneway_bike()},
{"max_speed", p.max_speed_km_per_h()},
{"from_level", to_float(level_t{p.from_level()})},
{"to_level", to_float(level_t{p.to_level()})},
{"from_level", p.from_level().to_float()},
{"to_level", p.to_level().to_float()},
{"is_elevator", p.is_elevator()},
{"is_steps", p.is_steps()},
{"is_parking", p.is_parking_}}},
Expand All @@ -116,8 +116,8 @@ struct geojson_writer {
{"oneway_car", p.is_oneway_car()},
{"oneway_bike", p.is_oneway_bike()},
{"max_speed", p.max_speed_km_per_h()},
{"from_level", to_float(level_t{p.from_level()})},
{"to_level", to_float(level_t{p.to_level()})},
{"from_level", p.from_level().to_float()},
{"to_level", p.to_level().to_float()},
{"is_elevator", p.is_elevator()},
{"is_steps", p.is_steps()}}},
{"geometry", to_line_string(w_.way_polylines_[i])}});
Expand All @@ -142,7 +142,7 @@ struct geojson_writer {

auto levels = std::vector<float>();
foot<true>::for_each_elevator_level(
*w_.r_, n, [&](auto&& l) { levels.push_back(to_float(level_t{l})); });
*w_.r_, n, [&](level_t const l) { levels.push_back(l.to_float()); });

auto properties = boost::json::object{
{"osm_node_id", to_idx(w_.node_to_osm_[n])},
Expand Down
2 changes: 1 addition & 1 deletion include/osr/location.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ struct location {
CISTA_FRIEND_COMPARABLE(location)

friend std::ostream& operator<<(std::ostream& out, location const& l) {
return out << "{ pos=" << l.pos_ << ", lvl=" << to_float(l.lvl_) << " }";
return out << "{ pos=" << l.pos_ << ", lvl=" << l.lvl_.to_float() << " }";
}

geo::latlng pos_;
Expand Down
2 changes: 1 addition & 1 deletion include/osr/platforms.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ struct platforms {

level_t get_level(ways const& w, platform_idx_t const i) const {
if (i == platform_idx_t::invalid()) {
return to_level(0.0);
return level_t{0.0F};
}
return std::visit(
utl::overloaded{
Expand Down
4 changes: 2 additions & 2 deletions include/osr/routing/profiles/bike_sharing.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,14 @@ struct bike_sharing {
boost::json::object geojson_properties(ways const& w) const {
auto properties =
boost::json::object{{"osm_node_id", to_idx(w.node_to_osm_[n_])},
{"level", to_float(lvl_)},
{"level", lvl_.to_float()},
{"type", node_type_to_str(type_)}};
return properties;
}

std::ostream& print(std::ostream& out, ways const& w) const {
return out << "(node=" << w.node_to_osm_[n_]
<< ", level=" << to_float(lvl_)
<< ", level=" << lvl_.to_float()
<< ", type=" << node_type_to_str(type_) << ")";
}

Expand Down
4 changes: 2 additions & 2 deletions include/osr/routing/profiles/car_parking.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ struct car_parking {
boost::json::object geojson_properties(ways const& w) const {
auto properties =
boost::json::object{{"osm_node_id", to_idx(w.node_to_osm_[n_])},
{"level", to_float(lvl_)},
{"level", lvl_.to_float()},
{"type", node_type_to_str(type_)}};
if (is_car_node()) {
properties.emplace("direction", to_str(dir_));
Expand All @@ -52,7 +52,7 @@ struct car_parking {

std::ostream& print(std::ostream& out, ways const& w) const {
return out << "(node=" << w.node_to_osm_[n_]
<< ", level=" << to_float(lvl_) << ", dir=" << to_str(dir_)
<< ", level=" << lvl_.to_float() << ", dir=" << to_str(dir_)
<< ", way=" << w.way_osm_idx_[w.r_->node_ways_[n_][way_]]
<< ", type=" << node_type_to_str(type_) << ")";
}
Expand Down
14 changes: 7 additions & 7 deletions include/osr/routing/profiles/foot.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ struct foot {
static constexpr mode get_mode() noexcept { return mode::kFoot; }

std::ostream& print(std::ostream& out, ways const& w) const {
return out << "(node=" << w.node_to_osm_[n_]
<< ", level=" << to_float(lvl_) << ")";
return out << "(node=" << w.node_to_osm_[n_] << ", level=" << lvl_ << ")";
}

node_idx_t n_;
Expand Down Expand Up @@ -107,9 +106,9 @@ struct foot {
if (lvl == kNoLevel ||
(p.from_level() == lvl || p.to_level() == lvl ||
can_use_elevator(w, n, lvl)) ||
(lvl == to_level(0.F) &&
(lvl == level_t{0.F} &&
(p.from_level() == kNoLevel && p.to_level() == kNoLevel))) {
f(node{n, lvl == kNoLevel ? p.from_level() : lvl});
f(node{n, p.from_level()});
}
}

Expand Down Expand Up @@ -243,7 +242,7 @@ struct foot {
return way_prop.from_level();
} else if (way_prop.from_level() == from_level ||
way_prop.from_level() == kNoLevel || from_level == kNoLevel) {
return from_level;
return way_prop.from_level();
} else {
return std::nullopt;
}
Expand All @@ -263,8 +262,9 @@ struct foot {
Fn&& f) {
auto const p = w.node_properties_[n];
if (p.is_multi_level()) {
utl::for_each_set_bit(get_elevator_multi_levels(w, n),
[&](auto&& l) { f(level_t{l}); });
utl::for_each_set_bit(get_elevator_multi_levels(w, n), [&](auto&& l) {
f(level_t{static_cast<std::uint8_t>(l)});
});
} else {
f(p.from_level());
f(p.to_level());
Expand Down
39 changes: 18 additions & 21 deletions include/osr/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,19 +138,26 @@ constexpr direction to_direction(std::string_view s) {
}

// level
constexpr auto const kMinLevel = -4.0F;
constexpr auto const kMaxLevel = 3.5F;

struct level_t {
static constexpr auto kNoLevel = 0U;

friend constexpr std::uint8_t to_idx(level_t l) { return l.v_; }

friend std::ostream& operator<<(std::ostream& out, level_t const l) {
if (to_idx(l) == 0) {
return out << "-";
} else {
return out << (-4.0 + ((to_idx(l) - 1U) / 4.0F));
}
return (l.v_ == kNoLevel) ? (out << "-") : (out << l.to_float());
}

template <std::integral X>
explicit constexpr level_t(X x) : v_{static_cast<std::uint8_t>(x)} {}
explicit constexpr level_t(std::uint8_t const x) : v_{x} {}

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

constexpr float to_float() const {
return (v_ == kNoLevel) ? 0.0F : (kMinLevel + ((v_ - 1U) / 4.0F));
}

constexpr level_t() = default;

Expand All @@ -161,20 +168,10 @@ struct level_t {
std::uint8_t v_;
};

constexpr auto const kNoLevel = level_t{0U};
constexpr auto const kMinLevel = -4.0F;
constexpr auto const kMaxLevel = 3.5F;

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

constexpr float to_float(level_t const l) {
return (l == kNoLevel) ? 0.0F : (kMinLevel + ((to_idx(l) - 1U) / 4.0F));
}
constexpr auto const kNoLevel = level_t{std::uint8_t{0U}};

constexpr auto const kLevelBits = cista::constexpr_trailing_zeros(
cista::next_power_of_two(to_idx(to_level(kMaxLevel)) + 1U));
cista::next_power_of_two(to_idx(level_t{kMaxLevel}) + 1U));

using level_bits_t = std::uint32_t;

Expand All @@ -186,8 +183,8 @@ constexpr std::tuple<level_t, level_t, bool> get_levels(
auto from = kNoLevel, to = kNoLevel;
utl::for_each_set_bit(levels, [&](auto&& bit) {
from == kNoLevel //
? from = level_t{bit}
: to = level_t{bit};
? from = level_t{static_cast<std::uint8_t>(bit)}
: to = level_t{static_cast<std::uint8_t>(bit)};
});
return {from, to == kNoLevel ? from : to, std::popcount(levels) > 2};
}
Expand Down
4 changes: 2 additions & 2 deletions src/route.cc
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@ double add_path(ways const& w,
}
}
} else {
segment.from_level_ = to_level(0);
segment.to_level_ = to_level(0);
segment.from_level_ = level_t{0.0F};
segment.to_level_ = level_t{0.0F};
segment.from_ = from.get_node();
segment.to_ = to.get_node();
// polyline has to be filled by the caller, because we don't know
Expand Down
9 changes: 6 additions & 3 deletions test/level_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@
using namespace osr;

TEST(osr, level) {
auto const lvl_0 = to_float(to_level(0.1F));
auto const lvl_0 = level_t{0.1F}.to_float();
EXPECT_EQ(0.0F, lvl_0);

auto const lvl_4 = to_float(to_level(4.0F));
auto const lvl_neg4 = level_t{-4.0F}.to_float();
EXPECT_EQ(-4.0F, lvl_neg4);

auto const lvl_4 = level_t{4.0F}.to_float();
EXPECT_EQ(4.0F, lvl_4);

auto const lvl_minus_3 = to_float(to_level(-3.0F));
auto const lvl_minus_3 = level_t{-3.0F}.to_float();
EXPECT_EQ(-3.0F, lvl_minus_3);
}
Loading

0 comments on commit 0bcf6ce

Please sign in to comment.