[test] Added Projection tests

This commit is contained in:
Bruno de Oliveira Abinader
2016-06-10 18:59:04 +03:00
parent 62d355ab15
commit 9b6c2e6940
4 changed files with 80 additions and 5 deletions

View File

@@ -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.

View File

@@ -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);
}

View File

@@ -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
View 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);
}