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 ++++++++++++++++++++++++++++++--- server/src/api.cppm | 2 ++ server/src/geo.cppm | 2 +- web/index.html | 9 +++------ web/index.js | 13 ++++++++++++- 5 files changed, 48 insertions(+), 11 deletions(-) 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 diff --git a/server/src/api.cppm b/server/src/api.cppm index c93e65e..8f639fd 100644 --- a/server/src/api.cppm +++ b/server/src/api.cppm @@ -55,6 +55,8 @@ struct process_gpx_result struct sysinfo { time::timestamp using_publication_of; + std::size_t lse_index_size; + std::size_t p_index_size; }; auto tag_invoke( diff --git a/server/src/geo.cppm b/server/src/geo.cppm index 4f8b840..f8f5ddf 100644 --- a/server/src/geo.cppm +++ b/server/src/geo.cppm @@ -9,7 +9,7 @@ export namespace bgeo = boost::geometry; export namespace routemon::geo { using point = - bgeo::model::point>; + bgeo::model::point>; using linestring = bgeo::model::linestring; using box = bgeo::model::box; using stype = bgeo::srs::spheroid; diff --git a/web/index.html b/web/index.html index fe9529f..877da14 100644 --- a/web/index.html +++ b/web/index.html @@ -29,12 +29,9 @@ Systeeminformatie - - - - - -
Situatiepublicatie van<onbekend>
+
+ (Nog geen contact gelegd met server.) +
diff --git a/web/index.js b/web/index.js index 1c2e34d..999e333 100644 --- a/web/index.js +++ b/web/index.js @@ -1,4 +1,5 @@ const apiBaseUrl = "https://routemon-api.fautchen.eu"; +// const apiBaseUrl = "http://localhost:8284"; const dialog = document.querySelector("dialog"); const closeButton = document.querySelector("dialog button"); @@ -87,7 +88,17 @@ async function getSysinfo() { } const res = await rsp.json(); - document.getElementById("situation-publication-of").innerText = new Date(res.using_publication_of).toLocaleString(); + let rows = [ + [el("span", { "class": "help-cursor", + "title": "Publicatietijdstip van ingeladen DATEX II-situatiepublicatie (van NDW)" }, + txt("Situatiepublicatie van")), + txt(new Date(res.using_publication_of).toLocaleString())], + [txt("Grootte LSE-index"), + txt(res.lse_index_size.toString())], + [txt("Grootte puntenindex"), + txt(res.p_index_size.toString())], + ]; + document.getElementById("sysinfo-details").replaceChildren(tbl(rows)); } async function load(gpxFile) { -- cgit v1.3