@rnmapbox/maps 10.0.0-rc.1 → 10.0.0-rc.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/android/rctmgl/build.gradle +1 -1
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/components/AbstractEventEmitter.kt +75 -0
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/components/annotation/RCTMGLMarkerViewManager.kt +1 -1
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/components/camera/RCTMGLCamera.kt +92 -9
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/components/images/RCTMGLImagesManager.kt +2 -2
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/components/location/LocationComponentManager.kt +3 -2
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/components/mapview/RCTMGLAndroidTextureMapViewManager.kt +23 -0
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/components/mapview/RCTMGLMapView.kt +86 -17
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/components/mapview/RCTMGLMapViewManager.kt +24 -8
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/components/styles/sources/RCTMGLRasterSourceManager.kt +1 -1
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/components/styles/sources/RCTMGLTileSourceManager.kt +1 -1
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/components/styles/sources/RCTMGLVectorSourceManager.kt +1 -1
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/events/AbstractEvent.kt +49 -0
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/events/IEvent.kt +17 -0
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/events/LocationEvent.kt +11 -16
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/events/MapUserTrackingModeEvent.kt +10 -10
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/events/constants/EventTypes.kt +44 -0
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/modules/RCTMGLLocationModule.kt +36 -1
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/modules/RCTMGLModule.kt +4 -3
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/modules/RCTMGLOfflineModule.kt +464 -428
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/utils/extensions/FeatureCollection.kt +10 -0
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/utils/extensions/Geometry.kt +22 -0
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/utils/extensions/JSONObject.kt +78 -0
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/utils/extensions/ReadableArray.kt +1 -1
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/utils/extensions/Value.kt +9 -0
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/utils/writeableMapArrayOf.kt +41 -0
- package/ios/RCTMGL-v10/RCTMGLCamera.swift +1 -6
- package/ios/RCTMGL-v10/RCTMGLEvent.swift +4 -5
- package/ios/RCTMGL-v10/RCTMGLLocationModule.m +2 -2
- package/ios/RCTMGL-v10/RCTMGLOfflineModule.swift +299 -312
- package/ios/install.md +7 -0
- package/lib/commonjs/components/MapView.js +12 -2
- package/lib/commonjs/components/MapView.js.map +1 -1
- package/lib/commonjs/components/NativeUserLocation.js.map +1 -1
- package/lib/commonjs/components/Terrain.js +1 -2
- package/lib/commonjs/components/Terrain.js.map +1 -1
- package/lib/commonjs/components/VectorSource.js +2 -0
- package/lib/commonjs/components/VectorSource.js.map +1 -1
- package/lib/commonjs/modules/location/locationManager.js +4 -0
- package/lib/commonjs/modules/location/locationManager.js.map +1 -1
- package/lib/module/components/MapView.js +12 -2
- package/lib/module/components/MapView.js.map +1 -1
- package/lib/module/components/NativeUserLocation.js.map +1 -1
- package/lib/module/components/Terrain.js +1 -2
- package/lib/module/components/Terrain.js.map +1 -1
- package/lib/module/components/VectorSource.js +3 -0
- package/lib/module/components/VectorSource.js.map +1 -1
- package/lib/module/modules/location/locationManager.js +4 -0
- package/lib/module/modules/location/locationManager.js.map +1 -1
- package/lib/typescript/components/MapView.d.ts +6 -0
- package/lib/typescript/components/MapView.d.ts.map +1 -1
- package/lib/typescript/components/NativeUserLocation.d.ts.map +1 -1
- package/lib/typescript/components/Terrain.d.ts.map +1 -1
- package/package.json +1 -1
- package/plugin/install.md +17 -0
- package/rnmapbox-maps.podspec +1 -1
- package/src/components/MapView.tsx +10 -2
- package/src/components/NativeUserLocation.tsx +5 -3
- package/src/components/Terrain.tsx +3 -5
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/components/AbstractEventEmitter.java +0 -82
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/components/mapview/RCTMGLAndroidTextureMapView.java +0 -16
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/components/mapview/RCTMGLAndroidTextureMapViewManager.java +0 -31
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/events/AbstractEvent.java +0 -62
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/events/IEvent.java +0 -18
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/events/constants/EventTypes.java +0 -51
|
@@ -98,9 +98,9 @@ class RCTMGLOfflineModule: RCTEventEmitter {
|
|
|
98
98
|
var cancelable: Cancelable? = nil
|
|
99
99
|
var progress : TileRegionLoadProgress? = nil
|
|
100
100
|
var state : State = .inactive
|
|
101
|
-
var metadata : [String:Any]
|
|
101
|
+
var metadata : [String:Any]
|
|
102
102
|
|
|
103
|
-
|
|
103
|
+
// Stored in metadata for resume functionality:
|
|
104
104
|
var bounds: Geometry? = nil
|
|
105
105
|
var zoomRange: ClosedRange<UInt8>? = nil
|
|
106
106
|
var styleURI: StyleURI? = nil
|
|
@@ -133,7 +133,7 @@ class RCTMGLOfflineModule: RCTEventEmitter {
|
|
|
133
133
|
@objc
|
|
134
134
|
override
|
|
135
135
|
static func requiresMainQueueSetup() -> Bool {
|
|
136
|
-
|
|
136
|
+
return true
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
@objc
|
|
@@ -141,56 +141,251 @@ class RCTMGLOfflineModule: RCTEventEmitter {
|
|
|
141
141
|
func constantsToExport() -> [AnyHashable: Any]! {
|
|
142
142
|
return [:]
|
|
143
143
|
}
|
|
144
|
-
|
|
145
|
-
|
|
144
|
+
|
|
146
145
|
@objc
|
|
147
146
|
override
|
|
148
147
|
func supportedEvents() -> [String] {
|
|
149
148
|
return [Callbacks.error.rawValue, Callbacks.progress.rawValue]
|
|
150
149
|
}
|
|
151
150
|
|
|
152
|
-
|
|
153
|
-
|
|
151
|
+
// MARK: react methods
|
|
152
|
+
|
|
153
|
+
@objc
|
|
154
|
+
func createPack(_ options: NSDictionary, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
|
|
155
|
+
DispatchQueue.main.async {
|
|
156
|
+
do {
|
|
157
|
+
let metadataStr = options["metadata"] as! String
|
|
158
|
+
var metadata = try JSONSerialization.jsonObject(with: metadataStr.data(using: .utf8)!, options: []) as! [String:Any]
|
|
159
|
+
metadata["styleURI"] = options["styleURL"]
|
|
160
|
+
let id = metadata["name"] as! String
|
|
161
|
+
|
|
162
|
+
let boundsStr = options["bounds"] as! String
|
|
163
|
+
let boundsData = boundsStr.data(using: .utf8)
|
|
164
|
+
var boundsFC = try JSONDecoder().decode(FeatureCollection.self, from: boundsData!)
|
|
165
|
+
|
|
166
|
+
var bounds = self.convertPointPairToBounds(RCTMGLFeatureUtils.fcToGeomtry(boundsFC))
|
|
167
|
+
|
|
168
|
+
let actPack = RCTMGLOfflineModule.TileRegionPack(
|
|
169
|
+
name: id,
|
|
170
|
+
styleURI: StyleURI(rawValue: options["styleURL"] as! String)!,
|
|
171
|
+
bounds: bounds,
|
|
172
|
+
zoomRange: (options["minZoom"] as! NSNumber).uint8Value...(options["maxZoom"] as! NSNumber).uint8Value,
|
|
173
|
+
metadata: metadata
|
|
174
|
+
)
|
|
175
|
+
self.tileRegionPacks[id] = actPack
|
|
176
|
+
self.startLoading(pack: actPack)
|
|
177
|
+
|
|
178
|
+
resolver([
|
|
179
|
+
"bounds": boundsStr,
|
|
180
|
+
"metadata": String(data:try! JSONSerialization.data(withJSONObject: metadata, options: [.prettyPrinted]), encoding: .utf8)
|
|
181
|
+
])
|
|
182
|
+
} catch {
|
|
183
|
+
rejecter("createPack", error.localizedDescription, error)
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
@objc
|
|
189
|
+
func getPackStatus(_ name: String,
|
|
190
|
+
resolver: @escaping RCTPromiseResolveBlock,
|
|
191
|
+
rejecter: @escaping RCTPromiseRejectBlock) {
|
|
192
|
+
guard let pack = tileRegionPacks[name] else {
|
|
193
|
+
rejecter("RCTMGLOfflineModule.getPackStatus", "pack \(name) not found", nil)
|
|
194
|
+
return
|
|
195
|
+
}
|
|
154
196
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
let
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
197
|
+
tileStore.tileRegionMetadata(forId: name) { result in
|
|
198
|
+
switch result {
|
|
199
|
+
case .success(let metadata):
|
|
200
|
+
var pack = TileRegionPack(
|
|
201
|
+
name: name,
|
|
202
|
+
metadata: logged("RCTMGLOfflineModule.getPackStatus") { metadata as? [String:Any] } ?? [:]
|
|
203
|
+
)
|
|
204
|
+
self.tileRegionPacks[name] = pack
|
|
205
|
+
resolver(self._makeRegionStatusPayload(pack: pack))
|
|
206
|
+
case .failure(let error):
|
|
207
|
+
Logger.log(level:.error, message: "Unable to fetch metadata for \(name)")
|
|
208
|
+
rejecter("RCTMGLOfflineModule.getPackStatus", error.localizedDescription, error)
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
@objc
|
|
214
|
+
func resumePackDownload(_ name: String, resolver: RCTPromiseResolveBlock, rejecter: RCTPromiseRejectBlock)
|
|
215
|
+
{
|
|
216
|
+
if let pack = tileRegionPacks[name] {
|
|
217
|
+
startLoading(pack: pack)
|
|
218
|
+
resolver(nil)
|
|
219
|
+
} else {
|
|
220
|
+
rejecter("resumePackDownload", "Unknown offline pack: \(name)", nil)
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
@objc
|
|
225
|
+
func pausePackDownload(_ name: String, resolver: RCTPromiseResolveBlock, rejecter: RCTPromiseRejectBlock)
|
|
226
|
+
{
|
|
227
|
+
if let pack = tileRegionPacks[name] {
|
|
228
|
+
if let cancelable = pack.cancelable {
|
|
229
|
+
cancelable.cancel()
|
|
230
|
+
tileRegionPacks[name]?.cancelable = nil
|
|
231
|
+
resolver(nil)
|
|
175
232
|
} else {
|
|
176
|
-
|
|
233
|
+
rejecter("pausePackDownload", "Offline pack: \(name) already cancelled", nil)
|
|
177
234
|
}
|
|
178
|
-
|
|
179
|
-
|
|
235
|
+
} else {
|
|
236
|
+
rejecter("pausePackDownload", "Unknown offline region: \(name)", nil)
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
@objc
|
|
241
|
+
func setTileCountLimit(_ limit: NSNumber) {
|
|
242
|
+
self.offlineRegionManager.setOfflineMapboxTileCountLimitForLimit(limit.uint64Value)
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
@objc
|
|
247
|
+
func deletePack(_ name: String,
|
|
248
|
+
resolver: RCTPromiseResolveBlock,
|
|
249
|
+
rejecter: RCTPromiseRejectBlock)
|
|
250
|
+
{
|
|
251
|
+
guard let pack = tileRegionPacks[name] else {
|
|
252
|
+
return resolver(nil)
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
guard pack.state != .invalid else {
|
|
256
|
+
return rejecter("deletePack", "Pack: \(name) has already been deleted", nil)
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
tileStore.removeTileRegion(forId: name)
|
|
260
|
+
tileRegionPacks[name]!.state = .invalid
|
|
261
|
+
resolver(nil)
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
@objc
|
|
265
|
+
func migrateOfflineCache(_ resolve : @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
266
|
+
// Old and new cache file paths
|
|
267
|
+
let srcURL = URL(fileURLWithPath: NSHomeDirectory()).appendingPathComponent("/Library/Application Support/com.mapbox.examples/.mapbox/cache.db")
|
|
268
|
+
|
|
269
|
+
let destURL = URL(fileURLWithPath: NSHomeDirectory()).appendingPathComponent("/Library/Application Support/.mapbox/map_data/map_data.db")
|
|
270
|
+
|
|
271
|
+
let fileManager = FileManager.default
|
|
272
|
+
|
|
273
|
+
do {
|
|
274
|
+
try fileManager.createDirectory(at: destURL.deletingLastPathComponent(), withIntermediateDirectories: true, attributes: nil)
|
|
275
|
+
try fileManager.moveItem(at: srcURL, to: destURL)
|
|
276
|
+
resolve(nil)
|
|
277
|
+
} catch {
|
|
278
|
+
reject("migrateOfflineCache", error.localizedDescription, error)
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
@objc
|
|
283
|
+
func resetDatabase(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
284
|
+
self.tileStore.allTileRegions { result in
|
|
285
|
+
switch result {
|
|
286
|
+
case .success(let regions):
|
|
287
|
+
regions.forEach { region in
|
|
288
|
+
self.tileStore.removeTileRegion(forId: region.id)
|
|
289
|
+
}
|
|
290
|
+
self.offlineManager.allStylePacks { result in
|
|
291
|
+
switch result {
|
|
292
|
+
case .success(let packs):
|
|
293
|
+
packs.forEach { pack in
|
|
294
|
+
if let url = logged("RCTMGLOfflineModule.resetDatabase invalid styleURI",fn: { return URL(string: pack.styleURI) }),
|
|
295
|
+
let styleUri = logged("RCTMGLOfflineModule.resetDatabase invalid styleURI2", fn: { return StyleURI(url: url) }) {
|
|
296
|
+
self.offlineManager.removeStylePack(for: styleUri)
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
resolve(nil)
|
|
300
|
+
case .failure(let error):
|
|
301
|
+
Logger.log(level:.error, message: "RCTMGLOfflineModule.resetDatabase/allStylePacks \(error.localizedDescription) \(error)")
|
|
302
|
+
reject("RCTMGLOfflineModule.resetDatabase/allStylePacks", error.localizedDescription, error)
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
case .failure(let error):
|
|
306
|
+
Logger.log(level:.error, message: "RCTMGLOfflineModule.resetDatabase/allTileRegions \(error.localizedDescription) \(error)")
|
|
307
|
+
reject("RCTMGLOfflineModule.resetDatabase/allTileRegions", error.localizedDescription, error)
|
|
180
308
|
}
|
|
181
|
-
|
|
182
|
-
result["metadata"] = String(data:try! JSONSerialization.data(withJSONObject: metadata, options: [.prettyPrinted]), encoding: .utf8)
|
|
183
|
-
|
|
184
|
-
result["bounds"] = jsonBounds
|
|
185
309
|
}
|
|
186
|
-
return result
|
|
187
310
|
}
|
|
188
311
|
|
|
189
|
-
|
|
190
|
-
|
|
312
|
+
@objc
|
|
313
|
+
func getPacks(_ resolve : @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
|
|
314
|
+
DispatchQueue.main.async {
|
|
315
|
+
self.tileStore.allTileRegions { result in
|
|
316
|
+
switch result {
|
|
317
|
+
case .success(let regions):
|
|
318
|
+
self.convertRegionsToJSON(regions: regions, resolve: resolve, rejecter: rejecter)
|
|
319
|
+
case .failure(let error):
|
|
320
|
+
rejecter("TileStoreError", error.localizedDescription, error)
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
191
324
|
}
|
|
192
325
|
|
|
193
|
-
func
|
|
326
|
+
func startLoading(pack: TileRegionPack) {
|
|
327
|
+
let id = pack.name
|
|
328
|
+
let metadata = pack.metadata
|
|
329
|
+
guard let bounds = pack.bounds else {
|
|
330
|
+
RCTMGLLogError("RCTMGLOfflineModule.startLoading failed as there are no bounds in pack")
|
|
331
|
+
return
|
|
332
|
+
}
|
|
333
|
+
guard let zoomRange = pack.zoomRange else {
|
|
334
|
+
RCTMGLLogError("RCTMGLOfflineModule.startLoading failed as there is no zoom range in pack")
|
|
335
|
+
return
|
|
336
|
+
}
|
|
337
|
+
guard let styleURI = pack.styleURI else {
|
|
338
|
+
RCTMGLLogError("RCTMGLOfflineModule.startLoading failed as there is no styleURI in pack")
|
|
339
|
+
return
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
let stylePackLoadOptions = StylePackLoadOptions(glyphsRasterizationMode: .ideographsRasterizedLocally, metadata: pack.metadata)
|
|
343
|
+
|
|
344
|
+
let descriptorOptions = TilesetDescriptorOptions(
|
|
345
|
+
styleURI: styleURI,
|
|
346
|
+
zoomRange: zoomRange,
|
|
347
|
+
stylePackOptions: stylePackLoadOptions
|
|
348
|
+
)
|
|
349
|
+
let tilesetDescriptor = self.offlineManager.createTilesetDescriptor(for: descriptorOptions)
|
|
350
|
+
|
|
351
|
+
let loadOptions = TileRegionLoadOptions(
|
|
352
|
+
geometry: bounds, // RCTMGLFeatureUtils.geometryToGeometry(bounds),
|
|
353
|
+
descriptors: [tilesetDescriptor],
|
|
354
|
+
metadata: metadata,
|
|
355
|
+
acceptExpired: true,
|
|
356
|
+
networkRestriction: .none,
|
|
357
|
+
averageBytesPerSecond: nil)
|
|
358
|
+
|
|
359
|
+
var lastProgress : TileRegionLoadProgress? = nil
|
|
360
|
+
let task = self.tileStore.loadTileRegion(forId: id, loadOptions: loadOptions!, progress: {
|
|
361
|
+
progress in
|
|
362
|
+
lastProgress = progress
|
|
363
|
+
self.tileRegionPacks[id]!.progress = progress
|
|
364
|
+
self.tileRegionPacks[id]!.state = .active
|
|
365
|
+
self.offlinePackProgressDidChange(progress: progress, metadata: metadata, state: .active)
|
|
366
|
+
}) { result in
|
|
367
|
+
switch result {
|
|
368
|
+
case .success(let _):
|
|
369
|
+
DispatchQueue.main.async {
|
|
370
|
+
if let progess = lastProgress {
|
|
371
|
+
self.offlinePackProgressDidChange(progress: progess, metadata: metadata, state: .complete)
|
|
372
|
+
} else {
|
|
373
|
+
Logger.log(level: .warn,
|
|
374
|
+
message: "RCTMGLOfflineModule: startLoading: tile region completed, but got no progress information")
|
|
375
|
+
}
|
|
376
|
+
self.tileRegionPacks[id]!.state = .complete
|
|
377
|
+
}
|
|
378
|
+
case .failure(let error):
|
|
379
|
+
DispatchQueue.main.async {
|
|
380
|
+
self.tileRegionPacks[id]!.state = .inactive
|
|
381
|
+
self.offlinePackDidReceiveError(name: id, error: error)
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
self.tileRegionPacks[id]!.cancelable = task
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
func convertRegionsToJSON(regions: [TileRegion], resolve: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
|
|
194
389
|
let taskGroup = DispatchGroup()
|
|
195
390
|
|
|
196
391
|
var geomteryResults : [String: (Result<Geometry,Error>,TileRegion)] = [:]
|
|
@@ -219,21 +414,21 @@ class RCTMGLOfflineModule: RCTEventEmitter {
|
|
|
219
414
|
return false
|
|
220
415
|
}
|
|
221
416
|
}
|
|
222
|
-
|
|
417
|
+
|
|
223
418
|
if let firstError = firstError {
|
|
224
419
|
switch firstError.value.0 {
|
|
225
420
|
case .failure(let error):
|
|
226
|
-
rejecter("
|
|
421
|
+
rejecter("convertRegionsToJSON", error.localizedDescription, error)
|
|
227
422
|
return
|
|
228
423
|
case .success:
|
|
229
|
-
fatalError("Expected failure but was success")
|
|
424
|
+
fatalError("convertRegionsToJson:Expected failure but was success")
|
|
230
425
|
}
|
|
231
426
|
}
|
|
232
|
-
|
|
427
|
+
|
|
233
428
|
let results = geomteryResults.map { (id, result) -> (String, (Geometry,TileRegion, [String:Any]?)) in
|
|
234
429
|
switch result.0 {
|
|
235
430
|
case .failure(_):
|
|
236
|
-
fatalError("Expected
|
|
431
|
+
fatalError("convertRegionsToJson:Expected success but was failure")
|
|
237
432
|
case .success(let geometry):
|
|
238
433
|
return (id, (geometry,result.1,(try? metadataResults[id]?.get()) as? [String:Any]))
|
|
239
434
|
}
|
|
@@ -248,60 +443,58 @@ class RCTMGLOfflineModule: RCTEventEmitter {
|
|
|
248
443
|
progress: self.toProgress(region: region),
|
|
249
444
|
metadata: logged("RCTMGLOfflineModule.getPacks metadata is null") { metadata } ?? [:]
|
|
250
445
|
)
|
|
251
|
-
|
|
252
|
-
if ((region.
|
|
446
|
+
|
|
447
|
+
if ((region.hasCompleted())) {
|
|
253
448
|
pack.state = .complete
|
|
254
449
|
}
|
|
255
|
-
|
|
450
|
+
|
|
256
451
|
self.tileRegionPacks[region.id] = pack
|
|
257
|
-
|
|
452
|
+
|
|
258
453
|
return ret
|
|
259
454
|
})
|
|
260
455
|
}
|
|
261
456
|
}
|
|
262
457
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
458
|
+
func convertRegionToJSON(region: TileRegion, geometry: Geometry, metadata: [String:Any]?) -> [String:Any] {
|
|
459
|
+
let bb = RCTMGLFeatureUtils.boundingBox(geometry: geometry)
|
|
460
|
+
|
|
461
|
+
if let bb = bb {
|
|
462
|
+
let jsonBounds = [
|
|
463
|
+
bb.northEast.longitude, bb.northEast.latitude,
|
|
464
|
+
bb.southWest.longitude, bb.southWest.latitude
|
|
465
|
+
]
|
|
466
|
+
|
|
467
|
+
let completed = (region.completedResourceCount == region.requiredResourceCount)
|
|
468
|
+
|
|
469
|
+
var metadata : [String:Any] = metadata ?? [:]
|
|
470
|
+
metadata["name"] = region.id
|
|
471
|
+
|
|
472
|
+
var result : [String:Any] = [
|
|
473
|
+
"requiredResourceCount": region.requiredResourceCount,
|
|
474
|
+
"completedResourceCount": region.completedResourceCount,
|
|
475
|
+
"completedResourceSize": region.completedResourceSize,
|
|
476
|
+
"state": completed ? State.complete.rawValue : State.unknown.rawValue,
|
|
477
|
+
"metadata": String(data:try! JSONSerialization.data(withJSONObject: metadata, options: [.prettyPrinted]), encoding: .utf8),
|
|
478
|
+
"bounds": jsonBounds
|
|
479
|
+
]
|
|
480
|
+
|
|
481
|
+
if region.requiredResourceCount > 0 {
|
|
482
|
+
result["percentage"] = region.toPercentage()
|
|
483
|
+
} else {
|
|
484
|
+
result["percentage"] = nil
|
|
485
|
+
}
|
|
486
|
+
if let expires = region.expires {
|
|
487
|
+
result["expires"] = expires.toJSONString()
|
|
275
488
|
}
|
|
276
489
|
|
|
277
|
-
/*
|
|
278
|
-
self.offlineManager.allStylePacks { (result) in
|
|
279
|
-
switch result {
|
|
280
|
-
case .success(let packs):
|
|
281
|
-
resolve(self.convertPacksToJson(packs: packs))
|
|
282
|
-
case .failure(let error):
|
|
283
|
-
rejecter(error.localizedDescription, error.localizedDescription, error)
|
|
284
|
-
}
|
|
285
|
-
}*/
|
|
286
490
|
}
|
|
491
|
+
return [:]
|
|
492
|
+
}
|
|
287
493
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
// dispatch_async(dispatch_get_main_queue(), ^{
|
|
291
|
-
/*
|
|
292
|
-
NSArray<MGLOfflinePack *> *packs = [[MGLOfflineStorage sharedOfflineStorage] packs];
|
|
293
|
-
|
|
294
|
-
if (packs == nil) {
|
|
295
|
-
// packs have not loaded yet
|
|
296
|
-
[self->packRequestQueue addObject:resolve];
|
|
297
|
-
return;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
resolve([self _convertPacksToJson:packs]);
|
|
301
|
-
});*/
|
|
494
|
+
func toProgress(region: TileRegion) -> TileRegionLoadProgress? {
|
|
495
|
+
return TileRegionLoadProgress(completedResourceCount: region.completedResourceCount, completedResourceSize: region.completedResourceSize, erroredResourceCount: 0, requiredResourceCount: region.requiredResourceCount, loadedResourceCount: 0, loadedResourceSize: 0)
|
|
302
496
|
}
|
|
303
497
|
|
|
304
|
-
|
|
305
498
|
func convertPointPairToBounds(_ bounds: Geometry) -> Geometry {
|
|
306
499
|
guard case .geometryCollection(let gc) = bounds else {
|
|
307
500
|
return bounds
|
|
@@ -320,10 +513,10 @@ class RCTMGLOfflineModule: RCTEventEmitter {
|
|
|
320
513
|
let pt1 = g1.coordinates
|
|
321
514
|
return .polygon(Polygon([
|
|
322
515
|
[
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
516
|
+
pt0,
|
|
517
|
+
CLLocationCoordinate2D(latitude: pt0.latitude, longitude: pt1.longitude),
|
|
518
|
+
pt1,
|
|
519
|
+
CLLocationCoordinate2D(latitude: pt1.latitude, longitude: pt0.longitude)
|
|
327
520
|
]
|
|
328
521
|
]))
|
|
329
522
|
}
|
|
@@ -338,12 +531,10 @@ class RCTMGLOfflineModule: RCTEventEmitter {
|
|
|
338
531
|
func _makeRegionStatusPayload(_ name:String, progress: TileRegionLoadProgress?, state: State, metadata:[String:Any]?) -> [String:Any?] {
|
|
339
532
|
var result : [String:Any?] = [:]
|
|
340
533
|
if let progress = progress {
|
|
341
|
-
let progressPercentage = Float(progress.completedResourceCount) / Float(progress.requiredResourceCount)
|
|
342
|
-
|
|
343
534
|
result = [
|
|
344
|
-
"state": (progress.
|
|
535
|
+
"state": (progress.hasCompleted()) ? State.complete.rawValue : state.rawValue,
|
|
345
536
|
"name": name,
|
|
346
|
-
"percentage":
|
|
537
|
+
"percentage": progress.toPercentage(),
|
|
347
538
|
"completedResourceCount": progress.completedResourceCount,
|
|
348
539
|
"completedResourceSize": progress.completedResourceSize,
|
|
349
540
|
"erroredResourceCount": progress.erroredResourceCount,
|
|
@@ -383,228 +574,7 @@ class RCTMGLOfflineModule: RCTEventEmitter {
|
|
|
383
574
|
let event = RCTMGLEvent(type: .offlineError, payload: ["name": name, "message": error.localizedDescription])
|
|
384
575
|
self._sendEvent(Callbacks.error.rawValue, event: event)
|
|
385
576
|
}
|
|
386
|
-
|
|
387
|
-
@objc
|
|
388
|
-
func createPack(_ options: NSDictionary, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
|
|
389
|
-
DispatchQueue.main.async {
|
|
390
|
-
do {
|
|
391
|
-
let metadataStr = options["metadata"] as! String
|
|
392
|
-
var metadata = try JSONSerialization.jsonObject(with: metadataStr.data(using: .utf8)!, options: []) as! [String:Any]
|
|
393
|
-
metadata["styleURI"] = options["styleURL"]
|
|
394
|
-
let id = metadata["name"] as! String
|
|
395
|
-
|
|
396
|
-
let boundsStr = options["bounds"] as! String
|
|
397
|
-
let boundsData = boundsStr.data(using: .utf8)
|
|
398
|
-
var boundsFC = try JSONDecoder().decode(FeatureCollection.self, from: boundsData!)
|
|
399
|
-
|
|
400
|
-
var bounds = self.convertPointPairToBounds(RCTMGLFeatureUtils.fcToGeomtry(boundsFC))
|
|
401
|
-
|
|
402
|
-
let actPack = RCTMGLOfflineModule.TileRegionPack(
|
|
403
|
-
name: id,
|
|
404
|
-
styleURI: StyleURI(rawValue: options["styleURL"] as! String)!,
|
|
405
|
-
bounds: bounds,
|
|
406
|
-
zoomRange: (options["minZoom"] as! NSNumber).uint8Value...(options["maxZoom"] as! NSNumber).uint8Value,
|
|
407
|
-
metadata: metadata
|
|
408
|
-
)
|
|
409
|
-
self.tileRegionPacks[id] = actPack
|
|
410
|
-
self.startLoading(pack: actPack)
|
|
411
|
-
|
|
412
|
-
resolver([
|
|
413
|
-
"bounds": boundsStr,
|
|
414
|
-
"metadata": String(data:try! JSONSerialization.data(withJSONObject: metadata, options: [.prettyPrinted]), encoding: .utf8)
|
|
415
|
-
])
|
|
416
|
-
} catch {
|
|
417
|
-
rejecter("createPack", error.localizedDescription, error)
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
func startLoading(pack: TileRegionPack) {
|
|
423
|
-
let id = pack.name
|
|
424
|
-
guard let bounds = pack.bounds else {
|
|
425
|
-
RCTMGLLogError("RCTMGLOfflineModule.startLoading failed as there are no bounds in pack")
|
|
426
|
-
return
|
|
427
|
-
}
|
|
428
|
-
guard let zoomRange = pack.zoomRange else {
|
|
429
|
-
RCTMGLLogError("RCTMGLOfflineModule.startLoading failed as there is no zoom range in pack")
|
|
430
|
-
return
|
|
431
|
-
}
|
|
432
|
-
guard let styleURI = pack.styleURI else {
|
|
433
|
-
RCTMGLLogError("RCTMGLOfflineModule.startLoading failed as there is no styleURI in pack")
|
|
434
|
-
return
|
|
435
|
-
}
|
|
436
|
-
guard let metadata = pack.metadata else {
|
|
437
|
-
RCTMGLLogError("RCTMGLOfflineModule.startLoading failed as there is no metadata in pack")
|
|
438
|
-
return
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
let stylePackLoadOptions = StylePackLoadOptions(glyphsRasterizationMode: .ideographsRasterizedLocally, metadata: pack.metadata)
|
|
442
|
-
|
|
443
|
-
let descriptorOptions = TilesetDescriptorOptions(
|
|
444
|
-
styleURI: styleURI,
|
|
445
|
-
zoomRange: zoomRange,
|
|
446
|
-
stylePackOptions: stylePackLoadOptions
|
|
447
|
-
)
|
|
448
|
-
let tilesetDescriptor = self.offlineManager.createTilesetDescriptor(for: descriptorOptions)
|
|
449
|
-
|
|
450
|
-
let loadOptions = TileRegionLoadOptions(
|
|
451
|
-
geometry: bounds, // RCTMGLFeatureUtils.geometryToGeometry(bounds),
|
|
452
|
-
descriptors: [tilesetDescriptor],
|
|
453
|
-
metadata: metadata,
|
|
454
|
-
acceptExpired: true,
|
|
455
|
-
networkRestriction: .none,
|
|
456
|
-
averageBytesPerSecond: nil)
|
|
457
|
-
|
|
458
|
-
var lastProgress : TileRegionLoadProgress? = nil
|
|
459
|
-
let task = self.tileStore.loadTileRegion(forId: id, loadOptions: loadOptions!, progress: {
|
|
460
|
-
progress in
|
|
461
|
-
lastProgress = progress
|
|
462
|
-
self.tileRegionPacks[id]!.progress = progress
|
|
463
|
-
self.tileRegionPacks[id]!.state = .active
|
|
464
|
-
self.offlinePackProgressDidChange(progress: progress, metadata: metadata, state: .active)
|
|
465
|
-
}) { result in
|
|
466
|
-
switch result {
|
|
467
|
-
case .success(let value):
|
|
468
|
-
DispatchQueue.main.async {
|
|
469
|
-
if let progess = lastProgress {
|
|
470
|
-
self.offlinePackProgressDidChange(progress: progess, metadata: metadata, state: .complete)
|
|
471
|
-
}
|
|
472
|
-
self.tileRegionPacks[id]!.state = .complete
|
|
473
|
-
}
|
|
474
|
-
case .failure(let error):
|
|
475
|
-
DispatchQueue.main.async {
|
|
476
|
-
self.tileRegionPacks[id]!.state = .inactive
|
|
477
|
-
self.offlinePackDidReceiveError(name: id, error: error)
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
self.tileRegionPacks[id]!.cancelable = task
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
func _getPack(fromName: String) -> TileRegionPack? {
|
|
485
|
-
return self.tileRegionPacks[fromName]
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
@objc
|
|
489
|
-
func getPackStatus(_ name: String,
|
|
490
|
-
resolver: @escaping RCTPromiseResolveBlock,
|
|
491
|
-
rejecter: @escaping RCTPromiseRejectBlock) {
|
|
492
|
-
guard let pack = self._getPack(fromName: name) else {
|
|
493
|
-
resolver(nil)
|
|
494
|
-
return
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
tileStore.tileRegionMetadata(forId: name) { result in
|
|
498
|
-
switch result {
|
|
499
|
-
case .failure(let error):
|
|
500
|
-
Logger.log(level:.error, message: "Unable to fetch metadata for \(name)")
|
|
501
|
-
rejecter("RCTMGLOfflineModule.getPackStatus", error.localizedDescription, error)
|
|
502
|
-
case .success(let metadata):
|
|
503
|
-
var pack = self.tileRegionPacks[name] ?? TileRegionPack(
|
|
504
|
-
name: name,
|
|
505
|
-
metadata: logged("RCTMGLOfflineModule.getPackStatus") { metadata as? [String:Any] } ?? [:]
|
|
506
|
-
)
|
|
507
|
-
self.tileRegionPacks[name] = pack
|
|
508
|
-
resolver(self._makeRegionStatusPayload(pack: pack))
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
@objc
|
|
515
|
-
func resumePackDownload(_ name: String, resolver: RCTPromiseResolveBlock, rejecter: RCTPromiseRejectBlock)
|
|
516
|
-
{
|
|
517
|
-
if let pack = _getPack(fromName: name) {
|
|
518
|
-
self.startLoading(pack: pack)
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
@objc
|
|
523
|
-
func pausePackDownload(_ name: String, resolver: RCTPromiseResolveBlock, rejecter: RCTPromiseRejectBlock)
|
|
524
|
-
{
|
|
525
|
-
if let pack = _getPack(fromName: name) {
|
|
526
|
-
pack.cancelable?.cancel()
|
|
527
|
-
resolver(nil)
|
|
528
|
-
} else {
|
|
529
|
-
rejecter("pausePackDownload", "Unknown offline region: \(name)", nil)
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
@objc
|
|
534
|
-
func setTileCountLimit(_ limit: NSNumber) {
|
|
535
|
-
self.offlineRegionManager.setOfflineMapboxTileCountLimitForLimit(limit.uint64Value)
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
@objc
|
|
540
|
-
func deletePack(_ name: String,
|
|
541
|
-
resolver: RCTPromiseResolveBlock,
|
|
542
|
-
rejecter: RCTPromiseRejectBlock)
|
|
543
|
-
{
|
|
544
|
-
guard let pack = _getPack(fromName: name) else {
|
|
545
|
-
return resolver(nil)
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
guard pack.state != .invalid else {
|
|
549
|
-
let error = NSError(domain:"RCTMGLErororDomain", code: 1, userInfo: [NSLocalizedDescriptionKey: "Pack has already beend deleted"])
|
|
550
|
-
return rejecter("deletePack", error.description, error)
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
self.tileStore.removeTileRegion(forId: name)
|
|
554
|
-
self.tileRegionPacks[name]!.state = .invalid
|
|
555
|
-
resolver(nil)
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
@objc
|
|
559
|
-
func migrateOfflineCache(_ resolve : @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
560
|
-
// Old and new cache file paths
|
|
561
|
-
let srcURL = URL(fileURLWithPath: NSHomeDirectory()).appendingPathComponent("/Library/Application Support/com.mapbox.examples/.mapbox/cache.db")
|
|
562
|
-
|
|
563
|
-
let destURL = URL(fileURLWithPath: NSHomeDirectory()).appendingPathComponent("/Library/Application Support/.mapbox/map_data/map_data.db")
|
|
564
|
-
|
|
565
|
-
let fileManager = FileManager.default
|
|
566
|
-
|
|
567
|
-
do {
|
|
568
|
-
try fileManager.createDirectory(at: destURL.deletingLastPathComponent(), withIntermediateDirectories: true, attributes: nil)
|
|
569
|
-
try fileManager.moveItem(at: srcURL, to: destURL)
|
|
570
|
-
resolve(nil)
|
|
571
|
-
} catch {
|
|
572
|
-
reject("migrateOfflineCache", error.localizedDescription, error)
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
@objc
|
|
577
|
-
func resetDatabase(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
578
|
-
self.tileStore.allTileRegions { result in
|
|
579
|
-
switch result {
|
|
580
|
-
case .success(let regions):
|
|
581
|
-
regions.forEach { region in
|
|
582
|
-
self.tileStore.removeTileRegion(forId: region.id)
|
|
583
|
-
}
|
|
584
|
-
self.offlineManager.allStylePacks { result in
|
|
585
|
-
switch result {
|
|
586
|
-
case .success(let packs):
|
|
587
|
-
packs.forEach { pack in
|
|
588
|
-
if let url = logged("RCTMGLOfflineModule.resetDatabase invalid styleURI",fn: { return URL(string: pack.styleURI) }),
|
|
589
|
-
let styleUri = logged("RCTMGLOfflineModule.resetDatabase invalid styleURI2", fn: { return StyleURI(url: url) }) {
|
|
590
|
-
self.offlineManager.removeStylePack(for: styleUri)
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
resolve(nil)
|
|
594
|
-
case .failure(let error):
|
|
595
|
-
Logger.log(level:.error, message: "RCTMGLOfflineModule.resetDatabase/allStylePacks \(error.localizedDescription) \(error)")
|
|
596
|
-
reject("RCTMGLOfflineModule.resetDatabase/allStylePacks", error.localizedDescription, error)
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
case .failure(let error):
|
|
600
|
-
Logger.log(level:.error, message: "RCTMGLOfflineModule.resetDatabase/allTileRegions \(error.localizedDescription) \(error)")
|
|
601
|
-
reject("RCTMGLOfflineModule.resetDatabase/allTileRegions", error.localizedDescription, error)
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
577
|
}
|
|
607
|
-
|
|
608
578
|
// MARK: progress throttle
|
|
609
579
|
|
|
610
580
|
extension RCTMGLOfflineModule {
|
|
@@ -639,3 +609,20 @@ extension RCTMGLOfflineModule {
|
|
|
639
609
|
}
|
|
640
610
|
}
|
|
641
611
|
|
|
612
|
+
extension TileRegionLoadProgress {
|
|
613
|
+
func toPercentage() -> Float {
|
|
614
|
+
return Float(100.0) * Float(completedResourceCount) / Float(requiredResourceCount);
|
|
615
|
+
}
|
|
616
|
+
func hasCompleted() -> Bool {
|
|
617
|
+
return (completedResourceCount == requiredResourceCount)
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
extension TileRegion {
|
|
622
|
+
func toPercentage() -> Float {
|
|
623
|
+
return Float(100.0) * Float(completedResourceCount) / Float(requiredResourceCount)
|
|
624
|
+
}
|
|
625
|
+
func hasCompleted() -> Bool {
|
|
626
|
+
return (completedResourceCount == requiredResourceCount)
|
|
627
|
+
}
|
|
628
|
+
}
|