react-native-google-maps-plus 1.6.2 → 1.7.0-dev.10

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 (96) hide show
  1. package/android/proguard-rules.pro +29 -0
  2. package/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt +461 -445
  3. package/android/src/main/java/com/rngooglemapsplus/LocationHandler.kt +5 -8
  4. package/android/src/main/java/com/rngooglemapsplus/MapCircleBuilder.kt +2 -1
  5. package/android/src/main/java/com/rngooglemapsplus/MapHeatmapBuilder.kt +1 -1
  6. package/android/src/main/java/com/rngooglemapsplus/MapHelper.kt +22 -0
  7. package/android/src/main/java/com/rngooglemapsplus/MapMarkerBuilder.kt +142 -2
  8. package/android/src/main/java/com/rngooglemapsplus/MapPolygonBuilder.kt +2 -1
  9. package/android/src/main/java/com/rngooglemapsplus/MapPolylineBuilder.kt.kt +2 -1
  10. package/android/src/main/java/com/rngooglemapsplus/MapUrlTileOverlayBuilder.kt +40 -0
  11. package/android/src/main/java/com/rngooglemapsplus/RNGoogleMapsPlusView.kt +93 -33
  12. package/android/src/main/java/com/rngooglemapsplus/extensions/LatLngBoundsExtension.kt +10 -0
  13. package/android/src/main/java/com/rngooglemapsplus/extensions/MapObjectTagExtensions.kt +84 -0
  14. package/android/src/main/java/com/rngooglemapsplus/extensions/RNLatLngBoundsExtension.kt +2 -8
  15. package/android/src/main/java/com/rngooglemapsplus/extensions/RNMapTypeExtension.kt +13 -0
  16. package/android/src/main/java/com/rngooglemapsplus/extensions/VisibleRegionExtension.kt +13 -0
  17. package/ios/GoogleMapViewImpl.swift +182 -48
  18. package/ios/MapCircleBuilder.swift +2 -0
  19. package/ios/MapHeatmapBuilder.swift +2 -1
  20. package/ios/MapMarkerBuilder.swift +54 -1
  21. package/ios/MapPolygonBuilder.swift +2 -0
  22. package/ios/MapPolylineBuilder.swift +2 -0
  23. package/ios/MapUrlTileOverlayBuilder.swift +24 -0
  24. package/ios/RNGoogleMapsPlusView.swift +75 -10
  25. package/ios/extensions/GMSCoordinateBounds+Extension.swift +4 -13
  26. package/ios/extensions/GMSVisibleRegion+Extension.swift +14 -0
  27. package/ios/extensions/MapObjectTag+Extension.swift +93 -0
  28. package/ios/extensions/RNLatLngBounds+Extension.swift +4 -4
  29. package/ios/extensions/RNMapType+Extension.swift +18 -0
  30. package/lib/module/types.js.map +1 -1
  31. package/lib/nitrogen/generated/shared/json/RNGoogleMapsPlusViewConfig.json +9 -0
  32. package/lib/typescript/src/RNGoogleMapsPlusView.nitro.d.ts +19 -8
  33. package/lib/typescript/src/RNGoogleMapsPlusView.nitro.d.ts.map +1 -1
  34. package/lib/typescript/src/types.d.ts +18 -5
  35. package/lib/typescript/src/types.d.ts.map +1 -1
  36. package/nitrogen/generated/android/RNGoogleMapsPlusOnLoad.cpp +8 -4
  37. package/nitrogen/generated/android/c++/JFunc_void_RNRegion_RNCamera.hpp +83 -0
  38. package/nitrogen/generated/android/c++/JFunc_void_RNRegion_RNCamera_bool.hpp +2 -0
  39. package/nitrogen/generated/android/c++/JFunc_void_std__string.hpp +75 -0
  40. package/nitrogen/generated/android/c++/JFunc_void_std__string_RNLatLng.hpp +77 -0
  41. package/nitrogen/generated/android/c++/JFunc_void_std__string_std__string_RNLatLng.hpp +77 -0
  42. package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusViewSpec.cpp +265 -73
  43. package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusViewSpec.hpp +34 -14
  44. package/nitrogen/generated/android/c++/JRNLatLngBounds.hpp +8 -8
  45. package/nitrogen/generated/android/c++/JRNMapUiSettings.hpp +11 -3
  46. package/nitrogen/generated/android/c++/JRNMarker.hpp +7 -3
  47. package/nitrogen/generated/android/c++/JRNRegion.hpp +23 -13
  48. package/nitrogen/generated/android/c++/JRNUrlTileOverlay.hpp +78 -0
  49. package/nitrogen/generated/android/c++/views/JHybridRNGoogleMapsPlusViewStateUpdater.cpp +36 -0
  50. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/Func_void_RNRegion_RNCamera.kt +81 -0
  51. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/{Func_void_std__optional_std__string_.kt → Func_void_std__string.kt} +12 -12
  52. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/{Func_void_std__optional_std__string__RNLatLng.kt → Func_void_std__string_RNLatLng.kt} +12 -12
  53. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/Func_void_std__string_std__string_RNLatLng.kt +81 -0
  54. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/HybridRNGoogleMapsPlusViewSpec.kt +147 -21
  55. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNLatLngBounds.kt +4 -4
  56. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNMapUiSettings.kt +9 -3
  57. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNMarker.kt +6 -3
  58. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNRegion.kt +11 -5
  59. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNUrlTileOverlay.kt +52 -0
  60. package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Bridge.cpp +32 -8
  61. package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Bridge.hpp +176 -36
  62. package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Umbrella.hpp +3 -0
  63. package/nitrogen/generated/ios/c++/HybridRNGoogleMapsPlusViewSpecSwift.hpp +98 -20
  64. package/nitrogen/generated/ios/c++/views/HybridRNGoogleMapsPlusViewComponent.mm +45 -0
  65. package/nitrogen/generated/ios/swift/Func_void_RNRegion_RNCamera.swift +47 -0
  66. package/nitrogen/generated/ios/swift/Func_void_std__optional_std__string_.swift +6 -6
  67. package/nitrogen/generated/ios/swift/Func_void_std__string.swift +47 -0
  68. package/nitrogen/generated/ios/swift/Func_void_std__string_RNLatLng.swift +47 -0
  69. package/nitrogen/generated/ios/swift/Func_void_std__string_std__string_RNLatLng.swift +47 -0
  70. package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusViewSpec.swift +18 -7
  71. package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusViewSpec_cxx.swift +392 -126
  72. package/nitrogen/generated/ios/swift/RNLatLngBounds.swift +8 -8
  73. package/nitrogen/generated/ios/swift/RNMapUiSettings.swift +61 -1
  74. package/nitrogen/generated/ios/swift/RNMarker.swift +24 -1
  75. package/nitrogen/generated/ios/swift/RNRegion.swift +33 -11
  76. package/nitrogen/generated/ios/swift/RNUrlTileOverlay.swift +133 -0
  77. package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusViewSpec.cpp +20 -0
  78. package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusViewSpec.hpp +43 -20
  79. package/nitrogen/generated/shared/c++/RNLatLngBounds.hpp +9 -9
  80. package/nitrogen/generated/shared/c++/RNMapUiSettings.hpp +10 -2
  81. package/nitrogen/generated/shared/c++/RNMarker.hpp +6 -2
  82. package/nitrogen/generated/shared/c++/RNRegion.hpp +24 -13
  83. package/nitrogen/generated/shared/c++/RNUrlTileOverlay.hpp +96 -0
  84. package/nitrogen/generated/shared/c++/views/HybridRNGoogleMapsPlusViewComponent.cpp +122 -14
  85. package/nitrogen/generated/shared/c++/views/HybridRNGoogleMapsPlusViewComponent.hpp +19 -9
  86. package/nitrogen/generated/shared/json/RNGoogleMapsPlusViewConfig.json +9 -0
  87. package/package.json +8 -5
  88. package/src/RNGoogleMapsPlusView.nitro.ts +21 -7
  89. package/src/types.ts +19 -5
  90. package/android/src/main/java/com/rngooglemapsplus/extensions/LatLngBounds.kt +0 -15
  91. package/nitrogen/generated/android/c++/JFunc_void_std__optional_std__string_.hpp +0 -76
  92. package/nitrogen/generated/android/c++/JFunc_void_std__optional_std__string__RNLatLng.hpp +0 -78
  93. package/nitrogen/generated/ios/swift/Func_void_std__optional_std__string__RNLatLng.swift +0 -54
  94. /package/android/src/main/java/com/rngooglemapsplus/extensions/{RNSize.kt → RNSizeExtension.kt} +0 -0
  95. /package/android/src/main/java/com/rngooglemapsplus/extensions/{RNSnapshotFormat.kt → RNSnapshotFormatExtension.kt} +0 -0
  96. /package/android/src/main/java/com/rngooglemapsplus/extensions/{RNSnapshotResultType.kt → RNSnapshotResultTypeExtension.kt} +0 -0
@@ -0,0 +1,84 @@
1
+ import android.util.Log
2
+ import com.google.android.gms.maps.model.Circle
3
+ import com.google.android.gms.maps.model.Marker
4
+ import com.google.android.gms.maps.model.Polygon
5
+ import com.google.android.gms.maps.model.Polyline
6
+ import com.rngooglemapsplus.RNMarkerSvg
7
+
8
+ sealed class MapObjectTag(
9
+ open val id: String,
10
+ )
11
+
12
+ data class MarkerTag(
13
+ override val id: String,
14
+ val iconSvg: RNMarkerSvg? = null,
15
+ ) : MapObjectTag(id)
16
+
17
+ data class PolylineTag(
18
+ override val id: String,
19
+ ) : MapObjectTag(id)
20
+
21
+ data class PolygonTag(
22
+ override val id: String,
23
+ ) : MapObjectTag(id)
24
+
25
+ data class CircleTag(
26
+ override val id: String,
27
+ ) : MapObjectTag(id)
28
+
29
+ val Marker.tagData: MarkerTag
30
+ get() =
31
+ (tag as? MarkerTag) ?: run {
32
+ Log.w("MapTag", "Marker without tag detected at $position")
33
+ val fallback = MarkerTag(id = "unknown")
34
+ tag = fallback
35
+ fallback
36
+ }
37
+
38
+ val Marker.idTag: String
39
+ get() = tagData.id
40
+
41
+ var Polyline.tagData: PolylineTag
42
+ get() =
43
+ (tag as? PolylineTag) ?: run {
44
+ Log.w("MapTag", "Polyline without tag detected")
45
+ val fallback = PolylineTag(id = "unknown")
46
+ tag = fallback
47
+ fallback
48
+ }
49
+ set(value) {
50
+ tag = value
51
+ }
52
+
53
+ val Polyline.idTag: String
54
+ get() = tagData.id
55
+
56
+ var Polygon.tagData: PolygonTag
57
+ get() =
58
+ (tag as? PolygonTag) ?: run {
59
+ Log.w("MapTag", "Polygon without tag detected")
60
+ val fallback = PolygonTag(id = "unknown")
61
+ tag = fallback
62
+ fallback
63
+ }
64
+ set(value) {
65
+ tag = value
66
+ }
67
+
68
+ val Polygon.idTag: String
69
+ get() = tagData.id
70
+
71
+ var Circle.tagData: CircleTag
72
+ get() =
73
+ (tag as? CircleTag) ?: run {
74
+ Log.w("MapTag", "Circle without tag detected")
75
+ val fallback = CircleTag(id = "unknown")
76
+ tag = fallback
77
+ fallback
78
+ }
79
+ set(value) {
80
+ tag = value
81
+ }
82
+
83
+ val Circle.idTag: String
84
+ get() = tagData.id
@@ -6,12 +6,6 @@ import com.rngooglemapsplus.RNLatLngBounds
6
6
 
7
7
  fun RNLatLngBounds.toLatLngBounds(): LatLngBounds =
8
8
  LatLngBounds(
9
- LatLng(
10
- southWest.latitude,
11
- southWest.longitude,
12
- ),
13
- LatLng(
14
- northEast.latitude,
15
- northEast.longitude,
16
- ),
9
+ southwest.toLatLng(),
10
+ northeast.toLatLng(),
17
11
  )
@@ -0,0 +1,13 @@
1
+ package com.rngooglemapsplus.extensions
2
+
3
+ import com.google.android.gms.maps.GoogleMap
4
+ import com.rngooglemapsplus.RNMapType
5
+
6
+ fun RNMapType.toGoogleMapType(): Int =
7
+ when (this) {
8
+ RNMapType.NONE -> GoogleMap.MAP_TYPE_NONE
9
+ RNMapType.NORMAL -> GoogleMap.MAP_TYPE_NORMAL
10
+ RNMapType.HYBRID -> GoogleMap.MAP_TYPE_HYBRID
11
+ RNMapType.SATELLITE -> GoogleMap.MAP_TYPE_SATELLITE
12
+ RNMapType.TERRAIN -> GoogleMap.MAP_TYPE_TERRAIN
13
+ }
@@ -0,0 +1,13 @@
1
+ package com.rngooglemapsplus.extensions
2
+
3
+ import com.google.android.gms.maps.model.VisibleRegion
4
+ import com.rngooglemapsplus.RNRegion
5
+
6
+ fun VisibleRegion.toRnRegion(): RNRegion =
7
+ RNRegion(
8
+ nearLeft = nearLeft.toRnLatLng(),
9
+ nearRight = nearRight.toRnLatLng(),
10
+ farLeft = farLeft.toRnLatLng(),
11
+ farRight = farRight.toRnLatLng(),
12
+ latLngBounds = latLngBounds.toRnLatLngBounds(),
13
+ )
@@ -10,7 +10,7 @@ GMSIndoorDisplayDelegate {
10
10
  private let markerBuilder: MapMarkerBuilder
11
11
  private var mapView: GMSMapView?
12
12
  private var initialized = false
13
- private var mapReady = false
13
+ private var loaded = false
14
14
  private var deInitialized = false
15
15
 
16
16
  private var pendingMarkers: [(id: String, marker: GMSMarker)] = []
@@ -19,6 +19,7 @@ GMSIndoorDisplayDelegate {
19
19
  private var pendingCircles: [(id: String, circle: GMSCircle)] = []
20
20
  private var pendingHeatmaps: [(id: String, heatmap: GMUHeatmapTileLayer)] = []
21
21
  private var pendingKmlLayers: [(id: String, kmlString: String)] = []
22
+ private var pendingUrlTileOverlays: [(id: String, urlTileOverlay: GMSURLTileLayer)] = []
22
23
 
23
24
  private var markersById: [String: GMSMarker] = [:]
24
25
  private var polylinesById: [String: GMSPolyline] = [:]
@@ -26,9 +27,9 @@ GMSIndoorDisplayDelegate {
26
27
  private var circlesById: [String: GMSCircle] = [:]
27
28
  private var heatmapsById: [String: GMUHeatmapTileLayer] = [:]
28
29
  private var kmlLayerById: [String: GMUGeometryRenderer] = [:]
30
+ private var urlTileOverlays: [String: GMSURLTileLayer] = [:]
29
31
 
30
32
  private var cameraMoveReasonIsGesture: Bool = false
31
- private var lastSubmittedCameraPosition: GMSCameraPosition?
32
33
 
33
34
  init(
34
35
  frame: CGRect = .zero,
@@ -75,7 +76,6 @@ GMSIndoorDisplayDelegate {
75
76
  applyProps()
76
77
  initLocationCallbacks()
77
78
  onMapReady?(true)
78
- mapReady = true
79
79
  }
80
80
 
81
81
  @MainActor
@@ -136,6 +136,12 @@ GMSIndoorDisplayDelegate {
136
136
  }
137
137
  pendingKmlLayers.removeAll()
138
138
  }
139
+ if !pendingUrlTileOverlays.isEmpty {
140
+ pendingUrlTileOverlays.forEach {
141
+ addUrlTileOverlayInternal(id: $0.id, urlTileOverlay: $0.urlTileOverlay)
142
+ }
143
+ pendingUrlTileOverlays.removeAll()
144
+ }
139
145
  }
140
146
 
141
147
  @MainActor
@@ -255,22 +261,49 @@ GMSIndoorDisplayDelegate {
255
261
 
256
262
  var onMapError: ((RNMapErrorCode) -> Void)?
257
263
  var onMapReady: ((Bool) -> Void)?
264
+ var onMapLoaded: ((RNRegion, RNCamera) -> Void)?
258
265
  var onLocationUpdate: ((RNLocation) -> Void)?
259
266
  var onLocationError: ((_ error: RNLocationErrorCode) -> Void)?
260
267
  var onMapPress: ((RNLatLng) -> Void)?
261
- var onMarkerPress: ((String?) -> Void)?
262
- var onPolylinePress: ((String?) -> Void)?
263
- var onPolygonPress: ((String?) -> Void)?
264
- var onCirclePress: ((String?) -> Void)?
265
- var onMarkerDragStart: ((String?, RNLatLng) -> Void)?
266
- var onMarkerDrag: ((String?, RNLatLng) -> Void)?
267
- var onMarkerDragEnd: ((String?, RNLatLng) -> Void)?
268
+ var onMapLongPress: ((RNLatLng) -> Void)?
269
+ var onPoiPress: ((String, String, RNLatLng) -> Void)?
270
+ var onMarkerPress: ((String) -> Void)?
271
+ var onPolylinePress: ((String) -> Void)?
272
+ var onPolygonPress: ((String) -> Void)?
273
+ var onCirclePress: ((String) -> Void)?
274
+ var onMarkerDragStart: ((String, RNLatLng) -> Void)?
275
+ var onMarkerDrag: ((String, RNLatLng) -> Void)?
276
+ var onMarkerDragEnd: ((String, RNLatLng) -> Void)?
268
277
  var onIndoorBuildingFocused: ((RNIndoorBuilding) -> Void)?
269
278
  var onIndoorLevelActivated: ((RNIndoorLevel) -> Void)?
279
+ var onInfoWindowPress: ((String) -> Void)?
280
+ var onInfoWindowClose: ((String) -> Void)?
281
+ var onInfoWindowLongPress: ((String) -> Void)?
282
+ var onMyLocationPress: ((RNLocation) -> Void)?
283
+ var onMyLocationButtonPress: ((Bool) -> Void)?
270
284
  var onCameraChangeStart: ((RNRegion, RNCamera, Bool) -> Void)?
271
285
  var onCameraChange: ((RNRegion, RNCamera, Bool) -> Void)?
272
286
  var onCameraChangeComplete: ((RNRegion, RNCamera, Bool) -> Void)?
273
287
 
288
+ @MainActor
289
+ func showMarkerInfoWindow(id: String) {
290
+ onMain {
291
+ guard let marker = self.markersById[id] else { return }
292
+ self.mapView?.selectedMarker = nil
293
+ self.mapView?.selectedMarker = marker
294
+ }
295
+ }
296
+
297
+ @MainActor
298
+ func hideMarkerInfoWindow(id: String) {
299
+ onMain {
300
+ guard let marker = self.markersById[id] else { return }
301
+ if self.mapView?.selectedMarker == marker {
302
+ self.mapView?.selectedMarker = nil
303
+ }
304
+ }
305
+ }
306
+
274
307
  @MainActor
275
308
  func setCamera(camera: GMSCameraPosition, animated: Bool, durationMs: Double) {
276
309
  if animated {
@@ -420,14 +453,19 @@ GMSIndoorDisplayDelegate {
420
453
 
421
454
  @MainActor
422
455
  private func addMarkerInternal(id: String, marker: GMSMarker) {
423
- marker.userData = id
424
456
  marker.map = mapView
425
457
  markersById[id] = marker
426
458
  }
427
459
 
428
460
  @MainActor
429
461
  func updateMarker(id: String, block: @escaping (GMSMarker) -> Void) {
430
- markersById[id].map { block($0) }
462
+ markersById[id].map {
463
+ block($0)
464
+ if let mapView, mapView.selectedMarker == $0 {
465
+ mapView.selectedMarker = nil
466
+ mapView.selectedMarker = $0
467
+ }
468
+ }
431
469
  }
432
470
 
433
471
  @MainActor
@@ -454,8 +492,8 @@ GMSIndoorDisplayDelegate {
454
492
 
455
493
  @MainActor
456
494
  private func addPolylineInternal(id: String, polyline: GMSPolyline) {
495
+ polyline.tagData = PolylineTag(id: id)
457
496
  polyline.map = mapView
458
- polyline.userData = id
459
497
  polylinesById[id] = polyline
460
498
  }
461
499
 
@@ -488,8 +526,8 @@ GMSIndoorDisplayDelegate {
488
526
 
489
527
  @MainActor
490
528
  private func addPolygonInternal(id: String, polygon: GMSPolygon) {
529
+ polygon.tagData = PolygonTag(id: id)
491
530
  polygon.map = mapView
492
- polygon.userData = id
493
531
  polygonsById[id] = polygon
494
532
  }
495
533
 
@@ -522,8 +560,8 @@ GMSIndoorDisplayDelegate {
522
560
 
523
561
  @MainActor
524
562
  private func addCircleInternal(id: String, circle: GMSCircle) {
563
+ circle.tagData = CircleTag(id: id)
525
564
  circle.map = mapView
526
- circle.userData = id
527
565
  circlesById[id] = circle
528
566
  }
529
567
 
@@ -611,6 +649,36 @@ GMSIndoorDisplayDelegate {
611
649
  pendingKmlLayers.removeAll()
612
650
  }
613
651
 
652
+ @MainActor
653
+ func addUrlTileOverlay(id: String, urlTileOverlay: GMSURLTileLayer) {
654
+ if mapView == nil {
655
+ pendingUrlTileOverlays.append((id, urlTileOverlay))
656
+ return
657
+ }
658
+ urlTileOverlays.removeValue(forKey: id).map { $0.map = nil }
659
+ addUrlTileOverlayInternal(id: id, urlTileOverlay: urlTileOverlay)
660
+ }
661
+
662
+ @MainActor
663
+ private func addUrlTileOverlayInternal(
664
+ id: String,
665
+ urlTileOverlay: GMSURLTileLayer
666
+ ) {
667
+ urlTileOverlay.map = mapView
668
+ }
669
+
670
+ @MainActor
671
+ func removeUrlTileOverlay(id: String) {
672
+ urlTileOverlays.removeValue(forKey: id).map { $0.map = nil }
673
+ }
674
+
675
+ @MainActor
676
+ func clearUrlTileOverlay() {
677
+ urlTileOverlays.values.forEach { $0.map = nil }
678
+ urlTileOverlays.removeAll()
679
+ pendingUrlTileOverlays.removeAll()
680
+ }
681
+
614
682
  func deinitInternal() {
615
683
  guard !deInitialized else { return }
616
684
  deInitialized = true
@@ -623,6 +691,7 @@ GMSIndoorDisplayDelegate {
623
691
  self.clearCircles()
624
692
  self.clearHeatmaps()
625
693
  self.clearKmlLayers()
694
+ self.clearUrlTileOverlay()
626
695
  self.mapView?.clear()
627
696
  self.mapView?.indoorDisplay.delegate = nil
628
697
  self.mapView?.delegate = nil
@@ -655,50 +724,46 @@ GMSIndoorDisplayDelegate {
655
724
  deinitInternal()
656
725
  }
657
726
 
727
+ func mapViewDidFinishTileRendering(_ mapView: GMSMapView) {
728
+ guard !loaded else { return }
729
+ loaded = true
730
+ let visibleRegion = mapView.projection.visibleRegion().toRNRegion()
731
+ let camera = mapView.camera.toRNCamera()
732
+
733
+ self.onMapLoaded?(visibleRegion, camera)
734
+ }
735
+
658
736
  func mapView(_ mapView: GMSMapView, willMove gesture: Bool) {
737
+ if !loaded { return }
659
738
  onMain {
660
739
  self.cameraMoveReasonIsGesture = gesture
661
- let visibleRegion = mapView.projection.visibleRegion()
662
- let bounds = GMSCoordinateBounds(region: visibleRegion)
663
740
 
664
- let region = bounds.toRNRegion()
741
+ let visibleRegion = mapView.projection.visibleRegion().toRNRegion()
665
742
  let camera = mapView.camera.toRNCamera()
666
743
 
667
- self.onCameraChangeStart?(region, camera, gesture)
744
+ self.onCameraChangeStart?(visibleRegion, camera, gesture)
668
745
  }
669
746
  }
670
747
 
671
748
  func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) {
749
+ if !loaded { return }
672
750
  onMain {
673
- if let last = self.lastSubmittedCameraPosition,
674
- last.target.latitude == position.target.latitude,
675
- last.target.longitude == position.target.longitude,
676
- last.zoom == position.zoom,
677
- last.bearing == position.bearing,
678
- last.viewingAngle == position.viewingAngle {
679
- return
680
- }
681
-
682
- self.lastSubmittedCameraPosition = position
683
- let visibleRegion = mapView.projection.visibleRegion()
684
- let bounds = GMSCoordinateBounds(region: visibleRegion)
685
-
686
- let region = bounds.toRNRegion()
751
+ let visibleRegion = mapView.projection.visibleRegion().toRNRegion()
687
752
  let camera = mapView.camera.toRNCamera()
753
+ let gesture = self.cameraMoveReasonIsGesture
688
754
 
689
- self.onCameraChange?(region, camera, self.cameraMoveReasonIsGesture)
755
+ self.onCameraChange?(visibleRegion, camera, gesture)
690
756
  }
691
757
  }
692
758
 
693
759
  func mapView(_ mapView: GMSMapView, idleAt position: GMSCameraPosition) {
760
+ if !loaded { return }
694
761
  onMain {
695
- let visibleRegion = mapView.projection.visibleRegion()
696
- let bounds = GMSCoordinateBounds(region: visibleRegion)
697
-
698
- let region = bounds.toRNRegion()
762
+ let visibleRegion = mapView.projection.visibleRegion().toRNRegion()
699
763
  let camera = mapView.camera.toRNCamera()
764
+ let gesture = self.cameraMoveReasonIsGesture
700
765
 
701
- self.onCameraChangeComplete?(region, camera, self.cameraMoveReasonIsGesture)
766
+ self.onCameraChangeComplete?(visibleRegion, camera, gesture)
702
767
  }
703
768
  }
704
769
 
@@ -713,25 +778,46 @@ GMSIndoorDisplayDelegate {
713
778
  }
714
779
  }
715
780
 
781
+ func mapView(
782
+ _ mapView: GMSMapView,
783
+ didLongPressAt coordinate: CLLocationCoordinate2D
784
+ ) {
785
+ onMain {
786
+ self.onMapLongPress?(
787
+ coordinate.toRNLatLng(),
788
+ )
789
+ }
790
+ }
791
+
792
+ func mapView(
793
+ _ mapView: GMSMapView,
794
+ didTapPOIWithPlaceID placeID: String,
795
+ name: String,
796
+ location: CLLocationCoordinate2D
797
+ ) {
798
+ onMain {
799
+ self.onPoiPress?(placeID, name, location.toRNLatLng())
800
+ }
801
+ }
802
+
716
803
  func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
717
804
  onMain {
718
- mapView.selectedMarker = marker
719
- self.onMarkerPress?(marker.userData as? String, )
805
+ self.onMarkerPress?(marker.idTag)
720
806
  }
721
- return true
807
+ return uiSettings?.consumeOnMarkerPress ?? false
722
808
  }
723
809
 
724
810
  func mapView(_ mapView: GMSMapView, didTap overlay: GMSOverlay) {
725
811
  onMain {
726
812
  switch overlay {
727
813
  case let circle as GMSCircle:
728
- self.onCirclePress?(circle.userData as? String, )
814
+ self.onCirclePress?(circle.idTag)
729
815
 
730
816
  case let polygon as GMSPolygon:
731
- self.onPolygonPress?(polygon.userData as? String, )
817
+ self.onPolygonPress?(polygon.idTag)
732
818
 
733
819
  case let polyline as GMSPolyline:
734
- self.onPolylinePress?(polyline.userData as? String, )
820
+ self.onPolylinePress?(polyline.idTag)
735
821
 
736
822
  default:
737
823
  break
@@ -742,7 +828,7 @@ GMSIndoorDisplayDelegate {
742
828
  func mapView(_ mapView: GMSMapView, didBeginDragging marker: GMSMarker) {
743
829
  onMain {
744
830
  self.onMarkerDragStart?(
745
- marker.userData as? String,
831
+ marker.idTag,
746
832
  marker.position.toRNLatLng()
747
833
  )
748
834
  }
@@ -751,7 +837,7 @@ GMSIndoorDisplayDelegate {
751
837
  func mapView(_ mapView: GMSMapView, didDrag marker: GMSMarker) {
752
838
  onMain {
753
839
  self.onMarkerDrag?(
754
- marker.userData as? String,
840
+ marker.idTag,
755
841
  marker.position.toRNLatLng()
756
842
  )
757
843
  }
@@ -760,7 +846,7 @@ GMSIndoorDisplayDelegate {
760
846
  func mapView(_ mapView: GMSMapView, didEndDragging marker: GMSMarker) {
761
847
  onMain {
762
848
  self.onMarkerDragEnd?(
763
- marker.userData as? String,
849
+ marker.idTag,
764
850
  marker.position.toRNLatLng()
765
851
  )
766
852
  }
@@ -791,4 +877,52 @@ GMSIndoorDisplayDelegate {
791
877
  )
792
878
  }
793
879
  }
880
+
881
+ func mapView(_ mapView: GMSMapView, didTapInfoWindowOf marker: GMSMarker) {
882
+ onMain {
883
+ self.onInfoWindowPress?(marker.idTag)
884
+ }
885
+ }
886
+
887
+ func mapView(_ mapView: GMSMapView, didCloseInfoWindowOf marker: GMSMarker) {
888
+ onMain {
889
+ self.onInfoWindowClose?(marker.idTag)
890
+ }
891
+ }
892
+
893
+ func mapView(
894
+ _ mapView: GMSMapView,
895
+ didLongPressInfoWindowOf marker: GMSMarker
896
+ ) {
897
+ onMain {
898
+ self.onInfoWindowLongPress?(marker.idTag)
899
+ }
900
+ }
901
+
902
+ func mapView(
903
+ _ mapView: GMSMapView,
904
+ didTapMyLocation location: CLLocationCoordinate2D
905
+ ) {
906
+ onMain {
907
+ self.mapView?.myLocation.map {
908
+ self.onMyLocationPress?($0.toRnLocation())
909
+ }
910
+ }
911
+ }
912
+
913
+ func didTapMyLocationButton(for mapView: GMSMapView) -> Bool {
914
+ onMain {
915
+ self.onMyLocationButtonPress?(true)
916
+ }
917
+ return uiSettings?.consumeOnMyLocationButtonPress ?? false
918
+ }
919
+
920
+ func mapView(_ mapView: GMSMapView, markerInfoWindow marker: GMSMarker) -> UIView? {
921
+ return markerBuilder.buildInfoWindow(iconSvg: marker.tagData.iconSvg)
922
+ }
923
+
924
+ func mapView(_ mapView: GMSMapView, markerInfoContents marker: GMSMarker)
925
+ -> UIView? {
926
+ return nil
927
+ }
794
928
  }
@@ -1,6 +1,7 @@
1
1
  import GoogleMaps
2
2
 
3
3
  final class MapCircleBuilder {
4
+ @MainActor
4
5
  func build(_ c: RNCircle) -> GMSCircle {
5
6
  let circle = GMSCircle()
6
7
  circle.position = c.center.toCLLocationCoordinate2D()
@@ -14,6 +15,7 @@ final class MapCircleBuilder {
14
15
  return circle
15
16
  }
16
17
 
18
+ @MainActor
17
19
  func update(_ prev: RNCircle, _ next: RNCircle, _ c: GMSCircle) {
18
20
  if prev.center.latitude != next.center.latitude
19
21
  || prev.center.longitude != next.center.longitude {
@@ -4,6 +4,7 @@ import GoogleMapsUtils
4
4
  import UIKit
5
5
 
6
6
  final class MapHeatmapBuilder {
7
+ @MainActor
7
8
  func build(_ h: RNHeatmap) -> GMUHeatmapTileLayer {
8
9
  let heatmap = GMUHeatmapTileLayer()
9
10
  heatmap.weightedData = h.weightedData.toWeightedLatLngs()
@@ -18,7 +19,7 @@ final class MapHeatmapBuilder {
18
19
  heatmap.gradient = GMUGradient(
19
20
  colors: colors,
20
21
  startPoints: startPoints,
21
- colorMapSize: 256
22
+ colorMapSize: UInt(g.colorMapSize)
22
23
  )
23
24
  }
24
25
 
@@ -10,11 +10,11 @@ final class MapMarkerBuilder {
10
10
  }()
11
11
  private var tasks: [String: Task<Void, Never>] = [:]
12
12
 
13
+ @MainActor
13
14
  func build(_ m: RNMarker, icon: UIImage?) -> GMSMarker {
14
15
  let marker = GMSMarker(
15
16
  position: m.coordinate.toCLLocationCoordinate2D()
16
17
  )
17
- marker.userData = m.id
18
18
  marker.tracksViewChanges = true
19
19
  marker.icon = icon
20
20
  m.title.map { marker.title = $0 }
@@ -34,6 +34,11 @@ final class MapMarkerBuilder {
34
34
  }
35
35
  m.zIndex.map { marker.zIndex = Int32($0) }
36
36
 
37
+ marker.tagData = MarkerTag(
38
+ id: m.id,
39
+ iconSvg: m.infoWindowIconSvg
40
+ )
41
+
37
42
  onMainAsync { [weak marker] in
38
43
  try? await Task.sleep(nanoseconds: 250_000_000)
39
44
  marker?.tracksViewChanges = false
@@ -119,6 +124,12 @@ final class MapMarkerBuilder {
119
124
  y: next.infoWindowAnchor?.y ?? 0
120
125
  )
121
126
  }
127
+
128
+ m.tagData = MarkerTag(
129
+ id: next.id,
130
+ iconSvg: next.infoWindowIconSvg
131
+ )
132
+
122
133
  }
123
134
  }
124
135
 
@@ -160,11 +171,13 @@ final class MapMarkerBuilder {
160
171
  tasks[id] = task
161
172
  }
162
173
 
174
+ @MainActor
163
175
  func cancelIconTask(_ id: String) {
164
176
  tasks[id]?.cancel()
165
177
  tasks.removeValue(forKey: id)
166
178
  }
167
179
 
180
+ @MainActor
168
181
  func cancelAllIconTasks() {
169
182
  let ids = Array(tasks.keys)
170
183
  for id in ids {
@@ -174,6 +187,46 @@ final class MapMarkerBuilder {
174
187
  iconCache.removeAllObjects()
175
188
  }
176
189
 
190
+ func buildInfoWindow(iconSvg: RNMarkerSvg?) -> UIImageView? {
191
+ guard let iconSvg = iconSvg else {
192
+ return nil
193
+ }
194
+
195
+ guard let data = iconSvg.svgString.data(using: .utf8),
196
+ let svgImg = SVGKImage(data: data)
197
+ else {
198
+ return nil
199
+ }
200
+
201
+ let size = CGSize(
202
+ width: max(1, CGFloat(iconSvg.width)),
203
+ height: max(1, CGFloat(iconSvg.height))
204
+ )
205
+
206
+ svgImg.size = size
207
+
208
+ guard let base = svgImg.uiImage else {
209
+ return nil
210
+ }
211
+
212
+ let fmt = UIGraphicsImageRendererFormat.default()
213
+ fmt.opaque = false
214
+ fmt.scale = UIScreen.main.scale
215
+ let renderer = UIGraphicsImageRenderer(size: size, format: fmt)
216
+
217
+ let finalImage = renderer.image { _ in
218
+ base.draw(in: CGRect(origin: .zero, size: size))
219
+ }
220
+
221
+ let imageView = UIImageView(image: finalImage)
222
+ imageView.frame = CGRect(origin: .zero, size: size)
223
+ imageView.contentMode = .scaleAspectFit
224
+ imageView.backgroundColor = .clear
225
+
226
+ return imageView
227
+ }
228
+
229
+ @MainActor
177
230
  private func renderUIImage(_ m: RNMarker, _ scale: CGFloat) async -> UIImage? {
178
231
  guard let iconSvg = m.iconSvg,
179
232
  let data = iconSvg.svgString.data(using: .utf8)
@@ -1,6 +1,7 @@
1
1
  import GoogleMaps
2
2
 
3
3
  final class MapPolygonBuilder {
4
+ @MainActor
4
5
  func build(_ p: RNPolygon) -> GMSPolygon {
5
6
  let path = GMSMutablePath()
6
7
  p.coordinates.forEach {
@@ -28,6 +29,7 @@ final class MapPolygonBuilder {
28
29
  return pg
29
30
  }
30
31
 
32
+ @MainActor
31
33
  func update(_ prev: RNPolygon, _ next: RNPolygon, _ pg: GMSPolygon) {
32
34
  let coordsChanged =
33
35
  prev.coordinates.count != next.coordinates.count
@@ -1,6 +1,7 @@
1
1
  import GoogleMaps
2
2
 
3
3
  final class MapPolylineBuilder {
4
+ @MainActor
4
5
  func build(_ p: RNPolyline) -> GMSPolyline {
5
6
  let path = GMSMutablePath()
6
7
  p.coordinates.forEach {
@@ -22,6 +23,7 @@ final class MapPolylineBuilder {
22
23
  return pl
23
24
  }
24
25
 
26
+ @MainActor
25
27
  func update(_ prev: RNPolyline, _ next: RNPolyline, _ pl: GMSPolyline) {
26
28
  let coordsChanged =
27
29
  prev.coordinates.count != next.coordinates.count