This repository has been archived by the owner on Aug 8, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Tile coverage updates #12310
Closed
Closed
Tile coverage updates #12310
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
b218d7d
[core] tileCover zoom is uint8_t
brunoabinader a9cd952
[core] Remove unused 'rendered' set
brunoabinader 160c7b4
[core] Limit TileCoordinate-based coverage
brunoabinader 9899518
[core] Increase pitch to 67.5 degrees
brunoabinader 12b8482
[core] Remove redundant check in scanLine
brunoabinader 1b795ea
[core] Do not render symbol layers for pan tiles
brunoabinader File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
#include <mbgl/util/tile_cover.hpp> | ||
#include <mbgl/util/constants.hpp> | ||
#include <mbgl/util/interpolate.hpp> | ||
#include <mbgl/util/math.hpp> | ||
#include <mbgl/map/mode.hpp> | ||
#include <mbgl/map/transform_state.hpp> | ||
#include <mbgl/util/tile_cover_impl.hpp> | ||
#include <mbgl/util/tile_coordinate.hpp> | ||
|
@@ -78,13 +80,15 @@ namespace util { | |
|
||
namespace { | ||
|
||
std::vector<UnwrappedTileID> tileCover(const Point<double>& tl, | ||
const Point<double>& tr, | ||
const Point<double>& br, | ||
const Point<double>& bl, | ||
std::vector<UnwrappedTileID> tileCover(Point<double> tl, | ||
Point<double> tr, | ||
Point<double> br, | ||
Point<double> bl, | ||
const Point<double>& c, | ||
int32_t z) { | ||
const int32_t tiles = 1 << z; | ||
uint8_t z, | ||
TileCoverMode mode, | ||
double bearing = 0) { | ||
const int32_t maxTilesPerAxis = 1 << z; | ||
|
||
struct ID { | ||
int32_t x, y; | ||
|
@@ -93,22 +97,51 @@ std::vector<UnwrappedTileID> tileCover(const Point<double>& tl, | |
|
||
std::vector<ID> t; | ||
|
||
// Rotate the center according to bearing. | ||
const Point<double> rotatedCenter = util::rotate(c, bearing); | ||
|
||
// Limits the tile coverage to an axis-aligned rectangle according to the | ||
// given bearing. | ||
auto limitTileCoordinate = [&](Point<double>& point) { | ||
auto clampAxis = [](double a, double b) -> double { | ||
const double min = a >= b ? b : b - 2.0; | ||
const double max = a >= b ? b + 2.0 : b; | ||
return util::clamp(a, min, max); | ||
}; | ||
|
||
// Rotate the tile coordinate according to bearing. | ||
Point<double> rotated = util::rotate(point, bearing); | ||
rotated.x = clampAxis(rotated.x, rotatedCenter.x); | ||
rotated.y = clampAxis(rotated.y, rotatedCenter.y); | ||
|
||
// After clamping, rotate back to original value. | ||
point = util::rotate(rotated, -bearing); | ||
}; | ||
|
||
// Limit tile coverage in continuous mode. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this comment still appropriate? How is continuous mode being checked here? |
||
if (mode == TileCoverMode::Limited5x5) { | ||
limitTileCoordinate(tl); | ||
limitTileCoordinate(tr); | ||
limitTileCoordinate(br); | ||
limitTileCoordinate(bl); | ||
} | ||
|
||
auto scanLine = [&](int32_t x0, int32_t x1, int32_t y) { | ||
int32_t x; | ||
if (y >= 0 && y <= tiles) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This condition is no longer necessary? I think it is necessary at the poles. |
||
for (x = x0; x < x1; ++x) { | ||
const auto dx = x + 0.5 - c.x, dy = y + 0.5 - c.y; | ||
t.emplace_back(ID{ x, y, dx * dx + dy * dy }); | ||
} | ||
double dx, dy; | ||
for (int32_t x = x0; x < x1; ++x) { | ||
// We don't know which corner of the tile coordinate is the closest, | ||
// so add 0.5 to calculate the distance from its tile center. | ||
dx = x + 0.5 - c.x; dy = y + 0.5 - c.y; | ||
t.emplace_back(ID{ x, y, dx * dx + dy * dy }); | ||
} | ||
}; | ||
|
||
// Divide the screen up in two triangles and scan each of them: | ||
// \---+ | ||
// | \ | | ||
// +---\. | ||
scanTriangle(tl, tr, br, 0, tiles, scanLine); | ||
scanTriangle(br, bl, tl, 0, tiles, scanLine); | ||
scanTriangle(tl, tr, br, 0, maxTilesPerAxis, scanLine); | ||
scanTriangle(br, bl, tl, 0, maxTilesPerAxis, scanLine); | ||
|
||
// Sort first by distance, then by x/y. | ||
std::sort(t.begin(), t.end(), [](const ID& a, const ID& b) { | ||
|
@@ -129,7 +162,7 @@ std::vector<UnwrappedTileID> tileCover(const Point<double>& tl, | |
|
||
} // namespace | ||
|
||
int32_t coveringZoomLevel(double zoom, style::SourceType type, uint16_t size) { | ||
uint8_t coveringZoomLevel(double zoom, style::SourceType type, uint16_t size) { | ||
zoom += ::log2(util::tileSize / size); | ||
if (type == style::SourceType::Raster || type == style::SourceType::Video) { | ||
return ::round(zoom); | ||
|
@@ -138,7 +171,7 @@ int32_t coveringZoomLevel(double zoom, style::SourceType type, uint16_t size) { | |
} | ||
} | ||
|
||
std::vector<UnwrappedTileID> tileCover(const LatLngBounds& bounds_, int32_t z) { | ||
std::vector<UnwrappedTileID> tileCover(const LatLngBounds& bounds_, uint8_t z) { | ||
if (bounds_.isEmpty() || | ||
bounds_.south() > util::LATITUDE_MAX || | ||
bounds_.north() < -util::LATITUDE_MAX) { | ||
|
@@ -155,24 +188,26 @@ std::vector<UnwrappedTileID> tileCover(const LatLngBounds& bounds_, int32_t z) { | |
Projection::project(bounds.southeast(), z), | ||
Projection::project(bounds.southwest(), z), | ||
Projection::project(bounds.center(), z), | ||
z); | ||
z, TileCoverMode::Full); | ||
} | ||
|
||
std::vector<UnwrappedTileID> tileCover(const TransformState& state, int32_t z) { | ||
std::vector<UnwrappedTileID> tileCover(const TransformState& state, uint8_t z, TileCoverMode mode) { | ||
assert(state.valid()); | ||
|
||
const double w = state.getSize().width; | ||
const double h = state.getSize().height; | ||
|
||
// top-left, top-right, bottom-right, bottom-left, center | ||
return tileCover( | ||
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); | ||
z, mode, state.getAngle()); | ||
} | ||
|
||
std::vector<UnwrappedTileID> tileCover(const Geometry<double>& geometry, int32_t z) { | ||
std::vector<UnwrappedTileID> tileCover(const Geometry<double>& geometry, uint8_t z) { | ||
std::vector<UnwrappedTileID> result; | ||
TileCover tc(geometry, z, true); | ||
while (tc.hasNext()) { | ||
|
@@ -182,7 +217,7 @@ std::vector<UnwrappedTileID> tileCover(const Geometry<double>& geometry, int32_t | |
return result; | ||
} | ||
|
||
// Taken from https://github.com/mapbox/sphericalmercator#xyzbbox-zoom-tms_style-srs | ||
// Taken from https://github.com/mapbox/sphericalmercator#xyzbbox-z-tms_style-srs | ||
// Computes the projected tiles for the lower left and upper right points of the bounds | ||
// and uses that to compute the tile cover count | ||
uint64_t tileCount(const LatLngBounds& bounds, uint8_t zoom){ | ||
|
@@ -212,7 +247,7 @@ uint64_t tileCount(const Geometry<double>& geometry, uint8_t z) { | |
return tileCount; | ||
} | ||
|
||
TileCover::TileCover(const LatLngBounds&bounds_, int32_t z) { | ||
TileCover::TileCover(const LatLngBounds&bounds_, uint8_t z) { | ||
LatLngBounds bounds = LatLngBounds::hull( | ||
{ std::max(bounds_.south(), -util::LATITUDE_MAX), bounds_.west() }, | ||
{ std::min(bounds_.north(), util::LATITUDE_MAX), bounds_.east() }); | ||
|
@@ -232,7 +267,7 @@ TileCover::TileCover(const LatLngBounds&bounds_, int32_t z) { | |
impl = std::make_unique<TileCover::Impl>(z, p, false); | ||
} | ||
|
||
TileCover::TileCover(const Geometry<double>& geom, int32_t z, bool project/* = true*/) | ||
TileCover::TileCover(const Geometry<double>& geom, uint8_t z, bool project/* = true*/) | ||
: impl( std::make_unique<TileCover::Impl>(z, geom, project)) { | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
#include <mbgl/util/tile_cover.hpp> | ||
#include <mbgl/util/geo.hpp> | ||
#include <mbgl/map/transform.hpp> | ||
#include <mbgl/util/tile_coordinate.hpp> | ||
#include <mbgl/util/math.hpp> | ||
|
||
#include <algorithm> | ||
#include <stdlib.h> /* srand, rand */ | ||
|
@@ -43,6 +45,22 @@ TEST(TileCover, Pitch) { | |
{ 2, 1, 2 }, { 2, 1, 1 }, { 2, 2, 2 }, { 2, 2, 1 }, { 2, 3, 2 } | ||
}), | ||
util::tileCover(transform.getState(), 2)); | ||
|
||
// 2 tiles on the left, 1 center tiler, then 2 tiles on the right. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Break this into a separate test |
||
constexpr uint32_t maximumLimitedTiles = 5 * 5; | ||
|
||
transform.resize({ 2048, 2048 }); | ||
transform.setAngle(-45.0 * M_PI / 180.0); | ||
|
||
transform.setPitch(67.5 * M_PI / 180.0); | ||
for (double zoom = 0.0; zoom < 16.0; zoom += 0.5) { | ||
uint8_t integerZoom = std::floor(zoom); | ||
transform.setZoom(zoom); | ||
auto fullTiles = util::tileCover(transform.getState(), integerZoom, util::TileCoverMode::Full); | ||
auto limitedTiles = util::tileCover(transform.getState(), integerZoom, util::TileCoverMode::Limited5x5); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be good to also check the correctness of the returned tiles as part of the test. |
||
EXPECT_GT(fullTiles.size(), limitedTiles.size()); | ||
EXPECT_GE(maximumLimitedTiles, limitedTiles.size()); | ||
} | ||
} | ||
|
||
TEST(TileCover, WorldZ1) { | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: non-uniform input arguments.
Would it be better to keep these as const references, and conditionally return a clamped point from
limitTileCoordinate
?