summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2016-05-12 12:38:12 -0700
committerJohn Firebaugh <john.firebaugh@gmail.com>2016-05-17 13:20:25 -0700
commit7e5d0ff49e2b5a6a3caa45464d8056e93431d780 (patch)
tree665519111b6877ccab34d02831dc66d09b4e75ac /src
parent3e21e3887aa08ea32e4370b8c6e990d9f8c4333f (diff)
downloadqtlocation-mapboxgl-7e5d0ff49e2b5a6a3caa45464d8056e93431d780.tar.gz
[core] Rewrite TileCoordinate in terms of geometry.hpp point
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/map/transform.cpp36
-rw-r--r--src/mbgl/map/transform_state.cpp65
-rw-r--r--src/mbgl/map/transform_state.hpp7
-rw-r--r--src/mbgl/source/source.cpp16
-rw-r--r--src/mbgl/util/tile_coordinate.hpp22
-rw-r--r--src/mbgl/util/tile_cover.cpp39
6 files changed, 70 insertions, 115 deletions
diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp
index 958f9d9b63..4a40e13202 100644
--- a/src/mbgl/map/transform.cpp
+++ b/src/mbgl/map/transform.cpp
@@ -109,14 +109,9 @@ void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& anim
// Find the shortest path otherwise.
else startLatLng.unwrapForShortestPath(latLng);
- const ScreenCoordinate startPoint = {
- state.lngX(startLatLng.longitude),
- state.latY(startLatLng.latitude),
- };
- const ScreenCoordinate endPoint = {
- state.lngX(latLng.longitude),
- state.latY(latLng.latitude),
- };
+ const Point<double> startPoint = state.project(startLatLng);
+ const Point<double> endPoint = state.project(latLng);
+
ScreenCoordinate center = getScreenCoordinate(padding);
center.y = state.height - center.y;
@@ -145,11 +140,8 @@ void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& anim
state.rotating = angle != startAngle;
startTransition(camera, animation, [=](double t) {
- ScreenCoordinate framePoint = util::interpolate(startPoint, endPoint, t);
- LatLng frameLatLng = {
- state.yLat(framePoint.y, startWorldSize),
- state.xLng(framePoint.x, startWorldSize)
- };
+ Point<double> framePoint = util::interpolate(startPoint, endPoint, t);
+ LatLng frameLatLng = state.unproject(framePoint, startWorldSize);
double frameScale = util::interpolate(startScale, scale, t);
state.setLatLngZoom(frameLatLng, state.scaleZoom(frameScale));
@@ -191,14 +183,9 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima
LatLng startLatLng = getLatLng(padding).wrapped();
startLatLng.unwrapForShortestPath(latLng);
- const ScreenCoordinate startPoint = {
- state.lngX(startLatLng.longitude),
- state.latY(startLatLng.latitude),
- };
- const ScreenCoordinate endPoint = {
- state.lngX(latLng.longitude),
- state.latY(latLng.latitude),
- };
+ const Point<double> startPoint = state.project(startLatLng);
+ const Point<double> endPoint = state.project(latLng);
+
ScreenCoordinate center = getScreenCoordinate(padding);
center.y = state.height - center.y;
@@ -316,14 +303,11 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima
double us = u(s);
// Calculate the current point and zoom level along the flight path.
- ScreenCoordinate framePoint = util::interpolate(startPoint, endPoint, us);
+ Point<double> framePoint = util::interpolate(startPoint, endPoint, us);
double frameZoom = startZoom + state.scaleZoom(1 / w(s));
// Convert to geographic coordinates and set the new viewpoint.
- LatLng frameLatLng = {
- state.yLat(framePoint.y, startWorldSize),
- state.xLng(framePoint.x, startWorldSize),
- };
+ LatLng frameLatLng = state.unproject(framePoint, startWorldSize);
state.setLatLngZoom(frameLatLng, frameZoom);
if (angle != startAngle) {
diff --git a/src/mbgl/map/transform_state.cpp b/src/mbgl/map/transform_state.cpp
index 0b8d831e54..ad41c9eea2 100644
--- a/src/mbgl/map/transform_state.cpp
+++ b/src/mbgl/map/transform_state.cpp
@@ -201,22 +201,20 @@ bool TransformState::isGestureInProgress() const {
#pragma mark - Projection
-double TransformState::lngX(double lng) const {
- return (util::LONGITUDE_MAX + lng) * worldSize() / util::DEGREES_MAX;
-}
-
-double TransformState::latY(double lat) const {
- double y_ = util::RAD2DEG * std::log(std::tan(M_PI / 4 + lat * M_PI / util::DEGREES_MAX));
- return (util::LONGITUDE_MAX - y_) * worldSize() / util::DEGREES_MAX;
-}
-
-double TransformState::xLng(double x_, double worldSize_) const {
- return x_ * util::DEGREES_MAX / worldSize_ - util::LONGITUDE_MAX;
-}
-
-double TransformState::yLat(double y_, double worldSize_) const {
- double y2 = util::LONGITUDE_MAX - y_ * util::DEGREES_MAX / worldSize_;
- return util::DEGREES_MAX / M_PI * std::atan(std::exp(y2 * util::DEG2RAD)) - 90.0f;
+Point<double> TransformState::project(const LatLng& ll) const {
+ return Point<double>(
+ (util::LONGITUDE_MAX + ll.longitude),
+ (util::LONGITUDE_MAX - util::RAD2DEG * std::log(std::tan(M_PI / 4 + ll.latitude * M_PI / util::DEGREES_MAX)))
+ ) * worldSize() / util::DEGREES_MAX;
+}
+
+LatLng TransformState::unproject(const Point<double>& p, double worldSize, LatLng::WrapMode wrapMode) const {
+ Point<double> p2 = p * util::DEGREES_MAX / worldSize;
+ return LatLng(
+ util::DEGREES_MAX / M_PI * std::atan(std::exp((util::LONGITUDE_MAX - p2.y) * util::DEG2RAD)) - 90.0f,
+ p2.x - util::LONGITUDE_MAX,
+ wrapMode
+ );
}
double TransformState::zoomScale(double zoom) const {
@@ -234,7 +232,8 @@ double TransformState::worldSize() const {
ScreenCoordinate TransformState::latLngToScreenCoordinate(const LatLng& latLng) const {
mat4 mat = coordinatePointMatrix(getZoom());
vec4 p;
- vec4 c = {{ lngX(latLng.longitude) / util::tileSize, latY(latLng.latitude) / util::tileSize, 0, 1 }};
+ Point<double> pt = project(latLng) / double(util::tileSize);
+ vec4 c = {{ pt.x, pt.y, 0, 1 }};
matrix::transformMat4(p, c, mat);
return { p[0] / p[3], height - p[1] / p[3] };
}
@@ -263,19 +262,15 @@ LatLng TransformState::screenCoordinateToLatLng(const ScreenCoordinate& point, L
double w0 = coord0[3];
double w1 = coord1[3];
- double x0 = coord0[0] / w0;
- double x1 = coord1[0] / w1;
- double y0 = coord0[1] / w0;
- double y1 = coord1[1] / w1;
+
+ Point<double> p0 = Point<double>(coord0[0], coord0[1]) / w0;
+ Point<double> p1 = Point<double>(coord1[0], coord1[1]) / w1;
+
double z0 = coord0[2] / w0;
double z1 = coord1[2] / w1;
-
double t = z0 == z1 ? 0 : (targetZ - z0) / (z1 - z0);
- return {
- yLat(util::interpolate(y0, y1, t), scale),
- xLng(util::interpolate(x0, x1, t), scale),
- wrapMode
- };
+
+ return unproject(util::interpolate(p0, p1, t), scale, wrapMode);
}
mat4 TransformState::coordinatePointMatrix(double z) const {
@@ -322,18 +317,10 @@ void TransformState::constrain(double& scale_, double& x_, double& y_) const {
}
void TransformState::moveLatLng(const LatLng& latLng, const ScreenCoordinate& anchor) {
- auto latLngToTileCoord = [&](const LatLng& ll) -> Point<double> {
- return { lngX(ll.longitude), latY(ll.latitude) };
- };
-
- auto tileCoordToLatLng = [&](const Point<double> coord) -> LatLng {
- return { yLat(coord.y, worldSize()), xLng(coord.x, worldSize()) };
- };
-
- auto centerCoord = latLngToTileCoord(getLatLng(LatLng::Unwrapped));
- auto latLngCoord = latLngToTileCoord(latLng);
- auto anchorCoord = latLngToTileCoord(screenCoordinateToLatLng(anchor));
- setLatLngZoom(tileCoordToLatLng(centerCoord + latLngCoord - anchorCoord), getZoom());
+ auto centerCoord = project(getLatLng(LatLng::Unwrapped));
+ auto latLngCoord = project(latLng);
+ auto anchorCoord = project(screenCoordinateToLatLng(anchor));
+ setLatLngZoom(unproject(centerCoord + latLngCoord - anchorCoord, worldSize()), getZoom());
}
void TransformState::setLatLngZoom(const LatLng &latLng, double zoom) {
diff --git a/src/mbgl/map/transform_state.hpp b/src/mbgl/map/transform_state.hpp
index 970dda2613..438094a4c5 100644
--- a/src/mbgl/map/transform_state.hpp
+++ b/src/mbgl/map/transform_state.hpp
@@ -3,6 +3,7 @@
#include <mbgl/map/mode.hpp>
#include <mbgl/util/geo.hpp>
+#include <mbgl/util/geometry.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/mat4.hpp>
@@ -69,10 +70,8 @@ public:
ScreenCoordinate latLngToScreenCoordinate(const LatLng&) const;
LatLng screenCoordinateToLatLng(const ScreenCoordinate&, LatLng::WrapMode = LatLng::Unwrapped) const;
- double xLng(double x, double worldSize) const;
- double yLat(double y, double worldSize) const;
- double lngX(double lon) const;
- double latY(double lat) const;
+ Point<double> project(const LatLng&) const;
+ LatLng unproject(const Point<double>&, double worldSize, LatLng::WrapMode = LatLng::Unwrapped) const;
private:
bool rotatedNorth() const;
diff --git a/src/mbgl/source/source.cpp b/src/mbgl/source/source.cpp
index 1173de3f88..285b79127c 100644
--- a/src/mbgl/source/source.cpp
+++ b/src/mbgl/source/source.cpp
@@ -335,10 +335,10 @@ std::vector<TileCoordinate> pointsToCoordinates(const std::vector<ScreenCoordina
static Point<int16_t> coordinateToTilePoint(const CanonicalTileID& tileID, const TileCoordinate& coord) {
auto zoomedCoord = coord.zoomTo(tileID.z);
return {
- int16_t(util::clamp<int64_t>((zoomedCoord.x - tileID.x) * util::EXTENT,
+ int16_t(util::clamp<int64_t>((zoomedCoord.p.x - tileID.x) * util::EXTENT,
std::numeric_limits<int16_t>::min(),
std::numeric_limits<int16_t>::max())),
- int16_t(util::clamp<int64_t>((zoomedCoord.y - tileID.y) * util::EXTENT,
+ int16_t(util::clamp<int64_t>((zoomedCoord.p.y - tileID.y) * util::EXTENT,
std::numeric_limits<int16_t>::min(),
std::numeric_limits<int16_t>::max()))
};
@@ -364,10 +364,10 @@ std::unordered_map<std::string, std::vector<Feature>> Source::queryRenderedFeatu
double z = queryGeometry[0].z;
for (const auto& c : queryGeometry) {
- minX = util::min(minX, c.x);
- minY = util::min(minY, c.y);
- maxX = util::max(maxX, c.x);
- maxY = util::max(maxY, c.y);
+ minX = util::min(minX, c.p.x);
+ minY = util::min(minY, c.p.y);
+ maxX = util::max(maxX, c.p.x);
+ maxY = util::max(maxY, c.p.y);
}
std::map<CanonicalTileID, TileQuery> tileQueries;
@@ -375,8 +375,8 @@ std::unordered_map<std::string, std::vector<Feature>> Source::queryRenderedFeatu
for (const auto& tilePtr : tiles) {
const auto& tile = tilePtr.second;
- auto tileSpaceBoundsMin = coordinateToTilePoint(tile.id.canonical, { minX, minY, z });
- auto tileSpaceBoundsMax = coordinateToTilePoint(tile.id.canonical, { maxX, maxY, z });
+ auto tileSpaceBoundsMin = coordinateToTilePoint(tile.id.canonical, { { minX, minY }, z });
+ auto tileSpaceBoundsMax = coordinateToTilePoint(tile.id.canonical, { { maxX, maxY }, z });
if (tileSpaceBoundsMin.x >= util::EXTENT || tileSpaceBoundsMin.y >= util::EXTENT ||
tileSpaceBoundsMax.x < 0 || tileSpaceBoundsMax.y < 0) continue;
diff --git a/src/mbgl/util/tile_coordinate.hpp b/src/mbgl/util/tile_coordinate.hpp
index 9962c35b18..df240a50e0 100644
--- a/src/mbgl/util/tile_coordinate.hpp
+++ b/src/mbgl/util/tile_coordinate.hpp
@@ -1,27 +1,20 @@
-#ifndef MBGL_UTIL_TILE_COORDINATE
-#define MBGL_UTIL_TILE_COORDINATE
+#pragma once
-#include <mbgl/style/types.hpp>
+#include <mbgl/util/geometry.hpp>
#include <mbgl/map/transform_state.hpp>
-
namespace mbgl {
-class TransformState;
-
// Has floating point x/y coordinates.
// Used for computing the tiles that need to be visible in the viewport.
class TileCoordinate {
public:
- double x, y, z;
+ Point<double> p;
+ double z;
static TileCoordinate fromLatLng(const TransformState& state, double zoom, const LatLng& latLng) {
const double scale = std::pow(2, zoom - state.getZoom());
- return {
- state.lngX(latLng.longitude) * scale / util::tileSize,
- state.latY(latLng.latitude) * scale / util::tileSize,
- zoom
- };
+ return { state.project(latLng) * scale / double(util::tileSize), zoom };
}
static TileCoordinate fromScreenCoordinate(const TransformState& state, double zoom, const ScreenCoordinate& point) {
@@ -29,11 +22,8 @@ public:
}
TileCoordinate zoomTo(double zoom) const {
- double scale = std::pow(2, zoom - z);
- return { x * scale, y * scale, zoom };
+ return { p * std::pow(2, zoom - z), zoom };
}
};
} // namespace mbgl
-
-#endif
diff --git a/src/mbgl/util/tile_cover.cpp b/src/mbgl/util/tile_cover.cpp
index 739528a8b8..5487fb269c 100644
--- a/src/mbgl/util/tile_cover.cpp
+++ b/src/mbgl/util/tile_cover.cpp
@@ -16,7 +16,7 @@ struct edge {
double x1 = 0, y1 = 0;
double dx = 0, dy = 0;
- edge(TileCoordinate a, TileCoordinate b) {
+ edge(Point<double> a, Point<double> b) {
if (a.y > b.y) std::swap(a, b);
x0 = a.x;
y0 = a.y;
@@ -54,7 +54,7 @@ static void scanSpans(edge e0, edge e1, int32_t ymin, int32_t ymax, ScanLine sca
}
// scan-line conversion
-static void scanTriangle(const TileCoordinate& a, const TileCoordinate& b, const TileCoordinate& c, int32_t ymin, int32_t ymax, ScanLine& scanLine) {
+static void scanTriangle(const Point<double>& a, const Point<double>& b, const Point<double>& c, int32_t ymin, int32_t ymax, ScanLine& scanLine) {
edge ab = edge(a, b);
edge bc = edge(b, c);
edge ca = edge(c, a);
@@ -75,17 +75,12 @@ namespace util {
namespace {
-std::vector<UnwrappedTileID> tileCover(const TileCoordinate& tl,
- const TileCoordinate& tr,
- const TileCoordinate& br,
- const TileCoordinate& bl,
- const TileCoordinate& c,
+std::vector<UnwrappedTileID> tileCover(const Point<double>& tl,
+ const Point<double>& tr,
+ const Point<double>& br,
+ const Point<double>& bl,
+ const Point<double>& c,
int32_t z) {
- assert(tl.z == z);
- assert(tr.z == z);
- assert(br.z == z);
- assert(bl.z == z);
- assert(c.z == z);
const int32_t tiles = 1 << z;
struct ID {
@@ -154,11 +149,11 @@ std::vector<UnwrappedTileID> tileCover(const LatLngBounds& bounds_, int32_t z) {
const TransformState state;
return tileCover(
- TileCoordinate::fromLatLng(state, z, bounds.northwest()),
- TileCoordinate::fromLatLng(state, z, bounds.northeast()),
- TileCoordinate::fromLatLng(state, z, bounds.southeast()),
- TileCoordinate::fromLatLng(state, z, bounds.southwest()),
- TileCoordinate::fromLatLng(state, z, bounds.center()),
+ TileCoordinate::fromLatLng(state, z, bounds.northwest()).p,
+ TileCoordinate::fromLatLng(state, z, bounds.northeast()).p,
+ TileCoordinate::fromLatLng(state, z, bounds.southeast()).p,
+ TileCoordinate::fromLatLng(state, z, bounds.southwest()).p,
+ TileCoordinate::fromLatLng(state, z, bounds.center()).p,
z);
}
@@ -166,11 +161,11 @@ std::vector<UnwrappedTileID> tileCover(const TransformState& state, int32_t z) {
const double w = state.getWidth();
const double h = state.getHeight();
return tileCover(
- TileCoordinate::fromScreenCoordinate(state, z, { 0, 0 }),
- TileCoordinate::fromScreenCoordinate(state, z, { w, 0 }),
- TileCoordinate::fromScreenCoordinate(state, z, { w, h }),
- TileCoordinate::fromScreenCoordinate(state, z, { 0, h }),
- TileCoordinate::fromScreenCoordinate(state, z, { w/2, h/2 }),
+ TileCoordinate::fromScreenCoordinate(state, z, { 0, 0 }).p,
+ TileCoordinate::fromScreenCoordinate(state, z, { w, 0 }).p,
+ TileCoordinate::fromScreenCoordinate(state, z, { w, h }).p,
+ TileCoordinate::fromScreenCoordinate(state, z, { 0, h }).p,
+ TileCoordinate::fromScreenCoordinate(state, z, { w/2, h/2 }).p,
z);
}