1212
1313#include < memory>
1414#include < unordered_set>
15+ #include < utility>
16+ #include < vector>
1517
1618#include " geom.hpp"
1719#include " geom-box.hpp"
2224
2325class reprojection ;
2426
25- /* *
26- * Implementation of the output of the tile expiry list to a file.
27- */
28- class tile_output_t
29- {
30- FILE *outfile;
31-
32- public:
33- explicit tile_output_t (char const *filename);
34-
35- ~tile_output_t ();
36-
37- /* *
38- * Output dirty tile.
39- *
40- * \param tile The tile to write out.
41- */
42- void output_dirty_tile (tile_t const &tile);
43- };
44-
4527class expire_tiles
4628{
4729public:
@@ -50,83 +32,20 @@ class expire_tiles
5032
5133 bool enabled () const noexcept { return m_maxzoom != 0 ; }
5234
53- void from_geometry (geom::geometry_t const &geom, osmid_t osm_id );
35+ void from_geometry (geom::geometry_t const &geom);
5436
5537 int from_bbox (geom::box_t const &box);
5638
5739 /* *
58- * Expire tiles based on an osm id.
59- *
60- * \param result Result of a database query into some table returning the
61- * geometries. (This is usally done using the "get_wkb"
62- * prepared statement.)
63- * \param osm_id The OSM id to look for.
64- * \return The number of elements that refer to the osm_id or -1 if
65- * expire is disabled.
40+ * Get tiles as a vector of quadkeys and remove them from the expire_tiles
41+ * object.
6642 */
67- int from_result ( pg_result_t const &result, osmid_t osm_id );
43+ quadkey_list_t get_tiles ( );
6844
6945 /* *
70- * Write the list of expired tiles to a file.
71- *
72- * You will probably use tile_output_t as template argument for production code
73- * and another class which does not write to a file for unit tests.
74- *
75- * \param filename name of the file
76- * \param minzoom minimum zoom level
77- */
78- void output_and_destroy (char const *filename, uint32_t minzoom);
79-
80- /* *
81- * Output expired tiles on all requested zoom levels.
82- *
83- * \tparam TILE_WRITER class which implements the method
84- * output_dirty_tile(tile_t const &tile) which usually writes the tile ID
85- * to a file (production code) or does something else (usually unit tests).
86- *
87- * \param minzoom minimum zoom level
46+ * Merge the list of expired tiles in the other object into this
47+ * object, destroying the list in the other object.
8848 */
89- template <class TILE_WRITER >
90- void output_and_destroy (TILE_WRITER &output_writer, uint32_t minzoom)
91- {
92- assert (minzoom <= m_maxzoom);
93- // build a sorted vector of all expired tiles
94- std::vector<uint64_t > tiles_maxzoom (m_dirty_tiles.begin (),
95- m_dirty_tiles.end ());
96- std::sort (tiles_maxzoom.begin (), tiles_maxzoom.end ());
97- /* Loop over all requested zoom levels (from maximum down to the minimum zoom level).
98- * Tile IDs of the tiles enclosing this tile at lower zoom levels are calculated using
99- * bit shifts.
100- *
101- * last_quadkey is initialized with a value which is not expected to exist
102- * (larger than largest possible quadkey). */
103- uint64_t last_quadkey = 1ULL << (2 * m_maxzoom);
104- std::size_t count = 0 ;
105- for (auto const quadkey : tiles_maxzoom) {
106- for (uint32_t dz = 0 ; dz <= m_maxzoom - minzoom; ++dz) {
107- // scale down to the current zoom level
108- uint64_t qt_current = quadkey >> (dz * 2 );
109- /* If dz > 0, there are propably multiple elements whose quadkey
110- * is equal because they are all sub-tiles of the same tile at the current
111- * zoom level. We skip all of them after we have written the first sibling.
112- */
113- if (qt_current == last_quadkey >> (dz * 2 )) {
114- continue ;
115- }
116- auto const tile =
117- tile_t::from_quadkey (qt_current, m_maxzoom - dz);
118- output_writer.output_dirty_tile (tile);
119- ++count;
120- }
121- last_quadkey = quadkey;
122- }
123- log_info (" Wrote {} entries to expired tiles list" , count);
124- }
125-
126- /* *
127- * merge the list of expired tiles in the other object into this
128- * object, destroying the list in the other object.
129- */
13049 void merge_and_destroy (expire_tiles *other);
13150
13251private:
@@ -149,7 +68,7 @@ class expire_tiles
14968 void from_point_list (geom::point_list_t const &list);
15069
15170 // / This is where we collect all the expired tiles.
152- std::unordered_set<uint64_t > m_dirty_tiles;
71+ std::unordered_set<quadkey_t > m_dirty_tiles;
15372
15473 // / The tile which has been added last to the unordered set.
15574 tile_t m_prev_tile;
@@ -159,6 +78,81 @@ class expire_tiles
15978 double m_max_bbox;
16079 uint32_t m_maxzoom;
16180 int m_map_width;
162- };
81+
82+ }; // class expire_tiles
83+
84+ /* *
85+ * Expire tiles based on an osm id.
86+ *
87+ * \param expire Where to mark expired tiles.
88+ * \param result Result of a database query into some table returning the
89+ * geometries. (This is usually done using the "get_wkb"
90+ * prepared statement.)
91+ * \return The number of tuples in the result or -1 if expire is disabled.
92+ */
93+ int expire_from_result (expire_tiles *expire, pg_result_t const &result);
94+
95+ /* *
96+ * Iterate over tiles and call output function for each tile on all requested
97+ * zoom levels.
98+ *
99+ * \tparam OUTPUT Class with operator() taking a tile_t argument
100+ *
101+ * \param tiles The list of tiles at maximum zoom level
102+ * \param minzoom Minimum zoom level
103+ * \param maxzoom Maximum zoom level
104+ * \param output Output function
105+ */
106+ template <class OUTPUT >
107+ std::size_t for_each_tile (quadkey_list_t const &tiles, uint32_t minzoom,
108+ uint32_t maxzoom, OUTPUT &&output)
109+ {
110+ assert (minzoom <= maxzoom);
111+
112+ if (minzoom == maxzoom) {
113+ for (auto const quadkey : tiles) {
114+ std::forward<OUTPUT>(output)(
115+ tile_t::from_quadkey (quadkey, maxzoom));
116+ }
117+ return tiles.size ();
118+ }
119+
120+ /* *
121+ * Loop over all requested zoom levels (from maximum down to the minimum
122+ * zoom level).
123+ */
124+ quadkey_t last_quadkey{};
125+ std::size_t count = 0 ;
126+ for (auto const quadkey : tiles) {
127+ for (uint32_t dz = 0 ; dz <= maxzoom - minzoom; ++dz) {
128+ auto const qt_current = quadkey.down (dz);
129+ /* *
130+ * If dz > 0, there are probably multiple elements whose quadkey
131+ * is equal because they are all sub-tiles of the same tile at the
132+ * current zoom level. We skip all of them after we have written
133+ * the first sibling.
134+ */
135+ if (qt_current != last_quadkey.down (dz)) {
136+ std::forward<OUTPUT>(output)(
137+ tile_t::from_quadkey (qt_current, maxzoom - dz));
138+ ++count;
139+ }
140+ }
141+ last_quadkey = quadkey;
142+ }
143+ return count;
144+ }
145+
146+ /* *
147+ * Write the list of tiles to a file.
148+ *
149+ * \param tiles The list of tiles at maximum zoom level
150+ * \param filename Name of the file
151+ * \param minzoom Minimum zoom level
152+ * \param maxzoom Maximum zoom level
153+ */
154+ std::size_t output_tiles_to_file (quadkey_list_t const &tiles,
155+ char const *filename, uint32_t minzoom,
156+ uint32_t maxzoom);
163157
164158#endif // OSM2PGSQL_EXPIRE_TILES_HPP
0 commit comments