From 589be8708a1c06c52c54746caccdedfca18d2cc0 Mon Sep 17 00:00:00 2001 From: Rutger Broekhoff Date: Sun, 30 Aug 2026 00:39:45 +0200 Subject: Performance improvements, messy code --- server/src/api.cpp | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) (limited to 'server/src/api.cpp') diff --git a/server/src/api.cpp b/server/src/api.cpp index e671f8a..fb1d228 100644 --- a/server/src/api.cpp +++ b/server/src/api.cpp @@ -92,6 +92,8 @@ auto tag_invoke(json::value_from_tag, json::value& jv, sysinfo const& info) jv = json::object{ {"using_publication_of", std::format("{:%FT%TZ}", info.using_publication_of)}, + {"lse_index_size", info.lse_index_size}, + {"p_index_size", info.p_index_size}, }; } @@ -127,12 +129,15 @@ handler::handler(log::logger const& l, datex2::situation_publication pub) auto handler::process_gpx(gpx::file&& gpx_file) -> std::optional { + const auto min_distance = 5.0; + auto const now = chrono::utc_clock::now(); auto const relevant = std::initializer_list{ time::period{now - chrono::days(7), now + chrono::days(7)} }; auto const check_periods = time::period_seq{relevant.begin(), relevant.end()}; + // TODO: eliminate use of overlap segments auto splits_with_overlap_segments = std::vector{}; for (auto const& track : gpx_file.tracks) for (auto const& seg : track.segments) @@ -142,6 +147,22 @@ auto handler::process_gpx(gpx::file&& gpx_file) splits_with_overlap_segments); auto const before_query = chrono::steady_clock::now(); + auto vincenty_strategy = geo::vincenty_strategy{}; + + const auto buffer_distance = min_distance; + const auto points_per_circle = 8; + // Note: thomas strategy does not work for geographic_join_round; + // need to use andoyer for that. + using formula = bgeo::strategy::thomas; + bgeo::strategy::buffer::distance_symmetric distance_strategy{buffer_distance}; + bgeo::strategy::buffer::geographic_join_miter join_strategy{buffer_distance}; + bgeo::strategy::buffer::geographic_end_round end_strategy{4}; + bgeo::strategy::buffer::geographic_point_circle circle_strategy{points_per_circle}; + bgeo::strategy::buffer::geographic_side_straight side_strategy; + + using polygon = bgeo::model::polygon; + auto buffered_ls = bgeo::model::multi_polygon{}; + l_.debug("Querying for relevant situations"); auto relevant_road_closures = std::unordered_set>{}; @@ -152,6 +173,7 @@ auto handler::process_gpx(gpx::file&& gpx_file) { l_.debug("Checking part [{}/{}]", ++i, splits_with_overlap_segments.size()); + // TODO: consider buffering with min_distance auto part_box = geo::box{}; bgeo::envelope(part, part_box); @@ -170,7 +192,8 @@ auto handler::process_gpx(gpx::file&& gpx_file) if (rc->validity && rc->validity->intersect(check_periods).periods().empty()) continue; - if (bgeo::distance(*ls, part, geo::vincenty_strategy{}) < 5.0) + bgeo::buffer(*ls, buffered_ls, distance_strategy, side_strategy, join_strategy, end_strategy, circle_strategy); + if (bgeo::intersects(buffered_ls, part)) relevant_road_closures.emplace(rc); ls_checked++; } @@ -183,7 +206,7 @@ auto handler::process_gpx(gpx::file&& gpx_file) if (rc->validity && rc->validity->intersect(check_periods).periods().empty()) continue; - if (bgeo::distance(p, part, geo::vincenty_strategy{}) < 5.0) + if (bgeo::distance(p, part, vincenty_strategy) < min_distance) relevant_road_closures.emplace(rc); p_checked++; } @@ -260,7 +283,11 @@ auto handler::process_gpx(gpx::file&& gpx_file) auto handler::sysinfo() -> struct sysinfo { - return {.using_publication_of = pub_.publication_time}; + return { + .using_publication_of = pub_.publication_time, + .lse_index_size = lse_index_.size(), + .p_index_size = p_index_.size(), + }; } } // namespace routemon::api -- cgit v1.3