@@ -80,6 +80,8 @@ const constexpr double TILE_SIZE = 256.0;
|
||||
// Converts projected mercator degrees to PX
|
||||
const constexpr double DEGREE_TO_PX = detail::MAXEXTENT / 180.0;
|
||||
|
||||
double degreeToPixel(FloatLatitude lat, unsigned zoom);
|
||||
double degreeToPixel(FloatLongitude lon, unsigned zoom);
|
||||
FloatLatitude yToLat(const double value);
|
||||
double latToY(const FloatLatitude latitude);
|
||||
void xyzToMercator(const int x, const int y, const int z, double &minx, double &miny, double &maxx, double &maxy);
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
#ifndef UTIL_TILES_HPP
|
||||
#define UTIL_TILES_HPP
|
||||
|
||||
#include "util/coordinate.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <cmath>
|
||||
#include <tuple>
|
||||
|
||||
// This is a port of the tilebelt algorithm https://github.com/mapbox/tilebelt
|
||||
namespace osrm
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
namespace tiles
|
||||
{
|
||||
struct Tile
|
||||
{
|
||||
unsigned x;
|
||||
unsigned y;
|
||||
unsigned z;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// optimized for 32bit integers
|
||||
static constexpr unsigned MAX_ZOOM = 32;
|
||||
|
||||
// Returns 1-indexed 1..32 of MSB if value > 0 or 0 if value == 0
|
||||
inline unsigned getMSBPosition(std::uint32_t value)
|
||||
{
|
||||
if (value == 0)
|
||||
return 0;
|
||||
std::uint8_t pos = 1;
|
||||
while (value >>= 1)
|
||||
pos++;
|
||||
return pos;
|
||||
}
|
||||
|
||||
inline unsigned getBBMaxZoom(const Tile top_left, const Tile bottom_left)
|
||||
{
|
||||
auto x_xor = top_left.x ^ bottom_left.x;
|
||||
auto y_xor = top_left.y ^ bottom_left.y;
|
||||
auto lon_msb = detail::getMSBPosition(x_xor);
|
||||
auto lat_msb = detail::getMSBPosition(y_xor);
|
||||
return MAX_ZOOM - std::max(lon_msb, lat_msb);
|
||||
}
|
||||
}
|
||||
|
||||
inline Tile pointToTile(const FloatLongitude lon, const FloatLatitude lat)
|
||||
{
|
||||
auto sin_lat = std::sin(static_cast<double>(lat) * M_PI / 180.);
|
||||
auto p2z = std::pow(2, detail::MAX_ZOOM);
|
||||
unsigned x = p2z * (static_cast<double>(lon) / 360. + 0.5);
|
||||
unsigned y = p2z * (0.5 - 0.25 * std::log((1 + sin_lat) / (1 - sin_lat)) / M_PI);
|
||||
|
||||
return Tile{x, y, detail::MAX_ZOOM};
|
||||
}
|
||||
|
||||
inline Tile getBBMaxZoomTile(const FloatLongitude min_lon,
|
||||
const FloatLatitude min_lat,
|
||||
const FloatLongitude max_lon,
|
||||
const FloatLatitude max_lat)
|
||||
{
|
||||
const auto top_left = pointToTile(min_lon, min_lat);
|
||||
const auto bottom_left = pointToTile(max_lon, max_lat);
|
||||
BOOST_ASSERT(top_left.z == detail::MAX_ZOOM);
|
||||
BOOST_ASSERT(bottom_left.z == detail::MAX_ZOOM);
|
||||
|
||||
const auto max_zoom = detail::getBBMaxZoom(top_left, bottom_left);
|
||||
|
||||
if (max_zoom == 0)
|
||||
{
|
||||
return Tile{0, 0, 0};
|
||||
}
|
||||
|
||||
auto x = top_left.x >> (detail::MAX_ZOOM - max_zoom);
|
||||
auto y = top_left.y >> (detail::MAX_ZOOM - max_zoom);
|
||||
|
||||
return Tile{x, y, max_zoom};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,48 @@
|
||||
#ifndef UTIL_VIEWPORT_HPP
|
||||
#define UTIL_VIEWPORT_HPP
|
||||
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/coordinate_calculation.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <cmath>
|
||||
#include <tuple>
|
||||
|
||||
// Port of https://github.com/mapbox/geo-viewport
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
namespace 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 * coordinate_calculation::mercator::TILE_SIZE;
|
||||
static constexpr double VIEWPORT_HEIGHT = 5 * coordinate_calculation::mercator::TILE_SIZE;
|
||||
static double INV_LOG_2 = 1. / std::log(2);
|
||||
}
|
||||
|
||||
unsigned getFittedZoom(util::Coordinate south_west, util::Coordinate north_east)
|
||||
{
|
||||
const auto min_x = coordinate_calculation::mercator::degreeToPixel(toFloating(south_west.lon), detail::MAX_ZOOM);
|
||||
const auto max_y = coordinate_calculation::mercator::degreeToPixel(toFloating(south_west.lat), detail::MAX_ZOOM);
|
||||
const auto max_x = coordinate_calculation::mercator::degreeToPixel(toFloating(north_east.lon), detail::MAX_ZOOM);
|
||||
const auto min_y = coordinate_calculation::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;
|
||||
|
||||
return std::max<unsigned>(detail::MIN_ZOOM, zoom);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user