2828#include " options.hpp"
2929#include " reprojection.hpp"
3030#include " table.hpp"
31+ #include " tile.hpp"
3132#include " wkb.hpp"
3233
33- #define EARTH_CIRCUMFERENCE 40075016.68
34- #define HALF_EARTH_CIRCUMFERENCE (EARTH_CIRCUMFERENCE / 2 )
35-
3634// How many tiles worth of space to leave either side of a changed feature
37- # define TILE_EXPIRY_LEEWAY 0.1
35+ static constexpr double const tile_expiry_leeway = 0.1 ;
3836
3937tile_output_t ::tile_output_t (char const *filename)
4038: outfile(fopen(filename, " a" ))
@@ -62,25 +60,23 @@ void tile_output_t::output_dirty_tile(tile_t const &tile)
6260 fmt::print (outfile, " {}/{}/{}\n " , tile.zoom (), tile.x (), tile.y ());
6361}
6462
63+ expire_tiles::expire_tiles (uint32_t max_zoom, double max_bbox,
64+ const std::shared_ptr<reprojection> &projection)
65+ : m_projection(projection), m_max_bbox(max_bbox), m_maxzoom(max_zoom),
66+ m_map_width(1U << m_maxzoom)
67+ {}
68+
6569void expire_tiles::output_and_destroy (char const *filename, uint32_t minzoom)
6670{
6771 tile_output_t output_writer{filename};
6872 output_and_destroy<tile_output_t >(output_writer, minzoom);
6973}
7074
71- expire_tiles::expire_tiles (uint32_t max, double bbox,
72- const std::shared_ptr<reprojection> &proj)
73- : max_bbox(bbox), maxzoom(max), projection(proj)
74- {
75- map_width = 1U << maxzoom;
76- tile_width = EARTH_CIRCUMFERENCE / map_width;
77- }
78-
7975void expire_tiles::expire_tile (uint32_t x, uint32_t y)
8076{
8177 // Only try to insert to tile into the set if the last inserted tile
8278 // is different from this tile.
83- tile_t const new_tile{maxzoom , x, y};
79+ tile_t const new_tile{m_maxzoom , x, y};
8480 if (!m_prev_tile.valid () || m_prev_tile != new_tile) {
8581 m_dirty_tiles.insert (new_tile.quadkey ());
8682 m_prev_tile = new_tile;
@@ -89,26 +85,25 @@ void expire_tiles::expire_tile(uint32_t x, uint32_t y)
8985
9086uint32_t expire_tiles::normalise_tile_x_coord (int x) const
9187{
92- x %= map_width ;
88+ x %= m_map_width ;
9389 if (x < 0 ) {
94- x = (map_width - x) + 1 ;
90+ x = (m_map_width - x) + 1 ;
9591 }
9692 return static_cast <uint32_t >(x);
9793}
9894
99- void expire_tiles::coords_to_tile (double lon, double lat, double *tilex,
100- double *tiley)
95+ geom::point_t expire_tiles::coords_to_tile (geom::point_t const &point)
10196{
102- auto const c = projection ->target_to_tile (geom:: point_t {lon, lat} );
97+ auto const c = m_projection ->target_to_tile (point );
10398
104- *tilex = map_width * (0.5 + c.x () / EARTH_CIRCUMFERENCE);
105- *tiley = map_width * (0.5 - c.y () / EARTH_CIRCUMFERENCE) ;
99+ return {m_map_width * (0.5 + c.x () / tile_t ::earth_circumference),
100+ m_map_width * (0.5 - c.y () / tile_t ::earth_circumference)} ;
106101}
107102
108103void expire_tiles::from_point_list (geom::point_list_t const &list)
109104{
110- for_each_segment (list, [&](geom::point_t a, geom::point_t b) {
111- from_line (a. x (), a. y (), b. x (), b. y () );
105+ for_each_segment (list, [&](geom::point_t const & a, geom::point_t const & b) {
106+ from_line (a, b );
112107 });
113108}
114109
@@ -154,41 +149,26 @@ void expire_tiles::from_geometry(geom::geometry_t const &geom, osmid_t osm_id)
154149/*
155150 * Expire tiles that a line crosses
156151 */
157- void expire_tiles::from_line (double lon_a, double lat_a, double lon_b,
158- double lat_b)
152+ void expire_tiles::from_line (geom::point_t const &a, geom::point_t const &b)
159153{
160- double tile_x_a = NAN;
161- double tile_y_a = NAN;
162- double tile_x_b = NAN;
163- double tile_y_b = NAN;
154+ auto tilec_a = coords_to_tile (a);
155+ auto tilec_b = coords_to_tile (b);
164156
165- coords_to_tile (lon_a, lat_a, &tile_x_a, &tile_y_a);
166- coords_to_tile (lon_b, lat_b, &tile_x_b, &tile_y_b);
167-
168- if (tile_x_a > tile_x_b) {
157+ if (tilec_a.x () > tilec_b.x ()) {
169158 /* We always want the line to go from left to right - swap the ends if it doesn't */
170- double temp = tile_x_b;
171- tile_x_b = tile_x_a;
172- tile_x_a = temp;
173- temp = tile_y_b;
174- tile_y_b = tile_y_a;
175- tile_y_a = temp;
159+ std::swap (tilec_a, tilec_b);
176160 }
177161
178- double const x_len = tile_x_b - tile_x_a ;
179- if (x_len > map_width / 2 ) {
162+ double const x_len = tilec_b. x () - tilec_a. x () ;
163+ if (x_len > m_map_width / 2 ) {
180164 /* If the line is wider than half the map, assume it
181165 crosses the international date line.
182166 These coordinates get normalised again later */
183- tile_x_a += map_width;
184- double temp = tile_x_b;
185- tile_x_b = tile_x_a;
186- tile_x_a = temp;
187- temp = tile_y_b;
188- tile_y_b = tile_y_a;
189- tile_y_a = temp;
167+ tilec_a.set_x (tilec_a.x () + m_map_width);
168+ std::swap (tilec_a, tilec_b);
190169 }
191- double const y_len = tile_y_b - tile_y_a;
170+
171+ double const y_len = tilec_b.y () - tilec_a.y ();
192172 double const hyp_len = sqrt (pow (x_len, 2 ) + pow (y_len, 2 )); /* Pythagoras */
193173 double const x_step = x_len / hyp_len;
194174 double const y_step = y_len / hyp_len;
@@ -199,10 +179,10 @@ void expire_tiles::from_line(double lon_a, double lat_a, double lon_b,
199179 if (next_step > hyp_len) {
200180 next_step = hyp_len;
201181 }
202- double x1 = tile_x_a + ((double )step * x_step);
203- double y1 = tile_y_a + ((double )step * y_step);
204- double x2 = tile_x_a + ((double )next_step * x_step);
205- double y2 = tile_y_a + ((double )next_step * y_step);
182+ double x1 = tilec_a. x () + ((double )step * x_step);
183+ double y1 = tilec_a. y () + ((double )step * y_step);
184+ double x2 = tilec_a. x () + ((double )next_step * x_step);
185+ double y2 = tilec_a. y () + ((double )next_step * y_step);
206186
207187 /* The line (x1,y1),(x2,y2) is up to 1 tile width long
208188 x1 will always be <= x2
@@ -214,10 +194,10 @@ void expire_tiles::from_line(double lon_a, double lat_a, double lon_b,
214194 y2 = y1;
215195 y1 = temp;
216196 }
217- for (int x = x1 - TILE_EXPIRY_LEEWAY ; x <= x2 + TILE_EXPIRY_LEEWAY ;
197+ for (int x = x1 - tile_expiry_leeway ; x <= x2 + tile_expiry_leeway ;
218198 ++x) {
219199 uint32_t const norm_x = normalise_tile_x_coord (x);
220- for (int y = y1 - TILE_EXPIRY_LEEWAY ; y <= y2 + TILE_EXPIRY_LEEWAY ;
200+ for (int y = y1 - tile_expiry_leeway ; y <= y2 + tile_expiry_leeway ;
221201 ++y) {
222202 if (y >= 0 ) {
223203 expire_tile (norm_x, static_cast <uint32_t >(y));
@@ -232,56 +212,46 @@ void expire_tiles::from_line(double lon_a, double lat_a, double lon_b,
232212 */
233213int expire_tiles::from_bbox (geom::box_t const &box)
234214{
235- double const min_lon = box.min_x ();
236- double const min_lat = box.min_y ();
237- double const max_lon = box.max_x ();
238- double const max_lat = box.max_y ();
239-
240- return from_bbox (min_lon, min_lat, max_lon, max_lat);
241- }
242-
243- int expire_tiles::from_bbox (double min_lon, double min_lat, double max_lon,
244- double max_lat)
245- {
246- if (maxzoom == 0 ) {
215+ if (!enabled ()) {
247216 return 0 ;
248217 }
249218
250- double const width = max_lon - min_lon ;
251- double const height = max_lat - min_lat ;
252- if (width > HALF_EARTH_CIRCUMFERENCE + 1 ) {
219+ double const width = box. width () ;
220+ double const height = box. height () ;
221+ if (width > tile_t ::half_earth_circumference + 1 ) {
253222 /* Over half the planet's width within the bounding box - assume the
254223 box crosses the international date line and split it into two boxes */
255- int ret =
256- from_bbox (-HALF_EARTH_CIRCUMFERENCE, min_lat, min_lon, max_lat);
257- ret += from_bbox (max_lon, min_lat, HALF_EARTH_CIRCUMFERENCE, max_lat);
224+ int ret = from_bbox ({-tile_t ::half_earth_circumference, box.min_y (),
225+ box.min_x (), box.max_y ()});
226+ ret += from_bbox ({box.max_x (), box.min_y (),
227+ tile_t ::half_earth_circumference, box.max_y ()});
258228 return ret;
259229 }
260230
261- if (width > max_bbox || height > max_bbox ) {
231+ if (width > m_max_bbox || height > m_max_bbox ) {
262232 return -1 ;
263233 }
264234
265235 /* Convert the box's Mercator coordinates into tile coordinates */
266- double tmp_x = NAN ;
267- double tmp_y = NAN ;
268- coords_to_tile (min_lon, max_lat, &tmp_x, &tmp_y) ;
269- int min_tile_x = tmp_x - TILE_EXPIRY_LEEWAY;
270- int min_tile_y = tmp_y - TILE_EXPIRY_LEEWAY ;
271- coords_to_tile (max_lon, min_lat, &tmp_x, &tmp_y) ;
272- int max_tile_x = tmp_x + TILE_EXPIRY_LEEWAY ;
273- int max_tile_y = tmp_y + TILE_EXPIRY_LEEWAY;
236+ auto const tmp_min = coords_to_tile ({box. min_x (), box. max_y ()}) ;
237+ int min_tile_x = tmp_min. x () - tile_expiry_leeway ;
238+ int min_tile_y = tmp_min. y () - tile_expiry_leeway ;
239+
240+ auto const tmp_max = coords_to_tile ({box. max_x (), box. min_y ()}) ;
241+ int max_tile_x = tmp_max. x () + tile_expiry_leeway ;
242+ int max_tile_y = tmp_max. y () + tile_expiry_leeway ;
243+
274244 if (min_tile_x < 0 ) {
275245 min_tile_x = 0 ;
276246 }
277247 if (min_tile_y < 0 ) {
278248 min_tile_y = 0 ;
279249 }
280- if (max_tile_x > map_width ) {
281- max_tile_x = map_width ;
250+ if (max_tile_x > m_map_width ) {
251+ max_tile_x = m_map_width ;
282252 }
283- if (max_tile_y > map_width ) {
284- max_tile_y = map_width ;
253+ if (max_tile_y > m_map_width ) {
254+ max_tile_y = m_map_width ;
285255 }
286256 for (int iterator_x = min_tile_x; iterator_x <= max_tile_x; ++iterator_x) {
287257 uint32_t const norm_x = normalise_tile_x_coord (iterator_x);
@@ -295,42 +265,32 @@ int expire_tiles::from_bbox(double min_lon, double min_lat, double max_lon,
295265
296266int expire_tiles::from_result (pg_result_t const &result, osmid_t osm_id)
297267{
298- // bail if we dont care about expiry
299- if (maxzoom == 0 ) {
268+ if (!enabled ()) {
300269 return -1 ;
301270 }
302271
303- // dirty the stuff
304272 auto const num_tuples = result.num_tuples ();
305273 for (int i = 0 ; i < num_tuples; ++i) {
306274 char const *const wkb = result.get_value (i, 0 );
307275 from_geometry (ewkb_to_geom (decode_hex (wkb)), osm_id);
308276 }
309277
310- // return how many rows were affected
311278 return num_tuples;
312279}
313280
314281void expire_tiles::merge_and_destroy (expire_tiles &other)
315282{
316- if (map_width != other.map_width ) {
283+ if (m_map_width != other.m_map_width ) {
317284 throw std::runtime_error{" Unable to merge tile expiry sets when "
318285 " map_width does not match: {} != {}." _format (
319- map_width, other.map_width )};
320- }
321-
322- if (tile_width != other.tile_width ) {
323- throw std::runtime_error{" Unable to merge tile expiry sets when "
324- " tile_width does not match: {} != {}." _format (
325- tile_width, other.tile_width )};
286+ m_map_width, other.m_map_width )};
326287 }
327288
328289 if (m_dirty_tiles.empty ()) {
329290 m_dirty_tiles = std::move (other.m_dirty_tiles );
330291 } else {
331292 m_dirty_tiles.insert (other.m_dirty_tiles .begin (),
332293 other.m_dirty_tiles .end ());
294+ other.m_dirty_tiles .clear ();
333295 }
334-
335- other.m_dirty_tiles .clear ();
336296}
0 commit comments