46 lines
1.5 KiB
C++
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
|