summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnsis Brammanis <brammanis@gmail.com>2015-08-20 18:50:17 -0400
committerAnsis Brammanis <brammanis@gmail.com>2015-08-24 18:41:51 -0400
commit51c93867aeeb34fd423bd0fb85d2cc06f074b88b (patch)
tree8193ce1ceea089721d8cf8cadf25f14c69743974
parent99c5976498f09ca2dffd46dd6e26d2a26b9efc13 (diff)
downloadqtlocation-mapboxgl-51c93867aeeb34fd423bd0fb85d2cc06f074b88b.tar.gz
fix LatLng --> point for perspective views
-rw-r--r--platform/ios/MGLMapView.mm8
-rw-r--r--src/mbgl/map/map.cpp4
-rw-r--r--src/mbgl/map/source.cpp2
-rw-r--r--src/mbgl/map/transform_state.cpp134
-rw-r--r--src/mbgl/map/transform_state.hpp26
-rw-r--r--src/mbgl/renderer/painter.cpp2
6 files changed, 77 insertions, 99 deletions
diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm
index cdd3044dcf..cdfa779350 100644
--- a/platform/ios/MGLMapView.mm
+++ b/platform/ios/MGLMapView.mm
@@ -1621,10 +1621,6 @@ mbgl::LatLngBounds MGLLatLngBoundsFromCoordinateBounds(MGLCoordinateBounds coord
{
CGPoint convertedPoint = [self convertPoint:point fromView:view];
- // flip y coordinate for iOS view origin top left
- //
- convertedPoint.y = self.bounds.size.height - convertedPoint.y;
-
return MGLLocationCoordinate2DFromLatLng(_mbglMap->latLngForPixel(mbgl::vec2<double>(convertedPoint.x, convertedPoint.y)));
}
@@ -1632,10 +1628,6 @@ mbgl::LatLngBounds MGLLatLngBoundsFromCoordinateBounds(MGLCoordinateBounds coord
{
mbgl::vec2<double> pixel = _mbglMap->pixelForLatLng(MGLLatLngFromLocationCoordinate2D(coordinate));
- // flip y coordinate for iOS view origin in top left
- //
- pixel.y = self.bounds.size.height - pixel.y;
-
return [self convertPoint:CGPointMake(pixel.x, pixel.y) toView:view];
}
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp
index e70972a13f..065c33ce5f 100644
--- a/src/mbgl/map/map.cpp
+++ b/src/mbgl/map/map.cpp
@@ -304,11 +304,11 @@ const LatLng Map::latLngForProjectedMeters(const ProjectedMeters projectedMeters
}
const vec2<double> Map::pixelForLatLng(const LatLng latLng) const {
- return transform->getState().pixelForLatLng(latLng);
+ return transform->getState().latLngToPoint(latLng);
}
const LatLng Map::latLngForPixel(const vec2<double> pixel) const {
- return transform->getState().latLngForPixel(pixel);
+ return transform->getState().pointToLatLng(pixel);
}
#pragma mark - Annotations
diff --git a/src/mbgl/map/source.cpp b/src/mbgl/map/source.cpp
index f60ddce573..9aedf26a65 100644
--- a/src/mbgl/map/source.cpp
+++ b/src/mbgl/map/source.cpp
@@ -333,7 +333,7 @@ std::forward_list<TileID> Source::coveringTiles(const TransformState& state) con
// Map four viewport corners to pixel coordinates
box points = state.cornersToBox(z);
- const TileCoordinate center = state.pointCoordinate({ state.getWidth() / 2.0f, state.getHeight()/ 2.0f }).zoomTo(z);
+ const TileCoordinate center = state.pointToCoordinate({ state.getWidth() / 2.0f, state.getHeight()/ 2.0f }).zoomTo(z);
std::forward_list<TileID> covering_tiles = tileCover(z, points, reparseOverscaled ? actualZ : z);
diff --git a/src/mbgl/map/transform_state.cpp b/src/mbgl/map/transform_state.cpp
index 2f62318281..9e4ea457eb 100644
--- a/src/mbgl/map/transform_state.cpp
+++ b/src/mbgl/map/transform_state.cpp
@@ -1,6 +1,5 @@
#include <mbgl/map/transform_state.hpp>
#include <mbgl/map/tile_id.hpp>
-#include <mbgl/util/projection.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/box.hpp>
#include <mbgl/util/tile_coordinate.hpp>
@@ -46,10 +45,10 @@ box TransformState::cornersToBox(uint32_t z) const {
double w = width;
double h = height;
box b(
- pointCoordinate({ 0, 0 }).zoomTo(z),
- pointCoordinate({ w, 0 }).zoomTo(z),
- pointCoordinate({ w, h }).zoomTo(z),
- pointCoordinate({ 0, h }).zoomTo(z));
+ pointToCoordinate({ 0, 0 }).zoomTo(z),
+ pointToCoordinate({ w, 0 }).zoomTo(z),
+ pointToCoordinate({ w, h }).zoomTo(z),
+ pointToCoordinate({ 0, h }).zoomTo(z));
return b;
}
@@ -158,94 +157,73 @@ float TransformState::getPitch() const {
#pragma mark - Projection
-const vec2<double> TransformState::pixelForLatLng(const LatLng latLng) const {
- LatLng ll = getLatLng();
- double zoom = getZoom();
-
- const double centerX = static_cast<double>(width) / 2.0;
- const double centerY = static_cast<double>(height) / 2.0;
-
- const double m = Projection::getMetersPerPixelAtLatitude(0, zoom);
-
- const double angle_sin = std::sin(-angle);
- const double angle_cos = std::cos(-angle);
-
- const ProjectedMeters givenMeters = Projection::projectedMetersForLatLng(latLng);
-
- const double givenAbsoluteX = givenMeters.easting / m;
- const double givenAbsoluteY = givenMeters.northing / m;
-
- const ProjectedMeters centerMeters = Projection::projectedMetersForLatLng(ll);
-
- const double centerAbsoluteX = centerMeters.easting / m;
- const double centerAbsoluteY = centerMeters.northing / m;
-
- const double deltaX = givenAbsoluteX - centerAbsoluteX;
- const double deltaY = givenAbsoluteY - centerAbsoluteY;
-
- const double translatedX = deltaX + centerX;
- const double translatedY = deltaY + centerY;
-
- const double rotatedX = translatedX * angle_cos - translatedY * angle_sin;
- const double rotatedY = translatedX * angle_sin + translatedY * angle_cos;
-
- const double rotatedCenterX = centerX * angle_cos - centerY * angle_sin;
- const double rotatedCenterY = centerX * angle_sin + centerY * angle_cos;
-
- double x_ = rotatedX + (centerX - rotatedCenterX);
- double y_ = rotatedY + (centerY - rotatedCenterY);
-
- return vec2<double>(x_, y_);
+float TransformState::lngX(float lng) const {
+ return (180.0f + lng) * worldSize() / 360.0f;
}
-const LatLng TransformState::latLngForPixel(const vec2<double> pixel) const {
- LatLng ll = getLatLng();
- double zoom = getZoom();
-
- const double centerX = static_cast<double>(width) / 2.0;
- const double centerY = static_cast<double>(height) / 2.0;
-
- const double m = Projection::getMetersPerPixelAtLatitude(0, zoom);
-
- const double angle_sin = std::sin(angle);
- const double angle_cos = std::cos(angle);
-
- const double unrotatedCenterX = centerX * angle_cos - centerY * angle_sin;
- const double unrotatedCenterY = centerX * angle_sin + centerY * angle_cos;
+float TransformState::latY(float lat) const {
+ float y_ = 180.0f / M_PI * std::log(std::tan(M_PI / 4 + lat * M_PI / 360.0f));
+ return (180.0f - y_) * worldSize() / 360.0f;
+}
- const double unrotatedX = pixel.x * angle_cos - pixel.y * angle_sin;
- const double unrotatedY = pixel.x * angle_sin + pixel.y * angle_cos;
+float TransformState::xLng(float x_, float worldSize_) const {
+ return x_ * 360.0f / worldSize_ - 180.0f;
+}
- const double givenX = unrotatedX + (centerX - unrotatedCenterX);
- const double givenY = unrotatedY + (centerY - unrotatedCenterY);
+float TransformState::yLat(float y_, float worldSize_) const {
+ float y2 = 180.0f - y_ * 360.0f / worldSize_;
+ return 360.0f / M_PI * std::atan(std::exp(y2 * M_PI / 180.0f)) - 90.0f;
+}
- const ProjectedMeters centerMeters = Projection::projectedMetersForLatLng(ll);
+float TransformState::zoomScale(float zoom) const {
+ return std::pow(2.0f, zoom);
+}
- const double centerAbsoluteX = centerMeters.easting / m;
- const double centerAbsoluteY = centerMeters.northing / m;
+float TransformState::worldSize() const {
+ return util::tileSize * scale;
+}
- const double givenAbsoluteX = givenX + centerAbsoluteX - centerX;
- const double givenAbsoluteY = givenY + centerAbsoluteY - centerY;
+vec2<double> TransformState::latLngToPoint(const LatLng& latLng) const {
+ return coordinateToPoint(latLngToCoordinate(latLng));
+}
- ProjectedMeters givenMeters = ProjectedMeters(givenAbsoluteY * m, givenAbsoluteX * m);
+LatLng TransformState::pointToLatLng(const vec2<double> point) const {
+ return coordinateToLatLng(pointToCoordinate(point));
+}
- // adjust for date line
- ProjectedMeters sw, ne;
- Projection::getWorldBoundsMeters(sw, ne);
- double d = ne.easting - sw.easting;
- if (ll.longitude > 0 && givenMeters.easting > centerMeters.easting) givenMeters.easting -= d;
+TileCoordinate TransformState::latLngToCoordinate(const LatLng& latLng) const {
+ const float tileZoom = getIntegerZoom();
+ const float k = zoomScale(tileZoom) / worldSize();
+ return {
+ lngX(latLng.longitude) * k,
+ latY(latLng.latitude) * k,
+ tileZoom
+ };
+}
- // adjust for world wrap
- while (givenMeters.easting < sw.easting) givenMeters.easting += d;
- while (givenMeters.easting > ne.easting) givenMeters.easting -= d;
+LatLng TransformState::coordinateToLatLng(const TileCoordinate& coord) const {
+ const float worldSize_ = zoomScale(coord.zoom);
+ LatLng latLng = {
+ yLat(coord.row, worldSize_),
+ xLng(coord.column, worldSize_)
+ };
+ while (latLng.longitude < 180.0f) latLng.longitude += 360.0f;
+ while (latLng.longitude > 180.0f) latLng.longitude -= 360.0f;
+ return latLng;
+}
- return Projection::latLngForProjectedMeters(givenMeters);
+vec2<double> TransformState::coordinateToPoint(const TileCoordinate& coord) const {
+ mat4 mat = coordinatePointMatrix(coord.zoom);
+ matrix::vec4 p;
+ matrix::vec4 c = {{ coord.column, coord.row, 0, 1 }};
+ matrix::transformMat4(p, c, mat);
+ return { p[0] / p[3], p[1] / p[3] };
}
-TileCoordinate TransformState::pointCoordinate(const vec2<double> point) const {
+TileCoordinate TransformState::pointToCoordinate(const vec2<double> point) const {
float targetZ = 0;
- float tileZoom = std::floor(getZoom());
+ const float tileZoom = getIntegerZoom();
mat4 mat = coordinatePointMatrix(tileZoom);
diff --git a/src/mbgl/map/transform_state.hpp b/src/mbgl/map/transform_state.hpp
index 521131b33a..d4b46f04b1 100644
--- a/src/mbgl/map/transform_state.hpp
+++ b/src/mbgl/map/transform_state.hpp
@@ -31,9 +31,6 @@ public:
uint16_t getWidth() const;
uint16_t getHeight() const;
- float worldSize() const;
- float lngX(float lon) const;
- float latY(float lat) const;
std::array<float, 2> locationCoordinate(float lon, float lat) const;
void getLonLat(double &lon, double &lat) const;
@@ -55,18 +52,22 @@ public:
float getAltitude() const;
float getPitch() const;
- // Projection
- const vec2<double> pixelForLatLng(const LatLng latLng) const;
- const LatLng latLngForPixel(const vec2<double> pixel) const;
-
// Changing
bool isChanging() const;
double pixel_x() const;
double pixel_y() const;
- // Conversions
- TileCoordinate pointCoordinate(const vec2<double> point) const;
+ // Conversion and projection
+
+ vec2<double> latLngToPoint(const LatLng& latLng) const;
+ LatLng pointToLatLng(const vec2<double> point) const;
+
+ TileCoordinate latLngToCoordinate(const LatLng& latLng) const;
+ LatLng coordinateToLatLng(const TileCoordinate& coord) const;
+
+ vec2<double> coordinateToPoint(const TileCoordinate& coord) const;
+ TileCoordinate pointToCoordinate(const vec2<double> point) const;
private:
void constrain(double& scale, double& y) const;
@@ -78,6 +79,13 @@ private:
// logical dimensions
uint16_t width = 0, height = 0;
+ float xLng(float x, float worldSize) const;
+ float yLat(float y, float worldSize) const;
+ float lngX(float lon) const;
+ float latY(float lat) const;
+ float zoomScale(float zoom) const;
+ float worldSize() const;
+
mat4 coordinatePointMatrix(float z) const;
mat4 getPixelMatrix() const;
diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp
index 6b78ca40d3..9ea75efb88 100644
--- a/src/mbgl/renderer/painter.cpp
+++ b/src/mbgl/renderer/painter.cpp
@@ -379,7 +379,7 @@ void Painter::renderBackground(const StyleLayer &layer_desc) {
patternShader->u_opacity = properties.opacity;
LatLng latLng = state.getLatLng();
- vec2<double> center = state.pixelForLatLng(latLng);
+ vec2<double> center = state.latLngToPoint(latLng);
float scale = 1 / std::pow(2, zoomFraction);
std::array<float, 2> sizeA = imagePosA.size;