diff options
| author | Rutger Broekhoff | 2026-08-30 00:39:45 +0200 |
|---|---|---|
| committer | Rutger Broekhoff | 2026-08-30 00:39:45 +0200 |
| commit | 589be8708a1c06c52c54746caccdedfca18d2cc0 (patch) | |
| tree | a240accace56062fe38742c055a22989559890cb | |
| parent | 4d32c476318e0ec37188616ae96eaa343bb59413 (diff) | |
| download | routemon-589be8708a1c06c52c54746caccdedfca18d2cc0.tar.gz routemon-589be8708a1c06c52c54746caccdedfca18d2cc0.zip | |
Performance improvements, messy code
| -rw-r--r-- | server/src/api.cpp | 33 | ||||
| -rw-r--r-- | server/src/api.cppm | 2 | ||||
| -rw-r--r-- | server/src/geo.cppm | 2 | ||||
| -rw-r--r-- | web/index.html | 9 | ||||
| -rw-r--r-- | 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) | |||
| 92 | jv = json::object{ | 92 | jv = json::object{ |
| 93 | {"using_publication_of", | 93 | {"using_publication_of", |
| 94 | std::format("{:%FT%TZ}", info.using_publication_of)}, | 94 | std::format("{:%FT%TZ}", info.using_publication_of)}, |
| 95 | {"lse_index_size", info.lse_index_size}, | ||
| 96 | {"p_index_size", info.p_index_size}, | ||
| 95 | }; | 97 | }; |
| 96 | } | 98 | } |
| 97 | 99 | ||
| @@ -127,12 +129,15 @@ handler::handler(log::logger const& l, datex2::situation_publication pub) | |||
| 127 | auto handler::process_gpx(gpx::file&& gpx_file) | 129 | auto handler::process_gpx(gpx::file&& gpx_file) |
| 128 | -> std::optional<process_gpx_result> | 130 | -> std::optional<process_gpx_result> |
| 129 | { | 131 | { |
| 132 | const auto min_distance = 5.0; | ||
| 133 | |||
| 130 | auto const now = chrono::utc_clock::now(); | 134 | auto const now = chrono::utc_clock::now(); |
| 131 | auto const relevant = std::initializer_list<time::period>{ | 135 | auto const relevant = std::initializer_list<time::period>{ |
| 132 | time::period{now - chrono::days(7), now + chrono::days(7)} | 136 | time::period{now - chrono::days(7), now + chrono::days(7)} |
| 133 | }; | 137 | }; |
| 134 | auto const check_periods = time::period_seq{relevant.begin(), relevant.end()}; | 138 | auto const check_periods = time::period_seq{relevant.begin(), relevant.end()}; |
| 135 | 139 | ||
| 140 | // TODO: eliminate use of overlap segments | ||
| 136 | auto splits_with_overlap_segments = std::vector<geo::linestring>{}; | 141 | auto splits_with_overlap_segments = std::vector<geo::linestring>{}; |
| 137 | for (auto const& track : gpx_file.tracks) | 142 | for (auto const& track : gpx_file.tracks) |
| 138 | for (auto const& seg : track.segments) | 143 | for (auto const& seg : track.segments) |
| @@ -142,6 +147,22 @@ auto handler::process_gpx(gpx::file&& gpx_file) | |||
| 142 | splits_with_overlap_segments); | 147 | splits_with_overlap_segments); |
| 143 | auto const before_query = chrono::steady_clock::now(); | 148 | auto const before_query = chrono::steady_clock::now(); |
| 144 | 149 | ||
| 150 | auto vincenty_strategy = geo::vincenty_strategy{}; | ||
| 151 | |||
| 152 | const auto buffer_distance = min_distance; | ||
| 153 | const auto points_per_circle = 8; | ||
| 154 | // Note: thomas strategy does not work for geographic_join_round; | ||
| 155 | // need to use andoyer for that. | ||
| 156 | using formula = bgeo::strategy::thomas; | ||
| 157 | bgeo::strategy::buffer::distance_symmetric<double> distance_strategy{buffer_distance}; | ||
| 158 | bgeo::strategy::buffer::geographic_join_miter<formula> join_strategy{buffer_distance}; | ||
| 159 | bgeo::strategy::buffer::geographic_end_round<formula> end_strategy{4}; | ||
| 160 | bgeo::strategy::buffer::geographic_point_circle<formula> circle_strategy{points_per_circle}; | ||
| 161 | bgeo::strategy::buffer::geographic_side_straight<formula> side_strategy; | ||
| 162 | |||
| 163 | using polygon = bgeo::model::polygon<geo::point>; | ||
| 164 | auto buffered_ls = bgeo::model::multi_polygon<polygon>{}; | ||
| 165 | |||
| 145 | l_.debug("Querying for relevant situations"); | 166 | l_.debug("Querying for relevant situations"); |
| 146 | auto relevant_road_closures = | 167 | auto relevant_road_closures = |
| 147 | std::unordered_set<std::shared_ptr<datex2::road_closure>>{}; | 168 | std::unordered_set<std::shared_ptr<datex2::road_closure>>{}; |
| @@ -152,6 +173,7 @@ auto handler::process_gpx(gpx::file&& gpx_file) | |||
| 152 | { | 173 | { |
| 153 | l_.debug("Checking part [{}/{}]", ++i, splits_with_overlap_segments.size()); | 174 | l_.debug("Checking part [{}/{}]", ++i, splits_with_overlap_segments.size()); |
| 154 | 175 | ||
| 176 | // TODO: consider buffering with min_distance | ||
| 155 | auto part_box = geo::box{}; | 177 | auto part_box = geo::box{}; |
| 156 | bgeo::envelope(part, part_box); | 178 | bgeo::envelope(part, part_box); |
| 157 | 179 | ||
| @@ -170,7 +192,8 @@ auto handler::process_gpx(gpx::file&& gpx_file) | |||
| 170 | if (rc->validity | 192 | if (rc->validity |
| 171 | && rc->validity->intersect(check_periods).periods().empty()) | 193 | && rc->validity->intersect(check_periods).periods().empty()) |
| 172 | continue; | 194 | continue; |
| 173 | if (bgeo::distance(*ls, part, geo::vincenty_strategy{}) < 5.0) | 195 | bgeo::buffer(*ls, buffered_ls, distance_strategy, side_strategy, join_strategy, end_strategy, circle_strategy); |
| 196 | if (bgeo::intersects(buffered_ls, part)) | ||
| 174 | relevant_road_closures.emplace(rc); | 197 | relevant_road_closures.emplace(rc); |
| 175 | ls_checked++; | 198 | ls_checked++; |
| 176 | } | 199 | } |
| @@ -183,7 +206,7 @@ auto handler::process_gpx(gpx::file&& gpx_file) | |||
| 183 | if (rc->validity | 206 | if (rc->validity |
| 184 | && rc->validity->intersect(check_periods).periods().empty()) | 207 | && rc->validity->intersect(check_periods).periods().empty()) |
| 185 | continue; | 208 | continue; |
| 186 | if (bgeo::distance(p, part, geo::vincenty_strategy{}) < 5.0) | 209 | if (bgeo::distance(p, part, vincenty_strategy) < min_distance) |
| 187 | relevant_road_closures.emplace(rc); | 210 | relevant_road_closures.emplace(rc); |
| 188 | p_checked++; | 211 | p_checked++; |
| 189 | } | 212 | } |
| @@ -260,7 +283,11 @@ auto handler::process_gpx(gpx::file&& gpx_file) | |||
| 260 | 283 | ||
| 261 | auto handler::sysinfo() -> struct sysinfo | 284 | auto handler::sysinfo() -> struct sysinfo |
| 262 | { | 285 | { |
| 263 | return {.using_publication_of = pub_.publication_time}; | 286 | return { |
| 287 | .using_publication_of = pub_.publication_time, | ||
| 288 | .lse_index_size = lse_index_.size(), | ||
| 289 | .p_index_size = p_index_.size(), | ||
| 290 | }; | ||
| 264 | } | 291 | } |
| 265 | 292 | ||
| 266 | } // namespace routemon::api | 293 | } // 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 | |||
| 55 | struct sysinfo | 55 | struct sysinfo |
| 56 | { | 56 | { |
| 57 | time::timestamp using_publication_of; | 57 | time::timestamp using_publication_of; |
| 58 | std::size_t lse_index_size; | ||
| 59 | std::size_t p_index_size; | ||
| 58 | }; | 60 | }; |
| 59 | 61 | ||
| 60 | auto tag_invoke( | 62 | 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; | |||
| 9 | export namespace routemon::geo { | 9 | export namespace routemon::geo { |
| 10 | 10 | ||
| 11 | using point = | 11 | using point = |
| 12 | bgeo::model::point<double, 2, bgeo::cs::spherical_equatorial<bgeo::degree>>; | 12 | bgeo::model::point<double, 2, bgeo::cs::geographic<bgeo::degree>>; |
| 13 | using linestring = bgeo::model::linestring<point>; | 13 | using linestring = bgeo::model::linestring<point>; |
| 14 | using box = bgeo::model::box<point>; | 14 | using box = bgeo::model::box<point>; |
| 15 | using stype = bgeo::srs::spheroid<double>; | 15 | using stype = bgeo::srs::spheroid<double>; |
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 @@ | |||
| 29 | <summary> | 29 | <summary> |
| 30 | <span>Systeeminformatie</span> | 30 | <span>Systeeminformatie</span> |
| 31 | </summary> | 31 | </summary> |
| 32 | <table> | 32 | <div id="sysinfo-details"> |
| 33 | <tr> | 33 | <span>(Nog geen contact gelegd met server.)</span> |
| 34 | <td class="help-cursor" title="Publicatietijdstip van ingeladen DATEX II-situatiepublicatie (van NDW)">Situatiepublicatie van</td> | 34 | </div> |
| 35 | <td id="situation-publication-of"><onbekend></td> | ||
| 36 | </tr> | ||
| 37 | </table> | ||
| 38 | </details> | 35 | </details> |
| 39 | </div> | 36 | </div> |
| 40 | 37 | ||
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 @@ | |||
| 1 | const apiBaseUrl = "https://routemon-api.fautchen.eu"; | 1 | const apiBaseUrl = "https://routemon-api.fautchen.eu"; |
| 2 | // const apiBaseUrl = "http://localhost:8284"; | ||
| 2 | 3 | ||
| 3 | const dialog = document.querySelector("dialog"); | 4 | const dialog = document.querySelector("dialog"); |
| 4 | const closeButton = document.querySelector("dialog button"); | 5 | const closeButton = document.querySelector("dialog button"); |
| @@ -87,7 +88,17 @@ async function getSysinfo() { | |||
| 87 | } | 88 | } |
| 88 | 89 | ||
| 89 | const res = await rsp.json(); | 90 | const res = await rsp.json(); |
| 90 | document.getElementById("situation-publication-of").innerText = new Date(res.using_publication_of).toLocaleString(); | 91 | let rows = [ |
| 92 | [el("span", { "class": "help-cursor", | ||
| 93 | "title": "Publicatietijdstip van ingeladen DATEX II-situatiepublicatie (van NDW)" }, | ||
| 94 | txt("Situatiepublicatie van")), | ||
| 95 | txt(new Date(res.using_publication_of).toLocaleString())], | ||
| 96 | [txt("Grootte LSE-index"), | ||
| 97 | txt(res.lse_index_size.toString())], | ||
| 98 | [txt("Grootte puntenindex"), | ||
| 99 | txt(res.p_index_size.toString())], | ||
| 100 | ]; | ||
| 101 | document.getElementById("sysinfo-details").replaceChildren(tbl(rows)); | ||
| 91 | } | 102 | } |
| 92 | 103 | ||
| 93 | async function load(gpxFile) { | 104 | async function load(gpxFile) { |