1 #include <mbgl/style/custom_tile_loader.hpp>
2 #include <mbgl/tile/custom_geometry_tile.hpp>
3 #include <mbgl/util/tile_range.hpp>
4
5 namespace mbgl {
6 namespace style {
7
CustomTileLoader(const TileFunction & fetchTileFn,const TileFunction & cancelTileFn)8 CustomTileLoader::CustomTileLoader(const TileFunction& fetchTileFn, const TileFunction& cancelTileFn) {
9 fetchTileFunction = fetchTileFn;
10 cancelTileFunction = cancelTileFn;
11 }
12
fetchTile(const OverscaledTileID & tileID,ActorRef<CustomGeometryTile> tileRef)13 void CustomTileLoader::fetchTile(const OverscaledTileID& tileID, ActorRef<CustomGeometryTile> tileRef) {
14 auto cachedTileData = dataCache.find(tileID.canonical);
15 if (cachedTileData != dataCache.end()) {
16 tileRef.invoke(&CustomGeometryTile::setTileData, *(cachedTileData->second));
17 }
18 auto tileCallbacks = tileCallbackMap.find(tileID.canonical);
19 if (tileCallbacks == tileCallbackMap.end()) {
20 auto tuple = std::make_tuple(tileID.overscaledZ, tileID.wrap, tileRef);
21 tileCallbackMap.insert({ tileID.canonical, std::vector<OverscaledIDFunctionTuple>(1, tuple) });
22 } else {
23 for (auto iter = tileCallbacks->second.begin(); iter != tileCallbacks->second.end(); iter++) {
24 if (std::get<0>(*iter) == tileID.overscaledZ && std::get<1>(*iter) == tileID.wrap ) {
25 std::get<2>(*iter) = tileRef;
26 return;
27 }
28 }
29 tileCallbacks->second.emplace_back(std::make_tuple(tileID.overscaledZ, tileID.wrap, tileRef));
30 }
31 if (cachedTileData == dataCache.end()) {
32 invokeTileFetch(tileID.canonical);
33 }
34 }
35
cancelTile(const OverscaledTileID & tileID)36 void CustomTileLoader::cancelTile(const OverscaledTileID& tileID) {
37 if (tileCallbackMap.find(tileID.canonical) != tileCallbackMap.end()) {
38 invokeTileCancel(tileID.canonical);
39 }
40 }
41
removeTile(const OverscaledTileID & tileID)42 void CustomTileLoader::removeTile(const OverscaledTileID& tileID) {
43 auto tileCallbacks = tileCallbackMap.find(tileID.canonical);
44 if (tileCallbacks == tileCallbackMap.end()) return;
45 for (auto iter = tileCallbacks->second.begin(); iter != tileCallbacks->second.end(); iter++) {
46 if (std::get<0>(*iter) == tileID.overscaledZ && std::get<1>(*iter) == tileID.wrap ) {
47 tileCallbacks->second.erase(iter);
48 invokeTileCancel(tileID.canonical);
49 break;
50 }
51 }
52 if (tileCallbacks->second.size() == 0) {
53 tileCallbackMap.erase(tileCallbacks);
54 dataCache.erase(tileID.canonical);
55 }
56 }
57
setTileData(const CanonicalTileID & tileID,const GeoJSON & data)58 void CustomTileLoader::setTileData(const CanonicalTileID& tileID, const GeoJSON& data) {
59
60 auto iter = tileCallbackMap.find(tileID);
61 if (iter == tileCallbackMap.end()) return;
62 auto dataPtr = std::make_unique<mapbox::geojson::geojson>(std::move(data));
63 for (auto tuple : iter->second) {
64 auto actor = std::get<2>(tuple);
65 actor.invoke(&CustomGeometryTile::setTileData, *dataPtr);
66 }
67 dataCache[tileID] = std::move(dataPtr);
68 }
69
invalidateTile(const CanonicalTileID & tileID)70 void CustomTileLoader::invalidateTile(const CanonicalTileID& tileID) {
71 auto tileCallbacks = tileCallbackMap.find(tileID);
72 if (tileCallbacks == tileCallbackMap.end()) { return; }
73 for (auto iter = tileCallbacks->second.begin(); iter != tileCallbacks->second.end(); iter++) {
74 auto actor = std::get<2>(*iter);
75 actor.invoke(&CustomGeometryTile::invalidateTileData);
76 invokeTileCancel(tileID);
77 }
78 tileCallbackMap.erase(tileCallbacks);
79 dataCache.erase(tileID);
80 }
81
invalidateRegion(const LatLngBounds & bounds,Range<uint8_t>)82 void CustomTileLoader::invalidateRegion(const LatLngBounds& bounds, Range<uint8_t> ) {
83 std::map<uint8_t, util::TileRange> tileRanges;
84
85 for (auto idtuple= tileCallbackMap.begin(); idtuple != tileCallbackMap.end(); idtuple++) {
86 auto zoom = idtuple->first.z;
87 auto tileRange = tileRanges.find(zoom);
88 if(tileRange == tileRanges.end()) {
89 tileRange = tileRanges.emplace(std::make_pair(zoom, util::TileRange::fromLatLngBounds(bounds, zoom))).first;
90 }
91 if (tileRange->second.contains(idtuple->first)) {
92 for (auto iter = idtuple->second.begin(); iter != idtuple->second.end(); iter++) {
93 auto actor = std::get<2>(*iter);
94 actor.invoke(&CustomGeometryTile::invalidateTileData);
95 invokeTileCancel(idtuple->first);
96 dataCache.erase(idtuple->first);
97 }
98 idtuple->second.clear();
99 }
100 }
101 }
102
invokeTileFetch(const CanonicalTileID & tileID)103 void CustomTileLoader::invokeTileFetch(const CanonicalTileID& tileID) {
104 if (fetchTileFunction != nullptr) {
105 fetchTileFunction(tileID);
106 }
107 }
108
invokeTileCancel(const CanonicalTileID & tileID)109 void CustomTileLoader::invokeTileCancel(const CanonicalTileID& tileID) {
110 if (cancelTileFunction != nullptr) {
111 cancelTileFunction(tileID);
112 }
113 }
114
115 } // namespace style
116 } // namespace mbgl
117