34
34
#include " tile.hpp"
35
35
#include " wkb.hpp"
36
36
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,
41
38
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)
44
41
{}
45
42
46
43
void expire_tiles::expire_tile (uint32_t x, uint32_t y)
@@ -71,68 +68,94 @@ geom::point_t expire_tiles::coords_to_tile(geom::point_t const &point)
71
68
m_map_width * (0.5 - c.y () / tile_t ::earth_circumference)};
72
69
}
73
70
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)
75
73
{
76
74
for_each_segment (list, [&](geom::point_t const &a, geom::point_t const &b) {
77
- from_line (a, b);
75
+ from_line_segment (a, b, expire_config );
78
76
});
79
77
}
80
78
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)
82
81
{
83
82
geom::box_t const box = geom::envelope (geom);
84
- from_bbox (box);
83
+ from_bbox (box, expire_config );
85
84
}
86
85
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)
88
88
{
89
- from_point_list (geom);
89
+ from_point_list (geom, expire_config );
90
90
}
91
91
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)
93
94
{
94
- from_point_list (geom.outer ());
95
+ from_point_list (geom.outer (), expire_config );
95
96
for (auto const &inner : geom.inners ()) {
96
- from_point_list (inner);
97
+ from_point_list (inner, expire_config );
97
98
}
98
99
}
99
100
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)
101
103
{
104
+ if (expire_config.mode == expire_mode::boundary_only) {
105
+ from_polygon_boundary (geom, expire_config);
106
+ return ;
107
+ }
108
+
102
109
geom::box_t const box = geom::envelope (geom);
103
- if (from_bbox (box)) {
110
+ if (from_bbox (box, expire_config )) {
104
111
/* 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);
106
121
}
107
122
}
108
123
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)
110
126
{
127
+ if (expire_config.mode == expire_mode::boundary_only) {
128
+ from_polygon_boundary (geom, expire_config);
129
+ return ;
130
+ }
131
+
111
132
geom::box_t const box = geom::envelope (geom);
112
- if (from_bbox (box)) {
133
+ if (from_bbox (box, expire_config )) {
113
134
/* 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);
117
136
}
118
137
}
119
138
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)
121
141
{
122
- geom.visit ([&](auto const &g) { from_geometry (g); });
142
+ geom.visit ([&](auto const &g) { from_geometry (g, expire_config ); });
123
143
}
124
144
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)
126
147
{
127
148
if (geom.srid () == 3857 ) {
128
- from_geometry (geom);
149
+ from_geometry (geom, expire_config );
129
150
}
130
151
}
131
152
132
153
/*
133
154
* Expire tiles that a line crosses
134
155
*/
135
- void expire_tiles::from_line (geom::point_t const &a, geom::point_t const &b)
156
+ void expire_tiles::from_line_segment (geom::point_t const &a,
157
+ geom::point_t const &b,
158
+ expire_config_t const &expire_config)
136
159
{
137
160
auto tilec_a = coords_to_tile (a);
138
161
auto tilec_b = coords_to_tile (b);
@@ -175,11 +198,11 @@ void expire_tiles::from_line(geom::point_t const &a, geom::point_t const &b)
175
198
if (y1 > y2) {
176
199
std::swap (y1, y2);
177
200
}
178
- for (int x = x1 - tile_expiry_leeway ; x <= x2 + tile_expiry_leeway ;
201
+ for (int x = x1 - expire_config. buffer ; x <= x2 + expire_config. buffer ;
179
202
++x) {
180
203
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) {
204
+ for (int y = y1 - expire_config. buffer ;
205
+ y <= y2 + expire_config. buffer ; ++y) {
183
206
if (y >= 0 ) {
184
207
expire_tile (norm_x, static_cast <uint32_t >(y));
185
208
}
@@ -191,7 +214,8 @@ void expire_tiles::from_line(geom::point_t const &a, geom::point_t const &b)
191
214
/*
192
215
* Expire tiles within a bounding box
193
216
*/
194
- int expire_tiles::from_bbox (geom::box_t const &box)
217
+ int expire_tiles::from_bbox (geom::box_t const &box,
218
+ expire_config_t const &expire_config)
195
219
{
196
220
if (!enabled ()) {
197
221
return 0 ;
@@ -203,28 +227,32 @@ int expire_tiles::from_bbox(geom::box_t const &box)
203
227
/* Over half the planet's width within the bounding box - assume the
204
228
box crosses the international date line and split it into two boxes */
205
229
int ret = from_bbox ({-tile_t ::half_earth_circumference, box.min_y (),
206
- box.min_x (), box.max_y ()});
230
+ box.min_x (), box.max_y ()},
231
+ expire_config);
207
232
ret += from_bbox ({box.max_x (), box.min_y (),
208
- tile_t ::half_earth_circumference, box.max_y ()});
233
+ tile_t ::half_earth_circumference, box.max_y ()},
234
+ expire_config);
209
235
return ret;
210
236
}
211
237
212
- if (width > m_max_bbox || height > m_max_bbox) {
238
+ if (expire_config.mode == expire_mode::hybrid &&
239
+ (width > expire_config.full_area_limit ||
240
+ height > expire_config.full_area_limit )) {
213
241
return -1 ;
214
242
}
215
243
216
244
/* Convert the box's Mercator coordinates into tile coordinates */
217
245
auto const tmp_min = coords_to_tile ({box.min_x (), box.max_y ()});
218
246
int const min_tile_x =
219
- std::clamp (int (tmp_min.x () - tile_expiry_leeway ), 0 , m_map_width);
247
+ std::clamp (int (tmp_min.x () - expire_config. buffer ), 0 , m_map_width);
220
248
int const min_tile_y =
221
- std::clamp (int (tmp_min.y () - tile_expiry_leeway ), 0 , m_map_width);
249
+ std::clamp (int (tmp_min.y () - expire_config. buffer ), 0 , m_map_width);
222
250
223
251
auto const tmp_max = coords_to_tile ({box.max_x (), box.min_y ()});
224
252
int const max_tile_x =
225
- std::clamp (int (tmp_max.x () + tile_expiry_leeway ), 0 , m_map_width);
253
+ std::clamp (int (tmp_max.x () + expire_config. buffer ), 0 , m_map_width);
226
254
int const max_tile_y =
227
- std::clamp (int (tmp_max.y () + tile_expiry_leeway ), 0 , m_map_width);
255
+ std::clamp (int (tmp_max.y () + expire_config. buffer ), 0 , m_map_width);
228
256
229
257
for (int iterator_x = min_tile_x; iterator_x <= max_tile_x; ++iterator_x) {
230
258
uint32_t const norm_x = normalise_tile_x_coord (iterator_x);
@@ -286,12 +314,13 @@ std::size_t output_tiles_to_file(quadkey_list_t const &tiles_at_maxzoom,
286
314
return count;
287
315
}
288
316
289
- int expire_from_result (expire_tiles *expire, pg_result_t const &result)
317
+ int expire_from_result (expire_tiles *expire, pg_result_t const &result,
318
+ expire_config_t const &expire_config)
290
319
{
291
320
auto const num_tuples = result.num_tuples ();
292
321
293
322
for (int i = 0 ; i < num_tuples; ++i) {
294
- expire->from_geometry (ewkb_to_geom (result.get (i, 0 )));
323
+ expire->from_geometry (ewkb_to_geom (result.get (i, 0 )), expire_config );
295
324
}
296
325
297
326
return num_tuples;
0 commit comments