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