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 <generator>
10
11namespace boat {
12
13struct tile {
14 int z, y, x;
15
16 static constexpr int size = 256;
17
18 friend auto operator<=>(tile const&, tile const&) = default;
19
20 friend auto hash_value(tile const& v) { return boost::pfr::hash_fields(v); }
21
23 static int zmax(int width, int height)
24 {
25 auto px = static_cast<size_t>(std::max<>({width, height, size}));
26 auto tl = static_cast<size_t>(std::bit_ceil(px) / size);
27 return static_cast<int>(std::bit_width(tl)) - 1;
28 }
29
30 static int zoom(int width, int height, double scale)
31 {
32 int lim = zmax(width, height);
33 scale *= pow2(lim);
34 for (int i = lim; i > 0; --i)
35 if (scale >= pow2(i))
36 return i;
37 return 0;
38 }
39
41 static int scale(int width, int height, int zoom)
42 {
43 return pow2(zmax(width, height) - zoom);
44 }
45
46 static std::generator<tile> all(int width, int height, int zoom)
47 {
48 if (width <= 0 || height <= 0)
49 co_return;
50 int px = scale(width, height, zoom);
51 int tl = size * px;
52 int xmax = (width - 1) / tl;
53 int ymax = (height - 1) / tl;
54 for (int y{}; y <= ymax; ++y)
55 for (int x{}; x <= xmax; ++x)
56 co_yield {.z = zoom, .y = y, .x = x};
57 }
58
60 std::tuple<int, int, int, int> rect(int width, int height) const
61 {
62 int px = scale(width, height, z);
63 int tl = size * px;
64 int x1 = std::clamp(x * tl, 0, width);
65 int y1 = std::clamp(y * tl, 0, height);
66 int x2 = std::clamp((x + 1) * tl, 0, width);
67 int y2 = std::clamp((y + 1) * tl, 0, height);
68 return {x1, y1, x2 - x1, y2 - y1};
69 }
70
72 auto affine(int width, int height) const
73 {
74 double px = scale(width, height, z);
75 double tl = size * px;
76 return boost::qvm::translation_mat(boost::qvm::vec{{x * tl, y * tl}}) *
77 boost::qvm::diag_mat(boost::qvm::vec{{px, px, 1.}});
78 }
79};
80
81} // namespace boat
82
83template <>
84struct std::hash<boat::tile> {
85 static auto operator()(boat::tile const& v) { return hash_value(v); }
86};
87
88#endif // BOAT_TILE_HPP
Definition blob.hpp:12
Definition tile.hpp:13
friend auto operator<=>(tile const &, tile const &)=default
static constexpr int size
Maximum tile side in pixels.
Definition tile.hpp:16
auto affine(int width, int height) const
Maps tile pixels to raster pixels.
Definition tile.hpp:72
static int scale(int width, int height, int zoom)
Raster pixels per tile pixel.
Definition tile.hpp:41
int y
Definition tile.hpp:14
friend auto hash_value(tile const &v)
Definition tile.hpp:20
std::tuple< int, int, int, int > rect(int width, int height) const
Clipped raster-pixel rectangle {x, y, width, height}.
Definition tile.hpp:60
static std::generator< tile > all(int width, int height, int zoom)
Definition tile.hpp:46
int z
Definition tile.hpp:14
static int zmax(int width, int height)
Finest zoom, with one raster pixel per tile pixel.
Definition tile.hpp:23
static int zoom(int width, int height, double scale)
Definition tile.hpp:30
int x
Definition tile.hpp:14
static auto operator()(boat::tile const &v)
Definition tile.hpp:85