36 lines
1.2 KiB
C++
36 lines
1.2 KiB
C++
#include "ground/TileMath.hpp"
|
|
|
|
#include <cmath>
|
|
|
|
namespace geopro::render {
|
|
|
|
namespace {
|
|
constexpr double kPi = 3.14159265358979323846;
|
|
int clampInt(int v, int lo, int hi) { return v < lo ? lo : (v > hi ? hi : v); }
|
|
} // namespace
|
|
|
|
TileXY lonLatToTile(double lonDeg, double latDeg, int z) {
|
|
if (z < 0) z = 0;
|
|
const double n = std::pow(2.0, z);
|
|
const double latR = latDeg * kPi / 180.0;
|
|
int x = static_cast<int>(std::floor((lonDeg + 180.0) / 360.0 * n));
|
|
int y = static_cast<int>(std::floor((1.0 - std::asinh(std::tan(latR)) / kPi) / 2.0 * n));
|
|
const int hi = static_cast<int>(n) - 1;
|
|
return TileXY{z, clampInt(x, 0, hi), clampInt(y, 0, hi)};
|
|
}
|
|
|
|
LonLatBox tileBounds(int z, int x, int y) {
|
|
if (z < 0) z = 0;
|
|
const double n = std::pow(2.0, z);
|
|
const double west = x / n * 360.0 - 180.0;
|
|
const double east = (x + 1) / n * 360.0 - 180.0;
|
|
auto latAt = [&](double yy) {
|
|
return std::atan(std::sinh(kPi * (1.0 - 2.0 * yy / n))) * 180.0 / kPi;
|
|
};
|
|
const double north = latAt(static_cast<double>(y));
|
|
const double south = latAt(static_cast<double>(y + 1));
|
|
return LonLatBox{west, south, east, north};
|
|
}
|
|
|
|
} // namespace geopro::render
|