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
105
106
107
108
109
110
111
112
113
114
115
116
|
#include <mbgl/style/custom_tile_loader.hpp>
#include <mbgl/tile/custom_geometry_tile.hpp>
#include <mbgl/util/tile_range.hpp>
namespace mbgl {
namespace style {
CustomTileLoader::CustomTileLoader(const TileFunction& fetchTileFn, const TileFunction& cancelTileFn) {
fetchTileFunction = fetchTileFn;
cancelTileFunction = cancelTileFn;
}
void CustomTileLoader::fetchTile(const OverscaledTileID& tileID, ActorRef<CustomGeometryTile> tileRef) {
auto cachedTileData = dataCache.find(tileID.canonical);
if (cachedTileData != dataCache.end()) {
tileRef.invoke(&CustomGeometryTile::setTileData, *(cachedTileData->second));
}
auto tileCallbacks = tileCallbackMap.find(tileID.canonical);
if (tileCallbacks == tileCallbackMap.end()) {
auto tuple = std::make_tuple(tileID.overscaledZ, tileID.wrap, tileRef);
tileCallbackMap.insert({ tileID.canonical, std::vector<OverscaledIDFunctionTuple>(1, tuple) });
} else {
for (auto iter = tileCallbacks->second.begin(); iter != tileCallbacks->second.end(); iter++) {
if (std::get<0>(*iter) == tileID.overscaledZ && std::get<1>(*iter) == tileID.wrap ) {
std::get<2>(*iter) = tileRef;
return;
}
}
tileCallbacks->second.emplace_back(std::make_tuple(tileID.overscaledZ, tileID.wrap, tileRef));
}
if (cachedTileData == dataCache.end()) {
invokeTileFetch(tileID.canonical);
}
}
void CustomTileLoader::cancelTile(const OverscaledTileID& tileID) {
if (tileCallbackMap.find(tileID.canonical) != tileCallbackMap.end()) {
invokeTileCancel(tileID.canonical);
}
}
void CustomTileLoader::removeTile(const OverscaledTileID& tileID) {
auto tileCallbacks = tileCallbackMap.find(tileID.canonical);
if (tileCallbacks == tileCallbackMap.end()) return;
for (auto iter = tileCallbacks->second.begin(); iter != tileCallbacks->second.end(); iter++) {
if (std::get<0>(*iter) == tileID.overscaledZ && std::get<1>(*iter) == tileID.wrap ) {
tileCallbacks->second.erase(iter);
invokeTileCancel(tileID.canonical);
break;
}
}
if (tileCallbacks->second.size() == 0) {
tileCallbackMap.erase(tileCallbacks);
dataCache.erase(tileID.canonical);
}
}
void CustomTileLoader::setTileData(const CanonicalTileID& tileID, const GeoJSON& data) {
auto iter = tileCallbackMap.find(tileID);
if (iter == tileCallbackMap.end()) return;
auto dataPtr = std::make_unique<mapbox::geojson::geojson>(std::move(data));
for (auto tuple : iter->second) {
auto actor = std::get<2>(tuple);
actor.invoke(&CustomGeometryTile::setTileData, *dataPtr);
}
dataCache[tileID] = std::move(dataPtr);
}
void CustomTileLoader::invalidateTile(const CanonicalTileID& tileID) {
auto tileCallbacks = tileCallbackMap.find(tileID);
if (tileCallbacks == tileCallbackMap.end()) { return; }
for (auto iter = tileCallbacks->second.begin(); iter != tileCallbacks->second.end(); iter++) {
auto actor = std::get<2>(*iter);
actor.invoke(&CustomGeometryTile::invalidateTileData);
invokeTileCancel(tileID);
}
tileCallbackMap.erase(tileCallbacks);
dataCache.erase(tileID);
}
void CustomTileLoader::invalidateRegion(const LatLngBounds& bounds, Range<uint8_t> ) {
std::map<uint8_t, util::TileRange> tileRanges;
for (auto idtuple= tileCallbackMap.begin(); idtuple != tileCallbackMap.end(); idtuple++) {
auto zoom = idtuple->first.z;
auto tileRange = tileRanges.find(zoom);
if(tileRange == tileRanges.end()) {
tileRange = tileRanges.emplace(std::make_pair(zoom, util::TileRange::fromLatLngBounds(bounds, zoom))).first;
}
if (tileRange->second.contains(idtuple->first)) {
for (auto iter = idtuple->second.begin(); iter != idtuple->second.end(); iter++) {
auto actor = std::get<2>(*iter);
actor.invoke(&CustomGeometryTile::invalidateTileData);
invokeTileCancel(idtuple->first);
dataCache.erase(idtuple->first);
}
idtuple->second.clear();
}
}
}
void CustomTileLoader::invokeTileFetch(const CanonicalTileID& tileID) {
if (fetchTileFunction != nullptr) {
fetchTileFunction(tileID);
}
}
void CustomTileLoader::invokeTileCancel(const CanonicalTileID& tileID) {
if (cancelTileFunction != nullptr) {
cancelTileFunction(tileID);
}
}
} // namespace style
} // namespace mbgl
|