@rnmapbox/maps 10.0.0-beta.62 → 10.0.0-beta.65

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 (39) hide show
  1. package/android/install.md +1 -1
  2. package/android/rctmgl/.settings/org.eclipse.buildship.core.prefs +12 -1
  3. package/android/rctmgl/src/main/java-mapboxgl/common/com/mapbox/rctmgl/modules/RCTMGLLocationModule.java +5 -0
  4. package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/components/mapview/RCTMGLMapView.kt +11 -7
  5. package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/components/styles/sources/RCTMGLVectorSource.java +3 -6
  6. package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/modules/RCTMGLLocationModule.kt +5 -0
  7. package/index.d.ts +1 -0
  8. package/ios/RCTMGL-v10/RCTMGLCamera.swift +113 -0
  9. package/ios/RCTMGL-v10/RCTMGLLocationModule.m +1 -0
  10. package/ios/RCTMGL-v10/RCTMGLLocationModule.swift +33 -18
  11. package/ios/RCTMGL-v10/RCTMGLMapView.swift +26 -23
  12. package/ios/RCTMGL-v10/RCTMGLMapViewManager.swift +2 -2
  13. package/ios/RCTMGL-v10/RCTMGLMarkerView.swift +1 -0
  14. package/ios/RCTMGL-v10/RCTMGLOfflineModule.swift +55 -16
  15. package/ios/RCTMGL-v10/RCTMGLPointAnnotation.swift +65 -43
  16. package/ios/RCTMGL-v10/RCTMGLPointAnnotationManager.m +1 -0
  17. package/ios/RCTMGL-v10/RCTMGLStyleValue.swift +8 -1
  18. package/javascript/components/MapView.js +1 -1
  19. package/javascript/components/UserLocation.js +11 -0
  20. package/javascript/modules/location/locationManager.js +23 -2
  21. package/javascript/modules/offline/offlineManager.js +1 -1
  22. package/javascript/web/install.md +25 -0
  23. package/lib/commonjs/components/MapView.js +1 -1
  24. package/lib/commonjs/components/MapView.js.map +1 -1
  25. package/lib/commonjs/components/UserLocation.js +10 -0
  26. package/lib/commonjs/components/UserLocation.js.map +1 -1
  27. package/lib/commonjs/modules/location/locationManager.js +16 -1
  28. package/lib/commonjs/modules/location/locationManager.js.map +1 -1
  29. package/lib/commonjs/modules/offline/offlineManager.js +1 -1
  30. package/lib/commonjs/web/install.md +25 -0
  31. package/lib/module/components/MapView.js +1 -1
  32. package/lib/module/components/MapView.js.map +1 -1
  33. package/lib/module/components/UserLocation.js +10 -0
  34. package/lib/module/components/UserLocation.js.map +1 -1
  35. package/lib/module/modules/location/locationManager.js +17 -2
  36. package/lib/module/modules/location/locationManager.js.map +1 -1
  37. package/lib/module/modules/offline/offlineManager.js +1 -1
  38. package/lib/module/web/install.md +25 -0
  39. package/package.json +1 -1
@@ -4,7 +4,7 @@
4
4
 
5
5
  - mapbox: v10 latest mapbox implementation - *recommended*, not opensource requires access for download
6
6
  - maplibre: *DEFAULT* open source fork of older open source mapbox libraries with many improvements, will be removed in next version
7
- - mapbox-gl: classic mapbox libraries - should work but will be dropped, recent versions are not open source and requires acess for download, will be removed in next version
7
+ - mapbox-gl: classic mapbox libraries - should work but will be dropped, recent versions are not open source and requires access for download, will be removed in next version
8
8
 
9
9
  ## Mapbox Maps SDK v10
10
10
 
@@ -1,2 +1,13 @@
1
- connection.project.dir=../../example/android
1
+ arguments=--init-script /var/folders/nf/xt27lc4j4sv73tqskhkd_8xc0000gn/T/d146c9752a26f79b52047fb6dc6ed385d064e120494f96f08ca63a317c41f94c.gradle --init-script /var/folders/nf/xt27lc4j4sv73tqskhkd_8xc0000gn/T/52cde0cfcf3e28b8b7510e992210d9614505e0911af0c190bd590d7158574963.gradle
2
+ auto.sync=false
3
+ build.scans.enabled=false
4
+ connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(7.4.2))
5
+ connection.project.dir=
2
6
  eclipse.preferences.version=1
7
+ gradle.user.home=
8
+ java.home=/Library/Java/JavaVirtualMachines/jdk-11.0.14.jdk/Contents/Home
9
+ jvm.arguments=
10
+ offline.mode=false
11
+ override.workspace.settings=true
12
+ show.console.view=true
13
+ show.executions.view=true
@@ -94,6 +94,11 @@ public class RCTMGLLocationModule extends ReactContextBaseJavaModule {
94
94
  }
95
95
  }
96
96
 
97
+ @ReactMethod
98
+ public void setRequestsAlwaysUse(boolean requestsAlwaysUse) {
99
+ // IOS only. Ignored on Android.
100
+ }
101
+
97
102
  @ReactMethod
98
103
  public void stop() {
99
104
  stopLocationManager();
@@ -733,19 +733,23 @@ open class RCTMGLMapView(private val mContext: Context, var mManager: RCTMGLMapV
733
733
  }
734
734
 
735
735
  fun queryRenderedFeaturesAtPoint(callbackID: String?, point: PointF, filter: Expression?, layerIDs: List<String>?) {
736
- mMap?.queryRenderedFeatures(
737
- ScreenCoordinate(point.x.toDouble(), point.y.toDouble()),
738
- RenderedQueryOptions(layerIDs, filter)
739
- ) { features ->
736
+ if (mMap == null) {
737
+ Logger.e("queryRenderedFeaturesAtPoint", "mapbox map is null")
738
+ return
739
+ }
740
+ val screenCoordinate = ScreenCoordinate(point.x.toDouble(), point.y.toDouble())
741
+ val queryGeometry = RenderedQueryGeometry(screenCoordinate)
742
+ val layers = layerIDs?.takeUnless { it.isEmpty() } ?: null;
743
+ val queryOptions = RenderedQueryOptions(layers, filter)
744
+ mMap.queryRenderedFeatures(queryGeometry, queryOptions) { features ->
740
745
  if (features.isValue) {
741
746
  val featuresList = ArrayList<Feature?>()
742
747
  for (i in features.value!!) {
743
748
  featuresList.add(i.feature)
744
749
  }
745
-
746
- sendResponse(callbackID, {
750
+ sendResponse(callbackID) {
747
751
  it.putString("data", FeatureCollection.fromFeatures(featuresList).toJson())
748
- })
752
+ }
749
753
  } else {
750
754
  Logger.e("queryRenderedFeaturesAtPoint", features.error ?: "n/a")
751
755
  }
@@ -73,9 +73,6 @@ public class RCTMGLVectorSource extends RCTMGLTileSource<VectorSource> {
73
73
  return;
74
74
  }
75
75
 
76
-
77
- WritableMap payload = new WritableNativeMap();
78
-
79
76
  mMap.querySourceFeatures(
80
77
  getID(),
81
78
  new SourceQueryOptions(layerIDs, filter),
@@ -83,6 +80,7 @@ public class RCTMGLVectorSource extends RCTMGLTileSource<VectorSource> {
83
80
  new QueryFeaturesCallback() {
84
81
  @Override
85
82
  public void run(@NonNull Expected<String, List<QueriedFeature>> queriedFeatures) {
83
+ WritableMap payload = new WritableNativeMap();
86
84
  if (queriedFeatures.isError()) {
87
85
  //V10todo
88
86
  payload.putString("error", queriedFeatures.getError());
@@ -93,11 +91,10 @@ public class RCTMGLVectorSource extends RCTMGLTileSource<VectorSource> {
93
91
  }
94
92
  payload.putString("data", FeatureCollection.fromFeatures(features).toJson());
95
93
  }
94
+ AndroidCallbackEvent event = new AndroidCallbackEvent(RCTMGLVectorSource.this, callbackID, payload);
95
+ mManager.handleEvent(event);
96
96
  }
97
97
  }
98
98
  );
99
-
100
- AndroidCallbackEvent event = new AndroidCallbackEvent(this, callbackID, payload);
101
- mManager.handleEvent(event);
102
99
  }
103
100
  }
@@ -87,6 +87,11 @@ class RCTMGLLocationModule(reactContext: ReactApplicationContext) :
87
87
  }
88
88
  }
89
89
 
90
+ @ReactMethod
91
+ fun setRequestsAlwaysUse(requestsAlwaysUse: Boolean) {
92
+ // IOS only. Ignored on Android.
93
+ }
94
+
90
95
  @ReactMethod
91
96
  fun stop() {
92
97
  stopLocationManager()
package/index.d.ts CHANGED
@@ -612,6 +612,7 @@ export interface UserLocationProps {
612
612
  animated?: boolean;
613
613
  children?: ReactNode;
614
614
  minDisplacement?: number;
615
+ requestsAlwaysUse?: boolean;
615
616
  onPress?: () => void;
616
617
  onUpdate?: (location: MapboxGL.Location) => void;
617
618
  renderMode?: 'normal' | 'native';
@@ -123,28 +123,35 @@ class RCTMGLCamera : RCTMGLMapComponentBase, LocationConsumer {
123
123
  _updateCameraFromTrackingMode()
124
124
  }
125
125
  }
126
+
126
127
  @objc var followUserMode: String? {
127
128
  didSet {
128
129
  _updateCameraFromTrackingMode()
129
130
  }
130
131
  }
132
+
131
133
  @objc var followUserLocation : Bool = false {
132
134
  didSet {
133
135
  _updateCameraFromTrackingMode()
134
136
  }
135
137
  }
138
+
136
139
  @objc var followZoomLevel: NSNumber? {
137
140
  didSet {
138
141
  _updateCameraFromTrackingMode()
139
142
  }
140
143
  }
144
+
141
145
  @objc var maxZoomLevel: NSNumber? {
142
146
  didSet { _updateMaxBounds() }
143
147
  }
148
+
144
149
  @objc var minZoomLevel: NSNumber? {
145
150
  didSet { _updateMaxBounds() }
146
151
  }
152
+
147
153
  @objc var onUserTrackingModeChange: RCTBubblingEventBlock? = nil
154
+
148
155
  @objc var stop: [String: Any]? {
149
156
  didSet {
150
157
  _updateCamera()
@@ -319,6 +326,7 @@ class RCTMGLCamera : RCTMGLMapComponentBase, LocationConsumer {
319
326
  }
320
327
  let followState = map.viewport.makeFollowPuckViewportState(options: followOptions)
321
328
  map.viewport.transition(to: followState)
329
+ map.viewport.addStatusObserver(self)
322
330
  map.mapboxMap.setCamera(to: _camera)
323
331
  }
324
332
  }
@@ -468,6 +476,11 @@ class RCTMGLCamera : RCTMGLMapComponentBase, LocationConsumer {
468
476
  map.reactCamera = self
469
477
  }
470
478
 
479
+ override func removeFromMap(_ map: RCTMGLMapView) {
480
+ map.viewport.removeStatusObserver(self)
481
+ super.removeFromMap(map)
482
+ }
483
+
471
484
  // MARK: - LocationConsumer
472
485
 
473
486
  func locationUpdate(newLocation: Location) {
@@ -495,6 +508,106 @@ class RCTMGLCamera : RCTMGLMapComponentBase, LocationConsumer {
495
508
  }
496
509
  }
497
510
 
511
+ // MARK: - ViewportStatusObserver
512
+
513
+ extension RCTMGLCamera : ViewportStatusObserver {
514
+ func toDict(_ status: ViewportStatus) -> [String: Any] {
515
+ switch (status) {
516
+ case .idle:
517
+ return ["state":"idle"]
518
+ case .state(let state):
519
+ return ["state":String(describing: type(of: state))]
520
+ case .transition(let transition, toState: let toState):
521
+ return [
522
+ "transition": String(describing: type(of: transition)),
523
+ "state":String(describing: type(of: toState))
524
+ ]
525
+ }
526
+ }
527
+
528
+ func toFollowUserLocation(_ status: ViewportStatus) -> Bool {
529
+ switch status {
530
+ case .idle:
531
+ return false
532
+ case .state(_):
533
+ return true
534
+ case .transition(_, toState: _):
535
+ return true
536
+ }
537
+ }
538
+
539
+ func toFollowUserMode(_ state: ViewportState) -> String? {
540
+ if let state = state as? FollowPuckViewportState {
541
+ switch state.options.bearing {
542
+ case .heading:
543
+ return "compass"
544
+ case .course:
545
+ return "course"
546
+ case .some(let bearing):
547
+ return "constant"
548
+ case .none:
549
+ return "normal"
550
+ }
551
+ } else if let state = state as? OverviewViewportState {
552
+ return "overview"
553
+ } else {
554
+ return "custom"
555
+ }
556
+ }
557
+
558
+ func toFollowUserMode(_ status: ViewportStatus) -> String? {
559
+ switch status {
560
+ case .idle:
561
+ return nil
562
+ case .state(let state):
563
+ return toFollowUserMode(state)
564
+ case .transition(_, toState: let state):
565
+ return toFollowUserMode(state)
566
+ }
567
+ }
568
+
569
+ func toString(_ reason: ViewportStatusChangeReason) -> String {
570
+ if reason == .idleRequested {
571
+ return "idleRequested"
572
+ } else if reason == .transitionFailed {
573
+ return "transitionFailied"
574
+ } else if reason == .transitionStarted {
575
+ return "transitionStarted"
576
+ } else if reason == .transitionSucceeded {
577
+ return "transitionSucceeded"
578
+ } else if reason == .userInteraction {
579
+ return "userInteraction"
580
+ } else {
581
+ return "unkown \(reason)"
582
+ }
583
+ }
584
+
585
+ func viewportStatusDidChange(from fromStatus: ViewportStatus,
586
+ to toStatus: ViewportStatus,
587
+ reason: ViewportStatusChangeReason)
588
+ {
589
+ if (reason == .userInteraction) {
590
+ followUserLocation = toFollowUserLocation(toStatus)
591
+
592
+ if let onUserTrackingModeChange = onUserTrackingModeChange {
593
+ let event = RCTMGLEvent(
594
+ type: .onUserTrackingModeChange,
595
+ payload: [
596
+ "followUserMode": toFollowUserMode(toStatus) as Any,
597
+ "followUserLocation": followUserLocation,
598
+ "fromViewportStatus": toDict(fromStatus),
599
+ "toViewportState": toDict(toStatus),
600
+ "reason": toString(reason)
601
+ ]
602
+ )
603
+
604
+ onUserTrackingModeChange(event.toJSON())
605
+ }
606
+ }
607
+ }
608
+ }
609
+
498
610
  private func toSeconds(_ ms: Double) -> TimeInterval {
499
611
  return ms * 0.001
500
612
  }
613
+
@@ -10,6 +10,7 @@ RCT_EXTERN_METHOD(stop)
10
10
  RCT_EXTERN_METHOD(getLastKnownLocation)
11
11
 
12
12
  RCT_EXTERN_METHOD(setMinDisplacement:(CLLocationDistance)minDisplacement)
13
+ RCT_EXTERN_METHOD(setRequestsAlwaysUse:(BOOL)requestsAlwaysUse)
13
14
 
14
15
 
15
16
  @end
@@ -7,6 +7,8 @@ class RCTMGLLocation: NSObject {
7
7
 
8
8
  var heading : CLHeading? = nil
9
9
 
10
+ var timestamp: Date? = nil
11
+
10
12
  func toJSON() -> [String:Any] {
11
13
  return [
12
14
  "coords": [
@@ -18,7 +20,7 @@ class RCTMGLLocation: NSObject {
18
20
  "course": location.course,
19
21
  "speed": location.speed,
20
22
  ],
21
- "timestamp": location.timestamp.timeIntervalSince1970 * 1000
23
+ "timestamp": (timestamp ?? location.timestamp).timeIntervalSince1970 * 1000
22
24
  ]
23
25
  }
24
26
  }
@@ -41,16 +43,20 @@ protocol RCTMGLLocationManagerDelegate : AnyObject {
41
43
  }
42
44
 
43
45
  class RCTMGLLocationManager : LocationProviderDelegate {
46
+ enum LocationUpdateType {
47
+ case heading
48
+ case location
49
+ }
50
+
44
51
  var provider: LocationProvider
45
52
 
46
53
  var lastKnownLocation : CLLocation?
47
54
  var lastKnownHeading : CLHeading?
55
+ var shouldRequestAlwaysAuthorization: Bool?
48
56
 
49
57
  weak var delegate: RCTMGLLocationManagerDelegate?
50
58
  weak var locationProviderDelage: LocationProviderDelegate?
51
59
 
52
- var listeners: [RCTMGLLocationBlock] = []
53
-
54
60
  init() {
55
61
  provider = AppleLocationProvider()
56
62
  provider.setDelegate(self)
@@ -62,8 +68,14 @@ class RCTMGLLocationManager : LocationProviderDelegate {
62
68
  provider.locationProviderOptions = options
63
69
  }
64
70
 
71
+ func setRequestsAlwaysUse(_ requestsAlwaysUse: Bool) {
72
+ shouldRequestAlwaysAuthorization = requestsAlwaysUse;
73
+ }
74
+
65
75
  func start() {
66
- provider.requestAlwaysAuthorization()
76
+ if shouldRequestAlwaysAuthorization == true {
77
+ provider.requestAlwaysAuthorization()
78
+ }
67
79
  provider.requestWhenInUseAuthorization()
68
80
  provider.setDelegate(self)
69
81
  provider.startUpdatingHeading()
@@ -76,7 +88,7 @@ class RCTMGLLocationManager : LocationProviderDelegate {
76
88
  provider.setDelegate(EmptyLocationProviderDelegate())
77
89
  }
78
90
 
79
- func _convertToMapboxLocation(_ location: CLLocation?) -> RCTMGLLocation {
91
+ func _convertToMapboxLocation(_ location: CLLocation?, type: LocationUpdateType) -> RCTMGLLocation {
80
92
  guard let location = location else {
81
93
  return RCTMGLLocation()
82
94
  }
@@ -84,19 +96,22 @@ class RCTMGLLocationManager : LocationProviderDelegate {
84
96
  let userLocation = RCTMGLLocation()
85
97
  userLocation.location = location;
86
98
  userLocation.heading = lastKnownHeading
99
+ switch type {
100
+ case .location:
101
+ userLocation.timestamp = location.timestamp
102
+ case .heading:
103
+ userLocation.timestamp = lastKnownHeading!.timestamp
104
+ }
87
105
  return userLocation;
88
106
  }
89
107
 
90
- func _updateDelegate() {
108
+ func _updateDelegate(type: LocationUpdateType) {
91
109
  if delegate == nil {
92
110
  return;
93
111
  }
94
112
 
95
- let userLocation = _convertToMapboxLocation(lastKnownLocation)
113
+ let userLocation = _convertToMapboxLocation(lastKnownLocation, type: type)
96
114
 
97
- for listener in listeners {
98
- listener(userLocation)
99
- }
100
115
  delegate?.locationManager(self, didUpdateLocation: userLocation)
101
116
  }
102
117
 
@@ -104,14 +119,14 @@ class RCTMGLLocationManager : LocationProviderDelegate {
104
119
 
105
120
  func locationProvider(_ provider: LocationProvider, didUpdateLocations locations: [CLLocation]) {
106
121
  lastKnownLocation = locations.last
107
- self._updateDelegate()
122
+ self._updateDelegate(type: .location)
108
123
 
109
124
  locationProviderDelage?.locationProvider(provider, didUpdateLocations: locations)
110
125
  }
111
126
 
112
127
  func locationProvider(_ provider: LocationProvider, didUpdateHeading newHeading: CLHeading) {
113
128
  lastKnownHeading = newHeading
114
- self._updateDelegate()
129
+ self._updateDelegate(type: .heading)
115
130
 
116
131
  locationProviderDelage?.locationProvider(provider, didUpdateHeading: newHeading)
117
132
  }
@@ -233,9 +248,7 @@ class RCTMGLLocationModule: RCTEventEmitter, RCTMGLLocationManagerDelegate {
233
248
 
234
249
  @objc
235
250
  override func constantsToExport() -> [AnyHashable: Any]! {
236
- return [
237
- "foo": "bar"
238
- ];
251
+ return [:];
239
252
  }
240
253
 
241
254
  @objc override func supportedEvents() -> [String]
@@ -260,6 +273,10 @@ class RCTMGLLocationModule: RCTEventEmitter, RCTMGLLocationManagerDelegate {
260
273
  locationManager.setDistanceFilter(minDisplacement)
261
274
  }
262
275
 
276
+ @objc func setRequestsAlwaysUse(_ requestsAlwaysUse: Bool) {
277
+ locationManager.setRequestsAlwaysUse(requestsAlwaysUse);
278
+ }
279
+
263
280
  @objc
264
281
  override func startObserving() {
265
282
  super.startObserving()
@@ -272,7 +289,6 @@ class RCTMGLLocationModule: RCTEventEmitter, RCTMGLLocationManagerDelegate {
272
289
  hasListener = false
273
290
  }
274
291
 
275
-
276
292
  func locationManager(_ locationManager: RCTMGLLocationManager, didUpdateLocation location: RCTMGLLocation) {
277
293
  guard hasListener else {
278
294
  return
@@ -281,8 +297,7 @@ class RCTMGLLocationModule: RCTEventEmitter, RCTMGLLocationManagerDelegate {
281
297
  guard let _ = bridge else {
282
298
  return
283
299
  }
284
-
300
+
285
301
  self.sendEvent(withName: RCT_MAPBOX_USER_LOCATION_UPDATE, body: location.toJSON())
286
302
  }
287
-
288
303
  }
@@ -33,7 +33,9 @@ open class RCTMGLMapView : MapView {
33
33
  var layerWaiters : [String:[(String) -> Void]] = [:]
34
34
 
35
35
  lazy var pointAnnotationManager : PointAnnotationManager = {
36
- return PointAnnotationManager(annotations: annotations, mapView: mapView)
36
+ let result = PointAnnotationManager(annotations: annotations, mapView: mapView)
37
+ self._removeMapboxLongPressGestureRecognizer()
38
+ return result
37
39
  }()
38
40
 
39
41
  lazy var calloutAnnotationManager : MapboxMaps.PointAnnotationManager = {
@@ -221,8 +223,8 @@ open class RCTMGLMapView : MapView {
221
223
  }
222
224
  }
223
225
 
224
- @objc func setReactCompassViewPosition(_ position: NSNumber) {
225
- mapView.ornaments.options.compass.position = toOrnamentPositon(Int(truncating: position))
226
+ @objc func setReactCompassViewPosition(_ position: NSInteger) {
227
+ mapView.ornaments.options.compass.position = toOrnamentPositon(Int(truncating: NSNumber(value: position)))
226
228
  }
227
229
 
228
230
  @objc func setReactCompassViewMargins(_ margins: CGPoint) {
@@ -329,6 +331,14 @@ open class RCTMGLMapView : MapView {
329
331
 
330
332
  return nil
331
333
  }
334
+
335
+ func _removeMapboxLongPressGestureRecognizer() {
336
+ mapView.gestureRecognizers?.forEach { recognizer in
337
+ if (String(describing: type(of:recognizer)) == "MapboxLongPressGestureRecognizer") {
338
+ mapView.removeGestureRecognizer(recognizer)
339
+ }
340
+ }
341
+ }
332
342
  }
333
343
 
334
344
  // MARK: - event handlers
@@ -992,23 +1002,16 @@ class PointAnnotationManager : AnnotationInteractionDelegate {
992
1002
  }
993
1003
 
994
1004
  case .changed:
995
- guard let annotation = self.draggedAnnotation else {
1005
+ guard var annotation = self.draggedAnnotation else {
996
1006
  return
997
1007
  }
998
1008
 
999
1009
  self.onDragHandler(self.manager, didDetectDraggedAnnotations: [annotation], dragState: .changed, targetPoint: targetPoint)
1000
1010
 
1001
- // For some reason Mapbox doesn't let us update the geometry of an existing annotation
1002
- // so we have to create a whole new one.
1003
- var newAnnotation = PointAnnotation(id: annotation.id, coordinate: targetPoint)
1004
- newAnnotation.image = annotation.image
1005
- newAnnotation.userInfo = annotation.userInfo
1006
-
1007
- var newAnnotations = self.manager.annotations.filter { an in
1008
- return an.id != annotation.id
1011
+ let idx = self.manager.annotations.firstIndex { an in return an.id == annotation.id }
1012
+ if let idx = idx {
1013
+ self.manager.annotations[idx].point = Point(targetPoint)
1009
1014
  }
1010
- newAnnotations.append(newAnnotation)
1011
- manager.annotations = newAnnotations
1012
1015
  case .cancelled, .ended:
1013
1016
  guard let annotation = self.draggedAnnotation else {
1014
1017
  return
@@ -1023,7 +1026,6 @@ class PointAnnotationManager : AnnotationInteractionDelegate {
1023
1026
  }
1024
1027
  }
1025
1028
 
1026
-
1027
1029
  func remove(_ annotation: PointAnnotation) {
1028
1030
  manager.annotations.removeAll(where: {$0.id == annotation.id})
1029
1031
  }
@@ -1032,15 +1034,16 @@ class PointAnnotationManager : AnnotationInteractionDelegate {
1032
1034
  manager.annotations.append(annotation)
1033
1035
  manager.syncSourceAndLayerIfNeeded()
1034
1036
  }
1035
-
1036
- func refresh(_ annotation: PointAnnotation) {
1037
+
1038
+ func update(_ annotation: PointAnnotation) {
1037
1039
  let index = manager.annotations.firstIndex { $0.id == annotation.id }
1038
- if let index = index {
1039
- manager.annotations[index] = annotation
1040
- manager.syncSourceAndLayerIfNeeded()
1041
- } else {
1042
- Logger.log(level: .warn, message: "RCTMGL - PointAnnotation.refresh: expected annotation already there - adding")
1043
- add(annotation)
1040
+
1041
+ guard let index = index else {
1042
+ Logger.log(level: .warn, message: "RCTMGL - PointAnnotation.refresh: annotation not found")
1043
+ return
1044
1044
  }
1045
+
1046
+ manager.annotations[index] = annotation
1047
+ manager.syncSourceAndLayerIfNeeded()
1045
1048
  }
1046
1049
  }
@@ -29,7 +29,7 @@ extension RCTMGLMapViewManager {
29
29
  self.bridge.uiManager.addUIBlock { (manager, viewRegistry) in
30
30
  let view = viewRegistry![reactTag]
31
31
 
32
- guard let view = view! as? RCTMGLMapView else {
32
+ guard let view = view, let view = view as? RCTMGLMapView else {
33
33
  RCTMGLLogError("Invalid react tag, could not find RCTMGLMapView");
34
34
  rejecter(name, "Unknown find reactTag: \(reactTag)", nil)
35
35
  return;
@@ -188,7 +188,7 @@ extension RCTMGLMapViewManager {
188
188
  let point = CGPoint(x: CGFloat(point[0].floatValue), y: CGFloat(point[1].floatValue))
189
189
 
190
190
  logged("queryRenderedFeaturesAtPoint.option", rejecter: rejecter) {
191
- let options = try RenderedQueryOptions(layerIds: layerIDs, filter: filter?.asExpression())
191
+ let options = try RenderedQueryOptions(layerIds: (layerIDs ?? []).isEmpty ? nil : layerIDs, filter: filter?.asExpression())
192
192
 
193
193
  mapboxMap.queryRenderedFeatures(with: point, options: options) { result in
194
194
  switch result {
@@ -195,6 +195,7 @@ class RCTMGLMarkerView: UIView, RCTMGLMapComponent {
195
195
 
196
196
  private func remove() {
197
197
  annotationManager?.remove(self)
198
+ didAddToMap = false
198
199
  }
199
200
 
200
201
  // MARK: - Helper functions
@@ -46,6 +46,15 @@ class RCTMGLOfflineModule: RCTEventEmitter {
46
46
 
47
47
  lazy var tileRegionPacks : [String: TileRegionPack] = [:]
48
48
 
49
+ var progressEventThrottle : (
50
+ waitBetweenEvents: Double?,
51
+ lastSentTimestamp: Double?,
52
+ lastSentState: State?
53
+ ) = (
54
+ 300,
55
+ nil,
56
+ nil
57
+ )
49
58
 
50
59
  @objc override
51
60
  func startObserving() {
@@ -301,12 +310,8 @@ class RCTMGLOfflineModule: RCTEventEmitter {
301
310
  RCTMGLEvent(type: .offlineProgress, payload: self._makeRegionStatusPayload(name, progress: progress, state: state, metadata: nil))
302
311
  }
303
312
 
304
- func shouldSendProgressEvent() -> Bool {
305
- return true
306
- }
307
-
308
313
  func offlinePackProgressDidChange(progress: TileRegionLoadProgress, metadata: [String:Any], state: State) {
309
- if self.shouldSendProgressEvent() {
314
+ if self.shouldSendProgressEvent(progress: progress, state: state) {
310
315
  let event = makeProgressEvent(metadata["name"] as! String, progress: progress, state: state)
311
316
  self._sendEvent(Callbacks.progress.rawValue, event: event)
312
317
  }
@@ -364,13 +369,17 @@ class RCTMGLOfflineModule: RCTEventEmitter {
364
369
  }) { result in
365
370
  switch result {
366
371
  case .success(let value):
367
- if let progess = lastProgress {
368
- self.offlinePackProgressDidChange(progress: progess, metadata: metadata, state: .complete)
372
+ DispatchQueue.main.async {
373
+ if let progess = lastProgress {
374
+ self.offlinePackProgressDidChange(progress: progess, metadata: metadata, state: .complete)
375
+ }
376
+ self.tileRegionPacks[id]!.state = .complete
369
377
  }
370
- self.tileRegionPacks[id]!.state = .complete
371
378
  case .failure(let error):
372
- self.tileRegionPacks[id]!.state = .inactive
373
- self.offlinePackDidReceiveError(name: id, error: error)
379
+ DispatchQueue.main.async {
380
+ self.tileRegionPacks[id]!.state = .inactive
381
+ self.offlinePackDidReceiveError(name: id, error: error)
382
+ }
374
383
  }
375
384
  }
376
385
 
@@ -436,12 +445,7 @@ class RCTMGLOfflineModule: RCTEventEmitter {
436
445
 
437
446
  @objc
438
447
  func setTileCountLimit(_ limit: NSNumber) {
439
- //v10todo
440
- }
441
-
442
- @objc
443
- func setProgressEventThrottle(_ throttleValue: NSNumber) {
444
- // v10todo improve progress event listener
448
+ RCTMGLLogWarn("setTileCountLimit is not yet implemented on v10")
445
449
  }
446
450
 
447
451
 
@@ -482,3 +486,38 @@ class RCTMGLOfflineModule: RCTEventEmitter {
482
486
  }
483
487
  }
484
488
  }
489
+
490
+ // MARK: progress throttle
491
+
492
+ extension RCTMGLOfflineModule {
493
+ @objc
494
+ func setProgressEventThrottle(_ throttleValue: NSNumber) {
495
+ progressEventThrottle.waitBetweenEvents = throttleValue.doubleValue
496
+ }
497
+
498
+
499
+ func shouldSendProgressEvent(progress: TileRegionLoadProgress, state: State) -> Bool
500
+ {
501
+ let currentTimestamp: Double = CACurrentMediaTime() * 1000.0
502
+
503
+ guard let lastSentState = progressEventThrottle.lastSentState, lastSentState == state else {
504
+ progressEventThrottle.lastSentState = state
505
+ progressEventThrottle.lastSentTimestamp = currentTimestamp
506
+ return true
507
+ }
508
+
509
+ guard let waitBetweenEvents = progressEventThrottle.waitBetweenEvents,
510
+ let lastSentTimestamp = progressEventThrottle.lastSentTimestamp else {
511
+ progressEventThrottle.lastSentTimestamp = currentTimestamp
512
+ return true;
513
+ }
514
+
515
+ if (currentTimestamp - lastSentTimestamp > waitBetweenEvents) {
516
+ progressEventThrottle.lastSentTimestamp = currentTimestamp
517
+ return true;
518
+ }
519
+
520
+ return false;
521
+ }
522
+ }
523
+