@rnmapbox/maps 10.0.0-beta.64 → 10.0.0-beta.66
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/android/rctmgl/.settings/org.eclipse.buildship.core.prefs +12 -1
- package/android/rctmgl/src/main/java-mapboxgl/common/com/mapbox/rctmgl/modules/RCTMGLLocationModule.java +5 -0
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/components/camera/RCTMGLCamera.kt +1 -1
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/components/styles/sources/RCTMGLVectorSource.java +3 -6
- package/android/rctmgl/src/main/java-v10/com/mapbox/rctmgl/modules/RCTMGLLocationModule.kt +5 -0
- package/index.d.ts +37 -166
- package/ios/RCTMGL-v10/RCTMGLCamera.swift +113 -0
- package/ios/RCTMGL-v10/RCTMGLLocationModule.m +1 -0
- package/ios/RCTMGL-v10/RCTMGLLocationModule.swift +12 -3
- package/ios/RCTMGL-v10/RCTMGLLogging.swift +13 -0
- package/ios/RCTMGL-v10/RCTMGLMarkerView.swift +87 -55
- package/ios/RCTMGL-v10/RCTMGLOfflineModule.swift +184 -66
- package/ios/RCTMGL-v10/RCTMGLStyleValue.swift +8 -1
- package/javascript/components/BackgroundLayer.tsx +91 -0
- package/javascript/components/CircleLayer.tsx +97 -0
- package/javascript/components/FillExtrusionLayer.tsx +95 -0
- package/javascript/components/FillLayer.tsx +91 -0
- package/javascript/components/HeatmapLayer.tsx +96 -0
- package/javascript/components/NativeUserLocation.tsx +33 -0
- package/javascript/components/RasterLayer.tsx +88 -0
- package/javascript/components/SkyLayer.tsx +70 -0
- package/javascript/components/UserLocation.js +11 -0
- package/javascript/modules/location/locationManager.js +23 -2
- package/javascript/modules/offline/offlineManager.js +1 -1
- package/lib/commonjs/components/BackgroundLayer.js +6 -55
- package/lib/commonjs/components/BackgroundLayer.js.map +1 -1
- package/lib/commonjs/components/CircleLayer.js +8 -58
- package/lib/commonjs/components/CircleLayer.js.map +1 -1
- package/lib/commonjs/components/FillExtrusionLayer.js +3 -55
- package/lib/commonjs/components/FillExtrusionLayer.js.map +1 -1
- package/lib/commonjs/components/FillLayer.js +2 -55
- package/lib/commonjs/components/FillLayer.js.map +1 -1
- package/lib/commonjs/components/HeatmapLayer.js +3 -56
- package/lib/commonjs/components/HeatmapLayer.js.map +1 -1
- package/lib/commonjs/components/NativeUserLocation.js +6 -31
- package/lib/commonjs/components/NativeUserLocation.js.map +1 -1
- package/lib/commonjs/components/RasterLayer.js +1 -53
- package/lib/commonjs/components/RasterLayer.js.map +1 -1
- package/lib/commonjs/components/SkyLayer.js +2 -43
- package/lib/commonjs/components/SkyLayer.js.map +1 -1
- package/lib/commonjs/components/UserLocation.js +10 -0
- package/lib/commonjs/components/UserLocation.js.map +1 -1
- package/lib/commonjs/modules/location/locationManager.js +16 -1
- package/lib/commonjs/modules/location/locationManager.js.map +1 -1
- package/lib/commonjs/modules/offline/offlineManager.js +1 -1
- package/lib/module/components/BackgroundLayer.js +6 -55
- package/lib/module/components/BackgroundLayer.js.map +1 -1
- package/lib/module/components/CircleLayer.js +7 -57
- package/lib/module/components/CircleLayer.js.map +1 -1
- package/lib/module/components/FillExtrusionLayer.js +2 -54
- package/lib/module/components/FillExtrusionLayer.js.map +1 -1
- package/lib/module/components/FillLayer.js +1 -54
- package/lib/module/components/FillLayer.js.map +1 -1
- package/lib/module/components/HeatmapLayer.js +2 -55
- package/lib/module/components/HeatmapLayer.js.map +1 -1
- package/lib/module/components/NativeUserLocation.js +4 -30
- package/lib/module/components/NativeUserLocation.js.map +1 -1
- package/lib/module/components/RasterLayer.js +1 -53
- package/lib/module/components/RasterLayer.js.map +1 -1
- package/lib/module/components/SkyLayer.js +1 -42
- package/lib/module/components/SkyLayer.js.map +1 -1
- package/lib/module/components/UserLocation.js +10 -0
- package/lib/module/components/UserLocation.js.map +1 -1
- package/lib/module/modules/location/locationManager.js +17 -2
- package/lib/module/modules/location/locationManager.js.map +1 -1
- package/lib/module/modules/offline/offlineManager.js +1 -1
- package/lib/typescript/components/BackgroundLayer.d.ts +62 -0
- package/lib/typescript/components/BackgroundLayer.d.ts.map +1 -0
- package/lib/typescript/components/CircleLayer.d.ts +66 -0
- package/lib/typescript/components/CircleLayer.d.ts.map +1 -0
- package/lib/typescript/components/FillExtrusionLayer.d.ts +65 -0
- package/lib/typescript/components/FillExtrusionLayer.d.ts.map +1 -0
- package/{javascript/components/FillLayer.js → lib/typescript/components/FillLayer.d.ts} +28 -57
- package/lib/typescript/components/FillLayer.d.ts.map +1 -0
- package/lib/typescript/components/HeatmapLayer.d.ts +66 -0
- package/lib/typescript/components/HeatmapLayer.d.ts.map +1 -0
- package/lib/typescript/components/NativeUserLocation.d.ts +22 -0
- package/lib/typescript/components/NativeUserLocation.d.ts.map +1 -0
- package/lib/typescript/components/RasterLayer.d.ts +62 -0
- package/lib/typescript/components/RasterLayer.d.ts.map +1 -0
- package/lib/typescript/components/SkyLayer.d.ts +52 -0
- package/lib/typescript/components/SkyLayer.d.ts.map +1 -0
- package/package.json +1 -1
- package/javascript/components/BackgroundLayer.js +0 -97
- package/javascript/components/CircleLayer.js +0 -101
- package/javascript/components/FillExtrusionLayer.js +0 -98
- package/javascript/components/HeatmapLayer.js +0 -99
- package/javascript/components/NativeUserLocation.js +0 -41
- package/javascript/components/RasterLayer.js +0 -95
- package/javascript/components/SkyLayer.js +0 -80
|
@@ -1,6 +1,36 @@
|
|
|
1
1
|
import MapboxMaps
|
|
2
2
|
import UIKit
|
|
3
3
|
|
|
4
|
+
/// dummy parent of RCTMGLMarkerView, so react-native changes visibility on RCTMGLMarkerView,
|
|
5
|
+
/// and Mapbox changes visibility on RCTMGLMarkerViewParentViewAnnotation
|
|
6
|
+
class RCTMGLMarkerViewParentViewAnnotation : UIView {
|
|
7
|
+
required init(marker: RCTMGLMarkerView) {
|
|
8
|
+
super.init(frame: marker.bounds)
|
|
9
|
+
insertSubview(marker, at: 0)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
required init?(coder: NSCoder) {
|
|
13
|
+
fatalError("not implented")
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
func remove(marker: RCTMGLMarkerView) {
|
|
17
|
+
marker.removeFromSuperview()
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
func updateSize(_ size: CGSize, oldOffset: CGVector, newOffset: CGVector) {
|
|
21
|
+
let actSize = self.frame.size
|
|
22
|
+
if actSize.width != size.width || actSize.height != size.height {
|
|
23
|
+
let dx = ((size.width/2.0) - newOffset.dx) - ((actSize.width/2.0) - oldOffset.dx)
|
|
24
|
+
let dy = ((size.height/2.0) + newOffset.dy) - ((actSize.height/2.0) + oldOffset.dy)
|
|
25
|
+
print(" => size=\(size) actSize=\(actSize) newOffset=\(newOffset) oldOffset=\(oldOffset) dx=\(dx) dy=\(dy)")
|
|
26
|
+
var frame = self.frame
|
|
27
|
+
frame = frame.offsetBy(dx: -dx, dy: -dy)
|
|
28
|
+
frame.size = size
|
|
29
|
+
self.frame = frame
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
4
34
|
class RCTMGLMarkerView: UIView, RCTMGLMapComponent {
|
|
5
35
|
// MARK: - Instance variables
|
|
6
36
|
|
|
@@ -8,6 +38,7 @@ class RCTMGLMarkerView: UIView, RCTMGLMapComponent {
|
|
|
8
38
|
let id: String = "marker-\(UUID().uuidString)"
|
|
9
39
|
|
|
10
40
|
weak var map: RCTMGLMapView?
|
|
41
|
+
weak var _annotationView: RCTMGLMarkerViewParentViewAnnotation?
|
|
11
42
|
|
|
12
43
|
var didAddToMap = false
|
|
13
44
|
|
|
@@ -31,13 +62,7 @@ class RCTMGLMarkerView: UIView, RCTMGLMapComponent {
|
|
|
31
62
|
|
|
32
63
|
@objc var isSelected: Bool = false {
|
|
33
64
|
didSet {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if hasBecomeSelected {
|
|
37
|
-
setSelected()
|
|
38
|
-
} else {
|
|
39
|
-
update()
|
|
40
|
-
}
|
|
65
|
+
update()
|
|
41
66
|
}
|
|
42
67
|
}
|
|
43
68
|
|
|
@@ -89,36 +114,33 @@ class RCTMGLMarkerView: UIView, RCTMGLMapComponent {
|
|
|
89
114
|
|
|
90
115
|
// MARK: - React methods
|
|
91
116
|
|
|
117
|
+
override var isHidden: Bool {
|
|
118
|
+
get {
|
|
119
|
+
return super.isHidden
|
|
120
|
+
}
|
|
121
|
+
set {
|
|
122
|
+
super.isHidden = newValue
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
92
126
|
override func reactSetFrame(_ frame: CGRect) {
|
|
93
127
|
let prev = self.frame
|
|
94
128
|
var next = frame
|
|
95
129
|
|
|
96
130
|
let frameDidChange = !next.equalTo(prev)
|
|
97
|
-
if
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
next
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
width: next.width,
|
|
105
|
-
height: next.height
|
|
106
|
-
)
|
|
107
|
-
} else {
|
|
108
|
-
// Calculate the next position to temporarily place the view before the annotation manager
|
|
109
|
-
// sets it to the correct point on the map.
|
|
110
|
-
let dx = (next.width - prev.width) / 2
|
|
111
|
-
let dy = (next.height - prev.height) / 2
|
|
112
|
-
next = CGRect(
|
|
113
|
-
x: prev.minX - dx,
|
|
114
|
-
y: prev.minY - dy,
|
|
115
|
-
width: next.width,
|
|
116
|
-
height: next.height
|
|
117
|
-
)
|
|
118
|
-
}
|
|
131
|
+
if frameDidChange {
|
|
132
|
+
next = CGRect(
|
|
133
|
+
x: 0,
|
|
134
|
+
y: 0,
|
|
135
|
+
width: next.width,
|
|
136
|
+
height: next.height
|
|
137
|
+
)
|
|
119
138
|
}
|
|
120
|
-
|
|
139
|
+
|
|
121
140
|
super.reactSetFrame(next)
|
|
141
|
+
if frameDidChange {
|
|
142
|
+
annotationView.updateSize(next.size, oldOffset:calcOffset(size: prev.size), newOffset: calcOffset(size: next.size))
|
|
143
|
+
}
|
|
122
144
|
addOrUpdate()
|
|
123
145
|
}
|
|
124
146
|
|
|
@@ -156,7 +178,7 @@ class RCTMGLMarkerView: UIView, RCTMGLMapComponent {
|
|
|
156
178
|
|
|
157
179
|
do {
|
|
158
180
|
let options = getOptions()
|
|
159
|
-
try annotationManager.add(
|
|
181
|
+
try annotationManager.add(annotationView, id: id, options: options)
|
|
160
182
|
didAddToMap = true
|
|
161
183
|
} catch {
|
|
162
184
|
Logger.log(level: .error, message: "[MarkerView] Error adding annotation", error: error)
|
|
@@ -174,27 +196,17 @@ class RCTMGLMarkerView: UIView, RCTMGLMapComponent {
|
|
|
174
196
|
|
|
175
197
|
do {
|
|
176
198
|
let options = getOptions()
|
|
177
|
-
try annotationManager.update(
|
|
199
|
+
try annotationManager.update(annotationView, options: options)
|
|
178
200
|
} catch {
|
|
179
201
|
Logger.log(level: .error, message: "[MarkerView] Error updating annotation", error: error)
|
|
180
202
|
}
|
|
181
203
|
}
|
|
182
204
|
|
|
183
|
-
/// There is a Mapbox bug where `selected` does not cause the marker to move to the front, so we can't simply update the component.
|
|
184
|
-
/// This forces that effect. See https://github.com/mapbox/mapbox-maps-ios/issues/1599.
|
|
185
|
-
private func setSelected() {
|
|
186
|
-
if let options = annotationManager?.options(for: self) {
|
|
187
|
-
do {
|
|
188
|
-
annotationManager?.remove(self)
|
|
189
|
-
try annotationManager?.add(self, id: id, options: options)
|
|
190
|
-
} catch {
|
|
191
|
-
Logger.log(level: .error, message: "[MarkerView] Error selecting annotation", error: error)
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
205
|
private func remove() {
|
|
197
|
-
annotationManager?.remove(
|
|
206
|
+
annotationManager?.remove(annotationView)
|
|
207
|
+
annotationView.remove(marker: self)
|
|
208
|
+
self._annotationView = nil
|
|
209
|
+
didAddToMap = false
|
|
198
210
|
}
|
|
199
211
|
|
|
200
212
|
// MARK: - Helper functions
|
|
@@ -205,29 +217,49 @@ class RCTMGLMarkerView: UIView, RCTMGLMapComponent {
|
|
|
205
217
|
geometry = Geometry.point(point)
|
|
206
218
|
}
|
|
207
219
|
|
|
208
|
-
let
|
|
220
|
+
let size = self.bounds.size
|
|
221
|
+
let offset = calcOffset(size: size)
|
|
209
222
|
|
|
210
223
|
let options = ViewAnnotationOptions(
|
|
211
224
|
geometry: geometry,
|
|
212
|
-
width:
|
|
213
|
-
height:
|
|
225
|
+
width: size.width,
|
|
226
|
+
height: size.height,
|
|
214
227
|
allowOverlap: allowOverlap,
|
|
215
228
|
offsetX: offset.dx,
|
|
216
|
-
offsetY: offset.dy
|
|
229
|
+
offsetY: offset.dy,
|
|
230
|
+
selected: isSelected
|
|
217
231
|
)
|
|
218
232
|
return options
|
|
219
233
|
}
|
|
220
234
|
|
|
221
|
-
private func
|
|
235
|
+
private func calcOffset(size: CGSize) -> CGVector {
|
|
222
236
|
guard let anchor = anchor, let anchorX = anchor["x"]?.CGFloat, let anchorY = anchor["y"]?.CGFloat else {
|
|
223
237
|
return .zero
|
|
224
238
|
}
|
|
225
239
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
let x = (anchorX * 2 - 1) * (self.bounds.width / 2) * -1
|
|
229
|
-
let y = (anchorY * 2 - 1) * (self.bounds.height / 2)
|
|
240
|
+
let x = (anchorX * 2 - 1) * (size.width / 2) * -1
|
|
241
|
+
let y = (anchorY * 2 - 1) * (size.height / 2)
|
|
230
242
|
|
|
231
243
|
return CGVector(dx: x, dy: y)
|
|
232
244
|
}
|
|
245
|
+
|
|
246
|
+
var annotationView : RCTMGLMarkerViewParentViewAnnotation {
|
|
247
|
+
if let result = _annotationView {
|
|
248
|
+
return result
|
|
249
|
+
}
|
|
250
|
+
let result = RCTMGLMarkerViewParentViewAnnotation(marker: self)
|
|
251
|
+
_annotationView = result
|
|
252
|
+
return result
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
@objc override func didMoveToSuperview() {
|
|
256
|
+
// React tends to add back us to our original superview,
|
|
257
|
+
// https://github.com/facebook/react-native/blob/11ece22fc6955d169def9ef9f2809c24bc457ba8/React/Views/UIView%2BReact.m#L172-L177
|
|
258
|
+
// fix that if we see that
|
|
259
|
+
if let expectedParent = _annotationView {
|
|
260
|
+
if superview != nil && superview != expectedParent {
|
|
261
|
+
expectedParent.addSubview(self)
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
233
265
|
}
|
|
@@ -11,10 +11,14 @@ extension Date {
|
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
|
|
15
|
+
|
|
14
16
|
@objc(RCTMGLOfflineModule)
|
|
15
17
|
class RCTMGLOfflineModule: RCTEventEmitter {
|
|
16
18
|
var hasListeners = false
|
|
17
19
|
|
|
20
|
+
static let RNMapboxInfoMetadataKey = "_rnmapbox"
|
|
21
|
+
|
|
18
22
|
enum Callbacks : String {
|
|
19
23
|
case error = "MapboOfflineRegionError"
|
|
20
24
|
case progress = "MapboxOfflineRegionProgress"
|
|
@@ -37,15 +41,78 @@ class RCTMGLOfflineModule: RCTEventEmitter {
|
|
|
37
41
|
}()
|
|
38
42
|
|
|
39
43
|
struct TileRegionPack {
|
|
44
|
+
init(name: String, state: State = .unknown, progress: TileRegionLoadProgress? = nil, metadata: [String:Any]) {
|
|
45
|
+
self.name = name
|
|
46
|
+
self.progress = progress
|
|
47
|
+
self.metadata = metadata
|
|
48
|
+
self.state = state
|
|
49
|
+
|
|
50
|
+
if let rnMetadata = metadata[RNMapboxInfoMetadataKey] as? [String:Any] {
|
|
51
|
+
if let styleURI = rnMetadata["styleURI"] as? String {
|
|
52
|
+
self.styleURI = StyleURI(rawValue: styleURI)
|
|
53
|
+
}
|
|
54
|
+
if let bounds = rnMetadata["bounds"] as? JSONObject {
|
|
55
|
+
self.bounds = logged("RCTMGLOfflineModule.TileRegionPack: cannot decode bounds") {
|
|
56
|
+
let jsonData = try JSONSerialization.data(withJSONObject: bounds)
|
|
57
|
+
return try JSONDecoder().decode(Geometry.self, from: jsonData)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if let zoomRange = rnMetadata["zoomRange"] as? JSONObject {
|
|
61
|
+
self.zoomRange = logged("RCTMGLOfflineModule.TileRegionPack: cannot decode zoomRange") {
|
|
62
|
+
let jsonData = try JSONSerialization.data(withJSONObject: zoomRange)
|
|
63
|
+
return try JSONDecoder().decode(ClosedRange<UInt8>.self, from: jsonData)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
init(name: String,
|
|
70
|
+
state: State = .unknown,
|
|
71
|
+
styleURI: StyleURI,
|
|
72
|
+
bounds: Geometry,
|
|
73
|
+
zoomRange: ClosedRange<UInt8>,
|
|
74
|
+
metadata: [String:Any]) {
|
|
75
|
+
self.name = name
|
|
76
|
+
self.progress = nil
|
|
77
|
+
self.cancelable = nil
|
|
78
|
+
self.state = state
|
|
79
|
+
|
|
80
|
+
self.styleURI = styleURI
|
|
81
|
+
self.bounds = bounds
|
|
82
|
+
self.zoomRange = zoomRange
|
|
83
|
+
|
|
84
|
+
var metadata = metadata
|
|
85
|
+
metadata[RNMapboxInfoMetadataKey] = [
|
|
86
|
+
"styleURI": styleURI.rawValue,
|
|
87
|
+
"bounds": logged("RCTMGLOfflineModule.TileRegionPack: cannot encode bounds") { try JSONSerialization.jsonObject(with: try! JSONEncoder().encode(bounds)) },
|
|
88
|
+
"zoomRange": logged("RCTMGLOfflineModule.TileRegionPack: cannot encode zoomRange") { try JSONSerialization.jsonObject(with: try! JSONEncoder().encode(zoomRange))}
|
|
89
|
+
]
|
|
90
|
+
self.metadata = metadata
|
|
91
|
+
}
|
|
92
|
+
|
|
40
93
|
var name: String
|
|
41
94
|
var cancelable: Cancelable? = nil
|
|
42
95
|
var progress : TileRegionLoadProgress? = nil
|
|
43
96
|
var state : State = .inactive
|
|
44
97
|
var metadata : [String:Any]? = nil
|
|
98
|
+
|
|
99
|
+
// Stored in metadata for resume functionality:
|
|
100
|
+
var bounds: Geometry? = nil
|
|
101
|
+
var zoomRange: ClosedRange<UInt8>? = nil
|
|
102
|
+
var styleURI: StyleURI? = nil
|
|
45
103
|
}
|
|
46
104
|
|
|
47
105
|
lazy var tileRegionPacks : [String: TileRegionPack] = [:]
|
|
48
106
|
|
|
107
|
+
var progressEventThrottle : (
|
|
108
|
+
waitBetweenEvents: Double?,
|
|
109
|
+
lastSentTimestamp: Double?,
|
|
110
|
+
lastSentState: State?
|
|
111
|
+
) = (
|
|
112
|
+
300,
|
|
113
|
+
nil,
|
|
114
|
+
nil
|
|
115
|
+
)
|
|
49
116
|
|
|
50
117
|
@objc override
|
|
51
118
|
func startObserving() {
|
|
@@ -107,7 +174,7 @@ class RCTMGLOfflineModule: RCTEventEmitter {
|
|
|
107
174
|
if let expires = region.expires {
|
|
108
175
|
result["expires"] = expires.toJSONString()
|
|
109
176
|
}
|
|
110
|
-
|
|
177
|
+
|
|
111
178
|
result["metadata"] = String(data:try! JSONSerialization.data(withJSONObject: metadata, options: [.prettyPrinted]), encoding: .utf8)
|
|
112
179
|
|
|
113
180
|
result["bounds"] = jsonBounds
|
|
@@ -173,9 +240,9 @@ class RCTMGLOfflineModule: RCTEventEmitter {
|
|
|
173
240
|
let ret = self.convertRegionToJSON(region: region, geometry: geometry, metadata: metadata)
|
|
174
241
|
var pack = self.tileRegionPacks[region.id] ?? TileRegionPack(
|
|
175
242
|
name: region.id,
|
|
176
|
-
progress: self.toProgress(region: region),
|
|
177
243
|
state: .unknown,
|
|
178
|
-
|
|
244
|
+
progress: self.toProgress(region: region),
|
|
245
|
+
metadata: logged("RCTMGLOfflineModule.getPacks metadata is null") { metadata } ?? [:]
|
|
179
246
|
)
|
|
180
247
|
|
|
181
248
|
if ((region.completedResourceCount == region.completedResourceSize)) {
|
|
@@ -301,12 +368,8 @@ class RCTMGLOfflineModule: RCTEventEmitter {
|
|
|
301
368
|
RCTMGLEvent(type: .offlineProgress, payload: self._makeRegionStatusPayload(name, progress: progress, state: state, metadata: nil))
|
|
302
369
|
}
|
|
303
370
|
|
|
304
|
-
func shouldSendProgressEvent() -> Bool {
|
|
305
|
-
return true
|
|
306
|
-
}
|
|
307
|
-
|
|
308
371
|
func offlinePackProgressDidChange(progress: TileRegionLoadProgress, metadata: [String:Any], state: State) {
|
|
309
|
-
if self.shouldSendProgressEvent() {
|
|
372
|
+
if self.shouldSendProgressEvent(progress: progress, state: state) {
|
|
310
373
|
let event = makeProgressEvent(metadata["name"] as! String, progress: progress, state: state)
|
|
311
374
|
self._sendEvent(Callbacks.progress.rawValue, event: event)
|
|
312
375
|
}
|
|
@@ -322,9 +385,9 @@ class RCTMGLOfflineModule: RCTEventEmitter {
|
|
|
322
385
|
DispatchQueue.main.async {
|
|
323
386
|
do {
|
|
324
387
|
let metadataStr = options["metadata"] as! String
|
|
325
|
-
|
|
388
|
+
var metadata = try JSONSerialization.jsonObject(with: metadataStr.data(using: .utf8)!, options: []) as! [String:Any]
|
|
389
|
+
metadata["styleURI"] = options["styleURL"]
|
|
326
390
|
let id = metadata["name"] as! String
|
|
327
|
-
let stylePackLoadOptions = StylePackLoadOptions(glyphsRasterizationMode: .ideographsRasterizedLocally, metadata: metadata)
|
|
328
391
|
|
|
329
392
|
let boundsStr = options["bounds"] as! String
|
|
330
393
|
let boundsData = boundsStr.data(using: .utf8)
|
|
@@ -332,53 +395,16 @@ class RCTMGLOfflineModule: RCTEventEmitter {
|
|
|
332
395
|
|
|
333
396
|
var bounds = self.convertPointPairToBounds(RCTMGLFeatureUtils.fcToGeomtry(boundsFC))
|
|
334
397
|
|
|
335
|
-
let descriptorOptions = TilesetDescriptorOptions(
|
|
336
|
-
styleURI: StyleURI(rawValue: options["styleURL"] as! String)!,
|
|
337
|
-
zoomRange: (options["minZoom"] as! NSNumber).uint8Value...(options["maxZoom"] as! NSNumber).uint8Value,
|
|
338
|
-
stylePackOptions: stylePackLoadOptions
|
|
339
|
-
)
|
|
340
|
-
let tilesetDescriptor = self.offlineManager.createTilesetDescriptor(for: descriptorOptions)
|
|
341
|
-
|
|
342
|
-
let loadOptions = TileRegionLoadOptions(
|
|
343
|
-
geometry: bounds, // RCTMGLFeatureUtils.geometryToGeometry(bounds),
|
|
344
|
-
descriptors: [tilesetDescriptor],
|
|
345
|
-
metadata: metadata,
|
|
346
|
-
acceptExpired: true,
|
|
347
|
-
networkRestriction: .none,
|
|
348
|
-
averageBytesPerSecond: nil)
|
|
349
|
-
|
|
350
398
|
let actPack = RCTMGLOfflineModule.TileRegionPack(
|
|
351
399
|
name: id,
|
|
352
|
-
|
|
353
|
-
|
|
400
|
+
styleURI: StyleURI(rawValue: options["styleURL"] as! String)!,
|
|
401
|
+
bounds: bounds,
|
|
402
|
+
zoomRange: (options["minZoom"] as! NSNumber).uint8Value...(options["maxZoom"] as! NSNumber).uint8Value,
|
|
403
|
+
metadata: metadata
|
|
354
404
|
)
|
|
355
405
|
self.tileRegionPacks[id] = actPack
|
|
406
|
+
self.startLoading(pack: actPack)
|
|
356
407
|
|
|
357
|
-
var lastProgress : TileRegionLoadProgress? = nil
|
|
358
|
-
let task = self.tileStore.loadTileRegion(forId: id, loadOptions: loadOptions!, progress: {
|
|
359
|
-
progress in
|
|
360
|
-
lastProgress = progress
|
|
361
|
-
self.tileRegionPacks[id]!.progress = progress
|
|
362
|
-
self.tileRegionPacks[id]!.state = .active
|
|
363
|
-
self.offlinePackProgressDidChange(progress: progress, metadata: metadata, state: .active)
|
|
364
|
-
}) { result in
|
|
365
|
-
switch result {
|
|
366
|
-
case .success(let value):
|
|
367
|
-
DispatchQueue.main.async {
|
|
368
|
-
if let progess = lastProgress {
|
|
369
|
-
self.offlinePackProgressDidChange(progress: progess, metadata: metadata, state: .complete)
|
|
370
|
-
}
|
|
371
|
-
self.tileRegionPacks[id]!.state = .complete
|
|
372
|
-
}
|
|
373
|
-
case .failure(let error):
|
|
374
|
-
DispatchQueue.main.async {
|
|
375
|
-
self.tileRegionPacks[id]!.state = .inactive
|
|
376
|
-
self.offlinePackDidReceiveError(name: id, error: error)
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
self.tileRegionPacks[id]!.cancelable = task
|
|
382
408
|
resolver([
|
|
383
409
|
"bounds": boundsStr,
|
|
384
410
|
"metadata": String(data:try! JSONSerialization.data(withJSONObject: metadata, options: [.prettyPrinted]), encoding: .utf8)
|
|
@@ -389,10 +415,72 @@ class RCTMGLOfflineModule: RCTEventEmitter {
|
|
|
389
415
|
}
|
|
390
416
|
}
|
|
391
417
|
|
|
418
|
+
func startLoading(pack: TileRegionPack) {
|
|
419
|
+
let id = pack.name
|
|
420
|
+
guard let bounds = pack.bounds else {
|
|
421
|
+
RCTMGLLogError("RCTMGLOfflineModule.startLoading failed as there are no bounds in pack")
|
|
422
|
+
return
|
|
423
|
+
}
|
|
424
|
+
guard let zoomRange = pack.zoomRange else {
|
|
425
|
+
RCTMGLLogError("RCTMGLOfflineModule.startLoading failed as there is no zoom range in pack")
|
|
426
|
+
return
|
|
427
|
+
}
|
|
428
|
+
guard let styleURI = pack.styleURI else {
|
|
429
|
+
RCTMGLLogError("RCTMGLOfflineModule.startLoading failed as there is no styleURI in pack")
|
|
430
|
+
return
|
|
431
|
+
}
|
|
432
|
+
guard let metadata = pack.metadata else {
|
|
433
|
+
RCTMGLLogError("RCTMGLOfflineModule.startLoading failed as there is no metadata in pack")
|
|
434
|
+
return
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
let stylePackLoadOptions = StylePackLoadOptions(glyphsRasterizationMode: .ideographsRasterizedLocally, metadata: pack.metadata)
|
|
438
|
+
|
|
439
|
+
let descriptorOptions = TilesetDescriptorOptions(
|
|
440
|
+
styleURI: styleURI,
|
|
441
|
+
zoomRange: zoomRange,
|
|
442
|
+
stylePackOptions: stylePackLoadOptions
|
|
443
|
+
)
|
|
444
|
+
let tilesetDescriptor = self.offlineManager.createTilesetDescriptor(for: descriptorOptions)
|
|
445
|
+
|
|
446
|
+
let loadOptions = TileRegionLoadOptions(
|
|
447
|
+
geometry: bounds, // RCTMGLFeatureUtils.geometryToGeometry(bounds),
|
|
448
|
+
descriptors: [tilesetDescriptor],
|
|
449
|
+
metadata: metadata,
|
|
450
|
+
acceptExpired: true,
|
|
451
|
+
networkRestriction: .none,
|
|
452
|
+
averageBytesPerSecond: nil)
|
|
453
|
+
|
|
454
|
+
var lastProgress : TileRegionLoadProgress? = nil
|
|
455
|
+
let task = self.tileStore.loadTileRegion(forId: id, loadOptions: loadOptions!, progress: {
|
|
456
|
+
progress in
|
|
457
|
+
lastProgress = progress
|
|
458
|
+
self.tileRegionPacks[id]!.progress = progress
|
|
459
|
+
self.tileRegionPacks[id]!.state = .active
|
|
460
|
+
self.offlinePackProgressDidChange(progress: progress, metadata: metadata, state: .active)
|
|
461
|
+
}) { result in
|
|
462
|
+
switch result {
|
|
463
|
+
case .success(let value):
|
|
464
|
+
DispatchQueue.main.async {
|
|
465
|
+
if let progess = lastProgress {
|
|
466
|
+
self.offlinePackProgressDidChange(progress: progess, metadata: metadata, state: .complete)
|
|
467
|
+
}
|
|
468
|
+
self.tileRegionPacks[id]!.state = .complete
|
|
469
|
+
}
|
|
470
|
+
case .failure(let error):
|
|
471
|
+
DispatchQueue.main.async {
|
|
472
|
+
self.tileRegionPacks[id]!.state = .inactive
|
|
473
|
+
self.offlinePackDidReceiveError(name: id, error: error)
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
self.tileRegionPacks[id]!.cancelable = task
|
|
478
|
+
}
|
|
479
|
+
|
|
392
480
|
func _getPack(fromName: String) -> TileRegionPack? {
|
|
393
481
|
return self.tileRegionPacks[fromName]
|
|
394
482
|
}
|
|
395
|
-
|
|
483
|
+
|
|
396
484
|
@objc
|
|
397
485
|
func getPackStatus(_ name: String,
|
|
398
486
|
resolver: @escaping RCTPromiseResolveBlock,
|
|
@@ -408,12 +496,10 @@ class RCTMGLOfflineModule: RCTEventEmitter {
|
|
|
408
496
|
Logger.log(level:.error, message: "Unable to fetch metadata for \(name)")
|
|
409
497
|
rejecter("RCTMGLOfflineModule.getPackStatus", error.localizedDescription, error)
|
|
410
498
|
case .success(let metadata):
|
|
411
|
-
var pack = self.tileRegionPacks[name] ?? TileRegionPack(
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
Logger.log(level:.error, message: "Unexpected metadata format for \(name) \(metadata)")
|
|
416
|
-
}
|
|
499
|
+
var pack = self.tileRegionPacks[name] ?? TileRegionPack(
|
|
500
|
+
name: name,
|
|
501
|
+
metadata: logged("RCTMGLOfflineModule.getPackStatus") { metadata as? [String:Any] } ?? [:]
|
|
502
|
+
)
|
|
417
503
|
self.tileRegionPacks[name] = pack
|
|
418
504
|
resolver(self._makeRegionStatusPayload(pack: pack))
|
|
419
505
|
}
|
|
@@ -424,7 +510,9 @@ class RCTMGLOfflineModule: RCTEventEmitter {
|
|
|
424
510
|
@objc
|
|
425
511
|
func resumePackDownload(_ name: String, resolver: RCTPromiseResolveBlock, rejecter: RCTPromiseRejectBlock)
|
|
426
512
|
{
|
|
427
|
-
|
|
513
|
+
if let pack = _getPack(fromName: name) {
|
|
514
|
+
self.startLoading(pack: pack)
|
|
515
|
+
}
|
|
428
516
|
}
|
|
429
517
|
|
|
430
518
|
@objc
|
|
@@ -440,12 +528,7 @@ class RCTMGLOfflineModule: RCTEventEmitter {
|
|
|
440
528
|
|
|
441
529
|
@objc
|
|
442
530
|
func setTileCountLimit(_ limit: NSNumber) {
|
|
443
|
-
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
@objc
|
|
447
|
-
func setProgressEventThrottle(_ throttleValue: NSNumber) {
|
|
448
|
-
// v10todo improve progress event listener
|
|
531
|
+
RCTMGLLogWarn("setTileCountLimit is not yet implemented on v10")
|
|
449
532
|
}
|
|
450
533
|
|
|
451
534
|
|
|
@@ -486,3 +569,38 @@ class RCTMGLOfflineModule: RCTEventEmitter {
|
|
|
486
569
|
}
|
|
487
570
|
}
|
|
488
571
|
}
|
|
572
|
+
|
|
573
|
+
// MARK: progress throttle
|
|
574
|
+
|
|
575
|
+
extension RCTMGLOfflineModule {
|
|
576
|
+
@objc
|
|
577
|
+
func setProgressEventThrottle(_ throttleValue: NSNumber) {
|
|
578
|
+
progressEventThrottle.waitBetweenEvents = throttleValue.doubleValue
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
|
|
582
|
+
func shouldSendProgressEvent(progress: TileRegionLoadProgress, state: State) -> Bool
|
|
583
|
+
{
|
|
584
|
+
let currentTimestamp: Double = CACurrentMediaTime() * 1000.0
|
|
585
|
+
|
|
586
|
+
guard let lastSentState = progressEventThrottle.lastSentState, lastSentState == state else {
|
|
587
|
+
progressEventThrottle.lastSentState = state
|
|
588
|
+
progressEventThrottle.lastSentTimestamp = currentTimestamp
|
|
589
|
+
return true
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
guard let waitBetweenEvents = progressEventThrottle.waitBetweenEvents,
|
|
593
|
+
let lastSentTimestamp = progressEventThrottle.lastSentTimestamp else {
|
|
594
|
+
progressEventThrottle.lastSentTimestamp = currentTimestamp
|
|
595
|
+
return true;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
if (currentTimestamp - lastSentTimestamp > waitBetweenEvents) {
|
|
599
|
+
progressEventThrottle.lastSentTimestamp = currentTimestamp
|
|
600
|
+
return true;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
return false;
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
|
|
@@ -5,6 +5,10 @@ func deg2rad(_ number: Double) -> Double {
|
|
|
5
5
|
return number * .pi / 180
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
+
enum StyleConversionError: Error {
|
|
9
|
+
case unexpectedType(message: String)
|
|
10
|
+
}
|
|
11
|
+
|
|
8
12
|
class RCTMGLStyleValue {
|
|
9
13
|
var value: Any
|
|
10
14
|
var styleType: String? = nil
|
|
@@ -325,11 +329,14 @@ class RCTMGLStyleValue {
|
|
|
325
329
|
return .constant(valueObj)
|
|
326
330
|
} else {
|
|
327
331
|
do {
|
|
332
|
+
if valueObj is String {
|
|
333
|
+
throw StyleConversionError.unexpectedType(message: "should be array constant or expression")
|
|
334
|
+
}
|
|
328
335
|
let data = try JSONSerialization.data(withJSONObject: valueObj, options: .prettyPrinted)
|
|
329
336
|
let decodedExpression = try JSONDecoder().decode(Expression.self, from: data)
|
|
330
337
|
return .expression(decodedExpression)
|
|
331
338
|
} catch {
|
|
332
|
-
Logger.log(level: .error, message: "Invalid value for array
|
|
339
|
+
Logger.log(level: .error, message: "Invalid value for array => value: \(value) error: \(error) setting dummy value")
|
|
333
340
|
return .constant([""])
|
|
334
341
|
}
|
|
335
342
|
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { NativeModules, requireNativeComponent } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
FilterExpression,
|
|
6
|
+
BackgroundLayerStyleProps,
|
|
7
|
+
} from '../utils/MapboxStyles';
|
|
8
|
+
import { StyleValue } from '../utils/StyleValue';
|
|
9
|
+
|
|
10
|
+
import AbstractLayer from './AbstractLayer';
|
|
11
|
+
|
|
12
|
+
const MapboxGL = NativeModules.MGLModule;
|
|
13
|
+
|
|
14
|
+
export type Props = {
|
|
15
|
+
/**
|
|
16
|
+
* A string that uniquely identifies the source in the style to which it is added.
|
|
17
|
+
*/
|
|
18
|
+
id: string;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The source from which to obtain the data to style.
|
|
22
|
+
* If the source has not yet been added to the current style, the behavior is undefined.
|
|
23
|
+
* Inferred from parent source only if the layer is a direct child to it.
|
|
24
|
+
*/
|
|
25
|
+
sourceID?: string;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Identifier of the layer within the source identified by the sourceID property from which the receiver obtains the data to style.
|
|
29
|
+
*/
|
|
30
|
+
sourceLayerID?: string;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Inserts a layer above aboveLayerID.
|
|
34
|
+
*/
|
|
35
|
+
aboveLayerID?: string;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Inserts a layer below belowLayerID
|
|
39
|
+
*/
|
|
40
|
+
belowLayerID?: string;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Inserts a layer at a specified index
|
|
44
|
+
*/
|
|
45
|
+
layerIndex?: number;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Filter only the features in the source layer that satisfy a condition that you define
|
|
49
|
+
*/
|
|
50
|
+
filter?: FilterExpression;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The minimum zoom level at which the layer gets parsed and appears.
|
|
54
|
+
*/
|
|
55
|
+
minZoomLevel?: number;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The maximum zoom level at which the layer gets parsed and appears.
|
|
59
|
+
*/
|
|
60
|
+
maxZoomLevel?: number;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Customizable style attributes
|
|
64
|
+
*/
|
|
65
|
+
style?: BackgroundLayerStyleProps;
|
|
66
|
+
} & React.ComponentProps<typeof AbstractLayer>;
|
|
67
|
+
|
|
68
|
+
export const NATIVE_MODULE_NAME = 'RCTMGLBackgroundLayer';
|
|
69
|
+
|
|
70
|
+
type NativeTypeProps = Omit<Props, 'style'> & {
|
|
71
|
+
reactStyle?: { [key: string]: StyleValue };
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
class BackgroundLayer extends AbstractLayer<Props, NativeTypeProps> {
|
|
75
|
+
static defaultProps = {
|
|
76
|
+
sourceID: MapboxGL.StyleSource.DefaultSourceID,
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
render() {
|
|
80
|
+
const props = {
|
|
81
|
+
...this.baseProps,
|
|
82
|
+
sourceLayerID: this.props.sourceLayerID,
|
|
83
|
+
};
|
|
84
|
+
return <RCTMGLBackgroundLayer ref={this.setNativeLayer} {...props} />;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const RCTMGLBackgroundLayer =
|
|
89
|
+
requireNativeComponent<NativeTypeProps>(NATIVE_MODULE_NAME);
|
|
90
|
+
|
|
91
|
+
export default BackgroundLayer;
|