Skip to content

Commit

Permalink
feat: add support for offline downloading of tilesets
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinmanncito committed Sep 20, 2024
1 parent 96552bc commit 915426e
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class TileRegionPack(var name: String, var state: TileRegionPackState = TileRegi

// stored in metadata for resume functionality
var styleURI: String? = null
var tilesets: List<String> = emptyList()
var bounds: Geometry? = null
var zoomRange: ZoomRange? = null

Expand Down Expand Up @@ -79,17 +80,20 @@ class TileRegionPack(var name: String, var state: TileRegionPackState = TileRegi
name: String,
state: TileRegionPackState = TileRegionPackState.UNKNOWN,
styleURI: String,
tilesets: List<String>,
bounds: Geometry,
zoomRange: ZoomRange,
metadata: JSONObject
) : this(name= name, state= state,progress= null, metadata= metadata) {
) : this(name= name, state= state, progress= null, metadata= metadata) {
val rnmeta = JSONObject()
rnmeta.put("styleURI", styleURI)
this.styleURI = styleURI
rnmeta.put("bounds", bounds.toJSONObject())
this.bounds = bounds
rnmeta.put("zoomRange", JSONArray(arrayOf(zoomRange.minZoom, zoomRange.maxZoom)))
this.zoomRange = zoomRange
rnmeta.put("tilesets", JSONArray(tilesets))
this.tilesets = tilesets
this.metadata.put(RNMapboxInfoMetadataKey, rnmeta);
}
}
Expand Down Expand Up @@ -143,9 +147,11 @@ class RNMBXOfflineModule(private val mReactContext: ReactApplicationContext) :
val boundsFC = FeatureCollection.fromJson(boundsStr)
val bounds = convertPointPairToBounds(boundsFC)

val tilesets = options.getArray("tilesets")?.toArrayList()?.map { it as String } ?: emptyList()
val actPack = TileRegionPack(
name = id,
styleURI = options.getString("styleURL")!!,
tilesets = tilesets,
bounds = bounds,
zoomRange = ZoomRange(
minZoom = options.getInt("minZoom").toByte(),
Expand Down Expand Up @@ -293,11 +299,20 @@ class RNMBXOfflineModule(private val mReactContext: ReactApplicationContext) :
.stylePackOptions(stylePackOptions)
.pixelRatio(2.0f)
.build()
val tilesetDescriptor = offlineManager.createTilesetDescriptor(descriptorOptions)

val descriptor = offlineManager.createTilesetDescriptor(descriptorOptions)
val tilesetDescriptorOptions = TilesetDescriptorOptionsForTilesets.Builder()
.tilesets(pack.tilesets)
.minZoom(zoomRange.minZoom)
.maxZoom(zoomRange.maxZoom)
.build()
val tilesetDescriptor = offlineManager.createTilesetDescriptor(tilesetDescriptorOptions)
val descriptors = arrayListOf(descriptor)
if (pack.tilesets.isNotEmpty()) {
descriptors.add(tilesetDescriptor)
}
val loadOptions = TileRegionLoadOptions.Builder()
.geometry(bounds)
.descriptors(arrayListOf(tilesetDescriptor))
.descriptors(descriptors)
.metadata(metadata.toMapboxValue())
.acceptExpired(true)
.networkRestriction(NetworkRestriction.NONE)
Expand Down
5 changes: 5 additions & 0 deletions example/src/examples/Map/OfflineExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ const OfflineExample = () => {
const options = {
name: packName,
styleURL: STYLE_URL,
tilesets: [
'mapbox://mapbox.mapbox-streets-v8',
'mapbox://mapbox.mapbox-terrain-dem-v1',
'mapbox://mapbox.country-boundaries-v1',
], // Any tilesets that should be included in the offline download
bounds: [
[bounds[0], bounds[1]],
[bounds[2], bounds[3]],
Expand Down
24 changes: 20 additions & 4 deletions ios/RNMBX/Offline/RNMBXOfflineModule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ class RNMBXOfflineModule: RCTEventEmitter {
self.state = state

if let rnMetadata = metadata[RNMapboxInfoMetadataKey] as? [String:Any] {
if let tilesets = rnMetadata["tilesets"] as? [String] {
self.tilesets = tilesets
}
if let styleURI = rnMetadata["styleURI"] as? String {
self.styleURI = StyleURI(rawValue: styleURI)
}
Expand All @@ -82,20 +85,22 @@ class RNMBXOfflineModule: RCTEventEmitter {
state: State = .unknown,
styleURI: StyleURI,
bounds: Geometry,
tilesets: [String],
zoomRange: ClosedRange<UInt8>,
metadata: [String:Any]) {
self.name = name
self.progress = nil
self.cancelable = nil
self.state = state

self.styleURI = styleURI
self.bounds = bounds
self.zoomRange = zoomRange
self.tilesets = tilesets

var metadata = metadata
metadata[RNMapboxInfoMetadataKey] = [
"styleURI": styleURI.rawValue,
"tilesets": logged("RNMBXOfflineModule.TileRegionPack: cannot encode tilesets") { try JSONSerialization.jsonObject(with: try! JSONEncoder().encode(tilesets)) },
"bounds": logged("RNMBXOfflineModule.TileRegionPack: cannot encode bounds") { try JSONSerialization.jsonObject(with: try! JSONEncoder().encode(bounds)) },
"zoomRange": logged("RNMBXOfflineModule.TileRegionPack: cannot encode zoomRange") { try JSONSerialization.jsonObject(with: try! JSONEncoder().encode(zoomRange))}
]
Expand All @@ -109,6 +114,7 @@ class RNMBXOfflineModule: RCTEventEmitter {
var metadata : [String:Any]

// Stored in metadata for resume functionality:
var tilesets : [String] = []
var bounds: Geometry? = nil
var zoomRange: ClosedRange<UInt8>? = nil
var styleURI: StyleURI? = nil
Expand Down Expand Up @@ -177,9 +183,11 @@ class RNMBXOfflineModule: RCTEventEmitter {
name: id,
styleURI: StyleURI(rawValue: options["styleURL"] as! String)!,
bounds: bounds,
tilesets: options["tilesets"] as? [String] ?? [],
zoomRange: (options["minZoom"] as! NSNumber).uint8Value...(options["maxZoom"] as! NSNumber).uint8Value,
metadata: metadata
)

self.tileRegionPacks[id] = actPack
self.startLoading(pack: actPack)

Expand Down Expand Up @@ -362,21 +370,29 @@ class RNMBXOfflineModule: RCTEventEmitter {
let descriptorOptions = TilesetDescriptorOptions(
styleURI: styleURI,
zoomRange: zoomRange,
tilesets: [], // RNMBX_11_TODO
tilesets: pack.tilesets,
stylePackOptions: stylePackLoadOptions
)
let tilesetDescriptor = self.offlineManager.createTilesetDescriptor(for: descriptorOptions)
let descriptors = [tilesetDescriptor]
#else
let descriptorOptions = TilesetDescriptorOptions(
styleURI: styleURI,
zoomRange: zoomRange,
stylePackOptions: stylePackLoadOptions
)
let descriptor = self.offlineManager.createTilesetDescriptor(for: descriptorOptions)
let tilesetDescriptorOptions = TilesetDescriptorOptionsForTilesets(tilesets: pack.tilesets, zoomRange: zoomRange)
let tilesetDescriptor = self.offlineManager.createTilesetDescriptorForTilesetDescriptorOptions(tilesetDescriptorOptions)
var descriptors = [descriptor]
if (!pack.tilesets.isEmpty) {
descriptors.append(tilesetDescriptor)
}
#endif
let tilesetDescriptor = self.offlineManager.createTilesetDescriptor(for: descriptorOptions)

let loadOptions = TileRegionLoadOptions(
geometry: bounds, // RNMBXFeatureUtils.geometryToGeometry(bounds),
descriptors: [tilesetDescriptor],
descriptors: descriptors,
metadata: metadata,
acceptExpired: true,
networkRestriction: .none,
Expand Down
3 changes: 3 additions & 0 deletions src/modules/offline/OfflineCreatePackOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export type OfflineCreatePackOptionsArgs = {
name: string;
styleURL: string;
bounds: [GeoJSON.Position, GeoJSON.Position];
tilesets?: string[];
minZoom?: number;
maxZoom?: number;
metadata?: Record<string, unknown>;
Expand All @@ -13,6 +14,7 @@ export type OfflineCreatePackOptionsArgs = {
class OfflineCreatePackOptions {
public readonly name: string;
public readonly styleURL: string;
public readonly tilesets: string[] | undefined;
public readonly bounds: string;
public readonly minZoom: number | undefined;
public readonly maxZoom: number | undefined;
Expand All @@ -27,6 +29,7 @@ class OfflineCreatePackOptions {
this.minZoom = options.minZoom;
this.maxZoom = options.maxZoom;
this.metadata = this._makeMetadata(options.metadata);
this.tilesets = options.tilesets;
}

_assert(options: OfflineCreatePackOptionsArgs) {
Expand Down

0 comments on commit 915426e

Please sign in to comment.