1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
#pragma once
#include <mbgl/tile/tile_id.hpp>
#include <set>
namespace mbgl {
namespace algorithm {
template <typename GetTileDataFn,
typename CreateTileDataFn,
typename RetainTileDataFn,
typename RenderTileFn,
typename IdealTileIDs,
typename SourceInfo>
void updateRenderables(GetTileDataFn getTileData,
CreateTileDataFn createTileData,
RetainTileDataFn retainTileData,
RenderTileFn renderTile,
const IdealTileIDs& idealTileIDs,
const SourceInfo& info,
const uint8_t dataTileZoom) {
std::set<UnwrappedTileID> checked;
bool covered;
int32_t overscaledZ;
// for (all in the set of ideal tiles of the source) {
for (const auto& idealRenderTileID : idealTileIDs) {
assert(idealRenderTileID.canonical.z >= info.minZoom);
assert(idealRenderTileID.canonical.z <= info.maxZoom);
assert(dataTileZoom >= idealRenderTileID.canonical.z);
const OverscaledTileID idealDataTileID(dataTileZoom, idealRenderTileID.canonical);
auto data = getTileData(idealDataTileID);
if (!data) {
data = createTileData(idealDataTileID, true);
assert(data);
}
// if (source has the tile and bucket is loaded) {
if (data->isRenderable()) {
retainTileData(*data);
renderTile(idealRenderTileID, *data);
} else {
// The tile isn't loaded yet, but retain it anyway because it's an ideal tile.
retainTileData(*data);
covered = true;
overscaledZ = dataTileZoom + 1;
if (overscaledZ > info.maxZoom) {
// We're looking for an overzoomed child tile.
const auto childDataTileID = idealDataTileID.scaledTo(overscaledZ);
data = getTileData(childDataTileID);
if (data && data->isRenderable()) {
retainTileData(*data);
renderTile(idealRenderTileID, *data);
} else {
covered = false;
}
} else {
// Check all four actual child tiles.
for (const auto& childTileID : idealDataTileID.canonical.children()) {
const OverscaledTileID childDataTileID(overscaledZ, childTileID);
data = getTileData(childDataTileID);
if (data && data->isRenderable()) {
retainTileData(*data);
renderTile(childDataTileID.unwrapTo(idealRenderTileID.wrap), *data);
} else {
// At least one child tile doesn't exist, so we are going to look for
// parents as well.
covered = false;
}
}
}
if (!covered) {
// We couldn't find child tiles that entirely cover the ideal tile.
for (overscaledZ = dataTileZoom - 1; overscaledZ >= info.minZoom; --overscaledZ) {
const auto parentDataTileID = idealDataTileID.scaledTo(overscaledZ);
const auto parentRenderTileID =
parentDataTileID.unwrapTo(idealRenderTileID.wrap);
if (checked.find(parentRenderTileID) != checked.end()) {
// Break parent tile ascent, this route has been checked by another child
// tile before.
break;
} else {
checked.emplace(parentRenderTileID);
}
data = getTileData(parentDataTileID);
if (data && data->isRenderable()) {
retainTileData(*data);
renderTile(parentRenderTileID, *data);
// Break parent tile ascent, since we found one.
break;
}
}
}
}
}
}
} // namespace algorithm
} // namespace mbgl
|