1#pragma once
2
3#include <mbgl/util/geo.hpp>
4#include <mbgl/util/range.hpp>
5#include <mbgl/util/optional.hpp>
6#include <mbgl/style/types.hpp>
7#include <mbgl/storage/response.hpp>
8
9#include <string>
10#include <vector>
11#include <functional>
12
13namespace mbgl {
14
15class TileID;
16
17/*
18 * An offline region defined by a style URL, geographic bounding box, zoom range, and
19 * device pixel ratio.
20 *
21 * Both minZoom and maxZoom must be ≥ 0, and maxZoom must be ≥ minZoom.
22 *
23 * maxZoom may be ∞, in which case for each tile source, the region will include
24 * tiles from minZoom up to the maximum zoom level provided by that source.
25 *
26 * pixelRatio must be ≥ 0 and should typically be 1.0 or 2.0.
27 */
28class OfflineTilePyramidRegionDefinition {
29public:
30 OfflineTilePyramidRegionDefinition(std::string, LatLngBounds, double, double, float);
31
32 /* Private */
33 std::vector<CanonicalTileID> tileCover(style::SourceType, uint16_t tileSize, const Range<uint8_t>& zoomRange) const;
34 uint64_t tileCount(style::SourceType, uint16_t tileSize, const Range<uint8_t>& zoomRange) const;
35 const std::string styleURL;
36 const LatLngBounds bounds;
37 const double minZoom;
38 const double maxZoom;
39 const float pixelRatio;
40private:
41 Range<uint8_t> coveringZoomRange(style::SourceType, uint16_t tileSize, const Range<uint8_t>& zoomRange) const;
42};
43
44/*
45 * For the present, a tile pyramid is the only type of offline region. In the future,
46 * other definition types will be available and this will be a variant type.
47 */
48using OfflineRegionDefinition = OfflineTilePyramidRegionDefinition;
49
50/*
51 * The encoded format is private.
52 */
53std::string encodeOfflineRegionDefinition(const OfflineRegionDefinition&);
54OfflineRegionDefinition decodeOfflineRegionDefinition(const std::string&);
55
56/*
57 * Arbitrary binary region metadata. The contents are opaque to the mbgl implementation;
58 * it just stores and retrieves a BLOB. SDK bindings should leave the interpretation of
59 * this data up to the application; they _should not_ enforce a higher-level data format.
60 * In the future we want offline database to be portable across target platforms, and a
61 * platform-specific metadata format would prevent that.
62 */
63using OfflineRegionMetadata = std::vector<uint8_t>;
64
65/*
66 * A region is either inactive (not downloading, but previously-downloaded
67 * resources are available for use), or active (resources are being downloaded
68 * or will be downloaded, if necessary, when network access is available).
69 *
70 * This state is independent of whether or not the complete set of resources
71 * is currently available for offline use. To check if that is the case, use
72 * `OfflineRegionStatus::complete()`.
73 */
74enum class OfflineRegionDownloadState {
75 Inactive,
76 Active
77};
78
79/*
80 * A region's status includes its active/inactive state as well as counts
81 * of the number of resources that have completed downloading, their total
82 * size in bytes, and the total number of resources that are required.
83 *
84 * Note that the total required size in bytes is not currently available. A
85 * future API release may provide an estimate of this number.
86 */
87class OfflineRegionStatus {
88public:
89 OfflineRegionDownloadState downloadState = OfflineRegionDownloadState::Inactive;
90
91 /**
92 * The number of resources that have been fully downloaded and are ready for
93 * offline access.
94 */
95 uint64_t completedResourceCount = 0;
96
97 /**
98 * The cumulative size, in bytes, of all resources (inclusive of tiles) that have
99 * been fully downloaded.
100 */
101 uint64_t completedResourceSize = 0;
102
103 /**
104 * The number of tiles that are known to be required for this region. This is a
105 * subset of `completedResourceCount`.
106 */
107 uint64_t completedTileCount = 0;
108
109 /**
110 * The cumulative size, in bytes, of all tiles that have been fully downloaded.
111 * This is a subset of `completedResourceSize`.
112 */
113 uint64_t completedTileSize = 0;
114
115 /**
116 * The number of resources that are known to be required for this region. See the
117 * documentation for `requiredResourceCountIsPrecise` for an important caveat
118 * about this number.
119 */
120 uint64_t requiredResourceCount = 0;
121
122 /**
123 * This property is true when the value of requiredResourceCount is a precise
124 * count of the number of required resources, and false when it is merely a lower
125 * bound.
126 *
127 * Specifically, it is false during early phases of an offline download. Once
128 * style and tile sources have been downloaded, it is possible to calculate the
129 * precise number of required resources, at which point it is set to true.
130 */
131 bool requiredResourceCountIsPrecise = false;
132
133 bool complete() const {
134 return completedResourceCount == requiredResourceCount;
135 }
136};
137
138/*
139 * A region can have a single observer, which gets notified whenever a change
140 * to the region's status occurs.
141 */
142class OfflineRegionObserver {
143public:
144 virtual ~OfflineRegionObserver() = default;
145
146 /*
147 * Implement this method to be notified of a change in the status of an
148 * offline region. Status changes include any change in state of the members
149 * of OfflineRegionStatus.
150 *
151 * Note that this method will be executed on the database thread; it is the
152 * responsibility of the SDK bindings to wrap this object in an interface that
153 * re-executes the user-provided implementation on the main thread.
154 */
155 virtual void statusChanged(OfflineRegionStatus) {}
156
157 /*
158 * Implement this method to be notified of errors encountered while downloading
159 * regional resources. Such errors may be recoverable; for example the implementation
160 * will attempt to re-request failed resources based on an exponential backoff
161 * algorithm, or when it detects that network access has been restored.
162 *
163 * Note that this method will be executed on the database thread; it is the
164 * responsibility of the SDK bindings to wrap this object in an interface that
165 * re-executes the user-provided implementation on the main thread.
166 */
167 virtual void responseError(Response::Error) {}
168
169 /*
170 * Implement this method to be notified when the limit on the number of Mapbox
171 * tiles stored for offline regions has been reached.
172 *
173 * Once the limit has been reached, the SDK will not download further offline
174 * tiles from Mapbox APIs until existing tiles have been removed. Contact your
175 * Mapbox sales representative to raise the limit.
176 *
177 * This limit does not apply to non-Mapbox tile sources.
178 *
179 * Note that this method will be executed on the database thread; it is the
180 * responsibility of the SDK bindings to wrap this object in an interface that
181 * re-executes the user-provided implementation on the main thread.
182 */
183 virtual void mapboxTileCountLimitExceeded(uint64_t /* limit */) {}
184};
185
186class OfflineRegion {
187public:
188 // Move-only; not publicly constructible.
189 OfflineRegion(OfflineRegion&&);
190 OfflineRegion& operator=(OfflineRegion&&);
191 ~OfflineRegion();
192
193 OfflineRegion() = delete;
194 OfflineRegion(const OfflineRegion&) = delete;
195 OfflineRegion& operator=(const OfflineRegion&) = delete;
196
197 int64_t getID() const;
198 const OfflineRegionDefinition& getDefinition() const;
199 const OfflineRegionMetadata& getMetadata() const;
200
201private:
202 friend class OfflineDatabase;
203
204 OfflineRegion(int64_t id,
205 OfflineRegionDefinition,
206 OfflineRegionMetadata);
207
208 const int64_t id;
209 const OfflineRegionDefinition definition;
210 const OfflineRegionMetadata metadata;
211};
212
213} // namespace mbgl
214

source code of qtlocation/src/3rdparty/mapbox-gl-native/include/mbgl/storage/offline.hpp