diff --git a/.pkg b/.pkg index ccc6375cf..1ca54d7b9 100644 --- a/.pkg +++ b/.pkg @@ -13,7 +13,7 @@ [utl] url=git@github.com:motis-project/utl.git branch=master - commit=2d8b992e23ecf7dcd0742420e92fac4a7c290d4e + commit=b3fcf40da923107152f2909f9600e893a9b797ff [adr] url=git@github.com:triptix-tech/adr.git branch=master diff --git a/.pkg.lock b/.pkg.lock index 53f8fb7a5..da6aacfce 100644 --- a/.pkg.lock +++ b/.pkg.lock @@ -1,4 +1,4 @@ -17221854697555080002 +1288970297968854858 cista 6362f3ad8c3133a0abf64e5d8c9ea3e21f531ee8 zlib-ng 68ab3e2d80253ec5dc3c83691d9ff70477b32cd3 boost 930f38eb0365ceb7853273e03da4d9e7787abfb9 @@ -8,7 +8,7 @@ mimalloc e2f4fe647e8aff4603a7d5119b8639fd1a47c8a6 libressl 24acd9e710fbe842e863572da9d738715fbc74b8 docs 75dc89a53e9c2d78574fc0ffda698e69f1682ed2 fmt dc10f83be70ac2873d5f8d1ce317596f1fd318a2 -utl 2d8b992e23ecf7dcd0742420e92fac4a7c290d4e +utl b3fcf40da923107152f2909f9600e893a9b797ff res b759b93316afeb529b6cb5b2548b24c41e382fb0 date ce88cc33b5551f66655614eeebb7c5b7189025fb yaml-cpp 1d8ca1f35eb3a9c9142462b28282a848e5d29a91 diff --git a/include/motis/data.h b/include/motis/data.h index 28d5da487..4ef25d081 100644 --- a/include/motis/data.h +++ b/include/motis/data.h @@ -50,7 +50,7 @@ struct data { friend std::ostream& operator<<(std::ostream&, data const&); void load_osr(); - void load_tt(); + void load_tt(std::filesystem::path const&); void load_shapes(); void load_railviz(); void load_geocoder(); diff --git a/src/compute_footpaths.cc b/src/compute_footpaths.cc index e42071fff..65964c86a 100644 --- a/src/compute_footpaths.cc +++ b/src/compute_footpaths.cc @@ -105,81 +105,91 @@ elevator_footpath_map_t compute_footpaths( auto const wheelchair_candidates = lookup_locations( w, lookup, pl, tt, matches, osr::search_profile::kWheelchair); + struct state { + std::vector sorted_tt_fps_; + std::vector missing_; + std::vector neighbors_; + std::vector neighbors_loc_; + std::vector neighbor_candidates_; + }; + for (auto const mode : {osr::search_profile::kFoot, osr::search_profile::kWheelchair}) { auto const& candidates = mode == osr::search_profile::kFoot ? foot_candidates : wheelchair_candidates; - utl::parallel_for_run(tt.n_locations(), [&](auto const i) { - auto const l = n::location_idx_t{i}; - auto& footpaths = - (mode == osr::search_profile::kFoot ? footpaths_out_foot[l] - : footpaths_out_wheelchair[l]); - auto neighbors = std::vector{}; - loc_rtree.in_radius(tt.locations_.coordinates_[l], kMaxDistance, - [&](n::location_idx_t const x) { - if (x != l) { - neighbors.emplace_back(x); - } - }); - auto const results = osr::route( - w, mode, get_loc(tt, w, pl, matches, l), - utl::to_vec(neighbors, - [&](auto&& x) { return get_loc(tt, w, pl, matches, x); }), - candidates[l], - utl::to_vec(neighbors, [&](auto&& x) { return candidates[x]; }), - kMaxDuration, osr::direction::kForward, nullptr, nullptr, - [](osr::path const& p) { return p.uses_elevator_; }); - for (auto const [n, r] : utl::zip(neighbors, results)) { - if (r.has_value()) { - auto const duration = n::duration_t{r->cost_ / 60U}; - footpaths.emplace_back(n::footpath{n, duration}); - for (auto const& s : r->segments_) { - add_if_elevator(s.from_, l, n); - add_if_elevator(s.from_, n, l); + utl::parallel_for_run_threadlocal( + tt.n_locations(), [&](state& s, auto const i) { + cista::for_each_field(s, [](auto& f) { f.clear(); }); + + auto const l = n::location_idx_t{i}; + auto& footpaths = (mode == osr::search_profile::kFoot + ? footpaths_out_foot[l] + : footpaths_out_wheelchair[l]); + loc_rtree.in_radius(tt.locations_.coordinates_[l], kMaxDistance, + [&](n::location_idx_t const x) { + if (x != l) { + s.neighbors_.emplace_back(x); + } + }); + auto const results = osr::route( + w, mode, get_loc(tt, w, pl, matches, l), + utl::transform_to( + s.neighbors_, s.neighbors_loc_, + [&](auto&& x) { return get_loc(tt, w, pl, matches, x); }), + candidates[l], + utl::transform_to(s.neighbors_, s.neighbor_candidates_, + [&](auto&& x) { return candidates[x]; }), + kMaxDuration, osr::direction::kForward, nullptr, nullptr, + [](osr::path const& p) { return p.uses_elevator_; }); + for (auto const [n, r] : utl::zip(s.neighbors_, results)) { + if (r.has_value()) { + auto const duration = n::duration_t{r->cost_ / 60U}; + footpaths.emplace_back(n::footpath{n, duration}); + for (auto const& seg : r->segments_) { + add_if_elevator(seg.from_, l, n); + add_if_elevator(seg.from_, n, l); + } + } } - } - } - if (extend_missing && mode == osr::search_profile::kFoot) { - auto const& tt_fps = tt.locations_.footpaths_out_[0][l]; - - auto sorted_tt_fps = std::vector{}; - sorted_tt_fps.resize(tt_fps.size()); - std::copy(begin(tt_fps), end(tt_fps), begin(sorted_tt_fps)); - utl::sort(sorted_tt_fps); - utl::sort(footpaths); - - auto missing = std::vector{}; - utl::sorted_diff( - sorted_tt_fps, footpaths, - [](auto&& a, auto&& b) { return a.target() < b.target(); }, - [](auto&& a, auto&& b) { return a.target() == b.target(); }, - utl::overloaded{ - [](n::footpath, n::footpath) { assert(false); }, - [&](utl::op const op, n::footpath const x) { - if (op == utl::op::kDel) { - auto const duration = n::duration_t{static_cast( - std::ceil((geo::distance( - tt.locations_.coordinates_[l], - tt.locations_.coordinates_[x.target()]) / - 0.7) / - 60.0))}; - missing.emplace_back(x.target(), duration); - } - }}); - - utl::concat(footpaths, missing); - } + if (extend_missing && mode == osr::search_profile::kFoot) { + auto const& tt_fps = tt.locations_.footpaths_out_[0].at(l); + s.sorted_tt_fps_.resize(tt_fps.size()); + std::copy(begin(tt_fps), end(tt_fps), begin(s.sorted_tt_fps_)); + utl::sort(s.sorted_tt_fps_); + utl::sort(footpaths); + + utl::sorted_diff( + s.sorted_tt_fps_, footpaths, + [](auto&& a, auto&& b) { return a.target() < b.target(); }, + [](auto&& a, auto&& b) { return a.target() == b.target(); }, + utl::overloaded{ + [](n::footpath, n::footpath) { assert(false); }, + [&](utl::op const op, n::footpath const x) { + if (op == utl::op::kDel) { + auto const duration = + n::duration_t{static_cast(std::ceil( + (geo::distance( + tt.locations_.coordinates_[l], + tt.locations_.coordinates_[x.target()]) / + 0.7) / + 60.0))}; + s.missing_.emplace_back(x.target(), duration); + } + }}); + + utl::concat(footpaths, s.missing_); + } - utl::erase_if(footpaths, [&](n::footpath fp) { - return fp.duration() > max_duration; - }); - utl::sort(footpaths); + utl::erase_if(footpaths, [&](n::footpath fp) { + return fp.duration() > max_duration; + }); + utl::sort(footpaths); - pt->update_monotonic( - (mode == osr::search_profile::kFoot ? 0U : tt.n_locations()) + i); - }); + pt->update_monotonic( + (mode == osr::search_profile::kFoot ? 0U : tt.n_locations()) + i); + }); } fmt::println(std::clog, " -> create ingoing footpaths"); diff --git a/src/data.cc b/src/data.cc index e58c09ba1..7f71b5852 100644 --- a/src/data.cc +++ b/src/data.cc @@ -98,7 +98,7 @@ data::data(std::filesystem::path p, config const& c) auto tt = std::async(std::launch::async, [&]() { if (c.timetable_) { - load_tt(); + load_tt(config_.osr_footpath_ ? "tt_ext.bin" : "tt.bin"); if (c.timetable_->with_shapes_) { load_shapes(); } @@ -189,9 +189,9 @@ void data::load_osr() { pl_->build_rtree(*w_); } -void data::load_tt() { +void data::load_tt(fs::path const& p) { tags_ = tag_lookup::read(path_ / "tags.bin"); - tt_ = n::timetable::read(path_ / "tt.bin"); + tt_ = n::timetable::read(path_ / p); tt_->locations_.resolve_timezones(); location_rtee_ = std::make_unique>( create_location_rtree(*tt_)); diff --git a/src/endpoints/footpaths.cc b/src/endpoints/footpaths.cc index 0d8940dab..f8eae85c3 100644 --- a/src/endpoints/footpaths.cc +++ b/src/endpoints/footpaths.cc @@ -31,12 +31,12 @@ api::footpaths_response footpaths::operator()( auto footpaths = hash_map{}; - for (auto const fp : tt_.locations_.footpaths_out_[0][l]) { + for (auto const fp : tt_.locations_.footpaths_out_[0].at(l)) { footpaths[fp.target()].default_ = fp.duration().count(); } if (!tt_.locations_.footpaths_out_[1].empty()) { - for (auto const fp : tt_.locations_.footpaths_out_[1][l]) { + for (auto const fp : tt_.locations_.footpaths_out_[1].at(l)) { footpaths[fp.target()].foot_ = fp.duration().count(); } } diff --git a/src/import.cc b/src/import.cc index 91d51b3d4..a79368840 100644 --- a/src/import.cc +++ b/src/import.cc @@ -262,7 +262,7 @@ data import(config const& c, fs::path const& data_path, bool const write) { utl::to_vec( t.datasets_, [&, src = n::source_idx_t{}](auto&& x) mutable - -> std::pair { + -> std::pair { auto const& [tag, dc] = x; d.tags_->add(src++, tag); return {dc.path_, @@ -297,7 +297,7 @@ data import(config const& c, fs::path const& data_path, bool const write) { } }, [&]() { - d.load_tt(); + d.load_tt("tt.bin"); if (c.timetable_->with_shapes_) { d.load_shapes(); } @@ -379,10 +379,10 @@ data import(config const& c, fs::path const& data_path, bool const write) { if (write) { cista::write(data_path / "elevator_footpath_map.bin", elevator_footpath_map); - d.tt_->write(data_path / "tt.bin"); + d.tt_->write(data_path / "tt_ext.bin"); } }, - [&]() {}, + [&]() { d.load_tt("tt_ext.bin"); }, {tt_hash, osm_hash, osr_version(), osr_footpath_version(), n_version()}}; auto matches =