forked from rnmapbox/maps
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRNMBXSnapshotModule.swift
More file actions
105 lines (94 loc) · 4.39 KB
/
RNMBXSnapshotModule.swift
File metadata and controls
105 lines (94 loc) · 4.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import MapboxMaps
@objc(RNMBXSnapshotModule)
class RNMBXSnapshotModule : NSObject {
@objc
static func requiresMainQueueSetup() -> Bool {
return true
}
@objc
func takeSnap(_ jsOptions: [String: Any],
resolver:@escaping RCTPromiseResolveBlock,
rejecter:@escaping RCTPromiseRejectBlock
) {
DispatchQueue.main.async {
logged("takeSnap", rejecter:rejecter) {
let snapshotterOptions = try self._getSnapshotterOptions(jsOptions)
let snapshotter = Snapshotter(options: snapshotterOptions)
let cameraOptions = try self._getCameraOptions(jsOptions, snapshotter)
snapshotter.setCamera(to: cameraOptions)
if let styleURL = jsOptions["styleURL"] as? String {
snapshotter.style.uri = StyleURI(rawValue:styleURL)
}
var snapshotterReference : Snapshotter? = snapshotter
snapshotter.start(overlayHandler: nil, completion: { result in
do {
switch (result) {
case .success(let image):
guard let writeToDisk = jsOptions["writeToDisk"] as? NSNumber else {
throw RNMBXError.paramError("writeToDisk: is not a number")
}
let value = writeToDisk.boolValue ? RNMBImageUtils.createTempFile(image) : RNMBImageUtils.createBase64(image)
_ = snapshotterReference
snapshotterReference = nil
resolver(value.absoluteString)
case .failure(let error):
_ = snapshotterReference
snapshotterReference = nil
Logger.log(level: .error, message: ":: Error - snapshot failed \(error) \(error.localizedDescription)")
rejecter("RNMBXSnapshotModule.start", error.localizedDescription, error)
}
} catch let error {
rejecter("RNMBXSnapshotModule.start", error.localizedDescription, error)
}
})
}
}
}
func _getCameraOptions(_ jsOptions: [String:Any], _ snaphotter: Snapshotter) throws -> CameraOptions {
guard let pitch = jsOptions["pitch"] as? NSNumber else {
throw RNMBXError.paramError("pitch: is not a number")
}
guard let zoomLevel = jsOptions["zoomLevel"] as? NSNumber else {
throw RNMBXError.paramError("zoomLevel: is not a number")
}
guard let heading = jsOptions["heading"] as? NSNumber else {
throw RNMBXError.paramError("heading: is not a number")
}
if let centerCoordinateString = jsOptions["centerCoordinate"] as? String {
guard let centerCoordinateData = centerCoordinateString.data(using: .utf8),
let centerCoordinateGeometry = try JSONDecoder().decode(Feature.self, from: centerCoordinateData).geometry,
case .point(let centerCoordinatePoint) = centerCoordinateGeometry else {
throw RNMBXError.paramError("centerCoordinate: bad format")
}
return CameraOptions(center: centerCoordinatePoint.coordinates, padding: nil, anchor: nil, zoom: zoomLevel.doubleValue, bearing: heading.doubleValue, pitch: pitch.doubleValue)
}
else if let bounds = jsOptions["bounds"] as? String {
guard let boundsData = bounds.data(using: .utf8) else {
throw RNMBXError.paramError("bounds: bad format")
}
let boundsFeatures = try JSONDecoder().decode(FeatureCollection.self, from: boundsData).features
let coords : [CLLocationCoordinate2D] = try boundsFeatures.map {
guard case .point(let centerCoordinatePoint) = $0.geometry else {
throw RNMBXError.paramError("Invalid bounds geometry")
}
return centerCoordinatePoint.coordinates
}
return snaphotter.camera(for: coords, padding: .zero, bearing: heading.doubleValue, pitch: pitch.doubleValue)
} else {
throw RNMBXError.paramError("neither centerCoordinate nor bounds provided")
}
}
func _getSnapshotterOptions(_ jsOptions: [String:Any]) throws -> MapSnapshotOptions {
guard let width = jsOptions["width"] as? NSNumber,
let height = jsOptions["height"] as? NSNumber else {
throw RNMBXError.paramError("width, height: is not a number")
}
let showsLogo = jsOptions["withLogo"] as? Bool ?? true
var mapSnapshotOptions = MapSnapshotOptions(
size: CGSize(width: width.doubleValue, height: height.doubleValue),
pixelRatio: 1.0
)
mapSnapshotOptions.showsLogo = showsLogo
return mapSnapshotOptions
}
}