Skip to content

Commit

Permalink
odm bounds (#759)
Browse files Browse the repository at this point in the history
  • Loading branch information
felixguendling authored Feb 21, 2025
1 parent 651b249 commit ef7e9bc
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 8 deletions.
8 changes: 7 additions & 1 deletion include/motis/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,13 @@ struct config {
std::optional<std::string> proxy_{};
};
std::optional<gbfs> gbfs_{};
std::optional<std::string> odm_{};

struct odm {
bool operator==(odm const&) const = default;
std::string url_{};
std::optional<std::string> bounds_{};
};
std::optional<odm> odm_{};

bool street_routing_{false};
bool osr_footpath_{false};
Expand Down
3 changes: 2 additions & 1 deletion include/motis/data.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ struct data {
// !!! Remember to add all new members !!!
return std::tie(config_, t_, r_, tc_, w_, pl_, l_, elevations_, tt_, tags_,
location_rtee_, elevator_nodes_, shapes_, railviz_static_,
matches_, rt_, gbfs_);
matches_, rt_, gbfs_, odm_bounds_);
}

std::filesystem::path path_;
Expand All @@ -90,6 +90,7 @@ struct data {
ptr<tiles_data> tiles_;
std::shared_ptr<rt> rt_{std::make_shared<rt>()};
std::shared_ptr<gbfs::gbfs_data> gbfs_{};
ptr<odm::bounds> odm_bounds_;
};

} // namespace motis
1 change: 1 addition & 0 deletions include/motis/endpoints/routing.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ struct routing {
std::shared_ptr<rt> const& rt_;
nigiri::shapes_storage const* shapes_;
std::shared_ptr<gbfs::gbfs_data> const& gbfs_;
odm::bounds const* odm_bounds_;
};

} // namespace motis::ep
4 changes: 4 additions & 0 deletions include/motis/fwd.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ struct railviz_static_index;
struct railviz_rt_index;
struct elevators;

namespace odm {
struct bounds;
}

namespace gbfs {
struct gbfs_data;
struct gbfs_provider;
Expand Down
20 changes: 20 additions & 0 deletions include/motis/odm/bounds.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#pragma once

#include <filesystem>

#include "geo/latlng.h"

struct tg_geom;

namespace motis::odm {

struct bounds {
explicit bounds(std::filesystem::path const&);
~bounds();

bool contains(geo::latlng const&) const;

tg_geom* geom_{nullptr};
};

} // namespace motis::odm
7 changes: 6 additions & 1 deletion src/data.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "cista/io.h"

#include "utl/read_file.h"
#include "utl/verify.h"

#include "adr/adr.h"
#include "adr/cache.h"
Expand All @@ -24,13 +25,13 @@
#include "motis/constants.h"
#include "motis/hashes.h"
#include "motis/match_platforms.h"
#include "motis/odm/bounds.h"
#include "motis/point_rtree.h"
#include "motis/railviz.h"
#include "motis/tag_lookup.h"
#include "motis/tiles_data.h"
#include "motis/tt_location_rtree.h"
#include "motis/update_rtt_td_footpaths.h"
#include "utl/verify.h"

namespace fs = std::filesystem;
namespace n = nigiri;
Expand Down Expand Up @@ -87,6 +88,10 @@ data::data(std::filesystem::path p, config const& c)

rt_ = std::make_shared<rt>();

if (c.odm_.has_value() && c.odm_->bounds_.has_value()) {
odm_bounds_ = std::make_unique<odm::bounds>(*c.odm_->bounds_);
}

auto geocoder = std::async(std::launch::async, [&]() {
if (c.geocoding_) {
load_geocoder();
Expand Down
40 changes: 40 additions & 0 deletions src/odm/bounds.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include "motis/odm/bounds.h"

#include "tg.h"

#include "fmt/std.h"

#include "utl/verify.h"

#include "cista/mmap.h"

namespace fs = std::filesystem;

namespace motis::odm {

bounds::bounds(fs::path const& p) {
auto const f =
cista::mmap{p.generic_string().c_str(), cista::mmap::protection::READ};

geom_ = tg_parse_geojsonn(f.view().data(), f.size());

if (tg_geom_error(geom_)) {
const char* err = tg_geom_error(geom_);
fmt::println("Error parsing ODM Bounds GeoJSON: {}", err);
tg_geom_free(geom_);
throw utl::fail("unable to parse {}: {}", p, err);
}

return;
}

bounds::~bounds() { tg_geom_free(geom_); }

bool bounds::contains(geo::latlng const& x) const {
auto const point = tg_geom_new_point(tg_point{x.lng(), x.lat()});
auto const result = tg_geom_within(point, geom_);
tg_geom_free(point);
return result;
}

} // namespace motis::odm
34 changes: 29 additions & 5 deletions src/odm/meta_router.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "motis/gbfs/routing_data.h"
#include "motis/http_req.h"
#include "motis/journey_to_response.h"
#include "motis/odm/bounds.h"
#include "motis/odm/mixer.h"
#include "motis/odm/odm.h"
#include "motis/odm/prima.h"
Expand Down Expand Up @@ -160,6 +161,14 @@ n::duration_t init_direct(std::vector<direct_ride>& direct_rides,
n::duration_t const fastest_direct) {
direct_rides.clear();

auto const from_pos = geo::latlng{from_p.lat_, from_p.lon_};
auto const to_pos = geo::latlng{to_p.lat_, to_p.lon_};
if (r.odm_bounds_ != nullptr && (!r.odm_bounds_->contains(from_pos) ||
!r.odm_bounds_->contains(to_pos))) {
fmt::println("No direct connection, from: {}, to: {}", from_pos, to_pos);
return ep::kInfinityDuration;
}

auto [_, taxi_duration] = r.route_direct(
e, gbfs, from_p, to_p, {api::ModeEnum::CAR}, std::nullopt, std::nullopt,
std::nullopt, intvl.from_,
Expand Down Expand Up @@ -209,13 +218,28 @@ void init_pt(std::vector<n::routing::start>& rides,
n::routing::query const& start_time,
n::routing::location_match_mode location_match_mode,
std::chrono::seconds const max) {
if (r.odm_bounds_ != nullptr && !r.odm_bounds_->contains(l.pos_)) {
fmt::println("no PT connection: {}", l.pos_);
return;
}

auto offsets = r.get_offsets(
l, dir, {api::ModeEnum::ODM}, std::nullopt, std::nullopt, std::nullopt,
query.pedestrianProfile_ == api::PedestrianProfileEnum::WHEELCHAIR, max,
query.maxMatchingDistance_, gbfs_rd);

std::erase_if(
offsets, [](auto const& o) { return o.duration_ < kMinODMOffsetLength; });
std::erase_if(offsets, [&](n::routing::offset const& o) {
if (o.duration_ < kMinODMOffsetLength) {
return true;
}
auto const out_of_bounds =
(r.odm_bounds_ != nullptr &&
!r.odm_bounds_->contains(r.tt_->locations_.coordinates_[o.target_]));
if (out_of_bounds) {
fmt::println("Bounds filtered: {}", n::location{*r.tt_, o.target_});
}
return out_of_bounds;
});

for (auto& o : offsets) {
o.duration_ += kODMTransferBuffer;
Expand Down Expand Up @@ -518,8 +542,8 @@ api::plan_response meta_router::run() {
ioc,
[&]() -> boost::asio::awaitable<void> {
auto const prima_msg = co_await http_POST(
boost::urls::url{*r_.config_.odm_ + kBlacklistPath}, kReqHeaders,
p->get_prima_request(*tt_), 10s);
boost::urls::url{r_.config_.odm_->url_ + kBlacklistPath},
kReqHeaders, p->get_prima_request(*tt_), 10s);
blacklist_response = get_http_body(prima_msg);
},
boost::asio::detached);
Expand Down Expand Up @@ -642,7 +666,7 @@ api::plan_response meta_router::run() {
ioc2,
[&]() -> boost::asio::awaitable<void> {
auto const prima_msg = co_await http_POST(
boost::urls::url{*r_.config_.odm_ + kWhitelistPath},
boost::urls::url{r_.config_.odm_->url_ + kWhitelistPath},
kReqHeaders, p->get_prima_request(*tt_), 10s);
whitelist_response = get_http_body(prima_msg);
},
Expand Down

0 comments on commit ef7e9bc

Please sign in to comment.