boat
C++23 geospatial library
Loading...
Searching...
No Matches
tile.hpp
Go to the documentation of this file.
1// Andrew Naplavkov
2
3#ifndef BOAT_TILE_HPP
4#define BOAT_TILE_HPP
5
6#include <boat/detail/utility.hpp>
7#include <boost/pfr/ops_fields.hpp>
8#include <boost/qvm/map_vec_mat.hpp>
9#include <boost/qvm/mat_operations.hpp>
10#include <boost/qvm/vec.hpp>
11#include <generator>
12
13namespace boat {
14
15struct tile {
16 int z, y, x;
17
18 static constexpr int size = 256;
19
20 friend auto operator<=>(tile const&, tile const&) = default;
21
22 friend auto hash_value(tile const& v) { return boost::pfr::hash_fields(v); }
23
25 static int zmax(int width, int height)
26 {
27 auto px = static_cast<size_t>(std::max<>({width, height, size}));
28 auto tl = static_cast<size_t>(std::bit_ceil(px) / size);
29 return static_cast<int>(std::bit_width(tl)) - 1;
30 }
31
32 static int zoom(int width, int height, double scale)
33 {
34 int lim = zmax(width, height);
35 scale *= pow2(lim);
36 for (int i = lim; i > 0; --i)
37 if (scale >= pow2(i))
38 return i;
39 return 0;
40 }
41
43 static int scale(int width, int height, int zoom)
44 {
45 return pow2(zmax(width, height) - zoom);
46 }
47
48 static std::generator<tile> all(int width, int height, int zoom)
49 {
50 if (width <= 0 || height <= 0)
51 co_return;
52 int px = scale(width, height, zoom);
53 int tl = size * px;
54 int xmax = (width - 1) / tl;
55 int ymax = (height - 1) / tl;
56 for (int y{}; y <= ymax; ++y)
57 for (int x{}; x <= xmax; ++x)
58 co_yield {.z = zoom, .y = y, .x = x};
59 }
60
62 std::tuple<int, int, int, int> rect(int width, int height) const
63 {
64 int px = scale(width, height, z);
65 int tl = size * px;
66 int x1 = std::clamp(x * tl, 0, width);
67 int y1 = std::clamp(y * tl, 0, height);
68 int x2 = std::clamp((x + 1) * tl, 0, width);
69 int y2 = std::clamp((y + 1) * tl, 0, height);
70 return {x1, y1, x2 - x1, y2 - y1};
71 }
72
74 auto affine(int width, int height) const
75 {
76 auto [x, y, w, h] = rect(width, height);
77 auto px = scale(width, height, z);
78 double sx = double(w) / ((w + px - 1) / px);
79 double sy = double(h) / ((h + px - 1) / px);
80 return boost::qvm::translation_mat(boost::qvm::vec{{x * 1., y * 1.}}) *
81 boost::qvm::diag_mat(boost::qvm::vec{{sx, sy, 1.}});
82 }
83};
84
85} // namespace boat
86
87template <>
88struct std::hash<boat::tile> {
89 static auto operator()(boat::tile const& v) { return hash_value(v); }
90};
91
92#endif // BOAT_TILE_HPP
Definition blob.hpp:12
Definition tile.hpp:15
friend auto operator<=>(tile const &, tile const &)=default
static constexpr int size
Maximum tile side in pixels.
Definition tile.hpp:18
auto affine(int width, int height) const
Maps tile pixels to raster pixels.
Definition tile.hpp:74
static int scale(int width, int height, int zoom)
Raster pixels per tile pixel.
Definition tile.hpp:43
int y
Definition tile.hpp:16
friend auto hash_value(tile const &v)
Definition tile.hpp:22
std::tuple< int, int, int, int > rect(int width, int height) const
Clipped raster-pixel rectangle {x, y, width, height}.
Definition tile.hpp:62
static std::generator< tile > all(int width, int height, int zoom)
Definition tile.hpp:48
int z
Definition tile.hpp:16
static int zmax(int width, int height)
Finest zoom, with one raster pixel per tile pixel.
Definition tile.hpp:25
static int zoom(int width, int height, double scale)
Definition tile.hpp:32
int x
Definition tile.hpp:16
static auto operator()(boat::tile const &v)
Definition tile.hpp:89