diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2016-05-12 12:38:12 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2016-05-17 13:20:25 -0700 |
commit | 7e5d0ff49e2b5a6a3caa45464d8056e93431d780 (patch) | |
tree | 665519111b6877ccab34d02831dc66d09b4e75ac /src | |
parent | 3e21e3887aa08ea32e4370b8c6e990d9f8c4333f (diff) | |
download | qtlocation-mapboxgl-7e5d0ff49e2b5a6a3caa45464d8056e93431d780.tar.gz |
[core] Rewrite TileCoordinate in terms of geometry.hpp point
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/map/transform.cpp | 36 | ||||
-rw-r--r-- | src/mbgl/map/transform_state.cpp | 65 | ||||
-rw-r--r-- | src/mbgl/map/transform_state.hpp | 7 | ||||
-rw-r--r-- | src/mbgl/source/source.cpp | 16 | ||||
-rw-r--r-- | src/mbgl/util/tile_coordinate.hpp | 22 | ||||
-rw-r--r-- | src/mbgl/util/tile_cover.cpp | 39 |
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); } |