Skip to content

Commit

Permalink
refactor, add routing for way_candidates
Browse files Browse the repository at this point in the history
  • Loading branch information
felixguendling committed Sep 8, 2024
1 parent cd409dc commit 5c5fe08
Show file tree
Hide file tree
Showing 11 changed files with 387 additions and 224 deletions.
2 changes: 1 addition & 1 deletion .pkg
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
[geo]
[email protected]:motis-project/geo.git
branch=master
commit=82ff7ceeb25abd8ddba01320be27d3cf1bdee1b0
commit=66b34885c7e96e29ddb78a84ae3ab43302ed94e4
[cista]
[email protected]:felixguendling/cista.git
branch=master
Expand Down
1 change: 1 addition & 0 deletions include/osr/geojson.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "utl/pipes/vec.h"

#include "osr/platforms.h"
#include "osr/routing/dijkstra.h"
#include "osr/routing/profiles/foot.h"
#include "osr/ways.h"

Expand Down
22 changes: 22 additions & 0 deletions include/osr/location.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once

#include <ostream>

#include "cista/reflection/comparable.h"

#include "osr/types.h"

namespace osr {

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_) << " }";
}

geo::latlng pos_;
level_t lvl_;
};

} // namespace osr
191 changes: 75 additions & 116 deletions include/osr/lookup.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "cista/reflection/printable.h"

#include "geo/box.h"
#include "geo/polyline.h"

#include "osr/ways.h"

Expand All @@ -14,18 +15,31 @@

#include "rtree.h"

namespace osr {
#include "osr/location.h"
#include "osr/routing/profile.h"

struct location {
CISTA_FRIEND_COMPARABLE(location)
namespace osr {

friend std::ostream& operator<<(std::ostream& out, location const& l) {
return out << "{ pos=" << l.pos_ << ", lvl=" << to_float(l.lvl_) << " }";
template <typename T, typename Collection, typename Fn>
void till_the_end(T const& start,
Collection const& c,
direction const dir,
Fn&& fn) {
if (dir == direction::kForward) {
for (auto i = start; i != c.size(); ++i) {
if (fn(c[i]) == utl::cflow::kBreak) {
break;
}
}
} else {
for (auto j = 0U; j <= start; ++j) {
auto i = start - j;
if (fn(c[i]) == utl::cflow::kBreak) {
break;
}
}
}

geo::latlng pos_;
level_t lvl_;
};
}

struct node_candidate {
bool valid() const { return node_ != node_idx_t::invalid(); }
Expand All @@ -47,62 +61,67 @@ struct way_candidate {
double dist_to_way_;
geo::latlng best_;
std::size_t segment_idx_;
location query_{};
way_idx_t way_{way_idx_t::invalid()};
node_candidate left_{}, right_{};
};

template <typename T, typename Collection, typename Fn>
void till_the_end(T const& start,
Collection const& c,
direction const dir,
Fn&& fn) {
if (dir == direction::kForward) {
for (auto i = start; i != c.size(); ++i) {
if (fn(c[i]) == utl::cflow::kBreak) {
break;
}
}
} else {
for (auto j = 0U; j <= start; ++j) {
auto i = start - j;
if (fn(c[i]) == utl::cflow::kBreak) {
break;
}
}
}
}

using match_t = std::vector<way_candidate>;
using match_view_t = std::span<way_candidate const>;

struct lookup {
lookup(ways const&);
~lookup();

match_t match(location const& query,
bool const reverse,
direction const search_dir,
double const max_match_distance,
bitvec<node_idx_t> const* blocked,
search_profile) const;

template <typename PolyLine>
way_candidate distance_to_way(geo::latlng const& x, PolyLine&& c) {
auto min = std::numeric_limits<double>::max();
auto best = geo::latlng{};
auto best_segment_idx = 0U;
auto segment_idx = 0U;
for (auto const [a, b] : utl::pairwise(c)) {
auto const candidate = geo::closest_on_segment(x, a, b);
auto const dist = geo::distance(x, candidate);
if (dist < min) {
min = dist;
best = candidate;
best_segment_idx = segment_idx;
template <typename Profile>
match_t match(location const& query,
bool const reverse,
direction const search_dir,
double const max_match_distance,
bitvec<node_idx_t> const* blocked) const {
auto way_candidates = get_way_candidates<Profile>(
query, reverse, search_dir, max_match_distance, blocked);
if (way_candidates.empty()) {
way_candidates = get_way_candidates<Profile>(
query, reverse, search_dir, max_match_distance * 2U, blocked);
}
++segment_idx;
return way_candidates;
}
return {.dist_to_way_ = min, .best_ = best, .segment_idx_ = best_segment_idx};
}

struct lookup {
lookup(ways const& ways) : rtree_{rtree_new()}, ways_{ways} {
utl::verify(rtree_ != nullptr, "rtree creation failed");
for (auto i = way_idx_t{0U}; i != ways.n_ways(); ++i) {
insert(i);
}
template <typename Fn>
void find(geo::latlng const& x, Fn&& fn) const {
find({{x.lat() - 0.01, x.lng() - 0.01}, {x.lat() + 0.01, x.lng() + 0.01}},
std::forward<Fn>(fn));
}

template <typename Fn>
void find(geo::box const& b, Fn&& fn) const {
auto const min = b.min_.lnglat();
auto const max = b.max_.lnglat();
rtree_search(
rtree_, min.data(), max.data(),
[](double const* /* min */, double const* /* max */, void const* item,
void* udata) {
(*reinterpret_cast<Fn*>(udata))(
way_idx_t{static_cast<way_idx_t::value_t>(
reinterpret_cast<std::size_t>(item))});
return true;
},
&fn);
}

~lookup() { rtree_free(rtree_); }
hash_set<node_idx_t> find_elevators(geo::box const& b) const;

void insert(way_idx_t);

private:
template <typename Profile>
match_t get_way_candidates(location const& query,
bool const reverse,
Expand All @@ -111,9 +130,11 @@ struct lookup {
bitvec<node_idx_t> const* blocked) const {
auto way_candidates = std::vector<way_candidate>{};
find(query.pos_, [&](way_idx_t const way) {
auto d = distance_to_way(query.pos_, ways_.way_polylines_[way]);
auto d = geo::distance_to_polyline<way_candidate>(
query.pos_, ways_.way_polylines_[way]);
if (d.dist_to_way_ < max_match_distance) {
auto& wc = way_candidates.emplace_back(std::move(d));
wc.query_ = query;
wc.way_ = way;
wc.left_ =
find_next_node<Profile>(wc, query, direction::kBackward, query.lvl_,
Expand All @@ -127,21 +148,6 @@ struct lookup {
return way_candidates;
}

template <typename Profile>
match_t match(location const& query,
bool const reverse,
direction const search_dir,
double const max_match_distance,
bitvec<node_idx_t> const* blocked) const {
auto way_candidates = get_way_candidates<Profile>(
query, reverse, search_dir, max_match_distance, blocked);
if (way_candidates.empty()) {
way_candidates = get_way_candidates<Profile>(
query, reverse, search_dir, max_match_distance * 2U, blocked);
}
return way_candidates;
}

template <typename Profile>
node_candidate find_next_node(way_candidate const& wc,
location const& query,
Expand Down Expand Up @@ -198,53 +204,6 @@ struct lookup {
return c;
}

template <typename Fn>
void find(geo::latlng const& x, Fn&& fn) const {
find({{x.lat() - 0.01, x.lng() - 0.01}, {x.lat() + 0.01, x.lng() + 0.01}},
std::forward<Fn>(fn));
}

template <typename Fn>
void find(geo::box const& b, Fn&& fn) const {
auto const min = b.min_.lnglat();
auto const max = b.max_.lnglat();
rtree_search(
rtree_, min.data(), max.data(),
[](double const* /* min */, double const* /* max */, void const* item,
void* udata) {
(*reinterpret_cast<Fn*>(udata))(
way_idx_t{static_cast<way_idx_t::value_t>(
reinterpret_cast<std::size_t>(item))});
return true;
},
&fn);
}

hash_set<node_idx_t> find_elevators(geo::box const& b) const {
auto elevators = hash_set<node_idx_t>{};
find(b, [&](way_idx_t const way) {
for (auto const n : ways_.r_->way_nodes_[way]) {
if (ways_.r_->node_properties_[n].is_elevator()) {
elevators.emplace(n);
}
}
});
return elevators;
}

void insert(way_idx_t const way) {
auto b = geo::box{};
for (auto const& c : ways_.way_polylines_[way]) {
b.extend(c);
}

auto const min = b.min_.lnglat();
auto const max = b.max_.lnglat();
rtree_insert(
rtree_, min.data(), max.data(),
reinterpret_cast<void*>(static_cast<std::size_t>(to_idx(way))));
}

rtree* rtree_;
ways const& ways_;
};
Expand Down
21 changes: 21 additions & 0 deletions include/osr/routing/profile.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once

#include <cinttypes>
#include <string_view>

namespace osr {

enum class search_profile : std::uint8_t {
kFoot,
kWheelchair,
kBike,
kCar,
kCarParking,
kCarParkingWheelchair
};

search_profile to_profile(std::string_view);

std::string_view to_str(search_profile);

} // namespace osr
4 changes: 0 additions & 4 deletions include/osr/routing/profiles/bike.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@ struct bike {

constexpr node_idx_t get_node() const noexcept { return n_; }

boost::json::object geojson_properties(ways const&) const {
return boost::json::object{{"node_id", n_.v_}, {"type", "bike"}};
}

constexpr node get_key() const noexcept { return *this; }

std::ostream& print(std::ostream& out, ways const& w) const {
Expand Down
4 changes: 0 additions & 4 deletions include/osr/routing/profiles/foot.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@ struct foot {
}
constexpr node_idx_t get_node() const noexcept { return n_; }

boost::json::object geojson_properties(ways const&) const {
return boost::json::object{{"node_id", n_.v_}, {"type", "foot"}};
}

constexpr node get_key() const noexcept { return *this; }

std::ostream& print(std::ostream& out, ways const& w) const {
Expand Down
Loading

0 comments on commit 5c5fe08

Please sign in to comment.