Skip to content

Commit

Permalink
tracking: tracks an attribute for a path
Browse files Browse the repository at this point in the history
works via labels + entry
dijkstra updates entry tracking with the label tracking

useful to know if a path contains an elevator somewhere
without having to actually reconstruct the whole path
  • Loading branch information
felixguendling committed Jul 20, 2024
1 parent 6cf0a46 commit eff9dbb
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 58 deletions.
2 changes: 1 addition & 1 deletion include/osr/routing/dijkstra.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ struct dijkstra {
cost_[neighbor.get_key()].update(
l, neighbor, static_cast<cost_t>(total), curr)) {
auto next = label{neighbor, static_cast<cost_t>(total)};
next.track(r, way, neighbor.get_node());
next.track(l, r, way, neighbor.get_node());
pq_.push(std::move(next));
}
});
Expand Down
2 changes: 1 addition & 1 deletion include/osr/routing/profiles/bike.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ struct bike {
constexpr node get_node() const noexcept { return {n_}; }
constexpr cost_t cost() const noexcept { return cost_; }

void track(ways::routing const&, way_idx_t, node_idx_t) {}
void track(label const&, ways::routing const&, way_idx_t, node_idx_t) {}

node_idx_t n_;
level_t lvl_;
Expand Down
4 changes: 1 addition & 3 deletions include/osr/routing/profiles/car.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ struct car {

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

void track(ways::routing const&, way_idx_t, node_idx_t) {}

std::ostream& print(std::ostream& out, ways const& w) const {
return out << "(node=" << w.node_to_osm_[n_] << ", dir=" << to_str(dir_)
<< ", way=" << w.way_osm_idx_[w.r_->node_ways_[n_][way_]]
Expand All @@ -53,7 +51,7 @@ struct car {
constexpr node get_node() const noexcept { return {n_, way_, dir_}; }
constexpr cost_t cost() const noexcept { return cost_; }

void track(ways::routing const&, way_idx_t, node_idx_t) {}
void track(label const&, ways::routing const&, way_idx_t, node_idx_t) {}

node_idx_t n_;
way_pos_t way_;
Expand Down
2 changes: 1 addition & 1 deletion include/osr/routing/profiles/car_parking.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ struct car_parking {

constexpr cost_t cost() const noexcept { return cost_; }

void track(ways::routing const&, way_idx_t, node_idx_t) {}
void track(label const&, ways::routing const&, way_idx_t, node_idx_t) {}

node_idx_t n_;
cost_t cost_;
Expand Down
7 changes: 5 additions & 2 deletions include/osr/routing/profiles/foot.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,11 @@ struct foot {
constexpr node get_node() const noexcept { return {n_, lvl_}; }
constexpr cost_t cost() const noexcept { return cost_; }

void track(ways::routing const& r, way_idx_t const w, node_idx_t const n) {
tracking_.track(r, w, n);
void track(label const& l,
ways::routing const& r,
way_idx_t const w,
node_idx_t const n) {
tracking_.track(l.tracking_, r, w, n);
}

node_idx_t n_;
Expand Down
5 changes: 4 additions & 1 deletion include/osr/routing/route.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,10 @@ std::vector<std::optional<path>> route(
cost_t max,
direction,
double max_match_distance,
bitvec<node_idx_t> const* blocked = nullptr);
bitvec<node_idx_t> const* blocked = nullptr,
std::function<bool(path const&)> const& = [](path const&) {
return false;
});

std::optional<path> route(ways const&,
lookup const&,
Expand Down
12 changes: 9 additions & 3 deletions include/osr/routing/tracking.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,22 @@ namespace osr {

struct elevator_tracking {
void write(path& p) const { p.uses_elevator_ = uses_elevator_; }
void track(ways::routing const& r, way_idx_t, node_idx_t const n) {
uses_elevator_ |= r.node_properties_[n].is_elevator();
void track(elevator_tracking const& l,
ways::routing const& r,
way_idx_t,
node_idx_t const n) {
uses_elevator_ = l.uses_elevator_ || r.node_properties_[n].is_elevator();
}

bool uses_elevator_{false};
};

struct noop_tracking {
void write(path&) const {}
void track(ways::routing const&, way_idx_t, node_idx_t) {}
void track(noop_tracking const&,
ways::routing const&,
way_idx_t,
node_idx_t) {}
};

} // namespace osr
108 changes: 62 additions & 46 deletions src/route.cc
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ template <typename Profile>
std::optional<std::tuple<node_candidate const*,
way_candidate const*,
typename Profile::node,
cost_t>>
path>>
best_candidate(ways const& w,
dijkstra<Profile>& d,
level_t const lvl,
Expand All @@ -213,7 +213,7 @@ best_candidate(ways const& w,
auto const get_best = [&](way_candidate const& dest,
node_candidate const* x) {
auto best_node = typename Profile::node{};
auto best_cost = std::numeric_limits<cost_t>::max();
auto best_cost = path{.cost_ = std::numeric_limits<cost_t>::max()};
Profile::resolve_all(*w.r_, x->node_, lvl, [&](auto&& node) {
if (!Profile::is_dest_reachable(*w.r_, node, dest.way_,
flip(opposite(dir), x->way_dir_),
Expand All @@ -227,26 +227,26 @@ best_candidate(ways const& w,
}

auto const total_cost = target_cost + x->cost_;
if (total_cost < max && total_cost < best_cost) {
if (total_cost < max && total_cost < best_cost.cost_) {
best_node = node;
best_cost = static_cast<cost_t>(total_cost);
best_cost.cost_ = static_cast<cost_t>(total_cost);
}
});
return std::pair{best_node, best_cost};
};

for (auto const& dest : m) {
auto best_node = typename Profile::node{};
auto best_cost = std::numeric_limits<cost_t>::max();
auto best_cost = path{.cost_ = std::numeric_limits<cost_t>::max()};
auto best = static_cast<node_candidate const*>(nullptr);

for (auto const x : {&dest.left_, &dest.right_}) {
if (x->valid() && x->cost_ < max) {
auto const [x_node, x_cost] = get_best(dest, x);
if (x_cost < max && x_cost < best_cost) {
if (x_cost.cost_ < max && x_cost.cost_ < best_cost.cost_) {
best = x;
best_node = x_node;
best_cost = static_cast<cost_t>(x_cost);
best_cost = x_cost;
}
}
}
Expand Down Expand Up @@ -282,10 +282,9 @@ std::optional<path> route(ways const& w,
for (auto const& start : from_match) {
for (auto const* nc : {&start.left_, &start.right_}) {
if (nc->valid() && nc->cost_ < max) {
Profile::resolve_start_node(*w.r_, start.way_, nc->node_, from.lvl_,
dir, [&](auto const node) {
d.add_start({node, nc->cost_});
});
Profile::resolve_start_node(
*w.r_, start.way_, nc->node_, from.lvl_, dir,
[&](auto const node) { d.add_start({node, nc->cost_}); });
}
}

Expand All @@ -297,24 +296,27 @@ std::optional<path> route(ways const& w,

auto const c = best_candidate(w, d, to.lvl_, to_match, max, dir);
if (c.has_value()) {
auto const [nc, wc, node, cost] = *c;
return reconstruct<Profile>(w, blocked, d, start, *nc, node, cost, dir);
auto const [nc, wc, node, p] = *c;
return reconstruct<Profile>(w, blocked, d, start, *nc, node, p.cost_,
dir);
}
}

return std::nullopt;
}

template <typename Profile>
std::vector<std::optional<path>> route(ways const& w,
lookup const& l,
dijkstra<Profile>& d,
location const& from,
std::vector<location> const& to,
cost_t const max,
direction const dir,
double const max_match_distance,
bitvec<node_idx_t> const* blocked) {
std::vector<std::optional<path>> route(
ways const& w,
lookup const& l,
dijkstra<Profile>& d,
location const& from,
std::vector<location> const& to,
cost_t const max,
direction const dir,
double const max_match_distance,
bitvec<node_idx_t> const* blocked,
std::function<bool(path const&)> const& do_reconstruct) {
auto const from_match =
l.match<Profile>(from, false, dir, max_match_distance, blocked);
auto const to_match = utl::to_vec(to, [&](auto&& x) {
Expand All @@ -332,10 +334,9 @@ std::vector<std::optional<path>> route(ways const& w,
for (auto const& start : from_match) {
for (auto const* nc : {&start.left_, &start.right_}) {
if (nc->valid() && nc->cost_ < max) {
Profile::resolve_start_node(*w.r_, start.way_, nc->node_, from.lvl_,
dir, [&](auto const node) {
d.add_start({node, nc->cost_});
});
Profile::resolve_start_node(
*w.r_, start.way_, nc->node_, from.lvl_, dir,
[&](auto const node) { d.add_start({node, nc->cost_}); });
}
}

Expand All @@ -348,7 +349,14 @@ std::vector<std::optional<path>> route(ways const& w,
} else {
auto const c = best_candidate(w, d, t.lvl_, m, max, dir);
if (c.has_value()) {
r = std::make_optional(path{.cost_ = std::get<3>(*c)});
auto [nc, wc, n, p] = *c;
d.cost_.at(n.get_key()).write(n, p);
if (do_reconstruct(p)) {
p = reconstruct<Profile>(w, blocked, d, start, *nc, n, p.cost_,
dir);
p.uses_elevator_ = true;
}
r = std::make_optional(p);
++found;
}
}
Expand All @@ -371,34 +379,36 @@ dijkstra<Profile>& get_dijkstra() {
return *s.get();
}

std::vector<std::optional<path>> route(ways const& w,
lookup const& l,
search_profile const profile,
location const& from,
std::vector<location> const& to,
cost_t const max,
direction const dir,
double const max_match_distance,
bitvec<node_idx_t> const* blocked) {
std::vector<std::optional<path>> route(
ways const& w,
lookup const& l,
search_profile const profile,
location const& from,
std::vector<location> const& to,
cost_t const max,
direction const dir,
double const max_match_distance,
bitvec<node_idx_t> const* blocked,
std::function<bool(path const&)> const& do_reconstruct) {
switch (profile) {
case search_profile::kFoot:
return route(w, l, get_dijkstra<foot<false>>(), from, to, max, dir,
max_match_distance, blocked);
return route(w, l, get_dijkstra<foot<false, elevator_tracking>>(), from,
to, max, dir, max_match_distance, blocked, do_reconstruct);
case search_profile::kWheelchair:
return route(w, l, get_dijkstra<foot<true>>(), from, to, max, dir,
max_match_distance, blocked);
return route(w, l, get_dijkstra<foot<true, elevator_tracking>>(), from,
to, max, dir, max_match_distance, blocked, do_reconstruct);
case search_profile::kBike:
return route(w, l, get_dijkstra<bike>(), from, to, max, dir,
max_match_distance, blocked);
max_match_distance, blocked, do_reconstruct);
case search_profile::kCar:
return route(w, l, get_dijkstra<car>(), from, to, max, dir,
max_match_distance, blocked);
max_match_distance, blocked, do_reconstruct);
case search_profile::kCarParking:
return route(w, l, get_dijkstra<car_parking<false>>(), from, to, max, dir,
max_match_distance, blocked);
max_match_distance, blocked, do_reconstruct);
case search_profile::kCarParkingWheelchair:
return route(w, l, get_dijkstra<car_parking<true>>(), from, to, max, dir,
max_match_distance, blocked);
max_match_distance, blocked, do_reconstruct);
}
throw utl::fail("not implemented");
}
Expand All @@ -414,8 +424,8 @@ std::optional<path> route(ways const& w,
bitvec<node_idx_t> const* blocked) {
switch (profile) {
case search_profile::kFoot:
return route(w, l, get_dijkstra<foot<false>>(), from, to, max, dir,
max_match_distance, blocked);
return route(w, l, get_dijkstra<foot<false, elevator_tracking>>(), from,
to, max, dir, max_match_distance, blocked);
case search_profile::kWheelchair:
return route(w, l, get_dijkstra<foot<true, elevator_tracking>>(), from,
to, max, dir, max_match_distance, blocked);
Expand All @@ -435,4 +445,10 @@ std::optional<path> route(ways const& w,
throw utl::fail("not implemented");
}

template dijkstra<foot<true, osr::noop_tracking>>&
get_dijkstra<foot<true, osr::noop_tracking>>();

template dijkstra<foot<false, osr::noop_tracking>>&
get_dijkstra<foot<false, osr::noop_tracking>>();

} // namespace osr

0 comments on commit eff9dbb

Please sign in to comment.