react-native-google-maps-plus 1.7.0-dev.8 → 1.7.0

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 (50) hide show
  1. package/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt +122 -126
  2. package/android/src/main/java/com/rngooglemapsplus/MapMarkerBuilder.kt +33 -0
  3. package/android/src/main/java/com/rngooglemapsplus/RNGoogleMapsPlusView.kt +27 -11
  4. package/android/src/main/java/com/rngooglemapsplus/extensions/BitmapExtension.kt +35 -0
  5. package/android/src/main/java/com/rngooglemapsplus/extensions/LatLngBoundsExtension.kt +31 -0
  6. package/android/src/main/java/com/rngooglemapsplus/extensions/MapObjectTagExtensions.kt +84 -0
  7. package/ios/GoogleMapViewImpl.swift +83 -66
  8. package/ios/MapMarkerBuilder.swift +55 -2
  9. package/ios/RNGoogleMapsPlusView.swift +20 -10
  10. package/ios/extensions/MapObjectTag+Extension.swift +93 -0
  11. package/ios/extensions/UIImage+Extension.swift +45 -0
  12. package/lib/module/types.js.map +1 -1
  13. package/lib/typescript/src/RNGoogleMapsPlusView.nitro.d.ts +12 -10
  14. package/lib/typescript/src/RNGoogleMapsPlusView.nitro.d.ts.map +1 -1
  15. package/lib/typescript/src/types.d.ts +3 -0
  16. package/lib/typescript/src/types.d.ts.map +1 -1
  17. package/nitrogen/generated/android/RNGoogleMapsPlusOnLoad.cpp +4 -4
  18. package/nitrogen/generated/android/c++/JFunc_void_std__string.hpp +75 -0
  19. package/nitrogen/generated/android/c++/JFunc_void_std__string_RNLatLng.hpp +77 -0
  20. package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusViewSpec.cpp +100 -92
  21. package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusViewSpec.hpp +22 -20
  22. package/nitrogen/generated/android/c++/JRNMapUiSettings.hpp +11 -3
  23. package/nitrogen/generated/android/c++/JRNMarker.hpp +7 -3
  24. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/{Func_void_std__optional_std__string_.kt → Func_void_std__string.kt} +12 -12
  25. 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
  26. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/HybridRNGoogleMapsPlusViewSpec.kt +38 -30
  27. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNMapUiSettings.kt +9 -3
  28. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNMarker.kt +6 -3
  29. package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Bridge.cpp +16 -8
  30. package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Bridge.hpp +58 -36
  31. package/nitrogen/generated/ios/c++/HybridRNGoogleMapsPlusViewSpecSwift.hpp +32 -20
  32. package/nitrogen/generated/ios/swift/Func_void_std__optional_std__string_.swift +6 -6
  33. package/nitrogen/generated/ios/swift/Func_void_std__string.swift +47 -0
  34. package/nitrogen/generated/ios/swift/Func_void_std__string_RNLatLng.swift +47 -0
  35. package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusViewSpec.swift +12 -10
  36. package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusViewSpec_cxx.swift +142 -180
  37. package/nitrogen/generated/ios/swift/RNMapUiSettings.swift +61 -1
  38. package/nitrogen/generated/ios/swift/RNMarker.swift +24 -1
  39. package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusViewSpec.cpp +2 -0
  40. package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusViewSpec.hpp +22 -20
  41. package/nitrogen/generated/shared/c++/RNMapUiSettings.hpp +10 -2
  42. package/nitrogen/generated/shared/c++/RNMarker.hpp +6 -2
  43. package/nitrogen/generated/shared/c++/views/HybridRNGoogleMapsPlusViewComponent.cpp +20 -20
  44. package/nitrogen/generated/shared/c++/views/HybridRNGoogleMapsPlusViewComponent.hpp +10 -10
  45. package/package.json +1 -1
  46. package/src/RNGoogleMapsPlusView.nitro.ts +14 -10
  47. package/src/types.ts +3 -0
  48. package/nitrogen/generated/android/c++/JFunc_void_std__optional_std__string_.hpp +0 -76
  49. package/nitrogen/generated/android/c++/JFunc_void_std__optional_std__string__RNLatLng.hpp +0 -78
  50. package/nitrogen/generated/ios/swift/Func_void_std__optional_std__string__RNLatLng.swift +0 -54
@@ -1,12 +1,15 @@
1
1
  package com.rngooglemapsplus
2
2
 
3
+ import CircleTag
4
+ import MarkerTag
5
+ import PolygonTag
6
+ import PolylineTag
3
7
  import android.annotation.SuppressLint
4
8
  import android.graphics.Bitmap
5
9
  import android.location.Location
6
- import android.util.Base64
7
10
  import android.util.Size
11
+ import android.view.View
8
12
  import android.widget.FrameLayout
9
- import androidx.core.graphics.scale
10
13
  import com.facebook.react.bridge.LifecycleEventListener
11
14
  import com.facebook.react.uimanager.PixelUtil.dpToPx
12
15
  import com.facebook.react.uimanager.ThemedReactContext
@@ -33,6 +36,7 @@ import com.google.android.gms.maps.model.TileOverlay
33
36
  import com.google.android.gms.maps.model.TileOverlayOptions
34
37
  import com.google.maps.android.data.kml.KmlLayer
35
38
  import com.margelo.nitro.core.Promise
39
+ import com.rngooglemapsplus.extensions.encode
36
40
  import com.rngooglemapsplus.extensions.onUi
37
41
  import com.rngooglemapsplus.extensions.onUiSync
38
42
  import com.rngooglemapsplus.extensions.toGooglePriority
@@ -45,10 +49,10 @@ import com.rngooglemapsplus.extensions.toRnCamera
45
49
  import com.rngooglemapsplus.extensions.toRnLatLng
46
50
  import com.rngooglemapsplus.extensions.toRnLocation
47
51
  import com.rngooglemapsplus.extensions.toRnRegion
52
+ import com.rngooglemapsplus.extensions.withPaddingPixels
53
+ import idTag
54
+ import tagData
48
55
  import java.io.ByteArrayInputStream
49
- import java.io.ByteArrayOutputStream
50
- import java.io.File
51
- import java.io.FileOutputStream
52
56
  import java.nio.charset.StandardCharsets
53
57
 
54
58
  class GoogleMapsViewImpl(
@@ -74,6 +78,7 @@ class GoogleMapsViewImpl(
74
78
  GoogleMap.OnInfoWindowLongClickListener,
75
79
  GoogleMap.OnMyLocationClickListener,
76
80
  GoogleMap.OnMyLocationButtonClickListener,
81
+ GoogleMap.InfoWindowAdapter,
77
82
  LifecycleEventListener {
78
83
  private var initialized = false
79
84
  private var loaded = false
@@ -81,7 +86,7 @@ class GoogleMapsViewImpl(
81
86
  private var googleMap: GoogleMap? = null
82
87
  private var mapView: MapView? = null
83
88
 
84
- private val pendingMarkers = mutableListOf<Pair<String, MarkerOptions>>()
89
+ private val pendingMarkers = mutableListOf<Triple<String, MarkerOptions, MarkerTag>>()
85
90
  private val pendingPolylines = mutableListOf<Pair<String, PolylineOptions>>()
86
91
  private val pendingPolygons = mutableListOf<Pair<String, PolygonOptions>>()
87
92
  private val pendingCircles = mutableListOf<Pair<String, CircleOptions>>()
@@ -142,6 +147,7 @@ class GoogleMapsViewImpl(
142
147
  googleMap?.setOnInfoWindowLongClickListener(this@GoogleMapsViewImpl)
143
148
  googleMap?.setOnMyLocationClickListener(this@GoogleMapsViewImpl)
144
149
  googleMap?.setOnMyLocationButtonClickListener(this@GoogleMapsViewImpl)
150
+ googleMap?.setInfoWindowAdapter(this@GoogleMapsViewImpl)
145
151
  loaded = true
146
152
  onMapLoaded?.invoke(
147
153
  map.projection.visibleRegion.toRnRegion(),
@@ -217,31 +223,31 @@ class GoogleMapsViewImpl(
217
223
  locationConfig = locationConfig
218
224
 
219
225
  if (pendingMarkers.isNotEmpty()) {
220
- pendingMarkers.forEach { (id, opts) -> internalAddMarker(id, opts) }
226
+ pendingMarkers.forEach { (id, opts, markerTag) -> addMarkerInternal(id, opts, markerTag) }
221
227
  pendingMarkers.clear()
222
228
  }
223
229
  if (pendingPolylines.isNotEmpty()) {
224
- pendingPolylines.forEach { (id, opts) -> internalAddPolyline(id, opts) }
230
+ pendingPolylines.forEach { (id, opts) -> addPolylineInternal(id, opts) }
225
231
  pendingPolylines.clear()
226
232
  }
227
233
  if (pendingPolygons.isNotEmpty()) {
228
- pendingPolygons.forEach { (id, opts) -> internalAddPolygon(id, opts) }
234
+ pendingPolygons.forEach { (id, opts) -> addPolygonInternal(id, opts) }
229
235
  pendingPolygons.clear()
230
236
  }
231
237
  if (pendingCircles.isNotEmpty()) {
232
- pendingCircles.forEach { (id, opts) -> internalAddCircle(id, opts) }
238
+ pendingCircles.forEach { (id, opts) -> addCircleInternal(id, opts) }
233
239
  pendingCircles.clear()
234
240
  }
235
241
  if (pendingHeatmaps.isNotEmpty()) {
236
- pendingHeatmaps.forEach { (id, opts) -> internalAddHeatmap(id, opts) }
242
+ pendingHeatmaps.forEach { (id, opts) -> addHeatmapInternal(id, opts) }
237
243
  pendingHeatmaps.clear()
238
244
  }
239
245
  if (pendingKmlLayers.isNotEmpty()) {
240
- pendingKmlLayers.forEach { (id, str) -> internalAddKmlLayer(id, str) }
246
+ pendingKmlLayers.forEach { (id, str) -> addKmlLayerInternal(id, str) }
241
247
  pendingKmlLayers.clear()
242
248
  }
243
249
  if (pendingUrlTilesOverlays.isNotEmpty()) {
244
- pendingUrlTilesOverlays.forEach { (id, opts) -> internalAddUrlTileOverlay(id, opts) }
250
+ pendingUrlTilesOverlays.forEach { (id, opts) -> addUrlTileOverlayInternal(id, opts) }
245
251
  pendingUrlTilesOverlays.clear()
246
252
  }
247
253
  }
@@ -368,24 +374,36 @@ class GoogleMapsViewImpl(
368
374
  var onMapPress: ((RNLatLng) -> Unit)? = null
369
375
  var onMapLongPress: ((RNLatLng) -> Unit)? = null
370
376
  var onPoiPress: ((String, String, RNLatLng) -> Unit)? = null
371
- var onMarkerPress: ((String?) -> Unit)? = null
372
- var onPolylinePress: ((String?) -> Unit)? = null
373
- var onPolygonPress: ((String?) -> Unit)? = null
374
- var onCirclePress: ((String?) -> Unit)? = null
375
- var onMarkerDragStart: ((String?, RNLatLng) -> Unit)? = null
376
- var onMarkerDrag: ((String?, RNLatLng) -> Unit)? = null
377
- var onMarkerDragEnd: ((String?, RNLatLng) -> Unit)? = null
377
+ var onMarkerPress: ((String) -> Unit)? = null
378
+ var onPolylinePress: ((String) -> Unit)? = null
379
+ var onPolygonPress: ((String) -> Unit)? = null
380
+ var onCirclePress: ((String) -> Unit)? = null
381
+ var onMarkerDragStart: ((String, RNLatLng) -> Unit)? = null
382
+ var onMarkerDrag: ((String, RNLatLng) -> Unit)? = null
383
+ var onMarkerDragEnd: ((String, RNLatLng) -> Unit)? = null
378
384
  var onIndoorBuildingFocused: ((RNIndoorBuilding) -> Unit)? = null
379
385
  var onIndoorLevelActivated: ((RNIndoorLevel) -> Unit)? = null
380
- var onInfoWindowPress: ((String?) -> Unit)? = null
381
- var onInfoWindowClose: ((String?) -> Unit)? = null
382
- var onInfoWindowLongPress: ((String?) -> Unit)? = null
386
+ var onInfoWindowPress: ((String) -> Unit)? = null
387
+ var onInfoWindowClose: ((String) -> Unit)? = null
388
+ var onInfoWindowLongPress: ((String) -> Unit)? = null
383
389
  var onMyLocationPress: ((RNLocation) -> Unit)? = null
384
390
  var onMyLocationButtonPress: ((Boolean) -> Unit)? = null
385
391
  var onCameraChangeStart: ((RNRegion, RNCamera, Boolean) -> Unit)? = null
386
392
  var onCameraChange: ((RNRegion, RNCamera, Boolean) -> Unit)? = null
387
393
  var onCameraChangeComplete: ((RNRegion, RNCamera, Boolean) -> Unit)? = null
388
394
 
395
+ fun showMarkerInfoWindow(id: String) =
396
+ onUi {
397
+ val marker = markersById[id] ?: return@onUi
398
+ marker.showInfoWindow()
399
+ }
400
+
401
+ fun hideMarkerInfoWindow(id: String) =
402
+ onUi {
403
+ val marker = markersById[id] ?: return@onUi
404
+ marker.hideInfoWindow()
405
+ }
406
+
389
407
  fun setCamera(
390
408
  cameraPosition: CameraPosition,
391
409
  animated: Boolean,
@@ -406,56 +424,23 @@ class GoogleMapsViewImpl(
406
424
  durationMs: Int,
407
425
  ) = onUi {
408
426
  if (coordinates.isEmpty()) return@onUi
409
- val builder = LatLngBounds.Builder()
427
+
428
+ val w = mapView?.width ?: 0
429
+ val h = mapView?.height ?: 0
430
+
431
+ val builder = LatLngBounds.builder()
410
432
  coordinates.forEach { coord -> builder.include(coord.toLatLng()) }
411
- val bounds = builder.build()
412
-
413
- val latSpan = bounds.northeast.latitude - bounds.southwest.latitude
414
- val lngSpan = bounds.northeast.longitude - bounds.southwest.longitude
415
-
416
- val h = (mapView?.height ?: 0)
417
- val w = (mapView?.width ?: 0)
418
- val latPerPixel = if (h != 0) latSpan / h else 0.0
419
- val lngPerPixel = if (w != 0) lngSpan / w else 0.0
420
-
421
- builder.include(
422
- LatLng(
423
- bounds.northeast.latitude + (padding.top.dpToPx() * latPerPixel),
424
- bounds.northeast.longitude,
425
- ),
426
- )
427
- builder.include(
428
- LatLng(
429
- bounds.southwest.latitude - (padding.bottom.dpToPx() * latPerPixel),
430
- bounds.southwest.longitude,
431
- ),
432
- )
433
- builder.include(
434
- LatLng(
435
- bounds.northeast.latitude,
436
- bounds.northeast.longitude + (padding.right.dpToPx() * lngPerPixel),
437
- ),
438
- )
439
- builder.include(
440
- LatLng(
441
- bounds.southwest.latitude,
442
- bounds.southwest.longitude - (padding.left.dpToPx() * lngPerPixel),
443
- ),
444
- )
445
-
446
- val paddedBounds = builder.build()
433
+
434
+ val baseBounds = builder.build()
435
+ val paddedBounds = baseBounds.withPaddingPixels(w, h, padding)
436
+
447
437
  val adjustedWidth =
448
438
  (w - padding.left.dpToPx() - padding.right.dpToPx()).toInt().coerceAtLeast(0)
449
439
  val adjustedHeight =
450
440
  (h - padding.top.dpToPx() - padding.bottom.dpToPx()).toInt().coerceAtLeast(0)
451
441
 
452
- val update =
453
- CameraUpdateFactory.newLatLngBounds(
454
- paddedBounds,
455
- adjustedWidth,
456
- adjustedHeight,
457
- 0,
458
- )
442
+ val update = CameraUpdateFactory.newLatLngBounds(paddedBounds, adjustedWidth, adjustedHeight, 0)
443
+
459
444
  if (animated) {
460
445
  googleMap?.animateCamera(update, durationMs, null)
461
446
  } else {
@@ -491,30 +476,9 @@ class GoogleMapsViewImpl(
491
476
  val promise = Promise<String?>()
492
477
  onUi {
493
478
  googleMap?.snapshot { bitmap ->
494
- try {
495
- if (bitmap == null) {
496
- promise.resolve(null)
497
- return@snapshot
498
- }
499
- val scaledBitmap = size?.let { bitmap.scale(it.width, it.height) } ?: bitmap
500
- val output = ByteArrayOutputStream()
501
- scaledBitmap.compress(compressFormat, (quality * 100).toInt().coerceIn(0, 100), output)
502
- val bytes = output.toByteArray()
503
-
504
- if (resultIsFile) {
505
- val file = File(context.cacheDir, "map_snapshot_${System.currentTimeMillis()}.$format")
506
- FileOutputStream(file).use { it.write(bytes) }
507
- promise.resolve(file.absolutePath)
508
- } else {
509
- val base64 = Base64.encodeToString(bytes, Base64.NO_WRAP)
510
- promise.resolve("data:image/$format;base64,$base64")
511
- }
512
-
513
- if (scaledBitmap !== bitmap) scaledBitmap.recycle()
514
- bitmap.recycle()
515
- } catch (_: Exception) {
516
- promise.resolve(null)
517
- }
479
+ bitmap
480
+ ?.encode(context, size, format, compressFormat, quality, resultIsFile)
481
+ ?.let(promise::resolve) ?: promise.resolve(null)
518
482
  }
519
483
  }
520
484
  return promise
@@ -523,21 +487,30 @@ class GoogleMapsViewImpl(
523
487
  fun addMarker(
524
488
  id: String,
525
489
  opts: MarkerOptions,
490
+ markerTag: MarkerTag,
526
491
  ) = onUi {
527
492
  if (googleMap == null) {
528
- pendingMarkers.add(id to opts)
493
+ pendingMarkers.add(Triple(id, opts, markerTag))
529
494
  return@onUi
530
495
  }
496
+
531
497
  markersById.remove(id)?.remove()
532
- internalAddMarker(id, opts)
498
+ addMarkerInternal(id, opts, markerTag)
533
499
  }
534
500
 
535
- private fun internalAddMarker(
501
+ private fun addMarkerInternal(
536
502
  id: String,
537
503
  opts: MarkerOptions,
504
+ markerTag: MarkerTag,
538
505
  ) = onUi {
539
- val marker = googleMap?.addMarker(opts).also { it?.tag = id }
540
- if (marker != null) markersById[id] = marker
506
+ val marker =
507
+ googleMap?.addMarker(opts)?.apply {
508
+ tag = markerTag
509
+ }
510
+
511
+ if (marker != null) {
512
+ markersById[id] = marker
513
+ }
541
514
  }
542
515
 
543
516
  fun updateMarker(
@@ -546,6 +519,10 @@ class GoogleMapsViewImpl(
546
519
  ) = onUi {
547
520
  val marker = markersById[id] ?: return@onUi
548
521
  block(marker)
522
+ if (marker.isInfoWindowShown) {
523
+ marker.hideInfoWindow()
524
+ marker.showInfoWindow()
525
+ }
549
526
  }
550
527
 
551
528
  fun removeMarker(id: String) =
@@ -569,14 +546,17 @@ class GoogleMapsViewImpl(
569
546
  return@onUi
570
547
  }
571
548
  polylinesById.remove(id)?.remove()
572
- internalAddPolyline(id, opts)
549
+ addPolylineInternal(id, opts)
573
550
  }
574
551
 
575
- private fun internalAddPolyline(
552
+ private fun addPolylineInternal(
576
553
  id: String,
577
554
  opts: PolylineOptions,
578
555
  ) = onUi {
579
- val pl = googleMap?.addPolyline(opts).also { it?.tag = id }
556
+ val pl =
557
+ googleMap?.addPolyline(opts).also {
558
+ it?.tag = PolylineTag(id = id)
559
+ }
580
560
  if (pl != null) polylinesById[id] = pl
581
561
  }
582
562
 
@@ -609,14 +589,17 @@ class GoogleMapsViewImpl(
609
589
  return@onUi
610
590
  }
611
591
  polygonsById.remove(id)?.remove()
612
- internalAddPolygon(id, opts)
592
+ addPolygonInternal(id, opts)
613
593
  }
614
594
 
615
- private fun internalAddPolygon(
595
+ private fun addPolygonInternal(
616
596
  id: String,
617
597
  opts: PolygonOptions,
618
598
  ) = onUi {
619
- val polygon = googleMap?.addPolygon(opts).also { it?.tag = id }
599
+ val polygon =
600
+ googleMap?.addPolygon(opts).also {
601
+ it?.tag = PolygonTag(id = id)
602
+ }
620
603
  if (polygon != null) polygonsById[id] = polygon
621
604
  }
622
605
 
@@ -649,14 +632,17 @@ class GoogleMapsViewImpl(
649
632
  return@onUi
650
633
  }
651
634
  circlesById.remove(id)?.remove()
652
- internalAddCircle(id, opts)
635
+ addCircleInternal(id, opts)
653
636
  }
654
637
 
655
- private fun internalAddCircle(
638
+ private fun addCircleInternal(
656
639
  id: String,
657
640
  opts: CircleOptions,
658
641
  ) = onUi {
659
- val circle = googleMap?.addCircle(opts).also { it?.tag = id }
642
+ val circle =
643
+ googleMap?.addCircle(opts).also {
644
+ it?.tag = CircleTag(id = id)
645
+ }
660
646
  if (circle != null) circlesById[id] = circle
661
647
  }
662
648
 
@@ -689,10 +675,10 @@ class GoogleMapsViewImpl(
689
675
  return@onUi
690
676
  }
691
677
  heatmapsById.remove(id)?.remove()
692
- internalAddHeatmap(id, opts)
678
+ addHeatmapInternal(id, opts)
693
679
  }
694
680
 
695
- private fun internalAddHeatmap(
681
+ private fun addHeatmapInternal(
696
682
  id: String,
697
683
  opts: TileOverlayOptions,
698
684
  ) = onUi {
@@ -710,7 +696,10 @@ class GoogleMapsViewImpl(
710
696
 
711
697
  fun clearHeatmaps() =
712
698
  onUi {
713
- heatmapsById.values.forEach { it.remove() }
699
+ heatmapsById.values.forEach {
700
+ it.clearTileCache()
701
+ it.remove()
702
+ }
714
703
  heatmapsById.clear()
715
704
  pendingHeatmaps.clear()
716
705
  }
@@ -724,10 +713,10 @@ class GoogleMapsViewImpl(
724
713
  return@onUi
725
714
  }
726
715
  kmlLayersById.remove(id)?.removeLayerFromMap()
727
- internalAddKmlLayer(id, kmlString)
716
+ addKmlLayerInternal(id, kmlString)
728
717
  }
729
718
 
730
- private fun internalAddKmlLayer(
719
+ private fun addKmlLayerInternal(
731
720
  id: String,
732
721
  kmlString: String,
733
722
  ) = onUi {
@@ -762,10 +751,10 @@ class GoogleMapsViewImpl(
762
751
  return@onUi
763
752
  }
764
753
  urlTileOverlaysById.remove(id)?.remove()
765
- internalAddUrlTileOverlay(id, opts)
754
+ addUrlTileOverlayInternal(id, opts)
766
755
  }
767
756
 
768
- private fun internalAddUrlTileOverlay(
757
+ private fun addUrlTileOverlayInternal(
769
758
  id: String,
770
759
  opts: TileOverlayOptions,
771
760
  ) = onUi {
@@ -783,7 +772,10 @@ class GoogleMapsViewImpl(
783
772
 
784
773
  fun clearUrlTileOverlays() =
785
774
  onUi {
786
- urlTileOverlaysById.values.forEach { it.remove() }
775
+ urlTileOverlaysById.values.forEach {
776
+ it.clearTileCache()
777
+ it.remove()
778
+ }
787
779
  urlTileOverlaysById.clear()
788
780
  pendingUrlTilesOverlays.clear()
789
781
  }
@@ -818,6 +810,7 @@ class GoogleMapsViewImpl(
818
810
  setOnInfoWindowLongClickListener(null)
819
811
  setOnMyLocationClickListener(null)
820
812
  setOnMyLocationButtonClickListener(null)
813
+ setInfoWindowAdapter(null)
821
814
  }
822
815
  googleMap = null
823
816
  mapView?.apply {
@@ -873,25 +866,24 @@ class GoogleMapsViewImpl(
873
866
 
874
867
  override fun onMarkerClick(marker: Marker): Boolean {
875
868
  onUi {
876
- marker.showInfoWindow()
877
- onMarkerPress?.invoke(marker.tag?.toString())
869
+ onMarkerPress?.invoke(marker.idTag)
878
870
  }
879
- return false
871
+ return uiSettings?.consumeOnMarkerPress ?: false
880
872
  }
881
873
 
882
874
  override fun onPolylineClick(polyline: Polyline) =
883
875
  onUi {
884
- onPolylinePress?.invoke(polyline.tag?.toString())
876
+ onPolylinePress?.invoke(polyline.idTag)
885
877
  }
886
878
 
887
879
  override fun onPolygonClick(polygon: Polygon) =
888
880
  onUi {
889
- onPolygonPress?.invoke(polygon.tag?.toString())
881
+ onPolygonPress?.invoke(polygon.idTag)
890
882
  }
891
883
 
892
884
  override fun onCircleClick(circle: Circle) =
893
885
  onUi {
894
- onCirclePress?.invoke(circle.tag?.toString())
886
+ onCirclePress?.invoke(circle.idTag)
895
887
  }
896
888
 
897
889
  override fun onMapClick(coordinates: LatLng) =
@@ -906,17 +898,17 @@ class GoogleMapsViewImpl(
906
898
 
907
899
  override fun onMarkerDragStart(marker: Marker) =
908
900
  onUi {
909
- onMarkerDragStart?.invoke(marker.tag?.toString(), marker.position.toRnLatLng())
901
+ onMarkerDragStart?.invoke(marker.idTag, marker.position.toRnLatLng())
910
902
  }
911
903
 
912
904
  override fun onMarkerDrag(marker: Marker) =
913
905
  onUi {
914
- onMarkerDrag?.invoke(marker.tag?.toString(), marker.position.toRnLatLng())
906
+ onMarkerDrag?.invoke(marker.idTag, marker.position.toRnLatLng())
915
907
  }
916
908
 
917
909
  override fun onMarkerDragEnd(marker: Marker) =
918
910
  onUi {
919
- onMarkerDragEnd?.invoke(marker.tag?.toString(), marker.position.toRnLatLng())
911
+ onMarkerDragEnd?.invoke(marker.idTag, marker.position.toRnLatLng())
920
912
  }
921
913
 
922
914
  override fun onIndoorBuildingFocused() =
@@ -941,17 +933,17 @@ class GoogleMapsViewImpl(
941
933
 
942
934
  override fun onInfoWindowClick(marker: Marker) =
943
935
  onUi {
944
- onInfoWindowPress?.invoke(marker.tag?.toString())
936
+ onInfoWindowPress?.invoke(marker.idTag)
945
937
  }
946
938
 
947
939
  override fun onInfoWindowClose(marker: Marker) =
948
940
  onUi {
949
- onInfoWindowClose?.invoke(marker.tag?.toString())
941
+ onInfoWindowClose?.invoke(marker.idTag)
950
942
  }
951
943
 
952
944
  override fun onInfoWindowLongClick(marker: Marker) =
953
945
  onUi {
954
- onInfoWindowLongPress?.invoke(marker.tag?.toString())
946
+ onInfoWindowLongPress?.invoke(marker.idTag)
955
947
  }
956
948
 
957
949
  override fun onMyLocationClick(location: Location) =
@@ -963,6 +955,10 @@ class GoogleMapsViewImpl(
963
955
  onUi {
964
956
  onMyLocationButtonPress?.invoke(true)
965
957
  }
966
- return false
958
+ return uiSettings?.consumeOnMyLocationButtonPress ?: false
967
959
  }
960
+
961
+ override fun getInfoContents(marker: Marker): View? = null
962
+
963
+ override fun getInfoWindow(marker: Marker): View? = markerBuilder.buildInfoWindow(marker.tagData.iconSvg)
968
964
  }
@@ -1,11 +1,15 @@
1
1
  package com.rngooglemapsplus
2
2
 
3
+ import MarkerTag
3
4
  import android.graphics.Bitmap
4
5
  import android.graphics.BitmapFactory
5
6
  import android.graphics.Canvas
6
7
  import android.graphics.Typeface
8
+ import android.graphics.drawable.PictureDrawable
7
9
  import android.util.Base64
8
10
  import android.util.LruCache
11
+ import android.widget.ImageView
12
+ import android.widget.LinearLayout
9
13
  import androidx.core.graphics.createBitmap
10
14
  import com.caverock.androidsvg.SVG
11
15
  import com.caverock.androidsvg.SVGExternalFileResolver
@@ -239,6 +243,10 @@ class MapMarkerBuilder(
239
243
  if (prev.zIndex != next.zIndex) {
240
244
  marker.zIndex = next.zIndex?.toFloat() ?: 0f
241
245
  }
246
+
247
+ if (prev.infoWindowIconSvg != next.infoWindowIconSvg) {
248
+ marker.tag = MarkerTag(id = next.id, iconSvg = next.infoWindowIconSvg)
249
+ }
242
250
  }
243
251
 
244
252
  fun buildIconAsync(
@@ -296,6 +304,31 @@ class MapMarkerBuilder(
296
304
  iconCache.evictAll()
297
305
  }
298
306
 
307
+ fun buildInfoWindow(iconSvg: RNMarkerSvg?): ImageView? {
308
+ val iconSvg = iconSvg ?: return null
309
+
310
+ val svgView =
311
+ ImageView(context).apply {
312
+ layoutParams =
313
+ LinearLayout.LayoutParams(
314
+ iconSvg.width.dpToPx().toInt(),
315
+ iconSvg.height.dpToPx().toInt(),
316
+ )
317
+ }
318
+
319
+ try {
320
+ val svg = SVG.getFromString(iconSvg.svgString)
321
+ svg.setDocumentWidth(iconSvg.width.dpToPx())
322
+ svg.setDocumentHeight(iconSvg.height.dpToPx())
323
+ val drawable = PictureDrawable(svg.renderToPicture())
324
+ svgView.setImageDrawable(drawable)
325
+ } catch (e: Exception) {
326
+ return null
327
+ }
328
+
329
+ return svgView
330
+ }
331
+
299
332
  private suspend fun renderBitmap(m: RNMarker): Bitmap? {
300
333
  m.iconSvg ?: return null
301
334
 
@@ -1,5 +1,6 @@
1
1
  package com.rngooglemapsplus
2
2
 
3
+ import MarkerTag
3
4
  import com.facebook.proguard.annotations.DoNotStrip
4
5
  import com.facebook.react.uimanager.ThemedReactContext
5
6
  import com.google.android.gms.maps.GoogleMapOptions
@@ -149,7 +150,14 @@ class RNGoogleMapsPlusView(
149
150
  when {
150
151
  prev == null ->
151
152
  markerBuilder.buildIconAsync(id, next) { icon ->
152
- view.addMarker(id, markerBuilder.build(next, icon))
153
+ view.addMarker(
154
+ id,
155
+ markerBuilder.build(next, icon),
156
+ MarkerTag(
157
+ id = id,
158
+ iconSvg = next.infoWindowIconSvg,
159
+ ),
160
+ )
153
161
  }
154
162
 
155
163
  !prev.markerEquals(next) ->
@@ -320,7 +328,7 @@ class RNGoogleMapsPlusView(
320
328
  view.onMapLongPress = cb
321
329
  }
322
330
 
323
- override var onMarkerPress: ((String?) -> Unit)? = null
331
+ override var onMarkerPress: ((String) -> Unit)? = null
324
332
  set(cb) {
325
333
  view.onMarkerPress = cb
326
334
  }
@@ -330,32 +338,32 @@ class RNGoogleMapsPlusView(
330
338
  view.onPoiPress = cb
331
339
  }
332
340
 
333
- override var onPolylinePress: ((String?) -> Unit)? = null
341
+ override var onPolylinePress: ((String) -> Unit)? = null
334
342
  set(cb) {
335
343
  view.onPolylinePress = cb
336
344
  }
337
345
 
338
- override var onPolygonPress: ((String?) -> Unit)? = null
346
+ override var onPolygonPress: ((String) -> Unit)? = null
339
347
  set(cb) {
340
348
  view.onPolygonPress = cb
341
349
  }
342
350
 
343
- override var onCirclePress: ((String?) -> Unit)? = null
351
+ override var onCirclePress: ((String) -> Unit)? = null
344
352
  set(cb) {
345
353
  view.onCirclePress = cb
346
354
  }
347
355
 
348
- override var onMarkerDragStart: ((String?, RNLatLng) -> Unit)? = null
356
+ override var onMarkerDragStart: ((String, RNLatLng) -> Unit)? = null
349
357
  set(cb) {
350
358
  view.onMarkerDragStart = cb
351
359
  }
352
360
 
353
- override var onMarkerDrag: ((String?, RNLatLng) -> Unit)? = null
361
+ override var onMarkerDrag: ((String, RNLatLng) -> Unit)? = null
354
362
  set(cb) {
355
363
  view.onMarkerDrag = cb
356
364
  }
357
365
 
358
- override var onMarkerDragEnd: ((String?, RNLatLng) -> Unit)? = null
366
+ override var onMarkerDragEnd: ((String, RNLatLng) -> Unit)? = null
359
367
  set(cb) {
360
368
  view.onMarkerDragEnd = cb
361
369
  }
@@ -370,17 +378,17 @@ class RNGoogleMapsPlusView(
370
378
  view.onIndoorLevelActivated = cb
371
379
  }
372
380
 
373
- override var onInfoWindowPress: ((String?) -> Unit)? = null
381
+ override var onInfoWindowPress: ((String) -> Unit)? = null
374
382
  set(cb) {
375
383
  view.onInfoWindowPress = cb
376
384
  }
377
385
 
378
- override var onInfoWindowClose: ((String?) -> Unit)? = null
386
+ override var onInfoWindowClose: ((String) -> Unit)? = null
379
387
  set(cb) {
380
388
  view.onInfoWindowClose = cb
381
389
  }
382
390
 
383
- override var onInfoWindowLongPress: ((String?) -> Unit)? = null
391
+ override var onInfoWindowLongPress: ((String) -> Unit)? = null
384
392
  set(cb) {
385
393
  view.onInfoWindowLongPress = cb
386
394
  }
@@ -410,6 +418,14 @@ class RNGoogleMapsPlusView(
410
418
  view.onCameraChangeComplete = cb
411
419
  }
412
420
 
421
+ override fun showMarkerInfoWindow(id: String) {
422
+ view.showMarkerInfoWindow(id)
423
+ }
424
+
425
+ override fun hideMarkerInfoWindow(id: String) {
426
+ view.hideMarkerInfoWindow(id)
427
+ }
428
+
413
429
  override fun setCamera(
414
430
  camera: RNCamera,
415
431
  animated: Boolean?,