osrm-backend/include/util/viewport.hpp
2022-12-20 18:00:11 +01:00

46 lines
1.5 KiB
C++

#ifndef UTIL_VIEWPORT_HPP
#define UTIL_VIEWPORT_HPP
#include "util/coordinate.hpp"
#include "util/web_mercator.hpp"
#include <boost/assert.hpp>
#include <cmath>
#include <tuple>
// Port of https://github.com/mapbox/geo-viewport
namespace osrm::util::viewport
{
namespace detail
{
static constexpr unsigned MAX_ZOOM = 18;
static constexpr unsigned MIN_ZOOM = 1;
// this is an upper bound to current display sizes
static constexpr double VIEWPORT_WIDTH = 8 * web_mercator::TILE_SIZE;
static constexpr double VIEWPORT_HEIGHT = 5 * web_mercator::TILE_SIZE;
static const double INV_LOG_2 = 1. / std::log(2);
} // namespace detail
inline unsigned getFittedZoom(util::Coordinate south_west, util::Coordinate north_east)
{
const auto min_x = web_mercator::degreeToPixel(toFloating(south_west.lon), detail::MAX_ZOOM);
const auto max_y = web_mercator::degreeToPixel(toFloating(south_west.lat), detail::MAX_ZOOM);
const auto max_x = web_mercator::degreeToPixel(toFloating(north_east.lon), detail::MAX_ZOOM);
const auto min_y = web_mercator::degreeToPixel(toFloating(north_east.lat), detail::MAX_ZOOM);
const double width_ratio = (max_x - min_x) / detail::VIEWPORT_WIDTH;
const double height_ratio = (max_y - min_y) / detail::VIEWPORT_HEIGHT;
const auto zoom = detail::MAX_ZOOM -
std::max(std::log(width_ratio), std::log(height_ratio)) * detail::INV_LOG_2;
if (std::isfinite(zoom))
return std::max<unsigned>(detail::MIN_ZOOM, zoom);
else
return detail::MIN_ZOOM;
}
} // namespace osrm::util::viewport
#endif