react-native-google-maps-plus 0.1.0 → 1.0.0-dev.1

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 (197) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +156 -0
  3. package/RNGoogleMapsPlus.podspec +34 -0
  4. package/android/CMakeLists.txt +32 -0
  5. package/android/build.gradle +135 -0
  6. package/android/fix-prefab.gradle +51 -0
  7. package/android/gradle.properties +8 -0
  8. package/android/src/main/AndroidManifest.xml +2 -0
  9. package/android/src/main/cpp/cpp-adapter.cpp +6 -0
  10. package/android/src/main/java/com/rngooglemapsplus/Color.kt +65 -0
  11. package/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt +847 -0
  12. package/android/src/main/java/com/rngooglemapsplus/LocationHandler.kt +205 -0
  13. package/android/src/main/java/com/rngooglemapsplus/MapCircle.kt +29 -0
  14. package/android/src/main/java/com/rngooglemapsplus/MapMarker.kt +146 -0
  15. package/android/src/main/java/com/rngooglemapsplus/MapPolygon.kt +38 -0
  16. package/android/src/main/java/com/rngooglemapsplus/MapPolyline.kt +61 -0
  17. package/android/src/main/java/com/rngooglemapsplus/PermissionHandler.kt +116 -0
  18. package/android/src/main/java/com/rngooglemapsplus/PlayServicesHandler.kt +25 -0
  19. package/android/src/main/java/com/rngooglemapsplus/RNGoogleMapsPlusModule.kt +22 -0
  20. package/android/src/main/java/com/rngooglemapsplus/RNGoogleMapsPlusPackage.kt +35 -0
  21. package/android/src/main/java/com/rngooglemapsplus/RNGoogleMapsPlusView.kt +364 -0
  22. package/ios/Color.swift +109 -0
  23. package/ios/GoogleMapViewImpl.swift +645 -0
  24. package/ios/LocationHandler.swift +205 -0
  25. package/ios/MapCircle.swift +43 -0
  26. package/ios/MapHelper.swift +18 -0
  27. package/ios/MapMarker.swift +200 -0
  28. package/ios/MapPolygon.swift +58 -0
  29. package/ios/MapPolyline.swift +85 -0
  30. package/ios/PermissionHandler.swift +73 -0
  31. package/ios/RNGoogleMapsPlusModule.swift +27 -0
  32. package/ios/RNGoogleMapsPlusView.swift +391 -0
  33. package/lib/module/RNGoogleMapsPlusModule.nitro.js +4 -0
  34. package/lib/module/RNGoogleMapsPlusModule.nitro.js.map +1 -0
  35. package/lib/module/RNGoogleMapsPlusView.nitro.js +4 -0
  36. package/lib/module/RNGoogleMapsPlusView.nitro.js.map +1 -0
  37. package/lib/module/index.js +8 -0
  38. package/lib/module/index.js.map +1 -0
  39. package/lib/module/package.json +1 -0
  40. package/lib/module/types.js +78 -0
  41. package/lib/module/types.js.map +1 -0
  42. package/lib/typescript/package.json +1 -0
  43. package/lib/typescript/src/RNGoogleMapsPlusModule.nitro.d.ts +12 -0
  44. package/lib/typescript/src/RNGoogleMapsPlusModule.nitro.d.ts.map +1 -0
  45. package/lib/typescript/src/RNGoogleMapsPlusView.nitro.d.ts +39 -0
  46. package/lib/typescript/src/RNGoogleMapsPlusView.nitro.d.ts.map +1 -0
  47. package/lib/typescript/src/index.d.ts +7 -0
  48. package/lib/typescript/src/index.d.ts.map +1 -0
  49. package/lib/typescript/src/types.d.ts +131 -0
  50. package/lib/typescript/src/types.d.ts.map +1 -0
  51. package/nitro.json +28 -0
  52. package/nitrogen/generated/.gitattributes +1 -0
  53. package/nitrogen/generated/android/RNGoogleMapsPlus+autolinking.cmake +85 -0
  54. package/nitrogen/generated/android/RNGoogleMapsPlus+autolinking.gradle +27 -0
  55. package/nitrogen/generated/android/RNGoogleMapsPlusOnLoad.cpp +70 -0
  56. package/nitrogen/generated/android/RNGoogleMapsPlusOnLoad.hpp +25 -0
  57. package/nitrogen/generated/android/c++/JFunc_void_RNLatLng.hpp +76 -0
  58. package/nitrogen/generated/android/c++/JFunc_void_RNLocation.hpp +78 -0
  59. package/nitrogen/generated/android/c++/JFunc_void_RNLocationErrorCode.hpp +76 -0
  60. package/nitrogen/generated/android/c++/JFunc_void_RNMapErrorCode.hpp +76 -0
  61. package/nitrogen/generated/android/c++/JFunc_void_RNRegion_RNCamera_bool.hpp +81 -0
  62. package/nitrogen/generated/android/c++/JFunc_void_bool.hpp +74 -0
  63. package/nitrogen/generated/android/c++/JFunc_void_std__string.hpp +75 -0
  64. package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusModuleSpec.cpp +83 -0
  65. package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusModuleSpec.hpp +67 -0
  66. package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusViewSpec.cpp +589 -0
  67. package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusViewSpec.hpp +118 -0
  68. package/nitrogen/generated/android/c++/JRNAndroidLocationPermissionResult.hpp +62 -0
  69. package/nitrogen/generated/android/c++/JRNCamera.hpp +67 -0
  70. package/nitrogen/generated/android/c++/JRNCircle.hpp +84 -0
  71. package/nitrogen/generated/android/c++/JRNIOSPermissionResult.hpp +59 -0
  72. package/nitrogen/generated/android/c++/JRNInitialProps.hpp +66 -0
  73. package/nitrogen/generated/android/c++/JRNLatLng.hpp +57 -0
  74. package/nitrogen/generated/android/c++/JRNLineCapType.hpp +62 -0
  75. package/nitrogen/generated/android/c++/JRNLineJoinType.hpp +62 -0
  76. package/nitrogen/generated/android/c++/JRNLocation.hpp +58 -0
  77. package/nitrogen/generated/android/c++/JRNLocationErrorCode.hpp +71 -0
  78. package/nitrogen/generated/android/c++/JRNLocationPermissionResult.hpp +61 -0
  79. package/nitrogen/generated/android/c++/JRNMapErrorCode.hpp +74 -0
  80. package/nitrogen/generated/android/c++/JRNMapPadding.hpp +65 -0
  81. package/nitrogen/generated/android/c++/JRNMapType.hpp +68 -0
  82. package/nitrogen/generated/android/c++/JRNMarker.hpp +82 -0
  83. package/nitrogen/generated/android/c++/JRNPolygon.hpp +98 -0
  84. package/nitrogen/generated/android/c++/JRNPolyline.hpp +106 -0
  85. package/nitrogen/generated/android/c++/JRNPosition.hpp +57 -0
  86. package/nitrogen/generated/android/c++/JRNRegion.hpp +62 -0
  87. package/nitrogen/generated/android/c++/JRNUserInterfaceStyle.hpp +62 -0
  88. package/nitrogen/generated/android/c++/views/JHybridRNGoogleMapsPlusViewStateUpdater.cpp +152 -0
  89. package/nitrogen/generated/android/c++/views/JHybridRNGoogleMapsPlusViewStateUpdater.hpp +49 -0
  90. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/Func_void_RNLatLng.kt +81 -0
  91. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/Func_void_RNLocation.kt +81 -0
  92. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/Func_void_RNLocationErrorCode.kt +81 -0
  93. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/Func_void_RNMapErrorCode.kt +81 -0
  94. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/Func_void_RNRegion_RNCamera_bool.kt +81 -0
  95. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/Func_void_bool.kt +81 -0
  96. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/Func_void_std__string.kt +81 -0
  97. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/HybridRNGoogleMapsPlusModuleSpec.kt +64 -0
  98. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/HybridRNGoogleMapsPlusViewSpec.kt +317 -0
  99. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNAndroidLocationPermissionResult.kt +22 -0
  100. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNCamera.kt +38 -0
  101. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNCircle.kt +50 -0
  102. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNGoogleMapsPlusOnLoad.kt +35 -0
  103. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNIOSPermissionResult.kt +21 -0
  104. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNInitialProps.kt +35 -0
  105. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNLatLng.kt +32 -0
  106. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNLineCapType.kt +22 -0
  107. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNLineJoinType.kt +22 -0
  108. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNLocation.kt +32 -0
  109. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNLocationErrorCode.kt +25 -0
  110. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNLocationPermissionResult.kt +32 -0
  111. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNMapErrorCode.kt +26 -0
  112. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNMapPadding.kt +38 -0
  113. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNMapType.kt +24 -0
  114. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNMarker.kt +47 -0
  115. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNPolygon.kt +47 -0
  116. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNPolyline.kt +50 -0
  117. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNPosition.kt +32 -0
  118. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNRegion.kt +35 -0
  119. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNUserInterfaceStyle.kt +22 -0
  120. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/views/HybridRNGoogleMapsPlusViewManager.kt +56 -0
  121. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/views/HybridRNGoogleMapsPlusViewStateUpdater.kt +23 -0
  122. package/nitrogen/generated/ios/RNGoogleMapsPlus+autolinking.rb +60 -0
  123. package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Bridge.cpp +121 -0
  124. package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Bridge.hpp +792 -0
  125. package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Umbrella.hpp +113 -0
  126. package/nitrogen/generated/ios/RNGoogleMapsPlusAutolinking.mm +41 -0
  127. package/nitrogen/generated/ios/RNGoogleMapsPlusAutolinking.swift +40 -0
  128. package/nitrogen/generated/ios/c++/HybridRNGoogleMapsPlusModuleSpecSwift.cpp +11 -0
  129. package/nitrogen/generated/ios/c++/HybridRNGoogleMapsPlusModuleSpecSwift.hpp +102 -0
  130. package/nitrogen/generated/ios/c++/HybridRNGoogleMapsPlusViewSpecSwift.cpp +11 -0
  131. package/nitrogen/generated/ios/c++/HybridRNGoogleMapsPlusViewSpecSwift.hpp +342 -0
  132. package/nitrogen/generated/ios/c++/views/HybridRNGoogleMapsPlusViewComponent.mm +216 -0
  133. package/nitrogen/generated/ios/swift/Func_void_RNLatLng.swift +47 -0
  134. package/nitrogen/generated/ios/swift/Func_void_RNLocation.swift +47 -0
  135. package/nitrogen/generated/ios/swift/Func_void_RNLocationErrorCode.swift +47 -0
  136. package/nitrogen/generated/ios/swift/Func_void_RNLocationPermissionResult.swift +47 -0
  137. package/nitrogen/generated/ios/swift/Func_void_RNMapErrorCode.swift +47 -0
  138. package/nitrogen/generated/ios/swift/Func_void_RNRegion_RNCamera_bool.swift +47 -0
  139. package/nitrogen/generated/ios/swift/Func_void_bool.swift +47 -0
  140. package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +47 -0
  141. package/nitrogen/generated/ios/swift/Func_void_std__string.swift +47 -0
  142. package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusModuleSpec.swift +52 -0
  143. package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusModuleSpec_cxx.swift +164 -0
  144. package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusViewSpec.swift +78 -0
  145. package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusViewSpec_cxx.swift +881 -0
  146. package/nitrogen/generated/ios/swift/RNAndroidLocationPermissionResult.swift +44 -0
  147. package/nitrogen/generated/ios/swift/RNCamera.swift +123 -0
  148. package/nitrogen/generated/ios/swift/RNCircle.swift +198 -0
  149. package/nitrogen/generated/ios/swift/RNIOSPermissionResult.swift +40 -0
  150. package/nitrogen/generated/ios/swift/RNInitialProps.swift +107 -0
  151. package/nitrogen/generated/ios/swift/RNLatLng.swift +46 -0
  152. package/nitrogen/generated/ios/swift/RNLineCapType.swift +44 -0
  153. package/nitrogen/generated/ios/swift/RNLineJoinType.swift +44 -0
  154. package/nitrogen/generated/ios/swift/RNLocation.swift +46 -0
  155. package/nitrogen/generated/ios/swift/RNLocationErrorCode.swift +56 -0
  156. package/nitrogen/generated/ios/swift/RNLocationPermissionResult.swift +70 -0
  157. package/nitrogen/generated/ios/swift/RNMapErrorCode.swift +60 -0
  158. package/nitrogen/generated/ios/swift/RNMapPadding.swift +68 -0
  159. package/nitrogen/generated/ios/swift/RNMapType.swift +52 -0
  160. package/nitrogen/generated/ios/swift/RNMarker.swift +132 -0
  161. package/nitrogen/generated/ios/swift/RNPolygon.swift +187 -0
  162. package/nitrogen/generated/ios/swift/RNPolyline.swift +203 -0
  163. package/nitrogen/generated/ios/swift/RNPosition.swift +46 -0
  164. package/nitrogen/generated/ios/swift/RNRegion.swift +57 -0
  165. package/nitrogen/generated/ios/swift/RNUserInterfaceStyle.swift +44 -0
  166. package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusModuleSpec.cpp +24 -0
  167. package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusModuleSpec.hpp +67 -0
  168. package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusViewSpec.cpp +76 -0
  169. package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusViewSpec.hpp +164 -0
  170. package/nitrogen/generated/shared/c++/RNAndroidLocationPermissionResult.hpp +67 -0
  171. package/nitrogen/generated/shared/c++/RNCamera.hpp +81 -0
  172. package/nitrogen/generated/shared/c++/RNCircle.hpp +98 -0
  173. package/nitrogen/generated/shared/c++/RNIOSPermissionResult.hpp +65 -0
  174. package/nitrogen/generated/shared/c++/RNInitialProps.hpp +78 -0
  175. package/nitrogen/generated/shared/c++/RNLatLng.hpp +71 -0
  176. package/nitrogen/generated/shared/c++/RNLineCapType.hpp +80 -0
  177. package/nitrogen/generated/shared/c++/RNLineJoinType.hpp +80 -0
  178. package/nitrogen/generated/shared/c++/RNLocation.hpp +72 -0
  179. package/nitrogen/generated/shared/c++/RNLocationErrorCode.hpp +73 -0
  180. package/nitrogen/generated/shared/c++/RNLocationPermissionResult.hpp +76 -0
  181. package/nitrogen/generated/shared/c++/RNMapErrorCode.hpp +67 -0
  182. package/nitrogen/generated/shared/c++/RNMapPadding.hpp +79 -0
  183. package/nitrogen/generated/shared/c++/RNMapType.hpp +88 -0
  184. package/nitrogen/generated/shared/c++/RNMarker.hpp +97 -0
  185. package/nitrogen/generated/shared/c++/RNPolygon.hpp +95 -0
  186. package/nitrogen/generated/shared/c++/RNPolyline.hpp +105 -0
  187. package/nitrogen/generated/shared/c++/RNPosition.hpp +71 -0
  188. package/nitrogen/generated/shared/c++/RNRegion.hpp +76 -0
  189. package/nitrogen/generated/shared/c++/RNUserInterfaceStyle.hpp +80 -0
  190. package/nitrogen/generated/shared/c++/views/HybridRNGoogleMapsPlusViewComponent.cpp +375 -0
  191. package/nitrogen/generated/shared/c++/views/HybridRNGoogleMapsPlusViewComponent.hpp +147 -0
  192. package/nitrogen/generated/shared/json/RNGoogleMapsPlusViewConfig.json +34 -0
  193. package/package.json +24 -8
  194. package/src/RNGoogleMapsPlusModule.nitro.ts +13 -0
  195. package/src/RNGoogleMapsPlusView.nitro.ts +86 -0
  196. package/src/index.tsx +24 -0
  197. package/src/types.ts +195 -0
@@ -0,0 +1,645 @@
1
+ import CoreLocation
2
+ import GoogleMaps
3
+ import UIKit
4
+
5
+ final class GoogleMapsViewImpl: UIView, GMSMapViewDelegate {
6
+
7
+ private let locationHandler: LocationHandler
8
+ private let markerOptions: MapMarkerOptions
9
+ private var mapView: GMSMapView?
10
+ private var initialized = false
11
+ private var mapReady = false
12
+
13
+ private var pendingMarkers: [(id: String, marker: GMSMarker)] = []
14
+ private var pendingPolylines: [(id: String, polyline: GMSPolyline)] = []
15
+ private var pendingPolygons: [(id: String, polygon: GMSPolygon)] = []
16
+ private var pendingCircles: [(id: String, circle: GMSCircle)] = []
17
+
18
+ private var markersById: [String: GMSMarker] = [:]
19
+ private var polylinesById: [String: GMSPolyline] = [:]
20
+ private var polygonsById: [String: GMSPolygon] = [:]
21
+ private var circlesById: [String: GMSCircle] = [:]
22
+
23
+ private var cameraMoveReasonIsGesture: Bool = false
24
+ private var lastSubmittedCameraPosition: GMSCameraPosition?
25
+ private var lastSubmittedLocation: CLLocation?
26
+
27
+ var onMapError: ((RNMapErrorCode) -> Void)?
28
+ var onMapReady: ((Bool) -> Void)?
29
+ var onLocationUpdate: ((RNLocation) -> Void)?
30
+ var onLocationError: ((_ error: RNLocationErrorCode) -> Void)?
31
+ var onMapPress: ((RNLatLng) -> Void)?
32
+ var onMarkerPress: ((String) -> Void)?
33
+ var onPolylinePress: ((String) -> Void)?
34
+ var onPolygonPress: ((String) -> Void)?
35
+ var onCirclePress: ((String) -> Void)?
36
+ var onCameraChangeStart: ((RNRegion, RNCamera, Bool) -> Void)?
37
+ var onCameraChange: ((RNRegion, RNCamera, Bool) -> Void)?
38
+ var onCameraChangeComplete: ((RNRegion, RNCamera, Bool) -> Void)?
39
+
40
+ init(
41
+ frame: CGRect = .zero,
42
+ locationHandler: LocationHandler,
43
+ markerOptions: MapMarkerOptions
44
+ ) {
45
+ self.locationHandler = locationHandler
46
+ self.markerOptions = markerOptions
47
+ super.init(frame: frame)
48
+ setupAppLifecycleObservers()
49
+ }
50
+
51
+ private func setupAppLifecycleObservers() {
52
+ NotificationCenter.default.addObserver(
53
+ self,
54
+ selector: #selector(appDidBecomeActive),
55
+ name: UIApplication.didBecomeActiveNotification,
56
+ object: nil
57
+ )
58
+ NotificationCenter.default.addObserver(
59
+ self,
60
+ selector: #selector(appDidEnterBackground),
61
+ name: UIApplication.didEnterBackgroundNotification,
62
+ object: nil
63
+ )
64
+ }
65
+
66
+ required init?(coder: NSCoder) {
67
+ fatalError("init(coder:) has not been implemented")
68
+ }
69
+
70
+ @MainActor
71
+ func initMapView(mapId: String?, liteMode: Bool?, camera: GMSCameraPosition?) {
72
+ if initialized { return }
73
+ initialized = true
74
+ let options = GMSMapViewOptions()
75
+ options.frame = bounds
76
+ if let mapId = mapId {
77
+ options.mapID = GMSMapID(identifier: mapId)
78
+ }
79
+ if let liteMode = liteMode {
80
+ /// not supported
81
+ }
82
+ if let camera = camera {
83
+ options.camera = camera
84
+ }
85
+ mapView = GMSMapView.init(options: options)
86
+ mapView?.delegate = self
87
+ mapView?.autoresizingMask = [.flexibleWidth, .flexibleHeight]
88
+ mapView?.paddingAdjustmentBehavior = .never
89
+ if let mapView = mapView {
90
+ addSubview(mapView)
91
+ }
92
+ initLocationCallbacks()
93
+ applyPending()
94
+ onMapReady?(true)
95
+ mapReady = true
96
+ }
97
+
98
+ private func initLocationCallbacks() {
99
+ locationHandler.onUpdate = { [weak self] loc in
100
+ guard let self = self else { return }
101
+ if self.lastSubmittedLocation?.coordinate.latitude
102
+ != loc.coordinate.latitude
103
+ || self.lastSubmittedLocation?.coordinate.longitude
104
+ != loc.coordinate.longitude {
105
+ self.onLocationUpdate?(
106
+ RNLocation(
107
+ RNLatLng(
108
+ latitude: loc.coordinate.latitude,
109
+ longitude: loc.coordinate.longitude
110
+ ),
111
+ loc.course
112
+ )
113
+ )
114
+ }
115
+ self.lastSubmittedLocation = loc
116
+ }
117
+ locationHandler.onError = { [weak self] error in
118
+ self?.onLocationError?(error)
119
+ }
120
+ locationHandler.start()
121
+ }
122
+
123
+ @MainActor
124
+ private func applyPending() {
125
+
126
+ if let padding = mapPadding {
127
+ mapView?.padding = UIEdgeInsets(
128
+ top: padding.top,
129
+ left: padding.left,
130
+ bottom: padding.bottom,
131
+ right: padding.right
132
+ )
133
+ }
134
+
135
+ if let style = customMapStyle {
136
+ mapView?.mapStyle = style
137
+ }
138
+
139
+ if let mapType = mapType {
140
+ mapView?.mapType = mapType
141
+ }
142
+
143
+ if let buildings = buildingEnabled {
144
+ mapView?.isBuildingsEnabled = buildings
145
+ }
146
+
147
+ if let traffic = trafficEnabled {
148
+ mapView?.isTrafficEnabled = traffic
149
+ }
150
+
151
+ if let uiStyle = userInterfaceStyle {
152
+ mapView?.overrideUserInterfaceStyle = uiStyle
153
+ }
154
+
155
+ if let minZoom = minZoomLevel, let maxZoom = maxZoomLevel {
156
+ mapView?.setMinZoom(Float(minZoom), maxZoom: Float(maxZoom))
157
+ }
158
+
159
+ if !pendingMarkers.isEmpty {
160
+ pendingMarkers.forEach {
161
+ addMarkerInternal(id: $0.id, marker: $0.marker)
162
+ }
163
+ pendingMarkers.removeAll()
164
+ }
165
+ if !pendingPolylines.isEmpty {
166
+ pendingPolylines.forEach {
167
+ addPolylineInternal(id: $0.id, polyline: $0.polyline)
168
+ }
169
+ pendingPolylines.removeAll()
170
+ }
171
+ if !pendingPolygons.isEmpty {
172
+ pendingPolygons.forEach {
173
+ addPolygonInternal(id: $0.id, polygon: $0.polygon)
174
+ }
175
+ pendingPolygons.removeAll()
176
+ }
177
+ if !pendingCircles.isEmpty {
178
+ pendingCircles.forEach {
179
+ addCircleInternal(id: $0.id, circle: $0.circle)
180
+ }
181
+ pendingCircles.removeAll()
182
+ }
183
+ }
184
+
185
+ var currentCamera: GMSCameraPosition? {
186
+ mapView?.camera
187
+ }
188
+
189
+ @MainActor
190
+ var buildingEnabled: Bool? {
191
+ didSet {
192
+ if let value = buildingEnabled {
193
+ mapView?.isBuildingsEnabled = value
194
+ }
195
+ }
196
+ }
197
+
198
+ @MainActor
199
+ var trafficEnabled: Bool? {
200
+ didSet {
201
+ if let value = trafficEnabled {
202
+ mapView?.isTrafficEnabled = value
203
+ }
204
+ }
205
+ }
206
+
207
+ @MainActor
208
+ var customMapStyle: GMSMapStyle? {
209
+ didSet {
210
+ if let style = customMapStyle {
211
+ mapView?.mapStyle = style
212
+ }
213
+ }
214
+ }
215
+
216
+ @MainActor
217
+ var userInterfaceStyle: UIUserInterfaceStyle? {
218
+ didSet {
219
+ if let style = userInterfaceStyle {
220
+ mapView?.overrideUserInterfaceStyle = style
221
+ }
222
+ }
223
+ }
224
+
225
+ @MainActor
226
+ var minZoomLevel: Double? {
227
+ didSet {
228
+ if let min = minZoomLevel, let max = maxZoomLevel {
229
+ mapView?.setMinZoom(Float(min), maxZoom: Float(max))
230
+ }
231
+ }
232
+ }
233
+
234
+ @MainActor
235
+ var maxZoomLevel: Double? {
236
+ didSet {
237
+ if let max = maxZoomLevel, let min = minZoomLevel {
238
+ mapView?.setMinZoom(Float(min), maxZoom: Float(max))
239
+ }
240
+ }
241
+ }
242
+
243
+ @MainActor
244
+ var mapPadding: RNMapPadding? {
245
+ didSet {
246
+ mapPadding
247
+ if let padding = mapPadding {
248
+ mapView?.padding = UIEdgeInsets(
249
+ top: padding.top,
250
+ left: padding.left,
251
+ bottom: padding.bottom,
252
+ right: padding.right
253
+ )
254
+ } else {
255
+ mapView?.padding = .zero
256
+ }
257
+ }
258
+ }
259
+
260
+ @MainActor var mapType: GMSMapViewType? {
261
+ didSet {
262
+ mapView?.mapType = mapType ?? .normal
263
+ }
264
+ }
265
+
266
+ func setCamera(camera: GMSCameraPosition, animated: Bool, durationMS: Double) {
267
+ if animated {
268
+ withCATransaction(
269
+ disableActions: false,
270
+ duration: durationMS / 1000.0
271
+ ) {
272
+ mapView?.animate(to: camera)
273
+ }
274
+ } else {
275
+ let update = GMSCameraUpdate.setCamera(camera)
276
+ mapView?.moveCamera(update)
277
+ }
278
+ }
279
+
280
+ func setCameraToCoordinates(
281
+ coordinates: [RNLatLng],
282
+ padding: RNMapPadding,
283
+ animated: Bool,
284
+ durationMS: Double
285
+ ) {
286
+ if coordinates.isEmpty {
287
+ return
288
+ }
289
+ var bounds = GMSCoordinateBounds(
290
+ coordinate: CLLocationCoordinate2D(
291
+ latitude: coordinates[0].latitude,
292
+ longitude: coordinates[0].longitude
293
+ ),
294
+ coordinate: CLLocationCoordinate2D(
295
+ latitude: coordinates[0].latitude,
296
+ longitude: coordinates[0].longitude
297
+ )
298
+ )
299
+
300
+ for coord in coordinates.dropFirst() {
301
+ bounds = bounds.includingCoordinate(
302
+ CLLocationCoordinate2D(
303
+ latitude: coord.latitude,
304
+ longitude: coord.longitude
305
+ )
306
+ )
307
+ }
308
+
309
+ let insets = UIEdgeInsets(
310
+ top: padding.top,
311
+ left: padding.left,
312
+ bottom: padding.bottom,
313
+ right: padding.right
314
+ )
315
+
316
+ let update = GMSCameraUpdate.fit(bounds, with: insets)
317
+ if animated {
318
+ withCATransaction(
319
+ disableActions: false,
320
+ duration: durationMS / 1000.0
321
+ ) {
322
+ mapView?.animate(with: update)
323
+ }
324
+ } else {
325
+ mapView?.moveCamera(update)
326
+ }
327
+ }
328
+
329
+ @MainActor
330
+ func addMarker(id: String, marker: GMSMarker) {
331
+ if mapView == nil {
332
+ pendingMarkers.append((id, marker))
333
+ return
334
+ }
335
+ if let old = markersById.removeValue(forKey: id) { old.map = nil }
336
+ addMarkerInternal(id: id, marker: marker)
337
+ }
338
+
339
+ @MainActor
340
+ private func addMarkerInternal(id: String, marker: GMSMarker) {
341
+ marker.userData = id
342
+ marker.map = mapView
343
+ markersById[id] = marker
344
+ }
345
+
346
+ @MainActor
347
+ func updateMarker(id: String, block: @escaping (GMSMarker) -> Void) {
348
+ guard let m = markersById[id] else { return }
349
+ block(m)
350
+ }
351
+
352
+ @MainActor
353
+ func removeMarker(id: String) {
354
+ if let m = markersById.removeValue(forKey: id) { m.map = nil }
355
+ }
356
+
357
+ @MainActor
358
+ func clearMarkers() {
359
+ markersById.values.forEach { $0.map = nil }
360
+ markersById.removeAll()
361
+ pendingMarkers.removeAll()
362
+ }
363
+
364
+ @MainActor
365
+ func addPolyline(id: String, polyline: GMSPolyline) {
366
+ if mapView == nil {
367
+ pendingPolylines.append((id, polyline))
368
+ return
369
+ }
370
+ if let old = polylinesById.removeValue(forKey: id) { old.map = nil }
371
+ addPolylineInternal(id: id, polyline: polyline)
372
+ }
373
+
374
+ @MainActor
375
+ private func addPolylineInternal(id: String, polyline: GMSPolyline) {
376
+ polyline.map = mapView
377
+ polyline.userData = id
378
+ polylinesById[id] = polyline
379
+ }
380
+
381
+ @MainActor
382
+ func updatePolyline(id: String, block: @escaping (GMSPolyline) -> Void) {
383
+ guard let pl = polylinesById[id] else { return }
384
+ block(pl)
385
+ }
386
+
387
+ @MainActor
388
+ func removePolyline(id: String) {
389
+ if let pl = polylinesById.removeValue(forKey: id) { pl.map = nil }
390
+ }
391
+
392
+ @MainActor
393
+ func clearPolylines() {
394
+ polylinesById.values.forEach { $0.map = nil }
395
+ polylinesById.removeAll()
396
+ pendingPolylines.removeAll()
397
+ }
398
+
399
+ @MainActor
400
+ func addPolygon(id: String, polygon: GMSPolygon) {
401
+ if mapView == nil {
402
+ pendingPolygons.append((id, polygon))
403
+ return
404
+ }
405
+ if let old = polygonsById.removeValue(forKey: id) { old.map = nil }
406
+ addPolygonInternal(id: id, polygon: polygon)
407
+ }
408
+
409
+ @MainActor
410
+ private func addPolygonInternal(id: String, polygon: GMSPolygon) {
411
+ polygon.map = mapView
412
+ polygon.userData = id
413
+ polygonsById[id] = polygon
414
+ }
415
+
416
+ @MainActor
417
+ func updatePolygon(id: String, block: @escaping (GMSPolygon) -> Void) {
418
+ guard let pg = polygonsById[id] else { return }
419
+ block(pg)
420
+ }
421
+
422
+ @MainActor
423
+ func removePolygon(id: String) {
424
+ if let pg = polygonsById.removeValue(forKey: id) { pg.map = nil }
425
+ }
426
+
427
+ @MainActor
428
+ func clearPolygons() {
429
+ polygonsById.values.forEach { $0.map = nil }
430
+ polygonsById.removeAll()
431
+ pendingPolygons.removeAll()
432
+ }
433
+
434
+ @MainActor
435
+ func addCircle(id: String, circle: GMSCircle) {
436
+ if mapView == nil {
437
+ pendingCircles.append((id, circle))
438
+ return
439
+ }
440
+ if let old = circlesById.removeValue(forKey: id) { old.map = nil }
441
+ addCircleInternal(id: id, circle: circle)
442
+ }
443
+
444
+ @MainActor
445
+ private func addCircleInternal(id: String, circle: GMSCircle) {
446
+ circle.map = mapView
447
+ circle.userData = id
448
+ circlesById[id] = circle
449
+ }
450
+
451
+ @MainActor
452
+ func updateCircle(id: String, block: @escaping (GMSCircle) -> Void) {
453
+ guard let circle = circlesById[id] else { return }
454
+ block(circle)
455
+ }
456
+
457
+ @MainActor
458
+ func removeCircle(id: String) {
459
+ if let circle = circlesById.removeValue(forKey: id) { circle.map = nil }
460
+ }
461
+
462
+ @MainActor
463
+ func clearCircles() {
464
+ circlesById.values.forEach { $0.map = nil }
465
+ circlesById.removeAll()
466
+ pendingCircles.removeAll()
467
+ }
468
+
469
+ func deinitInternal() {
470
+ markerOptions.cancelAllIconTasks()
471
+ clearMarkers()
472
+ clearPolylines()
473
+ clearPolygons()
474
+ clearCircles()
475
+ locationHandler.stop()
476
+ mapView?.clear()
477
+ mapView?.delegate = nil
478
+ mapView = nil
479
+ }
480
+
481
+ @objc private func appDidBecomeActive() {
482
+ if window != nil {
483
+ locationHandler.start()
484
+ }
485
+ }
486
+
487
+ @objc private func appDidEnterBackground() {
488
+ locationHandler.stop()
489
+ }
490
+
491
+ override func didMoveToWindow() {
492
+ super.didMoveToWindow()
493
+ if window != nil {
494
+ if mapView != nil && mapReady {
495
+ onMapReady?(true)
496
+ }
497
+ locationHandler.start()
498
+ } else {
499
+ locationHandler.stop()
500
+ }
501
+ }
502
+
503
+ deinit {
504
+ NotificationCenter.default.removeObserver(self)
505
+ deinitInternal()
506
+ }
507
+
508
+ func mapView(_ mapView: GMSMapView, willMove gesture: Bool) {
509
+ let visibleRegion = mapView.projection.visibleRegion()
510
+ let bounds = GMSCoordinateBounds(region: visibleRegion)
511
+
512
+ let center = CLLocationCoordinate2D(
513
+ latitude: (bounds.northEast.latitude + bounds.southWest.latitude) / 2.0,
514
+ longitude: (bounds.northEast.longitude + bounds.southWest.longitude) / 2.0
515
+ )
516
+
517
+ let latDelta = bounds.northEast.latitude - bounds.southWest.latitude
518
+ let lngDelta = bounds.northEast.longitude - bounds.southWest.longitude
519
+
520
+ let cp = mapView.camera
521
+ let region = RNRegion(
522
+ center: RNLatLng(center.latitude, center.longitude),
523
+ latitudeDelta: latDelta,
524
+ longitudeDelta: lngDelta
525
+ )
526
+ let cam = RNCamera(
527
+ center: RNLatLng(
528
+ latitude: cp.target.latitude,
529
+ longitude: cp.target.longitude
530
+ ),
531
+ zoom: Double(cp.zoom),
532
+ bearing: cp.bearing,
533
+ tilt: cp.viewingAngle
534
+ )
535
+ cameraMoveReasonIsGesture = gesture
536
+
537
+ onCameraChangeStart?(region, cam, gesture)
538
+ }
539
+
540
+ func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) {
541
+ if let last = lastSubmittedCameraPosition,
542
+ last.target.latitude == position.target.latitude,
543
+ last.target.longitude == position.target.longitude,
544
+ last.zoom == position.zoom,
545
+ last.bearing == position.bearing,
546
+ last.viewingAngle == position.viewingAngle {
547
+ return
548
+ }
549
+ let visibleRegion = mapView.projection.visibleRegion()
550
+ let bounds = GMSCoordinateBounds(region: visibleRegion)
551
+
552
+ let center = CLLocationCoordinate2D(
553
+ latitude: (bounds.northEast.latitude + bounds.southWest.latitude) / 2.0,
554
+ longitude: (bounds.northEast.longitude + bounds.southWest.longitude) / 2.0
555
+ )
556
+
557
+ let latDelta = bounds.northEast.latitude - bounds.southWest.latitude
558
+ let lngDelta = bounds.northEast.longitude - bounds.southWest.longitude
559
+
560
+ let cp = mapView.camera
561
+ let region = RNRegion(
562
+ center: RNLatLng(center.latitude, center.longitude),
563
+ latitudeDelta: latDelta,
564
+ longitudeDelta: lngDelta
565
+ )
566
+ let cam = RNCamera(
567
+ center: RNLatLng(
568
+ latitude: cp.target.latitude,
569
+ longitude: cp.target.longitude
570
+ ),
571
+ zoom: Double(cp.zoom),
572
+ bearing: cp.bearing,
573
+ tilt: cp.viewingAngle
574
+ )
575
+ onCameraChange?(region, cam, cameraMoveReasonIsGesture)
576
+ lastSubmittedCameraPosition = position
577
+ }
578
+
579
+ func mapView(_ mapView: GMSMapView, idleAt position: GMSCameraPosition) {
580
+ let visibleRegion = mapView.projection.visibleRegion()
581
+ let bounds = GMSCoordinateBounds(region: visibleRegion)
582
+
583
+ let center = CLLocationCoordinate2D(
584
+ latitude: (bounds.northEast.latitude + bounds.southWest.latitude) / 2.0,
585
+ longitude: (bounds.northEast.longitude + bounds.southWest.longitude) / 2.0
586
+ )
587
+
588
+ let latDelta = bounds.northEast.latitude - bounds.southWest.latitude
589
+ let lngDelta = bounds.northEast.longitude - bounds.southWest.longitude
590
+
591
+ let cp = mapView.camera
592
+ let region = RNRegion(
593
+ center: RNLatLng(center.latitude, center.longitude),
594
+ latitudeDelta: latDelta,
595
+ longitudeDelta: lngDelta
596
+ )
597
+ let cam = RNCamera(
598
+ center: RNLatLng(
599
+ latitude: cp.target.latitude,
600
+ longitude: cp.target.longitude
601
+ ),
602
+ zoom: Double(cp.zoom),
603
+ bearing: cp.bearing,
604
+ tilt: cp.viewingAngle
605
+ )
606
+ onCameraChangeComplete?(region, cam, cameraMoveReasonIsGesture)
607
+ }
608
+
609
+ func mapView(
610
+ _ mapView: GMSMapView,
611
+ didTapAt coordinate: CLLocationCoordinate2D
612
+ ) {
613
+ onMapPress?(
614
+ RNLatLng(
615
+ latitude: coordinate.latitude,
616
+ longitude: coordinate.longitude
617
+ )
618
+ )
619
+ }
620
+
621
+ func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
622
+ let id = (marker.userData as? String) ?? "unknown"
623
+ onMarkerPress?(id)
624
+ return true
625
+ }
626
+
627
+ func mapView(_ mapView: GMSMapView, didTap overlay: GMSOverlay) {
628
+ switch overlay {
629
+ case let circle as GMSCircle:
630
+ let id = (circle.userData as? String) ?? "unknown"
631
+ onCirclePress?(id)
632
+
633
+ case let polygon as GMSPolygon:
634
+ let id = (polygon.userData as? String) ?? "unknown"
635
+ onPolygonPress?(id)
636
+
637
+ case let polyline as GMSPolyline:
638
+ let id = (polyline.userData as? String) ?? "unknown"
639
+ onPolylinePress?(id)
640
+
641
+ default:
642
+ break
643
+ }
644
+ }
645
+ }