@rnmapbox/maps 10.0.0-rc.8 → 10.0.0

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.
Files changed (59) hide show
  1. package/README.md +1 -1
  2. package/android/rctmgl/src/main/AndroidManifest.xml +1 -0
  3. package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/components/AbstractEventEmitter.kt +2 -2
  4. package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/components/images/RCTMGLImagesManager.kt +2 -2
  5. package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/components/mapview/RCTMGLAndroidTextureMapViewManager.kt +7 -12
  6. package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/components/mapview/RCTMGLMapView.kt +29 -2
  7. package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/components/mapview/RCTMGLMapViewManager.kt +13 -2
  8. package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/modules/RCTMGLModule.kt +11 -0
  9. package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/modules/RCTMGLOfflineModule.kt +48 -80
  10. package/ios/RCTMGL-v10/Extensions/DefaultStringInterpolation+optional.swift +6 -2
  11. package/ios/RCTMGL-v10/RCTMGLEvent.swift +4 -5
  12. package/ios/RCTMGL-v10/RCTMGLImageSourceManager.m +1 -0
  13. package/ios/RCTMGL-v10/RCTMGLLogging.swift +1 -1
  14. package/ios/RCTMGL-v10/RCTMGLOfflineModule.swift +28 -17
  15. package/ios/RCTMGL-v10/RCTMGLRasterDemSourceManager.m +1 -0
  16. package/ios/RCTMGL-v10/RCTMGLRasterSourceManager.m +1 -0
  17. package/ios/RCTMGL-v10/RCTMGLShapeSourceManager.m +1 -0
  18. package/ios/RCTMGL-v10/RCTMGLSource.swift +8 -0
  19. package/ios/RCTMGL-v10/RCTMGLVectorSourceManager.m +1 -0
  20. package/lib/commonjs/components/MapView.js +4 -3
  21. package/lib/commonjs/components/MapView.js.map +1 -1
  22. package/lib/commonjs/components/RasterDemSource.js +1 -0
  23. package/lib/commonjs/components/RasterDemSource.js.map +1 -1
  24. package/lib/commonjs/components/RasterSource.js +1 -0
  25. package/lib/commonjs/components/RasterSource.js.map +1 -1
  26. package/lib/commonjs/components/ShapeSource.js +1 -0
  27. package/lib/commonjs/components/ShapeSource.js.map +1 -1
  28. package/lib/commonjs/components/VectorSource.js +1 -0
  29. package/lib/commonjs/components/VectorSource.js.map +1 -1
  30. package/lib/commonjs/utils/StyleValue.js +3 -0
  31. package/lib/commonjs/utils/StyleValue.js.map +1 -1
  32. package/lib/module/components/MapView.js +4 -3
  33. package/lib/module/components/MapView.js.map +1 -1
  34. package/lib/module/components/RasterDemSource.js +1 -0
  35. package/lib/module/components/RasterDemSource.js.map +1 -1
  36. package/lib/module/components/RasterSource.js +1 -0
  37. package/lib/module/components/RasterSource.js.map +1 -1
  38. package/lib/module/components/ShapeSource.js +1 -0
  39. package/lib/module/components/ShapeSource.js.map +1 -1
  40. package/lib/module/components/VectorSource.js +1 -0
  41. package/lib/module/components/VectorSource.js.map +1 -1
  42. package/lib/module/utils/StyleValue.js +3 -0
  43. package/lib/module/utils/StyleValue.js.map +1 -1
  44. package/lib/typescript/components/MapView.d.ts +5 -0
  45. package/lib/typescript/components/MapView.d.ts.map +1 -1
  46. package/lib/typescript/components/RasterDemSource.d.ts.map +1 -1
  47. package/lib/typescript/components/RasterSource.d.ts.map +1 -1
  48. package/lib/typescript/components/ShapeSource.d.ts.map +1 -1
  49. package/lib/typescript/components/VectorSource.d.ts.map +1 -1
  50. package/lib/typescript/utils/StyleValue.d.ts.map +1 -1
  51. package/package.json +1 -1
  52. package/rnmapbox-maps.podspec +4 -1
  53. package/src/components/MapView.tsx +10 -3
  54. package/src/components/RasterDemSource.tsx +1 -0
  55. package/src/components/RasterSource.tsx +1 -0
  56. package/src/components/ShapeSource.tsx +1 -0
  57. package/src/components/VectorSource.tsx +1 -0
  58. package/src/utils/StyleValue.ts +13 -0
  59. package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/components/mapview/RCTMGLAndroidTextureMapView.java +0 -16
package/README.md CHANGED
@@ -84,7 +84,7 @@ _See [iOS](ios/install.md) & [Android](android/install.md) setup guide for more
84
84
 
85
85
  - [node](https://nodejs.org)
86
86
  - [npm](https://www.npmjs.com/)
87
- - [React Native](https://facebook.github.io/react-native/) (0.60+)
87
+ - [React Native](https://facebook.github.io/react-native/) (0.64+)
88
88
 
89
89
 
90
90
  ## Installation
@@ -1,4 +1,5 @@
1
1
  <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.mapbox.rctmgl">
2
2
  <uses-permission android:name="android.permission.INTERNET" />
3
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
3
4
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
4
5
  </manifest>
@@ -46,7 +46,7 @@ abstract class AbstractEventEmitter<T : ViewGroup?>(reactApplicationContext: Rea
46
46
  )
47
47
  }
48
48
 
49
- override fun addEventEmitters(context: ThemedReactContext, @Nonnull view: T) {
49
+ override fun addEventEmitters(context: ThemedReactContext, view: T) {
50
50
  mEventDispatcher = context.getNativeModule(UIManagerModule::class.java)!!.eventDispatcher
51
51
  }
52
52
 
@@ -72,4 +72,4 @@ abstract class AbstractEventEmitter<T : ViewGroup?>(reactApplicationContext: Rea
72
72
  companion object {
73
73
  private const val BRIDGE_TIMEOUT_MS = 10.0
74
74
  }
75
- }
75
+ }
@@ -61,7 +61,7 @@ class RCTMGLImagesManager(private val mContext: ReactApplicationContext) :
61
61
  ReadableType.String -> {
62
62
  val resourceName = dynamic.asString();
63
63
  val drawable =
64
- ResourceUtils.getDrawableByName(mContext, resourceName) as BitmapDrawable
64
+ ResourceUtils.getDrawableByName(mContext, resourceName) as BitmapDrawable?
65
65
  if (drawable != null) {
66
66
  return NativeImage(resourceName, drawable)
67
67
  } else {
@@ -97,7 +97,7 @@ class RCTMGLImagesManager(private val mContext: ReactApplicationContext) :
97
97
  scale = map.getDouble("scale")
98
98
  }
99
99
  val drawable =
100
- ResourceUtils.getDrawableByName(mContext, resourceName) as BitmapDrawable
100
+ ResourceUtils.getDrawableByName(mContext, resourceName) as BitmapDrawable?
101
101
  if (drawable != null && resourceName != null) {
102
102
  return NativeImage(resourceName, drawable, scale, sdf, stretchX, stretchY)
103
103
  } else {
@@ -2,27 +2,22 @@ package com.mapbox.rctmgl.components.mapview
2
2
 
3
3
  import com.facebook.react.bridge.ReactApplicationContext
4
4
  import com.facebook.react.uimanager.ThemedReactContext
5
+ import com.mapbox.maps.MapInitOptions
5
6
 
6
- //import com.mapbox.mapboxsdk.maps.MapboxMapOptions;
7
- /**
8
- * Created by hernanmateo on 12/11/18.
9
- */
10
- class RCTMGLAndroidTextureMapViewManager(context: ReactApplicationContext?) : RCTMGLMapViewManager(
11
- context!!
7
+ class RCTMGLAndroidTextureMapViewManager(context: ReactApplicationContext) : RCTMGLMapViewManager(
8
+ context
12
9
  ) {
13
10
  override fun getName(): String {
14
11
  return REACT_CLASS
15
12
  }
16
13
 
17
- override fun createViewInstance(themedReactContext: ThemedReactContext): RCTMGLAndroidTextureMapView {
18
- //MapboxMapOptions options = new MapboxMapOptions();
19
- //options.textureMode(true);
20
- val context = activity ?: themedReactContext
21
- return RCTMGLAndroidTextureMapView(context, this /*, options*/)
14
+ override fun createViewInstance(themedReactContext: ThemedReactContext): RCTMGLMapView {
15
+ val context = getMapViewContext(themedReactContext)
16
+ val options = MapInitOptions(context = context, textureView= true)
17
+ return RCTMGLMapView(context, this, options)
22
18
  }
23
19
 
24
20
  companion object {
25
- const val LOG_TAG = "RCTMGLAndroidTextureMapViewManager"
26
21
  const val REACT_CLASS = "RCTMGLAndroidTextureMapView"
27
22
  }
28
23
  }
@@ -147,7 +147,7 @@ data class FeatureEntry(val feature: AbstractMapFeature?, val view: View?, var a
147
147
 
148
148
  }
149
149
 
150
- open class RCTMGLMapView(private val mContext: Context, var mManager: RCTMGLMapViewManager /*, MapboxMapOptions options*/) : FrameLayout(mContext), OnMapClickListener, OnMapLongClickListener, OnLayoutChangeListener {
150
+ open class RCTMGLMapView(private val mContext: Context, var mManager: RCTMGLMapViewManager, options: MapInitOptions?) : FrameLayout(mContext), OnMapClickListener, OnMapLongClickListener, OnLayoutChangeListener {
151
151
  /**
152
152
  * `PointAnnotations` are rendered to a canvas, but the React Native `Image` component is
153
153
  * implemented on top of Fresco (https://frescolib.org), which does not load images for
@@ -192,6 +192,13 @@ open class RCTMGLMapView(private val mContext: Context, var mManager: RCTMGLMapV
192
192
  val viewAnnotationManager: ViewAnnotationManager
193
193
  get() = mapView.viewAnnotationManager
194
194
 
195
+ var requestDisallowInterceptTouchEvent: Boolean = false
196
+ set(value) {
197
+ val oldValue = field
198
+ field = value
199
+ updateRequestDisallowInterceptTouchEvent(oldValue, value)
200
+ }
201
+
195
202
  fun getMapboxMap(): MapboxMap {
196
203
  return mapView.getMapboxMap()
197
204
  }
@@ -1041,7 +1048,7 @@ open class RCTMGLMapView(private val mContext: Context, var mManager: RCTMGLMapV
1041
1048
  offscreenAnnotationViewContainer?.setLayoutParams(p)
1042
1049
  addView(offscreenAnnotationViewContainer)
1043
1050
 
1044
- mMapView = MapView(mContext)
1051
+ mMapView = if (options != null) MapView(mContext, options) else MapView(mContext)
1045
1052
 
1046
1053
  val matchParent = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
1047
1054
  mMapView.setLayoutParams(matchParent)
@@ -1356,6 +1363,26 @@ open class RCTMGLMapView(private val mContext: Context, var mManager: RCTMGLMapV
1356
1363
  // endregion
1357
1364
  }
1358
1365
 
1366
+ // region requestDisallowInterceptTouchEvent
1367
+ fun RCTMGLMapView.updateRequestDisallowInterceptTouchEvent(oldValue: Boolean, value: Boolean) {
1368
+ if (oldValue == value) {
1369
+ return
1370
+ }
1371
+ if (value) {
1372
+ mapView.setOnTouchListener { view, event ->
1373
+ this.requestDisallowInterceptTouchEvent(true)
1374
+ mapView.onTouchEvent(event)
1375
+ true
1376
+ }
1377
+ } else {
1378
+ mapView.setOnTouchListener { view, event ->
1379
+ mapView.onTouchEvent(event)
1380
+ }
1381
+ }
1382
+ }
1383
+ // endregion
1384
+
1385
+
1359
1386
  fun OrnamentSettings.setPosAndMargins(posAndMargins: ReadableMap?) {
1360
1387
  if (posAndMargins == null) { return }
1361
1388
 
@@ -1,5 +1,6 @@
1
1
  package com.mapbox.rctmgl.components.mapview
2
2
 
3
+ import android.content.Context
3
4
  import android.util.Log
4
5
  import android.view.View
5
6
  import com.facebook.react.bridge.*
@@ -11,6 +12,7 @@ import com.facebook.react.uimanager.annotations.ReactProp
11
12
  import com.mapbox.rctmgl.events.constants.EventKeys
12
13
  import com.mapbox.maps.MapboxMap
13
14
  import com.facebook.react.common.MapBuilder
15
+ import com.mapbox.maps.MapInitOptions
14
16
  import com.mapbox.maps.extension.style.layers.properties.generated.ProjectionName
15
17
  import com.mapbox.maps.plugin.compass.compass
16
18
  import com.mapbox.maps.plugin.gestures.gestures
@@ -75,9 +77,13 @@ open class RCTMGLMapViewManager(context: ReactApplicationContext) :
75
77
  mapView!!.removeFeatureAt(index)
76
78
  }
77
79
 
80
+ fun getMapViewContext(themedReactContext: ThemedReactContext): Context {
81
+ return activity ?: themedReactContext
82
+ }
83
+
78
84
  override fun createViewInstance(themedReactContext: ThemedReactContext): RCTMGLMapView {
79
- val context = activity ?: themedReactContext
80
- return RCTMGLMapView(context, this /*, null*/)
85
+ val context = getMapViewContext(themedReactContext)
86
+ return RCTMGLMapView(context, this, options=null)
81
87
  }
82
88
 
83
89
  override fun onDropViewInstance(mapView: RCTMGLMapView) {
@@ -227,6 +233,11 @@ open class RCTMGLMapViewManager(context: ReactApplicationContext) :
227
233
  //mapView.setTintColor(tintColor);
228
234
  }
229
235
 
236
+ @ReactProp(name = "requestDisallowInterceptTouchEvent")
237
+ fun setRequestDisallowInterceptTouchEvent(mapView: RCTMGLMapView, requestDisallowInterceptTouchEvent: Boolean) {
238
+ mapView.requestDisallowInterceptTouchEvent = requestDisallowInterceptTouchEvent
239
+ }
240
+
230
241
  //endregion
231
242
  //region Custom Events
232
243
  override fun customEvents(): Map<String, String>? {
@@ -14,7 +14,9 @@ import com.mapbox.rctmgl.modules.RCTMGLLocationModule
14
14
  import com.facebook.react.bridge.ReactMethod
15
15
  import com.facebook.react.common.MapBuilder
16
16
  import com.mapbox.common.*
17
+ import com.mapbox.maps.MapView
17
18
  import com.mapbox.maps.Style
19
+ import com.mapbox.maps.plugin.attribution.attribution
18
20
  import com.mapbox.rctmgl.components.camera.constants.CameraMode
19
21
  import java.util.HashMap
20
22
 
@@ -115,6 +117,15 @@ class RCTMGLModule(private val mReactContext: ReactApplicationContext) : ReactCo
115
117
  .build()
116
118
  }
117
119
 
120
+ @ReactMethod
121
+ fun setTelemetryEnabled(telemetryEnabled: Boolean) {
122
+ mReactContext.runOnUiQueueThread {
123
+ val dummyView = MapView(mReactContext)
124
+ val telemetry = dummyView.attribution.getMapAttributionDelegate().telemetry()
125
+ telemetry.userTelemetryRequestState = telemetryEnabled
126
+ }
127
+ }
128
+
118
129
  @ReactMethod
119
130
  fun setAccessToken(accessToken: String?, promise: Promise) {
120
131
  mReactContext.runOnUiQueueThread(Runnable {
@@ -41,7 +41,7 @@ enum class TileRegionPackState(val rawValue: String) {
41
41
  COMPLETE("complete"),
42
42
  UNKNOWN("unkown")
43
43
  }
44
- class TileRegionPack(var name: String, var progress: TileRegionLoadProgress?, var state: TileRegionPackState, var metadata: JSONObject) {
44
+ class TileRegionPack(var name: String, var state: TileRegionPackState = TileRegionPackState.UNKNOWN, var progress: TileRegionLoadProgress? = null, var metadata: JSONObject) {
45
45
  var cancelable: Cancelable? = null
46
46
  var loadOptions: TileRegionLoadOptions? = null
47
47
 
@@ -78,7 +78,7 @@ class TileRegionPack(var name: String, var progress: TileRegionLoadProgress?, va
78
78
  bounds: Geometry,
79
79
  zoomRange: ZoomRange,
80
80
  metadata: JSONObject
81
- ) : this(name, null, state, metadata) {
81
+ ) : this(name= name, state= state,progress= null, metadata= metadata) {
82
82
  val rnmeta = JSONObject()
83
83
  rnmeta.put("styleURI", styleURI)
84
84
  this.styleURI = styleURI
@@ -163,12 +163,23 @@ class RCTMGLOfflineModule(private val mReactContext: ReactApplicationContext) :
163
163
  @ReactMethod
164
164
  fun getPackStatus(name: String, promise: Promise) {
165
165
  val pack = tileRegionPacks[name]
166
- if (pack != null) {
167
- promise.resolve(makeRegionStatus(name, pack.progress, pack))
168
- } else {
169
- promise.reject(Error("Pack not found"))
170
- Logger.w(REACT_CLASS, "getPackStatus - Unknown offline region")
166
+ if (pack == null) {
167
+ promise.reject(Error("Pack: $name not found"))
168
+ return
171
169
  }
170
+ tileStore.getTileRegionMetadata(name) { expected ->
171
+ expected.value?.also {
172
+ val pack = TileRegionPack(
173
+ name= name,
174
+ metadata= it.toJSONObject() ?: JSONObject()
175
+ )
176
+ tileRegionPacks[name] = pack
177
+ promise.resolve(_makeRegionStatusPayload(pack))
178
+ } ?: run {
179
+ promise.reject(LOG_TAG, expected.error!!.message)
180
+ }
181
+ }
182
+
172
183
  }
173
184
 
174
185
  @ReactMethod
@@ -246,7 +257,6 @@ class RCTMGLOfflineModule(private val mReactContext: ReactApplicationContext) :
246
257
  }
247
258
  })
248
259
  }
249
-
250
260
  // endregion
251
261
 
252
262
  fun startLoading(pack: TileRegionPack) {
@@ -277,6 +287,7 @@ class RCTMGLOfflineModule(private val mReactContext: ReactApplicationContext) :
277
287
  .minZoom(zoomRange.minZoom)
278
288
  .maxZoom(zoomRange.maxZoom)
279
289
  .stylePackOptions(stylePackOptions)
290
+ .pixelRatio(2.0f)
280
291
  .build()
281
292
  val tilesetDescriptor = offlineManager.createTilesetDescriptor(descriptorOptions)
282
293
 
@@ -368,7 +379,7 @@ class RCTMGLOfflineModule(private val mReactContext: ReactApplicationContext) :
368
379
  metadata= metadataJSON ?: JSONObject()
369
380
  )
370
381
 
371
- if (region.completedResourceCount == region.requiredResourceCount) {
382
+ if (region.hasCompleted()) {
372
383
  pack.state = TileRegionPackState.COMPLETE
373
384
  }
374
385
  tileRegionPacks[region.id] = pack
@@ -404,8 +415,7 @@ class RCTMGLOfflineModule(private val mReactContext: ReactApplicationContext) :
404
415
  );
405
416
 
406
417
  if (region.requiredResourceCount > 0) {
407
- val percentage = 100.0 * region.completedResourceCount.toDouble() / region.requiredResourceCount.toDouble()
408
- result.putDouble("percentage", percentage)
418
+ result.putDouble("percentage", region.toPercentage())
409
419
  } else {
410
420
  result.putNull("percentage")
411
421
  }
@@ -429,14 +439,17 @@ class RCTMGLOfflineModule(private val mReactContext: ReactApplicationContext) :
429
439
  )
430
440
  }
431
441
 
432
- private fun _makeRegionStatusPayload(name:String, progress: TileRegionLoadProgress?,state: TileRegionPackState, metadata: JSONObject?) : WritableMap {
442
+ private fun _makeRegionStatusPayload(pack: TileRegionPack): WritableMap {
443
+ return _makeRegionStatusPayload(pack.name, pack.progress, pack.state, pack.metadata)
444
+ }
445
+
446
+ private fun _makeRegionStatusPayload(name:String, progress: TileRegionLoadProgress?,state: TileRegionPackState, metadata: JSONObject?): WritableMap {
433
447
  var result = Arguments.createMap()
434
448
  if (progress != null) {
435
- val progressPercentage = progress.completedResourceCount.toDouble() / progress.requiredResourceCount.toDouble()
436
449
  result = writableMapOf(
437
- "state" to (if (progress.completedResourceCount == progress.requiredResourceCount) TileRegionPackState.COMPLETE.rawValue else state.rawValue),
450
+ "state" to (if (progress.hasCompleted()) TileRegionPackState.COMPLETE.rawValue else state.rawValue),
438
451
  "name" to name,
439
- "perentage" to progressPercentage * 100.0,
452
+ "percentage" to progress.toPercentage(),
440
453
  "completedResourceCount" to progress.completedResourceCount,
441
454
  "completedResourceSize" to progress.completedResourceSize,
442
455
  "erroredResourceCount" to progress.erroredResourceCount,
@@ -448,7 +461,7 @@ class RCTMGLOfflineModule(private val mReactContext: ReactApplicationContext) :
448
461
  result = writableMapOf(
449
462
  "state" to state.rawValue,
450
463
  "name" to name,
451
- "perentage" to null,
464
+ "percentage" to null,
452
465
  )
453
466
  }
454
467
  if (metadata != null) {
@@ -456,16 +469,10 @@ class RCTMGLOfflineModule(private val mReactContext: ReactApplicationContext) :
456
469
  }
457
470
  return result
458
471
  }
459
- private fun makeProgresEvent(name: String, progress: TileRegionLoadProgress, state: TileRegionPackState): OfflineEvent {
460
- return OfflineEvent(
461
- OFFLINE_PROGRESS,
462
- EventTypes.OFFLINE_STATUS,
463
- _makeRegionStatusPayload(name, progress, state, null)
464
- )
465
- }
472
+
466
473
  private fun offlinePackProgressDidChange(progress: TileRegionLoadProgress, metadata: JSONObject, state: TileRegionPackState) {
467
474
  // TODO throttle
468
- sendEvent(this.makeProgresEvent(metadata.getString("name"), progress, state))
475
+ sendEvent(this.makeProgressEvent(metadata.getString("name"), progress, state))
469
476
  }
470
477
 
471
478
  private fun offlinePackDidReceiveError(name: String, error: TileRegionError) {
@@ -505,36 +512,6 @@ class RCTMGLOfflineModule(private val mReactContext: ReactApplicationContext) :
505
512
  )
506
513
  }
507
514
 
508
- fun startPackDownload(pack: TileRegionPack) {
509
- val _this = this
510
- pack.cancelable = tileStore
511
- .loadTileRegion(
512
- pack.name,
513
- (pack.loadOptions)!!,
514
- TileRegionLoadProgressCallback { progress ->
515
- pack.progress = progress
516
- pack.state = TileRegionPackState.ACTIVE
517
- _this.sendEvent(_this.makeStatusEvent(pack.name, progress, pack))
518
- },
519
- object : TileRegionCallback {
520
- override fun run(region: Expected<TileRegionError, TileRegion>) {
521
- pack.cancelable = null
522
- if (region.isError) {
523
- pack.state = TileRegionPackState.INACTIVE
524
- _this.sendEvent(
525
- _this.makeErrorEvent(
526
- pack.name, "TileRegionError", region.error!!
527
- .message
528
- )
529
- )
530
- } else {
531
- pack.state = TileRegionPackState.COMPLETE
532
- _this.sendEvent(_this.makeStatusEvent(pack.name, pack.progress, pack))
533
- }
534
- }
535
- })
536
- }
537
-
538
515
  @ReactMethod
539
516
  fun resetDatabase(promise: Promise) {
540
517
  tileStore.getAllTileRegions { expected ->
@@ -622,38 +599,14 @@ class RCTMGLOfflineModule(private val mReactContext: ReactApplicationContext) :
622
599
  return OfflineEvent(OFFLINE_ERROR, errorType, payload)
623
600
  }
624
601
 
625
- private fun makeStatusEvent(
626
- regionName: String,
627
- status: TileRegionLoadProgress?,
628
- pack: TileRegionPack
629
- ): OfflineEvent {
602
+ private fun makeProgressEvent(name: String, progress: TileRegionLoadProgress, state: TileRegionPackState): OfflineEvent {
630
603
  return OfflineEvent(
631
604
  OFFLINE_PROGRESS,
632
605
  EventTypes.OFFLINE_STATUS,
633
- makeRegionStatus(regionName, status, pack)
606
+ _makeRegionStatusPayload(name, progress, state, null)
634
607
  )
635
608
  }
636
609
 
637
- private fun makeRegionStatus(
638
- regionName: String,
639
- status: TileRegionLoadProgress?,
640
- pack: TileRegionPack
641
- ): WritableMap {
642
- val map = Arguments.createMap()
643
- val progressPercentage =
644
- (status!!.completedResourceCount.toDouble() * 100.0) / (status.requiredResourceCount.toDouble())
645
- map.putString("name", regionName)
646
- map.putString("state", pack.state.rawValue)
647
- map.putDouble("percentage", progressPercentage)
648
- map.putInt("completedResourceCount", status.completedResourceCount.toInt())
649
- map.putInt("completedResourceSize", status.completedResourceSize.toInt())
650
- map.putInt("erroredResourceCount", status.erroredResourceCount.toInt())
651
- map.putInt("requiredResourceCount", status.requiredResourceCount.toInt())
652
- map.putInt("loadedResourceCount", status.loadedResourceCount.toInt())
653
- map.putInt("loadedResourceSize", status.loadedResourceSize.toInt())
654
- return map
655
- }
656
-
657
610
  companion object {
658
611
  const val REACT_CLASS = "RCTMGLOfflineModule"
659
612
  const val LOG_TAG = REACT_CLASS
@@ -663,6 +616,21 @@ class RCTMGLOfflineModule(private val mReactContext: ReactApplicationContext) :
663
616
  }
664
617
  }
665
618
 
619
+ fun TileRegionLoadProgress.toPercentage(): Double {
620
+ return (completedResourceCount.toDouble() * 100.0) / (requiredResourceCount.toDouble())
621
+ }
622
+
623
+ fun TileRegionLoadProgress.hasCompleted(): Boolean {
624
+ return (completedResourceCount == requiredResourceCount)
625
+ }
626
+
627
+ fun TileRegion.toPercentage(): Double {
628
+ return (completedResourceCount.toDouble() * 100.0) / (requiredResourceCount.toDouble())
629
+ }
630
+
631
+ fun TileRegion.hasCompleted(): Boolean {
632
+ return (completedResourceCount == requiredResourceCount)
633
+ }
666
634
 
667
635
 
668
636
 
@@ -1,5 +1,9 @@
1
1
  internal extension DefaultStringInterpolation {
2
2
  mutating func appendInterpolation<T>(optional: T?) {
3
- appendInterpolation(String(describing: optional))
3
+ if let optional = optional {
4
+ appendInterpolation(String(describing: optional))
5
+ } else {
6
+ appendInterpolation("nil")
7
+ }
4
8
  }
5
- }
9
+ }
@@ -1,15 +1,14 @@
1
1
  import Foundation
2
2
 
3
3
  protocol RCTMGLEventProtocol {
4
-
5
- func toJSON() -> [String: Any];
4
+ func toJSON() -> [String: Any?];
6
5
  }
7
6
 
8
7
  @objc
9
8
  class RCTMGLEvent : NSObject, RCTMGLEventProtocol {
10
9
  var type: String = ""
11
- var payload: [String:Any]? = nil
12
- func toJSON() -> [String: Any]
10
+ var payload: [String:Any?]? = nil
11
+ func toJSON() -> [String: Any?]
13
12
  {
14
13
  if let payload = payload {
15
14
  return ["type": type, "payload": payload];
@@ -41,7 +40,7 @@ class RCTMGLEvent : NSObject, RCTMGLEventProtocol {
41
40
  case shapeSourceLayerPress
42
41
  }
43
42
 
44
- init(type: EventType, payload: [String:Any]?) {
43
+ init(type: EventType, payload: [String:Any?]?) {
45
44
  self.type = type.rawValue
46
45
  self.payload = payload
47
46
  }
@@ -4,6 +4,7 @@
4
4
  @interface RCT_EXTERN_MODULE(RCTMGLImageSourceManager, RCTViewManager)
5
5
 
6
6
  RCT_EXPORT_VIEW_PROPERTY(id, NSString)
7
+ RCT_EXPORT_VIEW_PROPERTY(existing, BOOL)
7
8
  RCT_EXPORT_VIEW_PROPERTY(url, NSString)
8
9
  RCT_EXPORT_VIEW_PROPERTY(coordinates, NSArray)
9
10
 
@@ -20,7 +20,7 @@ class Logger {
20
20
  case verbose = "verbose"
21
21
  case debug = "debug"
22
22
  case info = "info"
23
- case warn = "warn"
23
+ case warn = "warning"
24
24
  case error = "error"
25
25
 
26
26
  var intValue : Int {
@@ -98,7 +98,7 @@ 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]? = nil
101
+ var metadata : [String:Any]
102
102
 
103
103
  // Stored in metadata for resume functionality:
104
104
  var bounds: Geometry? = nil
@@ -190,22 +190,22 @@ class RCTMGLOfflineModule: RCTEventEmitter {
190
190
  resolver: @escaping RCTPromiseResolveBlock,
191
191
  rejecter: @escaping RCTPromiseRejectBlock) {
192
192
  guard let pack = tileRegionPacks[name] else {
193
- resolver(nil)
193
+ rejecter("RCTMGLOfflineModule.getPackStatus", "pack \(name) not found", nil)
194
194
  return
195
195
  }
196
196
 
197
197
  tileStore.tileRegionMetadata(forId: name) { result in
198
198
  switch result {
199
- case .failure(let error):
200
- Logger.log(level:.error, message: "Unable to fetch metadata for \(name)")
201
- rejecter("RCTMGLOfflineModule.getPackStatus", error.localizedDescription, error)
202
199
  case .success(let metadata):
203
- var pack = self.tileRegionPacks[name] ?? TileRegionPack(
200
+ var pack = TileRegionPack(
204
201
  name: name,
205
202
  metadata: logged("RCTMGLOfflineModule.getPackStatus") { metadata as? [String:Any] } ?? [:]
206
203
  )
207
204
  self.tileRegionPacks[name] = pack
208
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
209
  }
210
210
  }
211
211
  }
@@ -325,6 +325,7 @@ class RCTMGLOfflineModule: RCTEventEmitter {
325
325
 
326
326
  func startLoading(pack: TileRegionPack) {
327
327
  let id = pack.name
328
+ let metadata = pack.metadata
328
329
  guard let bounds = pack.bounds else {
329
330
  RCTMGLLogError("RCTMGLOfflineModule.startLoading failed as there are no bounds in pack")
330
331
  return
@@ -337,10 +338,6 @@ class RCTMGLOfflineModule: RCTEventEmitter {
337
338
  RCTMGLLogError("RCTMGLOfflineModule.startLoading failed as there is no styleURI in pack")
338
339
  return
339
340
  }
340
- guard let metadata = pack.metadata else {
341
- RCTMGLLogError("RCTMGLOfflineModule.startLoading failed as there is no metadata in pack")
342
- return
343
- }
344
341
 
345
342
  let stylePackLoadOptions = StylePackLoadOptions(glyphsRasterizationMode: .ideographsRasterizedLocally, metadata: pack.metadata)
346
343
 
@@ -447,7 +444,7 @@ class RCTMGLOfflineModule: RCTEventEmitter {
447
444
  metadata: logged("RCTMGLOfflineModule.getPacks metadata is null") { metadata } ?? [:]
448
445
  )
449
446
 
450
- if ((region.completedResourceCount == region.requiredResourceCount)) {
447
+ if ((region.hasCompleted())) {
451
448
  pack.state = .complete
452
449
  }
453
450
 
@@ -482,8 +479,7 @@ class RCTMGLOfflineModule: RCTEventEmitter {
482
479
  ]
483
480
 
484
481
  if region.requiredResourceCount > 0 {
485
- let percentage = Float(100.0) * Float(region.completedResourceCount) / Float(region.requiredResourceCount)
486
- result["percentage"] = percentage
482
+ result["percentage"] = region.toPercentage()
487
483
  } else {
488
484
  result["percentage"] = nil
489
485
  }
@@ -535,12 +531,10 @@ class RCTMGLOfflineModule: RCTEventEmitter {
535
531
  func _makeRegionStatusPayload(_ name:String, progress: TileRegionLoadProgress?, state: State, metadata:[String:Any]?) -> [String:Any?] {
536
532
  var result : [String:Any?] = [:]
537
533
  if let progress = progress {
538
- let progressPercentage = Float(progress.completedResourceCount) / Float(progress.requiredResourceCount)
539
-
540
534
  result = [
541
- "state": (progress.completedResourceCount == progress.requiredResourceCount) ? State.complete.rawValue : state.rawValue,
535
+ "state": (progress.hasCompleted()) ? State.complete.rawValue : state.rawValue,
542
536
  "name": name,
543
- "percentage": progressPercentage * 100.0,
537
+ "percentage": progress.toPercentage(),
544
538
  "completedResourceCount": progress.completedResourceCount,
545
539
  "completedResourceSize": progress.completedResourceSize,
546
540
  "erroredResourceCount": progress.erroredResourceCount,
@@ -615,3 +609,20 @@ extension RCTMGLOfflineModule {
615
609
  }
616
610
  }
617
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
+ }
@@ -4,6 +4,7 @@
4
4
  @interface RCT_EXTERN_MODULE(RCTMGLRasterDemSourceManager, RCTViewManager)
5
5
 
6
6
  RCT_EXPORT_VIEW_PROPERTY(id, NSString)
7
+ RCT_EXPORT_VIEW_PROPERTY(existing, BOOL)
7
8
  RCT_EXPORT_VIEW_PROPERTY(url, NSString)
8
9
  RCT_EXPORT_VIEW_PROPERTY(tileUrlTemplates, NSArray)
9
10
  RCT_EXPORT_VIEW_PROPERTY(bounds, NSArray)
@@ -4,6 +4,7 @@
4
4
  @interface RCT_EXTERN_MODULE(RCTMGLRasterSourceManager, RCTViewManager)
5
5
 
6
6
  RCT_EXPORT_VIEW_PROPERTY(id, NSString)
7
+ RCT_EXPORT_VIEW_PROPERTY(existing, BOOL)
7
8
  RCT_EXPORT_VIEW_PROPERTY(url, NSString)
8
9
  RCT_EXPORT_VIEW_PROPERTY(tileUrlTemplates, NSArray)
9
10
 
@@ -5,6 +5,7 @@
5
5
  RCT_EXTERN_REMAP_MODULE(RCTMGLShapeSource, RCTMGLShapeSourceManager, RCTViewManager)
6
6
 
7
7
  RCT_EXPORT_VIEW_PROPERTY(id, NSString)
8
+ RCT_EXPORT_VIEW_PROPERTY(existing, BOOL)
8
9
  RCT_EXPORT_VIEW_PROPERTY(url, NSString)
9
10
  RCT_EXPORT_VIEW_PROPERTY(shape, NSString)
10
11
 
@@ -8,6 +8,8 @@ class RCTMGLSource : RCTMGLInteractiveElement {
8
8
  var source : Source? = nil
9
9
 
10
10
  var ownsSource : Bool = false
11
+
12
+ @objc var existing: Bool = false
11
13
 
12
14
  override func getLayerIDs() -> [String] {
13
15
  layers.compactMap {
@@ -69,8 +71,14 @@ class RCTMGLSource : RCTMGLInteractiveElement {
69
71
  self.map = map
70
72
 
71
73
  if style.sourceExists(withId: self.id) {
74
+ if (!existing) {
75
+ Logger.log(level: .warn, message: "Warning source with id:\(optional: id) referred to existing source but `existing` attibute was missing. https://github.com/rnmapbox/maps/wiki/Deprecated-ExistingSourceLayer")
76
+ }
72
77
  self.source = try! style.source(withId: self.id)
73
78
  } else {
79
+ if (existing) {
80
+ Logger.log(level: .warn, message: "Warning source with id:\(optional: id) marked as existing, but could not find in style, source identifiers: \(style.allSourceIdentifiers.map { [$0.id, $0.type.rawValue] })")
81
+ }
74
82
  let source = self.makeSource()
75
83
  self.ownsSource = true
76
84
  self.source = source