summaryrefslogtreecommitdiff
path: root/src/mbgl/util/tile_cover.cpp
diff options
context:
space:
mode:
authorBruno de Oliveira Abinader <bruno@mapbox.com>2016-02-29 22:03:37 +0000
committerBruno de Oliveira Abinader <bruno@mapbox.com>2016-03-01 20:58:54 +0000
commitfde0ab98eedd77e652e1232605e4bc96f9fa65b9 (patch)
tree5a89e4718cfcb5a04715262775f300ea7d2fc817 /src/mbgl/util/tile_cover.cpp
parent6e6d91478eb97afa750f2ad15625d6fca8981ae1 (diff)
downloadqtlocation-mapboxgl-fde0ab98eedd77e652e1232605e4bc96f9fa65b9.tar.gz
[core] Moved TileCoordinate to tile cover scope
Diffstat (limited to 'src/mbgl/util/tile_cover.cpp')
-rw-r--r--src/mbgl/util/tile_cover.cpp75
1 files changed, 43 insertions, 32 deletions
diff --git a/src/mbgl/util/tile_cover.cpp b/src/mbgl/util/tile_cover.cpp
index 7af3ebd8b1..0fae940271 100644
--- a/src/mbgl/util/tile_cover.cpp
+++ b/src/mbgl/util/tile_cover.cpp
@@ -1,20 +1,40 @@
#include <mbgl/util/tile_cover.hpp>
#include <mbgl/util/vec.hpp>
-#include <mbgl/util/tile_coordinate.hpp>
#include <mbgl/util/constants.hpp>
+#include <mbgl/util/interpolate.hpp>
#include <mbgl/map/transform_state.hpp>
namespace mbgl {
+namespace {
+
+// 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;
+
+ 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,
+ };
+ }
+
+ static TileCoordinate fromScreenCoordinate(const TransformState& state, double zoom, const ScreenCoordinate& point) {
+ return fromLatLng(state, zoom, state.screenCoordinateToLatLng(point, LatLng::Unwrapped));
+ }
+};
+
// Taken from polymaps src/Layer.js
// https://github.com/simplegeo/polymaps/blob/master/src/Layer.js#L333-L383
-
struct edge {
double x0 = 0, y0 = 0;
double x1 = 0, y1 = 0;
double dx = 0, dy = 0;
- edge(ScreenCoordinate a, ScreenCoordinate b) {
+ edge(TileCoordinate a, TileCoordinate b) {
if (a.y > b.y) std::swap(a, b);
x0 = a.x;
y0 = a.y;
@@ -25,7 +45,7 @@ struct edge {
}
};
-typedef const std::function<void(int32_t x0, int32_t x1, int32_t y)> ScanLine;
+using ScanLine = const std::function<void(int32_t x0, int32_t x1, int32_t y)>;
// scan-line conversion
static void scanSpans(edge e0, edge e1, int32_t ymin, int32_t ymax, ScanLine scanLine) {
@@ -52,7 +72,7 @@ static void scanSpans(edge e0, edge e1, int32_t ymin, int32_t ymax, ScanLine sca
}
// scan-line conversion
-static void scanTriangle(const ScreenCoordinate& a, const ScreenCoordinate& b, const ScreenCoordinate& c, int32_t ymin, int32_t ymax, ScanLine& scanLine) {
+static void scanTriangle(const TileCoordinate& a, const TileCoordinate& b, const TileCoordinate& c, int32_t ymin, int32_t ymax, ScanLine& scanLine) {
edge ab = edge(a, b);
edge bc = edge(b, c);
edge ca = edge(c, a);
@@ -67,6 +87,8 @@ static void scanTriangle(const ScreenCoordinate& a, const ScreenCoordinate& b, c
if (bc.dy) scanSpans(ca, bc, ymin, ymax, scanLine);
}
+} // namespace
+
int32_t coveringZoomLevel(double zoom, SourceType type, uint16_t tileSize) {
zoom += std::log(util::tileSize / tileSize) / std::log(2);
if (type == SourceType::Raster || type == SourceType::Video) {
@@ -76,16 +98,11 @@ int32_t coveringZoomLevel(double zoom, SourceType type, uint16_t tileSize) {
}
}
-static ScreenCoordinate zoomTo(const TileCoordinate& c, double z) {
- double scale = std::pow(2, z - c.zoom);
- return { c.column * scale, c.row * scale };
-}
-
-std::vector<TileID> tileCover(const TileCoordinate& tl_,
- const TileCoordinate& tr_,
- const TileCoordinate& br_,
- const TileCoordinate& bl_,
- const TileCoordinate& center,
+std::vector<TileID> tileCover(const TileCoordinate& tl,
+ const TileCoordinate& tr,
+ const TileCoordinate& br,
+ const TileCoordinate& bl,
+ const TileCoordinate& c,
int32_t z,
int32_t actualZ) {
int32_t tiles = 1 << z;
@@ -94,18 +111,12 @@ std::vector<TileID> tileCover(const TileCoordinate& tl_,
auto scanLine = [&](int32_t x0, int32_t x1, int32_t y) {
int32_t x;
if (y >= 0 && y <= tiles) {
- for (x = x0; x < x1; x++) {
+ for (x = x0; x < x1; ++x) {
t.emplace_front(actualZ, x, y, z);
}
}
};
- const ScreenCoordinate tl(zoomTo(tl_, z));
- const ScreenCoordinate tr(zoomTo(tr_, z));
- const ScreenCoordinate br(zoomTo(br_, z));
- const ScreenCoordinate bl(zoomTo(bl_, z));
- const ScreenCoordinate c(zoomTo(center, z));
-
// Divide the screen up in two triangles and scan each of them:
// \---+
// | \ |
@@ -138,11 +149,11 @@ std::vector<TileID> tileCover(const LatLngBounds& bounds_, int32_t z, int32_t ac
const TransformState state;
return tileCover(
- state.latLngToCoordinate(bounds.northwest()),
- state.latLngToCoordinate(bounds.northeast()),
- state.latLngToCoordinate(bounds.southeast()),
- state.latLngToCoordinate(bounds.southwest()),
- state.latLngToCoordinate(bounds.center()),
+ 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()),
z, actualZ);
}
@@ -150,11 +161,11 @@ std::vector<TileID> tileCover(const TransformState& state, int32_t z, int32_t ac
const double w = state.getWidth();
const double h = state.getHeight();
return tileCover(
- state.pointToCoordinate({ 0, 0 }),
- state.pointToCoordinate({ w, 0 }),
- state.pointToCoordinate({ w, h }),
- state.pointToCoordinate({ 0, h }),
- state.pointToCoordinate({ w/2, h/2 }),
+ 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 }),
z, actualZ);
}