summaryrefslogtreecommitdiff
path: root/include/mbgl/util/projection.hpp
diff options
context:
space:
mode:
authorJustin R. Miller <incanus@codesorcery.net>2015-02-16 09:52:36 -0800
committerJustin R. Miller <incanus@codesorcery.net>2015-02-16 09:52:36 -0800
commit6e41664cb033ee5edf6ae5ac66ed518d9f0d1f89 (patch)
treea70192b174ea6dc69b1fa0b13f9a33358a9110e5 /include/mbgl/util/projection.hpp
parentea31ad99a56f1e0afbcc7862ddc62dffd16bc5bb (diff)
downloadqtlocation-mapboxgl-6e41664cb033ee5edf6ae5ac66ed518d9f0d1f89.tar.gz
fixes #476 & #853: pixel/meter/latlng conversion routines in core & iOS
Diffstat (limited to 'include/mbgl/util/projection.hpp')
-rw-r--r--include/mbgl/util/projection.hpp65
1 files changed, 65 insertions, 0 deletions
diff --git a/include/mbgl/util/projection.hpp b/include/mbgl/util/projection.hpp
new file mode 100644
index 0000000000..f301d93005
--- /dev/null
+++ b/include/mbgl/util/projection.hpp
@@ -0,0 +1,65 @@
+#ifndef MBGL_UTIL_PROJECTION
+#define MBGL_UTIL_PROJECTION
+
+#include <mbgl/util/constants.hpp>
+#include <mbgl/util/geo.hpp>
+
+#include <cmath>
+
+namespace mbgl {
+
+class Projection {
+
+public:
+ static inline void getWorldBoundsMeters(ProjectedMeters &sw, ProjectedMeters &ne) {
+ const double d = util::EARTH_RADIUS_M * M_PI;
+
+ sw.easting = -d;
+ sw.northing = -d;
+
+ ne.easting = d;
+ ne.northing = d;
+ }
+
+ static inline void getWorldBoundsLatLng(LatLng &sw, LatLng &ne) {
+ ProjectedMeters projectedMetersSW = ProjectedMeters();
+ ProjectedMeters projectedMetersNE = ProjectedMeters();
+
+ getWorldBoundsMeters(projectedMetersSW, projectedMetersNE);
+
+ sw = latLngForProjectedMeters(projectedMetersSW);
+ ne = latLngForProjectedMeters(projectedMetersNE);
+ }
+
+ static inline double getMetersPerPixelAtLatitude(const double lat, const double zoom) {
+ const double mapPixelWidthAtZoom = std::pow(2.0, zoom) * util::tileSize;
+ const double constrainedLatitude = std::fmin(std::fmax(lat, -util::LATITUDE_MAX), util::LATITUDE_MAX);
+
+ return std::cos(constrainedLatitude * util::DEG2RAD) * util::M2PI * util::EARTH_RADIUS_M / mapPixelWidthAtZoom;
+ }
+
+ static inline const ProjectedMeters projectedMetersForLatLng(const LatLng latLng) {
+ const double constrainedLatitude = std::fmin(std::fmax(latLng.latitude, -util::LATITUDE_MAX), util::LATITUDE_MAX);
+
+ const double m = 1 - 1e-15;
+ const double f = std::fmin(std::fmax(std::sin(util::DEG2RAD * constrainedLatitude), -m), m);
+
+ const double easting = util::EARTH_RADIUS_M * latLng.longitude * util::DEG2RAD;
+ const double northing = 0.5 * util::EARTH_RADIUS_M * std::log((1 + f) / (1 - f));
+
+ return ProjectedMeters(northing, easting);
+ }
+
+ static inline const LatLng latLngForProjectedMeters(const ProjectedMeters projectedMeters) {
+ double latitude = (2 * std::atan(std::exp(projectedMeters.northing / util::EARTH_RADIUS_M)) - (M_PI / 2)) * util::RAD2DEG;
+ double longitude = projectedMeters.easting * util::RAD2DEG / util::EARTH_RADIUS_M;
+
+ latitude = std::fmin(std::fmax(latitude, -util::LATITUDE_MAX), util::LATITUDE_MAX);
+
+ return LatLng(latitude, longitude);
+ }
+};
+
+}
+
+#endif