summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/src/api.cpp17
-rw-r--r--server/src/api.cppm10
-rw-r--r--server/src/geo/multizonal.cppm63
3 files changed, 73 insertions, 17 deletions
diff --git a/server/src/api.cpp b/server/src/api.cpp
index 137666b..e35e1b3 100644
--- a/server/src/api.cpp
+++ b/server/src/api.cpp
@@ -95,7 +95,7 @@ auto tag_invoke(json::value_from_tag, json::value& jv, sysinfo const& info)
95 {"using_publication_of", 95 {"using_publication_of",
96 std::format("{:%FT%TZ}", info.using_publication_of)}, 96 std::format("{:%FT%TZ}", info.using_publication_of)},
97 {"blse_index_size", info.blse_index_size}, 97 {"blse_index_size", info.blse_index_size},
98 {"p_index_size", info.p_index_size}, 98 {"bpe_index_size", info.bpe_index_size},
99 }; 99 };
100} 100}
101 101
@@ -124,7 +124,7 @@ handler::handler(log::logger const& l, datex2::situation_publication pub)
124 } 124 }
125 for (auto p : rc->relevant_points) 125 for (auto p : rc->relevant_points)
126 { 126 {
127 p_index_.insert(p_index_value{p, rc}); 127 bpe_index_.insert(p, rc);
128 } 128 }
129 } 129 }
130 130
@@ -141,7 +141,7 @@ handler::handler(log::logger const& l, datex2::situation_publication pub)
141 auto const dur_build_s = chrono::duration<double>{after_build - before_build}; 141 auto const dur_build_s = chrono::duration<double>{after_build - before_build};
142 l_.info("Indexes built in {}", dur_build_s); 142 l_.info("Indexes built in {}", dur_build_s);
143 l_.info("BLSE index size: {}", blse_index_.size()); 143 l_.info("BLSE index size: {}", blse_index_.size());
144 l_.info("Point index size: {}", p_index_.size()); 144 l_.info("Point index size: {}", bpe_index_.size());
145} 145}
146 146
147auto handler::process_gpx(gpx::file&& gpx_file) 147auto handler::process_gpx(gpx::file&& gpx_file)
@@ -194,17 +194,12 @@ auto handler::process_gpx(gpx::file&& gpx_file)
194 // relevant_road_closures.emplace(rc); 194 // relevant_road_closures.emplace(rc);
195 ls_checked++; 195 ls_checked++;
196 } 196 }
197 for (auto it = p_index_.qbegin(bgeo::index::intersects(part_box)); 197 for (auto const& rc : bpe_index_.intersection(part_zone_lss))
198 it != p_index_.qend(); it++)
199 { 198 {
200 // Cannot use structured bindings here for the same reason as above.
201 geo::utm::zonable_wgs84_point const& p = std::get<0>(*it);
202 std::shared_ptr<datex2::road_closure> const& rc = std::get<1>(*it);
203 if (rc->validity 199 if (rc->validity
204 && rc->validity->intersect(check_periods).periods().empty()) 200 && rc->validity->intersect(check_periods).periods().empty())
205 continue; 201 continue;
206 if (bgeo::distance(p, part, vincenty_strategy) < min_distance_) 202 relevant_road_closures.emplace(rc);
207 relevant_road_closures.emplace(rc);
208 p_checked++; 203 p_checked++;
209 } 204 }
210 } 205 }
@@ -285,7 +280,7 @@ auto handler::sysinfo() -> struct sysinfo
285 return { 280 return {
286 .using_publication_of = pub_.publication_time, 281 .using_publication_of = pub_.publication_time,
287 .blse_index_size = blse_index_.size(), 282 .blse_index_size = blse_index_.size(),
288 .p_index_size = p_index_.size(), 283 .bpe_index_size = bpe_index_.size(),
289 }; 284 };
290} 285}
291 286
diff --git a/server/src/api.cppm b/server/src/api.cppm
index 77e0f85..0bb0868 100644
--- a/server/src/api.cppm
+++ b/server/src/api.cppm
@@ -57,7 +57,7 @@ struct sysinfo
57{ 57{
58 time::timestamp using_publication_of; 58 time::timestamp using_publication_of;
59 std::size_t blse_index_size; 59 std::size_t blse_index_size;
60 std::size_t p_index_size; 60 std::size_t bpe_index_size;
61}; 61};
62 62
63auto tag_invoke( 63auto tag_invoke(
@@ -82,15 +82,13 @@ class handler
82 82
83 using blse_index_value = std::shared_ptr<datex2::road_closure>; 83 using blse_index_value = std::shared_ptr<datex2::road_closure>;
84 using blse_index = geo::multizonal::linestring_rtree<blse_index_value>; 84 using blse_index = geo::multizonal::linestring_rtree<blse_index_value>;
85 using p_index_value = std::pair< 85 using bpe_index_value = std::shared_ptr<datex2::road_closure>;
86 geo::utm::zonable_wgs84_point, std::shared_ptr<datex2::road_closure> 86 using bpe_index = geo::multizonal::point_rtree<bpe_index_value>;
87 >;
88 using p_index = bgeo::index::rtree<p_index_value, bgeo::index::quadratic<16>>;
89 87
90 log::logger l_; 88 log::logger l_;
91 datex2::situation_publication pub_; 89 datex2::situation_publication pub_;
92 blse_index blse_index_; 90 blse_index blse_index_;
93 p_index p_index_; 91 bpe_index bpe_index_;
94 92
95public: 93public:
96 explicit handler(log::logger const& l, datex2::situation_publication pub); 94 explicit handler(log::logger const& l, datex2::situation_publication pub);
diff --git a/server/src/geo/multizonal.cppm b/server/src/geo/multizonal.cppm
index ed78a24..7930367 100644
--- a/server/src/geo/multizonal.cppm
+++ b/server/src/geo/multizonal.cppm
@@ -241,4 +241,67 @@ public:
241 } 241 }
242}; 242};
243 243
244template<class T>
245class point_rtree
246{
247public:
248 using index_value = std::tuple<utm::zone_local::prim::box, utm::zone_local::prim::point, T>;
249
250private:
251 multi_zone<bgeo::index::rtree<index_value, bgeo::index::quadratic<16>>> local_rtrees_;
252
253public:
254 template<std::convertible_to<T> U>
255 auto insert(utm::zonable_wgs84_point const& p, U&& arg) -> void
256 {
257 auto to_utm = wgs84::utm_transforms::instance();
258
259 auto p_zone = utm::zone::for_wgs84_point(p);
260 auto mp_alt_zone = std::optional<utm::zone>{};
261 if (auto [neighbor_zone, neighbor_zone_dist] = wgs84::neighbor_utm_zone(p);
262 neighbor_zone_dist < 30.0 /* m */)
263 mp_alt_zone = neighbor_zone;
264
265 auto insert = [&](utm::zone z) -> void
266 {
267 auto p_utm = to_utm[z].apply(p);
268 auto bpe = bgeo::return_buffer<utm::zone_local::prim::box>(bgeo::return_envelope<utm::zone_local::prim::box>(p_utm), 30.0 /* m */);
269 local_rtrees_[z].insert(index_value{bpe, p_utm, arg});
270 };
271
272 insert(p_zone);
273 if (mp_alt_zone)
274 insert(*mp_alt_zone);
275 }
276
277 auto size() const -> std::size_t
278 {
279 auto total_size = 0uz;
280 for (auto z = utm::zone::min(); z != utm::zone::max(); z = z.next())
281 total_size += local_rtrees_[z].size();
282 return total_size;
283 }
284
285 // Note: the same T may be generated more than once!
286 auto intersection(zoned_linestring_seg_seq const& lss) const -> std::generator<T const&>
287 {
288 for (auto const& ls : lss.segments)
289 {
290 // auto ls_box = bgeo::return_envelope<utm::zone_local::prim::box>(ls);
291 for (auto it = local_rtrees_[ls.zone].qbegin(bgeo::index::intersects(ls));
292 it != local_rtrees_[ls.zone].qend(); it++)
293 {
294 using multi_linestring = bgeo::model::multi_linestring<utm::zone_local::prim::linestring>;
295
296 auto relevant_ls_parts = multi_linestring{};
297 bgeo::intersection(std::get<0>(*it), static_cast<utm::zone_local::prim::linestring const&>(ls), relevant_ls_parts);
298 if (bgeo::distance(relevant_ls_parts, std::get<1>(*it)) < 30.0 /* m */)
299 {
300 co_yield std::get<2>(*it);
301 }
302 }
303 }
304 }
305};
306
244} // namespace routemon::geo::multizonal 307} // namespace routemon::geo::multizonal