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

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 (39) hide show
  1. package/android/proguard-rules.pro +29 -0
  2. package/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt +64 -2
  3. package/android/src/main/java/com/rngooglemapsplus/LocationHandler.kt +2 -0
  4. package/android/src/main/java/com/rngooglemapsplus/MapMarkerBuilder.kt +39 -0
  5. package/android/src/main/java/com/rngooglemapsplus/MapUrlTileOverlayBuilder.kt +40 -0
  6. package/android/src/main/java/com/rngooglemapsplus/RNGoogleMapsPlusView.kt +27 -3
  7. package/android/src/main/java/com/rngooglemapsplus/extensions/RNMapTypeExtension.kt +13 -0
  8. package/ios/GoogleMapViewImpl.swift +59 -2
  9. package/ios/MapUrlTileOverlayBuilder.swift +23 -0
  10. package/ios/RNGoogleMapsPlusView.swift +34 -3
  11. package/ios/extensions/RNMapType+Extension.swift +18 -0
  12. package/lib/module/types.js.map +1 -1
  13. package/lib/nitrogen/generated/shared/json/RNGoogleMapsPlusViewConfig.json +3 -0
  14. package/lib/typescript/src/RNGoogleMapsPlusView.nitro.d.ts +4 -1
  15. package/lib/typescript/src/RNGoogleMapsPlusView.nitro.d.ts.map +1 -1
  16. package/lib/typescript/src/types.d.ts +8 -0
  17. package/lib/typescript/src/types.d.ts.map +1 -1
  18. package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusViewSpec.cpp +68 -0
  19. package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusViewSpec.hpp +6 -0
  20. package/nitrogen/generated/android/c++/JRNUrlTileOverlay.hpp +78 -0
  21. package/nitrogen/generated/android/c++/views/JHybridRNGoogleMapsPlusViewStateUpdater.cpp +12 -0
  22. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/HybridRNGoogleMapsPlusViewSpec.kt +34 -0
  23. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNUrlTileOverlay.kt +52 -0
  24. package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Bridge.hpp +44 -0
  25. package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Umbrella.hpp +3 -0
  26. package/nitrogen/generated/ios/c++/HybridRNGoogleMapsPlusViewSpecSwift.hpp +24 -0
  27. package/nitrogen/generated/ios/c++/views/HybridRNGoogleMapsPlusViewComponent.mm +15 -0
  28. package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusViewSpec.swift +3 -0
  29. package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusViewSpec_cxx.swift +94 -0
  30. package/nitrogen/generated/ios/swift/RNUrlTileOverlay.swift +133 -0
  31. package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusViewSpec.cpp +6 -0
  32. package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusViewSpec.hpp +9 -0
  33. package/nitrogen/generated/shared/c++/RNUrlTileOverlay.hpp +96 -0
  34. package/nitrogen/generated/shared/c++/views/HybridRNGoogleMapsPlusViewComponent.cpp +36 -0
  35. package/nitrogen/generated/shared/c++/views/HybridRNGoogleMapsPlusViewComponent.hpp +4 -0
  36. package/nitrogen/generated/shared/json/RNGoogleMapsPlusViewConfig.json +3 -0
  37. package/package.json +5 -4
  38. package/src/RNGoogleMapsPlusView.nitro.ts +4 -0
  39. package/src/types.ts +9 -0
@@ -0,0 +1,29 @@
1
+ -keep class com.google.android.gms.** { *; }
2
+ -keep interface com.google.android.gms.** { *; }
3
+ -dontwarn com.google.android.gms.**
4
+ -dontnote com.google.android.gms.**
5
+
6
+ -keep class * implements android.os.Parcelable { *; }
7
+
8
+ -keepclassmembers class **$Companion {
9
+ public *;
10
+ }
11
+
12
+ -keep class com.google.maps.android.** { *; }
13
+ -keep interface com.google.maps.android.** { *; }
14
+ -dontwarn com.google.maps.android.**
15
+
16
+ -keep @androidx.annotation.Keep class * { *; }
17
+ -keepclassmembers class * {
18
+ @androidx.annotation.Keep *;
19
+ }
20
+
21
+ -keep class com.caverock.androidsvg.** { *; }
22
+ -dontwarn com.caverock.androidsvg.**
23
+
24
+ -keepclassmembers class com.caverock.androidsvg.** {
25
+ public *;
26
+ protected *;
27
+ }
28
+
29
+ -keep class com.rngooglemapsplus.** { *; }
@@ -58,6 +58,7 @@ class GoogleMapsViewImpl(
58
58
  GoogleMap.OnCameraMoveListener,
59
59
  GoogleMap.OnCameraIdleListener,
60
60
  GoogleMap.OnMapClickListener,
61
+ GoogleMap.OnMapLongClickListener,
61
62
  GoogleMap.OnMarkerClickListener,
62
63
  GoogleMap.OnPolylineClickListener,
63
64
  GoogleMap.OnPolygonClickListener,
@@ -66,7 +67,6 @@ class GoogleMapsViewImpl(
66
67
  GoogleMap.OnIndoorStateChangeListener,
67
68
  LifecycleEventListener {
68
69
  private var initialized = false
69
- private var mapReady = false
70
70
  private var destroyed = false
71
71
  private var googleMap: GoogleMap? = null
72
72
  private var mapView: MapView? = null
@@ -77,6 +77,7 @@ class GoogleMapsViewImpl(
77
77
  private val pendingCircles = mutableListOf<Pair<String, CircleOptions>>()
78
78
  private val pendingHeatmaps = mutableListOf<Pair<String, TileOverlayOptions>>()
79
79
  private val pendingKmlLayers = mutableListOf<Pair<String, String>>()
80
+ private val pendingUrlTilesOverlays = mutableListOf<Pair<String, TileOverlayOptions>>()
80
81
 
81
82
  private val markersById = mutableMapOf<String, Marker>()
82
83
  private val polylinesById = mutableMapOf<String, Polyline>()
@@ -84,6 +85,7 @@ class GoogleMapsViewImpl(
84
85
  private val circlesById = mutableMapOf<String, Circle>()
85
86
  private val heatmapsById = mutableMapOf<String, TileOverlay>()
86
87
  private val kmlLayersById = mutableMapOf<String, KmlLayer>()
88
+ private val urlTileOverlaysById = mutableMapOf<String, TileOverlay>()
87
89
 
88
90
  private var cameraMoveReason = -1
89
91
  private var lastSubmittedCameraPosition: CameraPosition? = null
@@ -128,11 +130,12 @@ class GoogleMapsViewImpl(
128
130
  googleMap?.setOnPolygonClickListener(this@GoogleMapsViewImpl)
129
131
  googleMap?.setOnCircleClickListener(this@GoogleMapsViewImpl)
130
132
  googleMap?.setOnMapClickListener(this@GoogleMapsViewImpl)
133
+ googleMap?.setOnMapLongClickListener(this@GoogleMapsViewImpl)
131
134
  googleMap?.setOnMarkerDragListener(this@GoogleMapsViewImpl)
135
+ onMapLoaded?.invoke(true)
132
136
  }
133
137
  applyProps()
134
138
  initLocationCallbacks()
135
- mapReady = true
136
139
  onMapReady?.invoke(true)
137
140
  }
138
141
  }
@@ -248,6 +251,13 @@ class GoogleMapsViewImpl(
248
251
  }
249
252
  pendingKmlLayers.clear()
250
253
  }
254
+
255
+ if (pendingUrlTilesOverlays.isNotEmpty()) {
256
+ pendingUrlTilesOverlays.forEach { (id, string) ->
257
+ internalAddUrlTileOverlay(id, string)
258
+ }
259
+ pendingUrlTilesOverlays.clear()
260
+ }
251
261
  }
252
262
 
253
263
  val currentCamera: CameraPosition?
@@ -378,9 +388,11 @@ class GoogleMapsViewImpl(
378
388
 
379
389
  var onMapError: ((RNMapErrorCode) -> Unit)? = null
380
390
  var onMapReady: ((Boolean) -> Unit)? = null
391
+ var onMapLoaded: ((Boolean) -> Unit)? = null
381
392
  var onLocationUpdate: ((RNLocation) -> Unit)? = null
382
393
  var onLocationError: ((RNLocationErrorCode) -> Unit)? = null
383
394
  var onMapPress: ((RNLatLng) -> Unit)? = null
395
+ var onMapLongPress: ((RNLatLng) -> Unit)? = null
384
396
  var onMarkerPress: ((String?) -> Unit)? = null
385
397
  var onPolylinePress: ((String?) -> Unit)? = null
386
398
  var onPolygonPress: ((String?) -> Unit)? = null
@@ -853,6 +865,48 @@ class GoogleMapsViewImpl(
853
865
  pendingKmlLayers.clear()
854
866
  }
855
867
 
868
+ fun addUrlTileOverlay(
869
+ id: String,
870
+ opts: TileOverlayOptions,
871
+ ) {
872
+ if (googleMap == null) {
873
+ pendingUrlTilesOverlays.add(id to opts)
874
+ return
875
+ }
876
+
877
+ onUi {
878
+ urlTileOverlaysById.remove(id)?.remove()
879
+ }
880
+ internalAddUrlTileOverlay(id, opts)
881
+ }
882
+
883
+ private fun internalAddUrlTileOverlay(
884
+ id: String,
885
+ opts: TileOverlayOptions,
886
+ ) {
887
+ onUi {
888
+ val urlTile =
889
+ googleMap?.addTileOverlay(opts)
890
+ if (urlTile != null) {
891
+ urlTileOverlaysById[id] = urlTile
892
+ }
893
+ }
894
+ }
895
+
896
+ fun removeUrlTileOverlay(id: String) {
897
+ onUi {
898
+ urlTileOverlaysById.remove(id)?.remove()
899
+ }
900
+ }
901
+
902
+ fun clearUrlTileOverlays() {
903
+ onUi {
904
+ urlTileOverlaysById.values.forEach { it.remove() }
905
+ }
906
+ urlTileOverlaysById.clear()
907
+ pendingUrlTilesOverlays.clear()
908
+ }
909
+
856
910
  fun destroyInternal() {
857
911
  if (destroyed) return
858
912
  destroyed = true
@@ -865,6 +919,7 @@ class GoogleMapsViewImpl(
865
919
  clearCircles()
866
920
  clearHeatmaps()
867
921
  clearKmlLayer()
922
+ clearUrlTileOverlays()
868
923
  googleMap?.apply {
869
924
  setOnCameraMoveStartedListener(null)
870
925
  setOnCameraMoveListener(null)
@@ -874,6 +929,7 @@ class GoogleMapsViewImpl(
874
929
  setOnPolygonClickListener(null)
875
930
  setOnCircleClickListener(null)
876
931
  setOnMapClickListener(null)
932
+ setOnMapLongClickListener(null)
877
933
  setOnMarkerDragListener(null)
878
934
  }
879
935
  googleMap = null
@@ -953,6 +1009,12 @@ class GoogleMapsViewImpl(
953
1009
  )
954
1010
  }
955
1011
 
1012
+ override fun onMapLongClick(coordinates: LatLng) {
1013
+ onMapLongPress?.invoke(
1014
+ coordinates.toRnLatLng(),
1015
+ )
1016
+ }
1017
+
956
1018
  override fun onMarkerDragStart(marker: Marker) {
957
1019
  onMarkerDragStart?.invoke(
958
1020
  marker.tag?.toString(),
@@ -57,6 +57,8 @@ class LocationHandler(
57
57
  this.interval = interval ?: INTERVAL_DEFAULT
58
58
  this.minUpdateInterval = minUpdateInterval ?: MIN_UPDATE_INTERVAL
59
59
  buildLocationRequest(this.priority, this.interval, this.minUpdateInterval)
60
+ stop()
61
+ start()
60
62
  }
61
63
 
62
64
  fun showLocationDialog() {
@@ -2,9 +2,11 @@ package com.rngooglemapsplus
2
2
 
3
3
  import android.graphics.Bitmap
4
4
  import android.graphics.Canvas
5
+ import android.util.Base64
5
6
  import android.util.LruCache
6
7
  import androidx.core.graphics.createBitmap
7
8
  import com.caverock.androidsvg.SVG
9
+ import com.caverock.androidsvg.SVGExternalFileResolver
8
10
  import com.facebook.react.uimanager.PixelUtil.dpToPx
9
11
  import com.google.android.gms.maps.model.BitmapDescriptor
10
12
  import com.google.android.gms.maps.model.BitmapDescriptorFactory
@@ -20,6 +22,7 @@ import kotlinx.coroutines.SupervisorJob
20
22
  import kotlinx.coroutines.ensureActive
21
23
  import kotlinx.coroutines.launch
22
24
  import kotlinx.coroutines.withContext
25
+ import java.net.URLDecoder
23
26
  import kotlin.coroutines.coroutineContext
24
27
 
25
28
  class MapMarkerBuilder(
@@ -35,6 +38,42 @@ class MapMarkerBuilder(
35
38
 
36
39
  private val jobsById = mutableMapOf<String, Job>()
37
40
 
41
+ init {
42
+ SVG.registerExternalFileResolver(
43
+ object : SVGExternalFileResolver() {
44
+ override fun resolveImage(filename: String?): Bitmap? {
45
+ if (filename.isNullOrBlank()) return null
46
+
47
+ return runCatching {
48
+ when {
49
+ filename.startsWith("data:image/svg+xml") -> {
50
+ val svgContent =
51
+ if ("base64," in filename) {
52
+ val base64 = filename.substringAfter("base64,")
53
+ String(Base64.decode(base64, Base64.DEFAULT), Charsets.UTF_8)
54
+ } else {
55
+ URLDecoder.decode(filename.substringAfter(","), "UTF-8")
56
+ }
57
+
58
+ val svg = SVG.getFromString(svgContent)
59
+ val width = (svg.documentWidth.takeIf { it > 0 } ?: 128f).toInt()
60
+ val height = (svg.documentHeight.takeIf { it > 0 } ?: 128f).toInt()
61
+
62
+ createBitmap(width, height).apply {
63
+ Canvas(this).also(svg::renderToCanvas)
64
+ }
65
+ }
66
+
67
+ else -> null
68
+ }
69
+ }.getOrNull()
70
+ }
71
+
72
+ override fun isFormatSupported(mimeType: String?): Boolean = mimeType?.startsWith("image/") == true
73
+ },
74
+ )
75
+ }
76
+
38
77
  fun build(
39
78
  m: RNMarker,
40
79
  icon: BitmapDescriptor?,
@@ -0,0 +1,40 @@
1
+ package com.rngooglemapsplus
2
+
3
+ import com.google.android.gms.maps.model.TileOverlayOptions
4
+ import com.google.android.gms.maps.model.UrlTileProvider
5
+ import java.net.URL
6
+
7
+ class MapUrlTileOverlayBuilder {
8
+ fun build(t: RNUrlTileOverlay): TileOverlayOptions {
9
+ val provider =
10
+ object : UrlTileProvider(
11
+ t.tileSize.toInt(),
12
+ t.tileSize.toInt(),
13
+ ) {
14
+ override fun getTileUrl(
15
+ x: Int,
16
+ y: Int,
17
+ zoom: Int,
18
+ ): URL? {
19
+ val url =
20
+ t.url
21
+ .replace("{x}", x.toString())
22
+ .replace("{y}", y.toString())
23
+ .replace("{z}", zoom.toString())
24
+
25
+ return try {
26
+ URL(url)
27
+ } catch (e: Exception) {
28
+ null
29
+ }
30
+ }
31
+ }
32
+
33
+ val opts = TileOverlayOptions().tileProvider(provider)
34
+
35
+ t.fadeIn?.let { opts.fadeIn(it) }
36
+ t.zIndex?.let { opts.zIndex(it.toFloat()) }
37
+ t.opacity?.let { opts.transparency(1f - it.toFloat()) }
38
+ return opts
39
+ }
40
+ }
@@ -14,6 +14,7 @@ import com.rngooglemapsplus.extensions.polylineEquals
14
14
  import com.rngooglemapsplus.extensions.toCameraPosition
15
15
  import com.rngooglemapsplus.extensions.toCompressFormat
16
16
  import com.rngooglemapsplus.extensions.toFileExtension
17
+ import com.rngooglemapsplus.extensions.toGoogleMapType
17
18
  import com.rngooglemapsplus.extensions.toLatLngBounds
18
19
  import com.rngooglemapsplus.extensions.toMapColorScheme
19
20
  import com.rngooglemapsplus.extensions.toSize
@@ -33,6 +34,7 @@ class RNGoogleMapsPlusView(
33
34
  private val polygonBuilder = MapPolygonBuilder()
34
35
  private val circleBuilder = MapCircleBuilder()
35
36
  private val heatmapBuilder = MapHeatmapBuilder()
37
+ private val urlTileOverlayBuilder = MapUrlTileOverlayBuilder()
36
38
 
37
39
  override val view =
38
40
  GoogleMapsViewImpl(context, locationHandler, playServiceHandler, markerBuilder)
@@ -128,9 +130,7 @@ class RNGoogleMapsPlusView(
128
130
  set(value) {
129
131
  if (field == value) return
130
132
  field = value
131
- value?.let {
132
- view.mapType = it.value
133
- }
133
+ view.mapType = value?.toGoogleMapType()
134
134
  }
135
135
 
136
136
  override var markers: Array<RNMarker>? = null
@@ -263,6 +263,20 @@ class RNGoogleMapsPlusView(
263
263
  view.addKmlLayer(id, next.kmlString)
264
264
  }
265
265
  }
266
+ override var urlTileOverlays: Array<RNUrlTileOverlay>? = null
267
+ set(value) {
268
+ if (field.contentEquals(value)) return
269
+ val prevById = field?.associateBy { it.id } ?: emptyMap()
270
+ val nextById = value?.associateBy { it.id } ?: emptyMap()
271
+ field = value
272
+ (prevById.keys - nextById.keys).forEach { id ->
273
+ view.removeUrlTileOverlay(id)
274
+ }
275
+
276
+ nextById.forEach { (id, next) ->
277
+ view.addUrlTileOverlay(id, urlTileOverlayBuilder.build(next))
278
+ }
279
+ }
266
280
 
267
281
  override var locationConfig: RNLocationConfig? = null
268
282
  set(value) {
@@ -281,6 +295,11 @@ class RNGoogleMapsPlusView(
281
295
  view.onMapReady = cb
282
296
  }
283
297
 
298
+ override var onMapLoaded: ((Boolean) -> Unit)? = null
299
+ set(cb) {
300
+ view.onMapLoaded = cb
301
+ }
302
+
284
303
  override var onLocationUpdate: ((RNLocation) -> Unit)? = null
285
304
  set(cb) {
286
305
  view.onLocationUpdate = cb
@@ -296,6 +315,11 @@ class RNGoogleMapsPlusView(
296
315
  view.onMapPress = cb
297
316
  }
298
317
 
318
+ override var onMapLongPress: ((RNLatLng) -> Unit)? = null
319
+ set(cb) {
320
+ view.onMapLongPress = cb
321
+ }
322
+
299
323
  override var onMarkerPress: ((String?) -> Unit)? = null
300
324
  set(cb) {
301
325
  view.onMarkerPress = cb
@@ -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
+ }
@@ -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,6 +27,7 @@ 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
33
  private var lastSubmittedCameraPosition: GMSCameraPosition?
@@ -75,7 +77,6 @@ GMSIndoorDisplayDelegate {
75
77
  applyProps()
76
78
  initLocationCallbacks()
77
79
  onMapReady?(true)
78
- mapReady = true
79
80
  }
80
81
 
81
82
  @MainActor
@@ -136,6 +137,12 @@ GMSIndoorDisplayDelegate {
136
137
  }
137
138
  pendingKmlLayers.removeAll()
138
139
  }
140
+ if !pendingUrlTileOverlays.isEmpty {
141
+ pendingUrlTileOverlays.forEach {
142
+ addUrlTileOverlayInternal(id: $0.id, urlTileOverlay: $0.urlTileOverlay)
143
+ }
144
+ pendingUrlTileOverlays.removeAll()
145
+ }
139
146
  }
140
147
 
141
148
  @MainActor
@@ -255,9 +262,11 @@ GMSIndoorDisplayDelegate {
255
262
 
256
263
  var onMapError: ((RNMapErrorCode) -> Void)?
257
264
  var onMapReady: ((Bool) -> Void)?
265
+ var onMapLoaded: ((Bool) -> Void)?
258
266
  var onLocationUpdate: ((RNLocation) -> Void)?
259
267
  var onLocationError: ((_ error: RNLocationErrorCode) -> Void)?
260
268
  var onMapPress: ((RNLatLng) -> Void)?
269
+ var onMapLongPress: ((RNLatLng) -> Void)?
261
270
  var onMarkerPress: ((String?) -> Void)?
262
271
  var onPolylinePress: ((String?) -> Void)?
263
272
  var onPolygonPress: ((String?) -> Void)?
@@ -611,6 +620,36 @@ GMSIndoorDisplayDelegate {
611
620
  pendingKmlLayers.removeAll()
612
621
  }
613
622
 
623
+ @MainActor
624
+ func addUrlTileOverlay(id: String, urlTileOverlay: GMSURLTileLayer) {
625
+ if mapView == nil {
626
+ pendingUrlTileOverlays.append((id, urlTileOverlay))
627
+ return
628
+ }
629
+ urlTileOverlays.removeValue(forKey: id).map { $0.map = nil }
630
+ addUrlTileOverlayInternal(id: id, urlTileOverlay: urlTileOverlay)
631
+ }
632
+
633
+ @MainActor
634
+ private func addUrlTileOverlayInternal(
635
+ id: String,
636
+ urlTileOverlay: GMSURLTileLayer
637
+ ) {
638
+ urlTileOverlay.map = mapView
639
+ }
640
+
641
+ @MainActor
642
+ func removeUrlTileOverlay(id: String) {
643
+ urlTileOverlays.removeValue(forKey: id).map { $0.map = nil }
644
+ }
645
+
646
+ @MainActor
647
+ func clearUrlTileOverlay() {
648
+ urlTileOverlays.values.forEach { $0.map = nil }
649
+ urlTileOverlays.removeAll()
650
+ pendingUrlTileOverlays.removeAll()
651
+ }
652
+
614
653
  func deinitInternal() {
615
654
  guard !deInitialized else { return }
616
655
  deInitialized = true
@@ -623,6 +662,7 @@ GMSIndoorDisplayDelegate {
623
662
  self.clearCircles()
624
663
  self.clearHeatmaps()
625
664
  self.clearKmlLayers()
665
+ self.clearUrlTileOverlay()
626
666
  self.mapView?.clear()
627
667
  self.mapView?.indoorDisplay.delegate = nil
628
668
  self.mapView?.delegate = nil
@@ -655,6 +695,12 @@ GMSIndoorDisplayDelegate {
655
695
  deinitInternal()
656
696
  }
657
697
 
698
+ func mapViewDidFinishTileRendering(_ mapView: GMSMapView) {
699
+ guard !loaded else { return }
700
+ loaded = true
701
+ onMapLoaded?(true)
702
+ }
703
+
658
704
  func mapView(_ mapView: GMSMapView, willMove gesture: Bool) {
659
705
  onMain {
660
706
  self.cameraMoveReasonIsGesture = gesture
@@ -713,6 +759,17 @@ GMSIndoorDisplayDelegate {
713
759
  }
714
760
  }
715
761
 
762
+ func mapView(
763
+ _ mapView: GMSMapView,
764
+ didLongPressAt coordinate: CLLocationCoordinate2D
765
+ ) {
766
+ onMain {
767
+ self.onMapLongPress?(
768
+ coordinate.toRNLatLng(),
769
+ )
770
+ }
771
+ }
772
+
716
773
  func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
717
774
  onMain {
718
775
  mapView.selectedMarker = marker
@@ -0,0 +1,23 @@
1
+ import GoogleMaps
2
+
3
+ class MapUrlTileOverlayBuilder {
4
+ func build(_ t: RNUrlTileOverlay) -> GMSURLTileLayer {
5
+
6
+ let constructor: GMSTileURLConstructor = { (x: UInt, y: UInt, zoom: UInt) in
7
+ let urlString = t.url
8
+ .replacingOccurrences(of: "{x}", with: "\(x)")
9
+ .replacingOccurrences(of: "{y}", with: "\(y)")
10
+ .replacingOccurrences(of: "{z}", with: "\(zoom)")
11
+ return URL(string: urlString)
12
+ }
13
+
14
+ let layer = GMSURLTileLayer(urlConstructor: constructor)
15
+
16
+ layer.tileSize = Int(t.tileSize)
17
+ t.opacity.map { layer.opacity = Float($0) }
18
+ t.zIndex.map { layer.zIndex = Int32($0) }
19
+ t.fadeIn.map { layer.fadeIn = $0 }
20
+
21
+ return layer
22
+ }
23
+ }
@@ -14,6 +14,7 @@ final class RNGoogleMapsPlusView: HybridRNGoogleMapsPlusViewSpec {
14
14
  private let polygonBuilder = MapPolygonBuilder()
15
15
  private let circleBuilder = MapCircleBuilder()
16
16
  private let heatmapBuilder = MapHeatmapBuilder()
17
+ private let urlTileOverlayBuilder = MapUrlTileOverlayBuilder()
17
18
 
18
19
  private let impl: GoogleMapsViewImpl
19
20
 
@@ -110,9 +111,7 @@ final class RNGoogleMapsPlusView: HybridRNGoogleMapsPlusViewSpec {
110
111
  @MainActor
111
112
  var mapType: RNMapType? {
112
113
  didSet {
113
- impl.mapType = mapType.map {
114
- GMSMapViewType(rawValue: UInt($0.rawValue)) ?? .normal
115
- }
114
+ impl.mapType = mapType?.toGMSMapViewType
116
115
  }
117
116
  }
118
117
 
@@ -286,6 +285,30 @@ final class RNGoogleMapsPlusView: HybridRNGoogleMapsPlusViewSpec {
286
285
  }
287
286
  }
288
287
 
288
+ @MainActor
289
+ var urlTileOverlays: [RNUrlTileOverlay]? {
290
+ didSet {
291
+ let prevById = Dictionary(
292
+ (oldValue ?? []).map { ($0.id, $0) },
293
+ uniquingKeysWith: { _, new in new }
294
+ )
295
+ let nextById = Dictionary(
296
+ (urlTileOverlays ?? []).map { ($0.id, $0) },
297
+ uniquingKeysWith: { _, new in new }
298
+ )
299
+
300
+ let removed = Set(prevById.keys).subtracting(nextById.keys)
301
+ removed.forEach { impl.removeUrlTileOverlay(id: $0) }
302
+
303
+ for (id, next) in nextById {
304
+ impl.addUrlTileOverlay(
305
+ id: id,
306
+ urlTileOverlay: urlTileOverlayBuilder.build(next)
307
+ )
308
+ }
309
+ }
310
+ }
311
+
289
312
  @MainActor
290
313
  var locationConfig: RNLocationConfig? {
291
314
  didSet {
@@ -302,6 +325,10 @@ final class RNGoogleMapsPlusView: HybridRNGoogleMapsPlusViewSpec {
302
325
  didSet { impl.onMapReady = onMapReady }
303
326
  }
304
327
  @MainActor
328
+ var onMapLoaded: ((Bool) -> Void)? {
329
+ didSet { impl.onMapLoaded = onMapLoaded }
330
+ }
331
+ @MainActor
305
332
  var onLocationUpdate: ((RNLocation) -> Void)? {
306
333
  didSet { impl.onLocationUpdate = onLocationUpdate }
307
334
  }
@@ -314,6 +341,10 @@ final class RNGoogleMapsPlusView: HybridRNGoogleMapsPlusViewSpec {
314
341
  didSet { impl.onMapPress = onMapPress }
315
342
  }
316
343
  @MainActor
344
+ var onMapLongPress: ((RNLatLng) -> Void)? {
345
+ didSet { impl.onMapLongPress = onMapLongPress }
346
+ }
347
+ @MainActor
317
348
  var onMarkerPress: ((String?) -> Void)? {
318
349
  didSet { impl.onMarkerPress = onMarkerPress }
319
350
  }
@@ -0,0 +1,18 @@
1
+ import GoogleMaps
2
+
3
+ extension RNMapType {
4
+ var toGMSMapViewType: GMSMapViewType {
5
+ switch self {
6
+ case .none:
7
+ return .none
8
+ case .normal:
9
+ return .normal
10
+ case .hybrid:
11
+ return .hybrid
12
+ case .satellite:
13
+ return .satellite
14
+ case .terrain:
15
+ return .terrain
16
+ }
17
+ }
18
+ }
@@ -1 +1 @@
1
- {"version":3,"names":["RNAndroidLocationPriority","RNIOSLocationAccuracy","RNAndroidLocationPermissionResult","RNIOSPermissionResult","RNLocationErrorCode","RNMapErrorCode"],"sourceRoot":"../../src","sources":["types.ts"],"mappings":";;AAgEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIA;AACA;AACA;;AA6JA,WAAYA,yBAAyB,0BAAzBA,yBAAyB;EAAzBA,yBAAyB,CAAzBA,yBAAyB;EAAzBA,yBAAyB,CAAzBA,yBAAyB;EAAzBA,yBAAyB,CAAzBA,yBAAyB;EAAzBA,yBAAyB,CAAzBA,yBAAyB;EAAA,OAAzBA,yBAAyB;AAAA;AAYrC,WAAYC,qBAAqB,0BAArBA,qBAAqB;EAArBA,qBAAqB,CAArBA,qBAAqB;EAArBA,qBAAqB,CAArBA,qBAAqB;EAArBA,qBAAqB,CAArBA,qBAAqB;EAArBA,qBAAqB,CAArBA,qBAAqB;EAAA,OAArBA,qBAAqB;AAAA;AAYjC,WAAYC,iCAAiC,0BAAjCA,iCAAiC;EAAjCA,iCAAiC,CAAjCA,iCAAiC;EAAjCA,iCAAiC,CAAjCA,iCAAiC;EAAjCA,iCAAiC,CAAjCA,iCAAiC;EAAA,OAAjCA,iCAAiC;AAAA;AAM7C,WAAYC,qBAAqB,0BAArBA,qBAAqB;EAArBA,qBAAqB,CAArBA,qBAAqB;EAArBA,qBAAqB,CAArBA,qBAAqB;EAAA,OAArBA,qBAAqB;AAAA;AAoCjC,WAAYC,mBAAmB,0BAAnBA,mBAAmB;EAAnBA,mBAAmB,CAAnBA,mBAAmB;EAAnBA,mBAAmB,CAAnBA,mBAAmB;EAAnBA,mBAAmB,CAAnBA,mBAAmB;EAAnBA,mBAAmB,CAAnBA,mBAAmB;EAAnBA,mBAAmB,CAAnBA,mBAAmB;EAAnBA,mBAAmB,CAAnBA,mBAAmB;EAAA,OAAnBA,mBAAmB;AAAA;AAS/B,WAAYC,cAAc,0BAAdA,cAAc;EAAdA,cAAc,CAAdA,cAAc;EAAdA,cAAc,CAAdA,cAAc;EAAdA,cAAc,CAAdA,cAAc;EAAdA,cAAc,CAAdA,cAAc;EAAdA,cAAc,CAAdA,cAAc;EAAdA,cAAc,CAAdA,cAAc;EAAdA,cAAc,CAAdA,cAAc;EAAA,OAAdA,cAAc;AAAA","ignoreList":[]}
1
+ {"version":3,"names":["RNAndroidLocationPriority","RNIOSLocationAccuracy","RNAndroidLocationPermissionResult","RNIOSPermissionResult","RNLocationErrorCode","RNMapErrorCode"],"sourceRoot":"../../src","sources":["types.ts"],"mappings":";;AAgEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIA;AACA;AACA;;AAsKA,WAAYA,yBAAyB,0BAAzBA,yBAAyB;EAAzBA,yBAAyB,CAAzBA,yBAAyB;EAAzBA,yBAAyB,CAAzBA,yBAAyB;EAAzBA,yBAAyB,CAAzBA,yBAAyB;EAAzBA,yBAAyB,CAAzBA,yBAAyB;EAAA,OAAzBA,yBAAyB;AAAA;AAYrC,WAAYC,qBAAqB,0BAArBA,qBAAqB;EAArBA,qBAAqB,CAArBA,qBAAqB;EAArBA,qBAAqB,CAArBA,qBAAqB;EAArBA,qBAAqB,CAArBA,qBAAqB;EAArBA,qBAAqB,CAArBA,qBAAqB;EAAA,OAArBA,qBAAqB;AAAA;AAYjC,WAAYC,iCAAiC,0BAAjCA,iCAAiC;EAAjCA,iCAAiC,CAAjCA,iCAAiC;EAAjCA,iCAAiC,CAAjCA,iCAAiC;EAAjCA,iCAAiC,CAAjCA,iCAAiC;EAAA,OAAjCA,iCAAiC;AAAA;AAM7C,WAAYC,qBAAqB,0BAArBA,qBAAqB;EAArBA,qBAAqB,CAArBA,qBAAqB;EAArBA,qBAAqB,CAArBA,qBAAqB;EAAA,OAArBA,qBAAqB;AAAA;AAoCjC,WAAYC,mBAAmB,0BAAnBA,mBAAmB;EAAnBA,mBAAmB,CAAnBA,mBAAmB;EAAnBA,mBAAmB,CAAnBA,mBAAmB;EAAnBA,mBAAmB,CAAnBA,mBAAmB;EAAnBA,mBAAmB,CAAnBA,mBAAmB;EAAnBA,mBAAmB,CAAnBA,mBAAmB;EAAnBA,mBAAmB,CAAnBA,mBAAmB;EAAA,OAAnBA,mBAAmB;AAAA;AAS/B,WAAYC,cAAc,0BAAdA,cAAc;EAAdA,cAAc,CAAdA,cAAc;EAAdA,cAAc,CAAdA,cAAc;EAAdA,cAAc,CAAdA,cAAc;EAAdA,cAAc,CAAdA,cAAc;EAAdA,cAAc,CAAdA,cAAc;EAAdA,cAAc,CAAdA,cAAc;EAAdA,cAAc,CAAdA,cAAc;EAAA,OAAdA,cAAc;AAAA","ignoreList":[]}
@@ -21,12 +21,15 @@
21
21
  "circles": true,
22
22
  "heatmaps": true,
23
23
  "kmlLayers": true,
24
+ "urlTileOverlays": true,
24
25
  "locationConfig": true,
25
26
  "onMapError": true,
26
27
  "onMapReady": true,
28
+ "onMapLoaded": true,
27
29
  "onLocationUpdate": true,
28
30
  "onLocationError": true,
29
31
  "onMapPress": true,
32
+ "onMapLongPress": true,
30
33
  "onMarkerPress": true,
31
34
  "onPolylinePress": true,
32
35
  "onPolygonPress": true,
@@ -1,5 +1,5 @@
1
1
  import type { HybridView, HybridViewMethods, HybridViewProps } from 'react-native-nitro-modules';
2
- import type { RNCamera, RNLatLng, RNMapPadding, RNPolygon, RNPolyline, RNUserInterfaceStyle, RNLocationErrorCode, RNMarker, RNLocationPermissionResult, RNRegion, RNLocation, RNMapErrorCode, RNMapType, RNInitialProps, RNCircle, RNMapUiSettings, RNLocationConfig, RNMapZoomConfig, RNHeatmap, RNKMLayer, RNIndoorBuilding, RNIndoorLevel, RNLatLngBounds, RNSnapshotOptions } from './types';
2
+ import type { RNCamera, RNLatLng, RNMapPadding, RNPolygon, RNPolyline, RNUserInterfaceStyle, RNLocationErrorCode, RNMarker, RNLocationPermissionResult, RNRegion, RNLocation, RNMapErrorCode, RNMapType, RNInitialProps, RNCircle, RNMapUiSettings, RNLocationConfig, RNMapZoomConfig, RNHeatmap, RNKMLayer, RNIndoorBuilding, RNIndoorLevel, RNLatLngBounds, RNSnapshotOptions, RNUrlTileOverlay } from './types';
3
3
  export interface RNGoogleMapsPlusViewProps extends HybridViewProps {
4
4
  initialProps?: RNInitialProps;
5
5
  uiSettings?: RNMapUiSettings;
@@ -18,12 +18,15 @@ export interface RNGoogleMapsPlusViewProps extends HybridViewProps {
18
18
  circles?: RNCircle[];
19
19
  heatmaps?: RNHeatmap[];
20
20
  kmlLayers?: RNKMLayer[];
21
+ urlTileOverlays?: RNUrlTileOverlay[];
21
22
  locationConfig?: RNLocationConfig;
22
23
  onMapError?: (error: RNMapErrorCode) => void;
23
24
  onMapReady?: (ready: boolean) => void;
25
+ onMapLoaded?: (loaded: boolean) => void;
24
26
  onLocationUpdate?: (location: RNLocation) => void;
25
27
  onLocationError?: (error: RNLocationErrorCode) => void;
26
28
  onMapPress?: (coordinate: RNLatLng) => void;
29
+ onMapLongPress?: (coordinate: RNLatLng) => void;
27
30
  onMarkerPress?: (id?: string | undefined) => void;
28
31
  onPolylinePress?: (id?: string | undefined) => void;
29
32
  onPolygonPress?: (id?: string | undefined) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"RNGoogleMapsPlusView.nitro.d.ts","sourceRoot":"","sources":["../../../src/RNGoogleMapsPlusView.nitro.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"RNGoogleMapsPlusView.nitro.d.ts","sourceRoot":"","sources":["../../../src/RNGoogleMapsPlusView.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,iBAAiB,EACjB,eAAe,EAChB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACV,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,UAAU,EACV,oBAAoB,EACpB,mBAAmB,EACnB,QAAQ,EACR,0BAA0B,EAC1B,QAAQ,EACR,UAAU,EACV,cAAc,EACd,SAAS,EACT,cAAc,EACd,QAAQ,EACR,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,yBAA0B,SAAQ,eAAe;IAChE,YAAY,CAAC,EAAE,cAAc,CAAC;IAC9B,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,oBAAoB,CAAC;IAC1C,aAAa,CAAC,EAAE,eAAe,CAAC;IAChC,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,EAAE,CAAC;IACvB,SAAS,CAAC,EAAE,UAAU,EAAE,CAAC;IACzB,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,EAAE,CAAC;IACvB,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC;IACxB,eAAe,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACrC,cAAc,CAAC,EAAE,gBAAgB,CAAC;IAClC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAC7C,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACxC,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,UAAU,KAAK,IAAI,CAAC;IAClD,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAC;IACvD,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,QAAQ,KAAK,IAAI,CAAC;IAC5C,cAAc,CAAC,EAAE,CAAC,UAAU,EAAE,QAAQ,KAAK,IAAI,CAAC;IAChD,aAAa,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAClD,eAAe,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IACpD,cAAc,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IACnD,aAAa,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAClD,iBAAiB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IACzE,YAAY,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IACpE,eAAe,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IACvE,uBAAuB,CAAC,EAAE,CAAC,cAAc,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACrE,sBAAsB,CAAC,EAAE,CAAC,WAAW,EAAE,aAAa,KAAK,IAAI,CAAC;IAC9D,mBAAmB,CAAC,EAAE,CACpB,MAAM,EAAE,QAAQ,EAChB,MAAM,EAAE,QAAQ,EAChB,SAAS,EAAE,OAAO,KACf,IAAI,CAAC;IACV,cAAc,CAAC,EAAE,CACf,MAAM,EAAE,QAAQ,EAChB,MAAM,EAAE,QAAQ,EAChB,SAAS,EAAE,OAAO,KACf,IAAI,CAAC;IACV,sBAAsB,CAAC,EAAE,CACvB,MAAM,EAAE,QAAQ,EAChB,MAAM,EAAE,QAAQ,EAChB,SAAS,EAAE,OAAO,KACf,IAAI,CAAC;CACX;AAED,MAAM,WAAW,2BAA4B,SAAQ,iBAAiB;IACpE,SAAS,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE3E,sBAAsB,CACpB,WAAW,EAAE,QAAQ,EAAE,EACvB,OAAO,CAAC,EAAE,YAAY,EACtB,QAAQ,CAAC,EAAE,OAAO,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,IAAI,CAAC;IAER,eAAe,CAAC,MAAM,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAE/C,eAAe,CACb,MAAM,EAAE,cAAc,EACtB,OAAO,CAAC,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,OAAO,GACnB,IAAI,CAAC;IAER,QAAQ,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAElE,kBAAkB,IAAI,IAAI,CAAC;IAE3B,oBAAoB,IAAI,IAAI,CAAC;IAE7B,yBAAyB,IAAI,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAEjE,6BAA6B,IAAI,OAAO,CAAC;CAC1C;AAED,MAAM,MAAM,oBAAoB,GAAG,UAAU,CAC3C,yBAAyB,EACzB,2BAA2B,CAC5B,CAAC"}