[test] Added Projection tests
This commit is contained in:
@@ -67,8 +67,8 @@ inline bool operator!=(const LatLng& a, const LatLng& b) {
|
||||
|
||||
class ProjectedMeters {
|
||||
public:
|
||||
double northing = 0;
|
||||
double easting = 0;
|
||||
double northing;
|
||||
double easting;
|
||||
|
||||
ProjectedMeters(double n = 0, double e = 0)
|
||||
: northing(n), easting(e) {}
|
||||
@@ -78,6 +78,10 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
inline bool operator==(const ProjectedMeters& a, const ProjectedMeters& b) {
|
||||
return a.northing == b.northing && a.easting == b.easting;
|
||||
}
|
||||
|
||||
class LatLngBounds {
|
||||
public:
|
||||
// Return a bounds covering the entire (unwrapped) world.
|
||||
|
||||
@@ -12,19 +12,20 @@ class Projection {
|
||||
|
||||
public:
|
||||
static inline double getMetersPerPixelAtLatitude(double lat, double zoom) {
|
||||
const double mapPixelWidthAtZoom = std::pow(2.0, zoom) * util::tileSize;
|
||||
const double constrainedZoom = util::clamp(zoom, util::MIN_ZOOM, util::MAX_ZOOM);
|
||||
const double mapPixelWidthAtZoom = std::pow(2.0, constrainedZoom) * util::tileSize;
|
||||
const double constrainedLatitude = util::clamp(lat, -util::LATITUDE_MAX, util::LATITUDE_MAX);
|
||||
|
||||
return std::cos(constrainedLatitude * util::DEG2RAD) * util::M2PI * util::EARTH_RADIUS_M / mapPixelWidthAtZoom;
|
||||
}
|
||||
|
||||
static inline ProjectedMeters projectedMetersForLatLng(const LatLng& latLng) {
|
||||
const double constrainedLatitude = util::clamp(latLng.latitude, -util::LATITUDE_MAX, util::LATITUDE_MAX);
|
||||
const double constrainedLongitude = util::clamp(latLng.longitude, -util::LONGITUDE_MAX, util::LONGITUDE_MAX);
|
||||
|
||||
const double m = 1 - 1e-15;
|
||||
const double f = util::clamp(std::sin(util::DEG2RAD * constrainedLatitude), -m, m);
|
||||
|
||||
const double easting = util::EARTH_RADIUS_M * latLng.longitude * util::DEG2RAD;
|
||||
const double easting = util::EARTH_RADIUS_M * constrainedLongitude * util::DEG2RAD;
|
||||
const double northing = 0.5 * util::EARTH_RADIUS_M * std::log((1 + f) / (1 - f));
|
||||
|
||||
return ProjectedMeters(northing, easting);
|
||||
@@ -35,6 +36,7 @@ public:
|
||||
double longitude = projectedMeters.easting * util::RAD2DEG / util::EARTH_RADIUS_M;
|
||||
|
||||
latitude = util::clamp(latitude, -util::LATITUDE_MAX, util::LATITUDE_MAX);
|
||||
longitude = util::clamp(longitude, -util::LONGITUDE_MAX, util::LONGITUDE_MAX);
|
||||
|
||||
return LatLng(latitude, longitude);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
'util/timer.cpp',
|
||||
'util/token.cpp',
|
||||
'util/work_queue.cpp',
|
||||
'util/projection.cpp',
|
||||
|
||||
'algorithm/covered_by_children.cpp',
|
||||
'algorithm/generate_clip_ids.cpp',
|
||||
|
||||
68
test/util/projection.cpp
Normal file
68
test/util/projection.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
#include <mbgl/test/util.hpp>
|
||||
|
||||
#include <mbgl/util/constants.hpp>
|
||||
#include <mbgl/util/geo.hpp>
|
||||
#include <mbgl/util/projection.hpp>
|
||||
|
||||
#include <limits>
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
TEST(Projection, MetersPerPixelAtLatitude) {
|
||||
double zoom = 0;
|
||||
EXPECT_DOUBLE_EQ(Projection::getMetersPerPixelAtLatitude(0, zoom), 78271.516964020484);
|
||||
EXPECT_DOUBLE_EQ(Projection::getMetersPerPixelAtLatitude(-util::LATITUDE_MAX, zoom), 6752.2284729446501);
|
||||
EXPECT_DOUBLE_EQ(Projection::getMetersPerPixelAtLatitude(util::LATITUDE_MAX, zoom),
|
||||
Projection::getMetersPerPixelAtLatitude(-util::LATITUDE_MAX, zoom));
|
||||
|
||||
zoom = 20;
|
||||
EXPECT_DOUBLE_EQ(Projection::getMetersPerPixelAtLatitude(0, zoom), 0.074645535434742435);
|
||||
EXPECT_DOUBLE_EQ(Projection::getMetersPerPixelAtLatitude(-util::LATITUDE_MAX, zoom), 0.0064394268731543065);
|
||||
|
||||
EXPECT_DOUBLE_EQ(Projection::getMetersPerPixelAtLatitude(std::numeric_limits<double>::lowest(), zoom),
|
||||
Projection::getMetersPerPixelAtLatitude(std::numeric_limits<double>::max(), zoom));
|
||||
|
||||
zoom = std::numeric_limits<double>::min();
|
||||
EXPECT_DOUBLE_EQ(Projection::getMetersPerPixelAtLatitude(0, zoom),
|
||||
Projection::getMetersPerPixelAtLatitude(0, util::MIN_ZOOM));
|
||||
|
||||
zoom = std::numeric_limits<double>::lowest();
|
||||
EXPECT_DOUBLE_EQ(Projection::getMetersPerPixelAtLatitude(0, zoom),
|
||||
Projection::getMetersPerPixelAtLatitude(0, util::MIN_ZOOM));
|
||||
|
||||
zoom = std::numeric_limits<double>::max();
|
||||
EXPECT_DOUBLE_EQ(Projection::getMetersPerPixelAtLatitude(0, zoom),
|
||||
Projection::getMetersPerPixelAtLatitude(0, util::MAX_ZOOM));
|
||||
}
|
||||
|
||||
TEST(Projection, ProjectedMeters) {
|
||||
const auto southWest = LatLng { -util::LATITUDE_MAX, -util::LONGITUDE_MAX };
|
||||
const auto northEast = LatLng { util::LATITUDE_MAX, util::LONGITUDE_MAX };
|
||||
|
||||
auto latLng = LatLng {};
|
||||
auto projectedMeters = Projection::projectedMetersForLatLng(latLng);
|
||||
EXPECT_EQ(projectedMeters.northing, projectedMeters.easting);
|
||||
EXPECT_EQ(latLng, Projection::latLngForProjectedMeters(projectedMeters));
|
||||
|
||||
latLng = LatLng { std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest() };
|
||||
projectedMeters = Projection::projectedMetersForLatLng(latLng);
|
||||
EXPECT_EQ(projectedMeters, Projection::projectedMetersForLatLng(southWest));
|
||||
EXPECT_DOUBLE_EQ(projectedMeters.northing, -20037508.342789274);
|
||||
EXPECT_DOUBLE_EQ(projectedMeters.easting, -20037508.342789244);
|
||||
|
||||
latLng = LatLng { std::numeric_limits<double>::max(), std::numeric_limits<double>::max() };
|
||||
projectedMeters = Projection::projectedMetersForLatLng(latLng);
|
||||
EXPECT_EQ(projectedMeters, Projection::projectedMetersForLatLng(northEast));
|
||||
EXPECT_DOUBLE_EQ(projectedMeters.northing, -Projection::projectedMetersForLatLng(southWest).northing);
|
||||
EXPECT_DOUBLE_EQ(projectedMeters.easting, -Projection::projectedMetersForLatLng(southWest).easting);
|
||||
|
||||
projectedMeters = ProjectedMeters { std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest() };
|
||||
latLng = Projection::latLngForProjectedMeters(projectedMeters);
|
||||
EXPECT_EQ(latLng.latitude, -util::LATITUDE_MAX);
|
||||
EXPECT_EQ(latLng.longitude, -util::LONGITUDE_MAX);
|
||||
|
||||
projectedMeters = ProjectedMeters { std::numeric_limits<double>::max(), std::numeric_limits<double>::max() };
|
||||
latLng = Projection::latLngForProjectedMeters(projectedMeters);
|
||||
EXPECT_EQ(latLng.latitude, util::LATITUDE_MAX);
|
||||
EXPECT_EQ(latLng.longitude, util::LONGITUDE_MAX);
|
||||
}
|
||||
Reference in New Issue
Block a user