From 06ddcbb6ca05a9636373f015c2c852a11874bc79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20G=C3=BCndling?= Date: Sun, 3 Nov 2024 20:22:36 +0100 Subject: [PATCH] prefer level bits if both, level bits and layer bits are there --- include/osr/extract/tags.h | 37 +++++++++++++++++++++++-------------- src/extract.cc | 9 +++++++-- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/include/osr/extract/tags.h b/include/osr/extract/tags.h index 59da382..45474c3 100644 --- a/include/osr/extract/tags.h +++ b/include/osr/extract/tags.h @@ -14,6 +14,19 @@ enum class override : std::uint8_t { kNone, kWhitelist, kBlacklist }; struct tags { explicit tags(osmium::OSMObject const& o) { + auto const add_levels = [](auto&& t, level_bits_t& level_bits) { + auto s = utl::cstr{t.value()}; + while (s) { + auto l = 0.0F; + utl::parse_arg(s, l); + auto const lvl = level_t{std::clamp(l, kMinLevel, kMaxLevel)}; + level_bits |= (1U << to_idx(lvl)); + if (s) { + ++s; + } + } + }; + for (auto const& t : o.tags()) { switch (cista::hash(std::string_view{t.key()})) { using namespace std::string_view_literals; @@ -53,23 +66,15 @@ struct tags { is_platform_ = true; } break; + case cista::hash("level"): + has_level_ = true; + add_levels(t, level_bits_); + 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 = level_t{std::clamp(l, kMinLevel, kMaxLevel)}; - level_bits_ |= (1U << to_idx(lvl)); - if (s) { - ++s; - } - } + has_layer_ = true; + add_levels(t, layer_bits_); break; - } case cista::hash("name"): name_ = t.value(); break; case cista::hash("ref"): ref_ = t.value(); break; case cista::hash("entrance"): is_entrance_ = true; break; @@ -197,6 +202,10 @@ struct tags { // https://wiki.openstreetmap.org/wiki/Key:level bool has_level_{false}; level_bits_t level_bits_{0U}; + + // https://wiki.openstreetmap.org/wiki/Key:layer + bool has_layer_{false}; + level_bits_t layer_bits_{0U}; }; template diff --git a/src/extract.cc b/src/extract.cc index cd206fa..4c69534 100644 --- a/src/extract.cc +++ b/src/extract.cc @@ -92,8 +92,13 @@ struct rel_way { using rel_ways_t = hash_map; +std::tuple get_levels(tags const& t) { + return t.has_level_ ? get_levels(t.has_level_, t.level_bits_) + : get_levels(t.has_layer_, t.layer_bits_); +} + way_properties get_way_properties(tags const& t) { - auto const [from, to, _] = get_levels(t.has_level_, t.level_bits_); + auto const [from, to, _] = get_levels(t); auto p = way_properties{}; std::memset(&p, 0, sizeof(way_properties)); p.is_foot_accessible_ = is_accessible(t, osm_obj_type::kWay); @@ -113,7 +118,7 @@ way_properties get_way_properties(tags const& t) { } std::pair get_node_properties(tags const& t) { - auto const [from, to, is_multi] = get_levels(t.has_level_, t.level_bits_); + auto const [from, to, is_multi] = get_levels(t); auto p = node_properties{}; std::memset(&p, 0, sizeof(node_properties)); p.from_level_ = to_idx(from);