3434#include " tile.hpp"
3535#include " wkb.hpp"
3636
37- // How many tiles worth of space to leave either side of a changed feature
38- static constexpr double const tile_expiry_leeway = 0.1 ;
39-
40- expire_tiles::expire_tiles (uint32_t max_zoom, double max_bbox,
37+ expire_tiles::expire_tiles (uint32_t max_zoom,
4138 std::shared_ptr<reprojection> projection)
42- : m_projection(std::move(projection)), m_max_bbox(max_bbox ),
43- m_maxzoom(max_zoom), m_map_width(1U << m_maxzoom)
39+ : m_projection(std::move(projection)), m_maxzoom(max_zoom ),
40+ m_map_width(1U << m_maxzoom)
4441{}
4542
4643void expire_tiles::expire_tile (uint32_t x, uint32_t y)
@@ -71,68 +68,93 @@ geom::point_t expire_tiles::coords_to_tile(geom::point_t const &point)
7168 m_map_width * (0.5 - c.y () / tile_t ::earth_circumference)};
7269}
7370
74- void expire_tiles::from_point_list (geom::point_list_t const &list)
71+ void expire_tiles::from_point_list (geom::point_list_t const &list,
72+ expire_config_t const &expire_config)
7573{
7674 for_each_segment (list, [&](geom::point_t const &a, geom::point_t const &b) {
77- from_line (a, b);
75+ from_line (a, b, expire_config );
7876 });
7977}
8078
81- void expire_tiles::from_geometry (geom::point_t const &geom)
79+ void expire_tiles::from_geometry (geom::point_t const &geom,
80+ expire_config_t const &expire_config)
8281{
8382 geom::box_t const box = geom::envelope (geom);
84- from_bbox (box);
83+ from_bbox (box, expire_config );
8584}
8685
87- void expire_tiles::from_geometry (geom::linestring_t const &geom)
86+ void expire_tiles::from_geometry (geom::linestring_t const &geom,
87+ expire_config_t const &expire_config)
8888{
89- from_point_list (geom);
89+ from_point_list (geom, expire_config );
9090}
9191
92- void expire_tiles::from_polygon_boundary (geom::polygon_t const &geom)
92+ void expire_tiles::from_polygon_boundary (geom::polygon_t const &geom,
93+ expire_config_t const &expire_config)
9394{
94- from_point_list (geom.outer ());
95+ from_point_list (geom.outer (), expire_config );
9596 for (auto const &inner : geom.inners ()) {
96- from_point_list (inner);
97+ from_point_list (inner, expire_config );
9798 }
9899}
99100
100- void expire_tiles::from_geometry (geom::polygon_t const &geom)
101+ void expire_tiles::from_geometry (geom::polygon_t const &geom,
102+ expire_config_t const &expire_config)
101103{
104+ if (expire_config.mode == expire_mode::boundary_only) {
105+ from_polygon_boundary (geom, expire_config);
106+ return ;
107+ }
108+
102109 geom::box_t const box = geom::envelope (geom);
103- if (from_bbox (box)) {
110+ if (from_bbox (box, expire_config )) {
104111 /* Bounding box too big - just expire tiles on the boundary */
105- from_polygon_boundary (geom);
112+ from_polygon_boundary (geom, expire_config);
113+ }
114+ }
115+
116+ void expire_tiles::from_polygon_boundary (geom::multipolygon_t const &geom,
117+ expire_config_t const &expire_config)
118+ {
119+ for (auto const &sgeom : geom) {
120+ from_polygon_boundary (sgeom, expire_config);
106121 }
107122}
108123
109- void expire_tiles::from_geometry (geom::multipolygon_t const &geom)
124+ void expire_tiles::from_geometry (geom::multipolygon_t const &geom,
125+ expire_config_t const &expire_config)
110126{
127+ if (expire_config.mode == expire_mode::boundary_only) {
128+ from_polygon_boundary (geom, expire_config);
129+ return ;
130+ }
131+
111132 geom::box_t const box = geom::envelope (geom);
112- if (from_bbox (box)) {
133+ if (from_bbox (box, expire_config )) {
113134 /* Bounding box too big - just expire tiles on the boundary */
114- for (auto const &sgeom : geom) {
115- from_polygon_boundary (sgeom);
116- }
135+ from_polygon_boundary (geom, expire_config);
117136 }
118137}
119138
120- void expire_tiles::from_geometry (geom::geometry_t const &geom)
139+ void expire_tiles::from_geometry (geom::geometry_t const &geom,
140+ expire_config_t const &expire_config)
121141{
122- geom.visit ([&](auto const &g) { from_geometry (g); });
142+ geom.visit ([&](auto const &g) { from_geometry (g, expire_config ); });
123143}
124144
125- void expire_tiles::from_geometry_if_3857 (geom::geometry_t const &geom)
145+ void expire_tiles::from_geometry_if_3857 (geom::geometry_t const &geom,
146+ expire_config_t const &expire_config)
126147{
127148 if (geom.srid () == 3857 ) {
128- from_geometry (geom);
149+ from_geometry (geom, expire_config );
129150 }
130151}
131152
132153/*
133154 * Expire tiles that a line crosses
134155 */
135- void expire_tiles::from_line (geom::point_t const &a, geom::point_t const &b)
156+ void expire_tiles::from_line (geom::point_t const &a, geom::point_t const &b,
157+ expire_config_t const &expire_config)
136158{
137159 auto tilec_a = coords_to_tile (a);
138160 auto tilec_b = coords_to_tile (b);
@@ -175,11 +197,11 @@ void expire_tiles::from_line(geom::point_t const &a, geom::point_t const &b)
175197 if (y1 > y2) {
176198 std::swap (y1, y2);
177199 }
178- for (int x = x1 - tile_expiry_leeway ; x <= x2 + tile_expiry_leeway ;
200+ for (int x = x1 - expire_config. buffer ; x <= x2 + expire_config. buffer ;
179201 ++x) {
180202 uint32_t const norm_x = normalise_tile_x_coord (x);
181- for (int y = y1 - tile_expiry_leeway; y <= y2 + tile_expiry_leeway ;
182- ++y) {
203+ for (int y = y1 - expire_config. buffer ;
204+ y <= y2 + expire_config. buffer ; ++y) {
183205 if (y >= 0 ) {
184206 expire_tile (norm_x, static_cast <uint32_t >(y));
185207 }
@@ -191,7 +213,8 @@ void expire_tiles::from_line(geom::point_t const &a, geom::point_t const &b)
191213/*
192214 * Expire tiles within a bounding box
193215 */
194- int expire_tiles::from_bbox (geom::box_t const &box)
216+ int expire_tiles::from_bbox (geom::box_t const &box,
217+ expire_config_t const &expire_config)
195218{
196219 if (!enabled ()) {
197220 return 0 ;
@@ -203,28 +226,32 @@ int expire_tiles::from_bbox(geom::box_t const &box)
203226 /* Over half the planet's width within the bounding box - assume the
204227 box crosses the international date line and split it into two boxes */
205228 int ret = from_bbox ({-tile_t ::half_earth_circumference, box.min_y (),
206- box.min_x (), box.max_y ()});
229+ box.min_x (), box.max_y ()},
230+ expire_config);
207231 ret += from_bbox ({box.max_x (), box.min_y (),
208- tile_t ::half_earth_circumference, box.max_y ()});
232+ tile_t ::half_earth_circumference, box.max_y ()},
233+ expire_config);
209234 return ret;
210235 }
211236
212- if (width > m_max_bbox || height > m_max_bbox) {
237+ if (expire_config.mode == expire_mode::hybrid &&
238+ (width > expire_config.full_area_limit ||
239+ height > expire_config.full_area_limit )) {
213240 return -1 ;
214241 }
215242
216243 /* Convert the box's Mercator coordinates into tile coordinates */
217244 auto const tmp_min = coords_to_tile ({box.min_x (), box.max_y ()});
218245 int const min_tile_x =
219- std::clamp (int (tmp_min.x () - tile_expiry_leeway ), 0 , m_map_width);
246+ std::clamp (int (tmp_min.x () - expire_config. buffer ), 0 , m_map_width);
220247 int const min_tile_y =
221- std::clamp (int (tmp_min.y () - tile_expiry_leeway ), 0 , m_map_width);
248+ std::clamp (int (tmp_min.y () - expire_config. buffer ), 0 , m_map_width);
222249
223250 auto const tmp_max = coords_to_tile ({box.max_x (), box.min_y ()});
224251 int const max_tile_x =
225- std::clamp (int (tmp_max.x () + tile_expiry_leeway ), 0 , m_map_width);
252+ std::clamp (int (tmp_max.x () + expire_config. buffer ), 0 , m_map_width);
226253 int const max_tile_y =
227- std::clamp (int (tmp_max.y () + tile_expiry_leeway ), 0 , m_map_width);
254+ std::clamp (int (tmp_max.y () + expire_config. buffer ), 0 , m_map_width);
228255
229256 for (int iterator_x = min_tile_x; iterator_x <= max_tile_x; ++iterator_x) {
230257 uint32_t const norm_x = normalise_tile_x_coord (iterator_x);
@@ -286,12 +313,13 @@ std::size_t output_tiles_to_file(quadkey_list_t const &tiles_at_maxzoom,
286313 return count;
287314}
288315
289- int expire_from_result (expire_tiles *expire, pg_result_t const &result)
316+ int expire_from_result (expire_tiles *expire, pg_result_t const &result,
317+ expire_config_t const &expire_config)
290318{
291319 auto const num_tuples = result.num_tuples ();
292320
293321 for (int i = 0 ; i < num_tuples; ++i) {
294- expire->from_geometry (ewkb_to_geom (result.get (i, 0 )));
322+ expire->from_geometry (ewkb_to_geom (result.get (i, 0 )), expire_config );
295323 }
296324
297325 return num_tuples;
0 commit comments