react-native-google-maps-plus 1.0.2 → 1.1.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 (107) hide show
  1. package/README.md +127 -11
  2. package/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt +359 -139
  3. package/android/src/main/java/com/rngooglemapsplus/LocationHandler.kt +44 -44
  4. package/android/src/main/java/com/rngooglemapsplus/MapCircleBuilder.kt +19 -0
  5. package/android/src/main/java/com/rngooglemapsplus/{MapMarker.kt → MapMarkerBuilder.kt} +7 -6
  6. package/android/src/main/java/com/rngooglemapsplus/{MapPolygon.kt → MapPolygonBuilder.kt} +4 -18
  7. package/android/src/main/java/com/rngooglemapsplus/{MapPolyline.kt → MapPolylineBuilder.kt.kt} +4 -19
  8. package/android/src/main/java/com/rngooglemapsplus/RNGoogleMapsPlusView.kt +145 -129
  9. package/android/src/main/java/com/rngooglemapsplus/extensions/RNCameraExtension.kt +19 -0
  10. package/android/src/main/java/com/rngooglemapsplus/extensions/RNLocationPriorityExtension.kt +12 -0
  11. package/android/src/main/java/com/rngooglemapsplus/extensions/RNMapCircleExtension.kt +14 -0
  12. package/android/src/main/java/com/rngooglemapsplus/extensions/RNPolygonExtension.kt +20 -0
  13. package/android/src/main/java/com/rngooglemapsplus/extensions/RNPolylineExtension.kt +21 -0
  14. package/android/src/main/java/com/rngooglemapsplus/extensions/RNUserInterfaceExtension.kt +12 -0
  15. package/android/src/main/java/com/rngooglemapsplus/{Color.kt → extensions/StringExtension.kt} +1 -1
  16. package/android/src/main/java/com/rngooglemapsplus/extensions/ThrowableExtension.kt +38 -0
  17. package/ios/GoogleMapViewImpl.swift +348 -150
  18. package/ios/LocationHandler.swift +29 -69
  19. package/ios/MapCircleBuilder.swift +20 -0
  20. package/ios/{MapMarker.swift → MapMarkerBuilder.swift} +11 -42
  21. package/ios/MapPolygonBuilder.swift +20 -0
  22. package/ios/MapPolylineBuilder.swift +24 -0
  23. package/ios/PermissionHandler.swift +1 -1
  24. package/ios/RNGoogleMapsPlusModule.swift +1 -1
  25. package/ios/RNGoogleMapsPlusView.swift +159 -168
  26. package/ios/extensions/RNCamera+Extension.swift +22 -0
  27. package/ios/extensions/RNCircle+Extension.swift +24 -0
  28. package/ios/extensions/RNIOSLocationAccuracy+Extensions.swift +19 -0
  29. package/ios/extensions/RNMarker+Extension.swift +24 -0
  30. package/ios/{MapPolygon.swift → extensions/RNPolygon+Extension.swift.swift} +7 -23
  31. package/ios/extensions/RNPolyline+Extension.swift.swift +62 -0
  32. package/ios/extensions/RNUserInterface+Extension.swift +16 -0
  33. package/ios/{Color.swift → extensions/String+Extensions.swift} +20 -20
  34. package/lib/module/types.js +14 -0
  35. package/lib/module/types.js.map +1 -1
  36. package/lib/typescript/src/RNGoogleMapsPlusView.nitro.d.ts +21 -12
  37. package/lib/typescript/src/RNGoogleMapsPlusView.nitro.d.ts.map +1 -1
  38. package/lib/typescript/src/types.d.ts +59 -3
  39. package/lib/typescript/src/types.d.ts.map +1 -1
  40. package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusViewSpec.cpp +233 -69
  41. package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusViewSpec.hpp +40 -22
  42. package/nitrogen/generated/android/c++/JRNAndroidLocationConfig.hpp +63 -0
  43. package/nitrogen/generated/android/c++/JRNAndroidLocationPriority.hpp +65 -0
  44. package/nitrogen/generated/android/c++/JRNCircle.hpp +84 -0
  45. package/nitrogen/generated/android/c++/JRNIOSLocationAccuracy.hpp +65 -0
  46. package/nitrogen/generated/android/c++/JRNIOSLocationConfig.hpp +59 -0
  47. package/nitrogen/generated/android/c++/JRNInitialProps.hpp +66 -0
  48. package/nitrogen/generated/android/c++/JRNLocationConfig.hpp +65 -0
  49. package/nitrogen/generated/android/c++/JRNMapType.hpp +68 -0
  50. package/nitrogen/generated/android/c++/JRNMapUiSettings.hpp +93 -0
  51. package/nitrogen/generated/android/c++/JRNMarker.hpp +4 -4
  52. package/nitrogen/generated/android/c++/JRNPolygon.hpp +8 -4
  53. package/nitrogen/generated/android/c++/JRNPolyline.hpp +8 -4
  54. package/nitrogen/generated/android/c++/views/JHybridRNGoogleMapsPlusViewStateUpdater.cpp +40 -4
  55. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/HybridRNGoogleMapsPlusViewSpec.kt +89 -11
  56. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNAndroidLocationConfig.kt +35 -0
  57. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNAndroidLocationPriority.kt +23 -0
  58. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNCircle.kt +50 -0
  59. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNIOSLocationAccuracy.kt +23 -0
  60. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNIOSLocationConfig.kt +32 -0
  61. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNInitialProps.kt +35 -0
  62. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNLocationConfig.kt +32 -0
  63. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNMapType.kt +24 -0
  64. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNMapUiSettings.kt +59 -0
  65. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNMarker.kt +1 -1
  66. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNPolygon.kt +4 -1
  67. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNPolyline.kt +4 -1
  68. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/views/HybridRNGoogleMapsPlusViewManager.kt +7 -1
  69. package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Bridge.hpp +296 -45
  70. package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Umbrella.hpp +27 -0
  71. package/nitrogen/generated/ios/c++/HybridRNGoogleMapsPlusViewSpecSwift.hpp +131 -37
  72. package/nitrogen/generated/ios/c++/views/HybridRNGoogleMapsPlusViewComponent.mm +61 -16
  73. package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusViewSpec.swift +20 -11
  74. package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusViewSpec_cxx.swift +378 -45
  75. package/nitrogen/generated/ios/swift/RNAndroidLocationConfig.swift +93 -0
  76. package/nitrogen/generated/ios/swift/RNAndroidLocationPriority.swift +48 -0
  77. package/nitrogen/generated/ios/swift/RNCircle.swift +198 -0
  78. package/nitrogen/generated/ios/swift/RNIOSLocationAccuracy.swift +48 -0
  79. package/nitrogen/generated/ios/swift/RNIOSLocationConfig.swift +70 -0
  80. package/nitrogen/generated/ios/swift/RNInitialProps.swift +107 -0
  81. package/nitrogen/generated/ios/swift/RNLocationConfig.swift +84 -0
  82. package/nitrogen/generated/ios/swift/RNMapType.swift +52 -0
  83. package/nitrogen/generated/ios/swift/RNMapUiSettings.swift +277 -0
  84. package/nitrogen/generated/ios/swift/RNMarker.swift +17 -5
  85. package/nitrogen/generated/ios/swift/RNPolygon.swift +40 -5
  86. package/nitrogen/generated/ios/swift/RNPolyline.swift +40 -5
  87. package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusViewSpec.cpp +20 -2
  88. package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusViewSpec.hpp +59 -26
  89. package/nitrogen/generated/shared/c++/RNAndroidLocationConfig.hpp +77 -0
  90. package/nitrogen/generated/shared/c++/RNAndroidLocationPriority.hpp +64 -0
  91. package/nitrogen/generated/shared/c++/RNCircle.hpp +98 -0
  92. package/nitrogen/generated/shared/c++/RNIOSLocationAccuracy.hpp +64 -0
  93. package/nitrogen/generated/shared/c++/RNIOSLocationConfig.hpp +73 -0
  94. package/nitrogen/generated/shared/c++/RNInitialProps.hpp +78 -0
  95. package/nitrogen/generated/shared/c++/RNLocationConfig.hpp +76 -0
  96. package/nitrogen/generated/shared/c++/RNMapType.hpp +88 -0
  97. package/nitrogen/generated/shared/c++/RNMapUiSettings.hpp +107 -0
  98. package/nitrogen/generated/shared/c++/RNMarker.hpp +6 -6
  99. package/nitrogen/generated/shared/c++/RNPolygon.hpp +10 -6
  100. package/nitrogen/generated/shared/c++/RNPolyline.hpp +10 -6
  101. package/nitrogen/generated/shared/c++/views/HybridRNGoogleMapsPlusViewComponent.cpp +138 -30
  102. package/nitrogen/generated/shared/c++/views/HybridRNGoogleMapsPlusViewComponent.hpp +27 -13
  103. package/nitrogen/generated/shared/json/RNGoogleMapsPlusViewConfig.json +10 -1
  104. package/package.json +5 -5
  105. package/src/RNGoogleMapsPlusView.nitro.ts +25 -11
  106. package/src/types.ts +67 -3
  107. package/ios/MapPolyline.swift +0 -83
@@ -5,65 +5,34 @@ import UIKit
5
5
  final class GoogleMapsViewImpl: UIView, GMSMapViewDelegate {
6
6
 
7
7
  private let locationHandler: LocationHandler
8
- private let markerOptions: MapMarkerOptions
9
- private var mapView: GMSMapView!
8
+ private let markerBuilder: MapMarkerBuilder
9
+ private var mapView: GMSMapView?
10
+ private var initialized = false
10
11
  private var mapReady = false
11
12
 
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
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)] = []
30
17
 
31
- private var polygonsById: [String: GMSPolygon] = [:]
32
- private var polylinesById: [String: GMSPolyline] = [:]
33
18
  private var markersById: [String: GMSMarker] = [:]
19
+ private var polylinesById: [String: GMSPolyline] = [:]
20
+ private var polygonsById: [String: GMSPolygon] = [:]
21
+ private var circlesById: [String: GMSCircle] = [:]
34
22
 
35
23
  private var cameraMoveReasonIsGesture: Bool = false
36
24
  private var lastSubmittedCameraPosition: GMSCameraPosition?
37
25
  private var lastSubmittedLocation: CLLocation?
38
26
 
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
27
  init(
50
28
  frame: CGRect = .zero,
51
29
  locationHandler: LocationHandler,
52
- markerOptions: MapMarkerOptions
30
+ markerBuilder: MapMarkerBuilder
53
31
  ) {
54
32
  self.locationHandler = locationHandler
55
- self.markerOptions = markerOptions
33
+ self.markerBuilder = markerBuilder
56
34
  super.init(frame: frame)
57
35
  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
36
  }
68
37
 
69
38
  private func setupAppLifecycleObservers() {
@@ -86,14 +55,31 @@ final class GoogleMapsViewImpl: UIView, GMSMapViewDelegate {
86
55
  }
87
56
 
88
57
  @MainActor
89
- private func setupMap() {
58
+ func initMapView(mapId: String?, liteMode: Bool?, camera: GMSCameraPosition?) {
59
+ if initialized { return }
60
+ initialized = true
90
61
  let options = GMSMapViewOptions()
91
62
  options.frame = bounds
63
+ if let mapId = mapId {
64
+ options.mapID = GMSMapID(identifier: mapId)
65
+ }
66
+ if let liteMode = liteMode {
67
+ /// not supported
68
+ }
69
+ if let camera = camera {
70
+ options.camera = camera
71
+ }
92
72
  mapView = GMSMapView.init(options: options)
93
- mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
94
- mapView.paddingAdjustmentBehavior = .never
95
- mapView.delegate = self
96
- addSubview(mapView)
73
+ mapView?.delegate = self
74
+ mapView?.autoresizingMask = [.flexibleWidth, .flexibleHeight]
75
+ mapView?.paddingAdjustmentBehavior = .never
76
+ if let mapView = mapView {
77
+ addSubview(mapView)
78
+ }
79
+ initLocationCallbacks()
80
+ applyPending()
81
+ onMapReady?(true)
82
+ mapReady = true
97
83
  }
98
84
 
99
85
  private func initLocationCallbacks() {
@@ -102,7 +88,7 @@ final class GoogleMapsViewImpl: UIView, GMSMapViewDelegate {
102
88
  if self.lastSubmittedLocation?.coordinate.latitude
103
89
  != loc.coordinate.latitude
104
90
  || self.lastSubmittedLocation?.coordinate.longitude
105
- != loc.coordinate.longitude {
91
+ != loc.coordinate.longitude {
106
92
  self.onLocationUpdate?(
107
93
  RNLocation(
108
94
  RNLatLng(
@@ -123,21 +109,92 @@ final class GoogleMapsViewImpl: UIView, GMSMapViewDelegate {
123
109
 
124
110
  @MainActor
125
111
  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
112
 
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
- )
113
+ if let padding = mapPadding {
114
+ mapView?.padding = UIEdgeInsets(
115
+ top: padding.top,
116
+ left: padding.left,
117
+ bottom: padding.bottom,
118
+ right: padding.right
119
+ )
120
+ }
121
+
122
+ if let uiSettings = uiSettings {
123
+ if let allGesturesEnabled = uiSettings.allGesturesEnabled {
124
+ mapView?.settings.setAllGesturesEnabled(allGesturesEnabled)
125
+ }
126
+ if let compassEnabled = uiSettings.compassEnabled {
127
+ mapView?.settings.compassButton = compassEnabled
128
+ }
129
+ if let indoorLevelPickerEnabled = uiSettings.indoorLevelPickerEnabled {
130
+ mapView?.settings.indoorPicker = indoorLevelPickerEnabled
131
+ }
132
+ if let mapToolbarEnabled = uiSettings.mapToolbarEnabled {
133
+ /// not supported
134
+ }
135
+ if let myLocationButtonEnabled = uiSettings.myLocationButtonEnabled {
136
+ mapView?.settings.myLocationButton = myLocationButtonEnabled
137
+ }
138
+ if let rotateEnabled = uiSettings.rotateEnabled {
139
+ mapView?.settings.rotateGestures = rotateEnabled
140
+ }
141
+ if let scrollEnabled = uiSettings.scrollEnabled {
142
+ mapView?.settings.scrollGestures = scrollEnabled
143
+ }
144
+ if let scrollDuringRotateOrZoomEnabled = uiSettings
145
+ .scrollDuringRotateOrZoomEnabled {
146
+ mapView?.settings.allowScrollGesturesDuringRotateOrZoom =
147
+ scrollDuringRotateOrZoomEnabled
148
+ }
149
+ if let tiltEnabled = uiSettings.tiltEnabled {
150
+ mapView?.settings.tiltGestures = tiltEnabled
151
+ }
152
+ if let zoomControlsEnabled = uiSettings.zoomControlsEnabled {
153
+ /// not supported
154
+ }
155
+ if let zoomGesturesEnabled = uiSettings.zoomGesturesEnabled {
156
+ mapView?.settings.zoomGestures = zoomGesturesEnabled
157
+ }
158
+ }
159
+
160
+ if let myLocation = myLocationEnabled {
161
+ mapView?.isMyLocationEnabled = myLocation
162
+ }
163
+
164
+ if let buildings = buildingEnabled {
165
+ mapView?.isBuildingsEnabled = buildings
166
+ }
167
+
168
+ if let traffic = trafficEnabled {
169
+ mapView?.isTrafficEnabled = traffic
170
+ }
171
+
172
+ if let indoor = indoorEnabled {
173
+ mapView?.isIndoorEnabled = indoor
174
+ }
175
+
176
+ if let style = customMapStyle {
177
+ mapView?.mapStyle = style
178
+ }
179
+
180
+ if let mapType = mapType {
181
+ mapView?.mapType = mapType
182
+ }
183
+
184
+ if let uiStyle = userInterfaceStyle {
185
+ mapView?.overrideUserInterfaceStyle = uiStyle
186
+ }
187
+
188
+ if let minZoom = minZoomLevel, let maxZoom = maxZoomLevel {
189
+ mapView?.setMinZoom(Float(minZoom), maxZoom: Float(maxZoom))
190
+ }
191
+
192
+ if let locationConfig = locationConfig {
193
+ locationHandler.desiredAccuracy =
194
+ locationConfig.ios?.desiredAccuracy?.toCLLocationAccuracy
195
+ locationHandler.distanceFilterMeters =
196
+ locationConfig.ios?.distanceFilterMeters
197
+ }
141
198
 
142
199
  if !pendingMarkers.isEmpty {
143
200
  pendingMarkers.forEach {
@@ -157,119 +214,209 @@ final class GoogleMapsViewImpl: UIView, GMSMapViewDelegate {
157
214
  }
158
215
  pendingPolygons.removeAll()
159
216
  }
217
+ if !pendingCircles.isEmpty {
218
+ pendingCircles.forEach {
219
+ addCircleInternal(id: $0.id, circle: $0.circle)
220
+ }
221
+ pendingCircles.removeAll()
222
+ }
160
223
  }
161
224
 
162
- var currentCamera: GMSCameraPosition {
163
- mapView.camera
225
+ var currentCamera: GMSCameraPosition? {
226
+ mapView?.camera
164
227
  }
165
228
 
166
229
  @MainActor
167
- var buildingEnabled: Bool {
168
- get { mapView.isBuildingsEnabled }
169
- set {
170
- pendingBuildingEnabled = newValue
171
- mapView.isBuildingsEnabled = newValue
230
+ var uiSettings: RNMapUiSettings? {
231
+ didSet {
232
+ guard let mapView = mapView else { return }
233
+ let settings = mapView.settings
234
+
235
+ if let v = uiSettings {
236
+ if let allGesturesEnabled = v.allGesturesEnabled {
237
+ settings.setAllGesturesEnabled(allGesturesEnabled)
238
+ }
239
+ if let compassEnabled = v.compassEnabled {
240
+ settings.compassButton = compassEnabled
241
+ }
242
+ if let indoorLevelPickerEnabled = v.indoorLevelPickerEnabled {
243
+ settings.indoorPicker = indoorLevelPickerEnabled
244
+ }
245
+ if let mapToolbarEnabled = v.mapToolbarEnabled {
246
+ /// not supported
247
+ }
248
+ if let myLocationButtonEnabled = v.myLocationButtonEnabled {
249
+ settings.myLocationButton = myLocationButtonEnabled
250
+ }
251
+ if let rotateEnabled = v.rotateEnabled {
252
+ settings.rotateGestures = rotateEnabled
253
+ }
254
+ if let scrollEnabled = v.scrollEnabled {
255
+ settings.scrollGestures = scrollEnabled
256
+ }
257
+ if let scrollDuringRotateOrZoomEnabled = v
258
+ .scrollDuringRotateOrZoomEnabled {
259
+ settings.allowScrollGesturesDuringRotateOrZoom =
260
+ scrollDuringRotateOrZoomEnabled
261
+ }
262
+ if let tiltEnabled = v.tiltEnabled {
263
+ settings.tiltGestures = tiltEnabled
264
+ }
265
+ if let zoomControlsEnabled = v.zoomControlsEnabled {
266
+ /// not supported
267
+ }
268
+ if let zoomGesturesEnabled = v.zoomGesturesEnabled {
269
+ settings.zoomGestures = zoomGesturesEnabled
270
+ }
271
+ } else {
272
+ settings.setAllGesturesEnabled(true)
273
+ settings.compassButton = false
274
+ settings.indoorPicker = false
275
+ settings.myLocationButton = false
276
+ settings.rotateGestures = true
277
+ settings.scrollGestures = true
278
+ settings.allowScrollGesturesDuringRotateOrZoom = true
279
+ settings.tiltGestures = true
280
+ settings.zoomGestures = false
281
+ }
172
282
  }
173
283
  }
174
284
 
175
285
  @MainActor
176
- var trafficEnabled: Bool {
177
- get { mapView.isTrafficEnabled }
178
- set {
179
- pendingTrafficEnabled = newValue
180
- mapView.isTrafficEnabled = newValue
286
+ var myLocationEnabled: Bool? {
287
+ didSet {
288
+ if let value = myLocationEnabled {
289
+ mapView?.isMyLocationEnabled = value
290
+ } else {
291
+ mapView?.isMyLocationEnabled = false
292
+ }
181
293
  }
182
294
  }
183
295
 
184
296
  @MainActor
185
- var customMapStyle: GMSMapStyle? {
186
- get { pendingCustomMapStyle }
187
- set {
188
- pendingCustomMapStyle = newValue
189
- mapView.mapStyle = newValue
297
+ var buildingEnabled: Bool? {
298
+ didSet {
299
+ if let value = buildingEnabled {
300
+ mapView?.isBuildingsEnabled = value
301
+ } else {
302
+ mapView?.isBuildingsEnabled = false
303
+ }
190
304
  }
191
305
  }
192
306
 
193
307
  @MainActor
194
- var initialCamera: GMSCameraPosition {
195
- get { pendingInitialCamera }
196
- set {
197
- pendingInitialCamera = newValue
198
- if mapView != nil && !mapReady {
199
- mapView.camera = newValue
308
+ var trafficEnabled: Bool? {
309
+ didSet {
310
+ if let value = trafficEnabled {
311
+ mapView?.isTrafficEnabled = value
312
+ } else {
313
+ mapView?.isTrafficEnabled = false
200
314
  }
201
315
  }
202
316
  }
203
317
 
204
318
  @MainActor
205
- var userInterfaceStyle: UIUserInterfaceStyle {
206
- get { pendingUserInterfaceStyle }
207
- set {
208
- pendingUserInterfaceStyle = newValue
209
- mapView.overrideUserInterfaceStyle = newValue
319
+ var indoorEnabled: Bool? {
320
+ didSet {
321
+ if let value = indoorEnabled {
322
+ mapView?.isIndoorEnabled = value
323
+ } else {
324
+ mapView?.isIndoorEnabled = false
325
+ }
210
326
  }
211
327
  }
212
328
 
213
329
  @MainActor
214
- var minZoomLevel: Double {
215
- get { pendingMinZoomLevel }
216
- set {
217
- pendingMinZoomLevel = newValue
218
- mapView.setMinZoom(Float(newValue), maxZoom: Float(pendingMaxZoomLevel))
330
+ var customMapStyle: GMSMapStyle? {
331
+ didSet {
332
+ if let style = customMapStyle {
333
+ mapView?.mapStyle = style
334
+ }
219
335
  }
220
336
  }
221
337
 
222
338
  @MainActor
223
- var maxZoomLevel: Double {
224
- get { pendingMaxZoomLevel }
225
- set {
226
- pendingMaxZoomLevel = newValue
227
- mapView.setMinZoom(Float(pendingMinZoomLevel), maxZoom: Float(newValue))
339
+ var userInterfaceStyle: UIUserInterfaceStyle? {
340
+ didSet {
341
+ if let style = userInterfaceStyle {
342
+ mapView?.overrideUserInterfaceStyle = style
343
+ }
228
344
  }
229
345
  }
230
346
 
231
347
  @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
- )
348
+ var minZoomLevel: Double? {
349
+ didSet {
350
+ if let min = minZoomLevel, let max = maxZoomLevel {
351
+ mapView?.setMinZoom(Float(min), maxZoom: Float(max))
352
+ }
242
353
  }
243
354
  }
244
355
 
245
- func setCamera(camera: RNCamera, animated: Bool, durationMS: Double) {
246
- let current = mapView.camera
356
+ @MainActor
357
+ var maxZoomLevel: Double? {
358
+ didSet {
359
+ if let max = maxZoomLevel, let min = minZoomLevel {
360
+ mapView?.setMinZoom(Float(min), maxZoom: Float(max))
361
+ }
362
+ }
363
+ }
364
+
365
+ @MainActor
366
+ var mapPadding: RNMapPadding? {
367
+ didSet {
368
+ if let padding = mapPadding {
369
+ mapView?.padding = UIEdgeInsets(
370
+ top: padding.top,
371
+ left: padding.left,
372
+ bottom: padding.bottom,
373
+ right: padding.right
374
+ )
375
+ } else {
376
+ mapView?.padding = .zero
377
+ }
378
+ }
379
+ }
247
380
 
248
- let zoom = Float(camera.zoom ?? Double(current.zoom))
249
- let bearing = camera.bearing ?? current.bearing
250
- let viewingAngle = camera.bearing ?? current.viewingAngle
381
+ @MainActor var mapType: GMSMapViewType? {
382
+ didSet {
383
+ mapView?.mapType = mapType ?? .normal
384
+ }
385
+ }
251
386
 
252
- let target = CLLocationCoordinate2D(
253
- latitude: camera.center?.latitude ?? mapView.camera.target.latitude,
254
- longitude: camera.center?.longitude ?? mapView.camera.target.longitude
255
- )
387
+ @MainActor var locationConfig: RNLocationConfig? {
388
+ didSet {
389
+ locationHandler.desiredAccuracy =
390
+ locationConfig?.ios?.desiredAccuracy?.toCLLocationAccuracy
391
+ locationHandler.distanceFilterMeters =
392
+ locationConfig?.ios?.distanceFilterMeters
393
+ }
394
+ }
256
395
 
257
- let cam = GMSCameraPosition.camera(
258
- withTarget: target,
259
- zoom: zoom,
260
- bearing: bearing,
261
- viewingAngle: viewingAngle
262
- )
396
+ var onMapError: ((RNMapErrorCode) -> Void)?
397
+ var onMapReady: ((Bool) -> Void)?
398
+ var onLocationUpdate: ((RNLocation) -> Void)?
399
+ var onLocationError: ((_ error: RNLocationErrorCode) -> Void)?
400
+ var onMapPress: ((RNLatLng) -> Void)?
401
+ var onMarkerPress: ((String) -> Void)?
402
+ var onPolylinePress: ((String) -> Void)?
403
+ var onPolygonPress: ((String) -> Void)?
404
+ var onCirclePress: ((String) -> Void)?
405
+ var onCameraChangeStart: ((RNRegion, RNCamera, Bool) -> Void)?
406
+ var onCameraChange: ((RNRegion, RNCamera, Bool) -> Void)?
407
+ var onCameraChangeComplete: ((RNRegion, RNCamera, Bool) -> Void)?
408
+
409
+ func setCamera(camera: GMSCameraPosition, animated: Bool, durationMS: Double) {
263
410
  if animated {
264
411
  withCATransaction(
265
412
  disableActions: false,
266
413
  duration: durationMS / 1000.0
267
414
  ) {
268
- mapView.animate(to: cam)
415
+ mapView?.animate(to: camera)
269
416
  }
270
417
  } else {
271
- let update = GMSCameraUpdate.setCamera(cam)
272
- mapView.moveCamera(update)
418
+ let update = GMSCameraUpdate.setCamera(camera)
419
+ mapView?.moveCamera(update)
273
420
  }
274
421
  }
275
422
 
@@ -315,10 +462,10 @@ final class GoogleMapsViewImpl: UIView, GMSMapViewDelegate {
315
462
  disableActions: false,
316
463
  duration: durationMS / 1000.0
317
464
  ) {
318
- mapView.animate(with: update)
465
+ mapView?.animate(with: update)
319
466
  }
320
467
  } else {
321
- mapView.moveCamera(update)
468
+ mapView?.moveCamera(update)
322
469
  }
323
470
  }
324
471
 
@@ -427,19 +574,50 @@ final class GoogleMapsViewImpl: UIView, GMSMapViewDelegate {
427
574
  pendingPolygons.removeAll()
428
575
  }
429
576
 
430
- func clearAll() {
431
- markerOptions.cancelAllIconTasks()
577
+ @MainActor
578
+ func addCircle(id: String, circle: GMSCircle) {
579
+ if mapView == nil {
580
+ pendingCircles.append((id, circle))
581
+ return
582
+ }
583
+ if let old = circlesById.removeValue(forKey: id) { old.map = nil }
584
+ addCircleInternal(id: id, circle: circle)
585
+ }
586
+
587
+ @MainActor
588
+ private func addCircleInternal(id: String, circle: GMSCircle) {
589
+ circle.map = mapView
590
+ circle.userData = id
591
+ circlesById[id] = circle
592
+ }
593
+
594
+ @MainActor
595
+ func updateCircle(id: String, block: @escaping (GMSCircle) -> Void) {
596
+ guard let circle = circlesById[id] else { return }
597
+ block(circle)
598
+ }
599
+
600
+ @MainActor
601
+ func removeCircle(id: String) {
602
+ if let circle = circlesById.removeValue(forKey: id) { circle.map = nil }
603
+ }
604
+
605
+ @MainActor
606
+ func clearCircles() {
607
+ circlesById.values.forEach { $0.map = nil }
608
+ circlesById.removeAll()
609
+ pendingCircles.removeAll()
610
+ }
611
+
612
+ func deinitInternal() {
613
+ markerBuilder.cancelAllIconTasks()
432
614
  clearMarkers()
433
615
  clearPolylines()
434
616
  clearPolygons()
617
+ clearCircles()
435
618
  locationHandler.stop()
436
- clearMap()
437
- }
438
-
439
- @MainActor
440
- func clearMap() {
441
- mapView.clear()
442
- mapView.delegate = nil
619
+ mapView?.clear()
620
+ mapView?.delegate = nil
443
621
  mapView = nil
444
622
  }
445
623
 
@@ -457,7 +635,7 @@ final class GoogleMapsViewImpl: UIView, GMSMapViewDelegate {
457
635
  super.didMoveToWindow()
458
636
  if window != nil {
459
637
  if mapView != nil && mapReady {
460
- onMapReady?(true)
638
+ onMapReady?(true)
461
639
  }
462
640
  locationHandler.start()
463
641
  } else {
@@ -467,7 +645,7 @@ final class GoogleMapsViewImpl: UIView, GMSMapViewDelegate {
467
645
 
468
646
  deinit {
469
647
  NotificationCenter.default.removeObserver(self)
470
- clearAll()
648
+ deinitInternal()
471
649
  }
472
650
 
473
651
  func mapView(_ mapView: GMSMapView, willMove gesture: Bool) {
@@ -504,11 +682,11 @@ final class GoogleMapsViewImpl: UIView, GMSMapViewDelegate {
504
682
 
505
683
  func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) {
506
684
  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 {
685
+ last.target.latitude == position.target.latitude,
686
+ last.target.longitude == position.target.longitude,
687
+ last.zoom == position.zoom,
688
+ last.bearing == position.bearing,
689
+ last.viewingAngle == position.viewingAngle {
512
690
  return
513
691
  }
514
692
  let visibleRegion = mapView.projection.visibleRegion()
@@ -576,10 +754,11 @@ final class GoogleMapsViewImpl: UIView, GMSMapViewDelegate {
576
754
  didTapAt coordinate: CLLocationCoordinate2D
577
755
  ) {
578
756
  onMapPress?(
579
- RNLatLng(
580
- latitude: coordinate.latitude,
581
- longitude: coordinate.longitude
582
- ))
757
+ RNLatLng(
758
+ latitude: coordinate.latitude,
759
+ longitude: coordinate.longitude
760
+ )
761
+ )
583
762
  }
584
763
 
585
764
  func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
@@ -587,4 +766,23 @@ final class GoogleMapsViewImpl: UIView, GMSMapViewDelegate {
587
766
  onMarkerPress?(id)
588
767
  return true
589
768
  }
769
+
770
+ func mapView(_ mapView: GMSMapView, didTap overlay: GMSOverlay) {
771
+ switch overlay {
772
+ case let circle as GMSCircle:
773
+ let id = (circle.userData as? String) ?? "unknown"
774
+ onCirclePress?(id)
775
+
776
+ case let polygon as GMSPolygon:
777
+ let id = (polygon.userData as? String) ?? "unknown"
778
+ onPolygonPress?(id)
779
+
780
+ case let polyline as GMSPolyline:
781
+ let id = (polyline.userData as? String) ?? "unknown"
782
+ onPolylinePress?(id)
783
+
784
+ default:
785
+ break
786
+ }
787
+ }
590
788
  }