react-native-google-maps-plus 1.3.0-dev.2 → 1.3.0-dev.4

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 (52) hide show
  1. package/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt +92 -8
  2. package/android/src/main/java/com/rngooglemapsplus/LocationHandler.kt +0 -1
  3. package/android/src/main/java/com/rngooglemapsplus/RNGoogleMapsPlusView.kt +52 -9
  4. package/android/src/main/java/com/rngooglemapsplus/extensions/RNLatLngBoundsExtension.kt +17 -0
  5. package/android/src/main/java/com/rngooglemapsplus/extensions/RNSize.kt +7 -0
  6. package/android/src/main/java/com/rngooglemapsplus/extensions/RNSnapshotFormat.kt +16 -0
  7. package/android/src/main/java/com/rngooglemapsplus/extensions/RNSnapshotResultType.kt +9 -0
  8. package/ios/GoogleMapViewImpl.swift +285 -145
  9. package/ios/RNGoogleMapsPlusView.swift +86 -38
  10. package/ios/extensions/RNLatLngBounds+Extension.swift +16 -0
  11. package/ios/extensions/RNSize+Extension.swift +7 -0
  12. package/ios/extensions/RNSnapshotFormat+Extension.swift +28 -0
  13. package/ios/extensions/RNSnapshotResultType+Extension.swift +12 -0
  14. package/lib/module/types.js.map +1 -1
  15. package/lib/typescript/src/RNGoogleMapsPlusView.nitro.d.ts +6 -3
  16. package/lib/typescript/src/RNGoogleMapsPlusView.nitro.d.ts.map +1 -1
  17. package/lib/typescript/src/types.d.ts +13 -1
  18. package/lib/typescript/src/types.d.ts.map +1 -1
  19. package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusViewSpec.cpp +51 -7
  20. package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusViewSpec.hpp +5 -2
  21. package/nitrogen/generated/android/c++/JRNLatLngBounds.hpp +58 -0
  22. package/nitrogen/generated/android/c++/JRNSize.hpp +57 -0
  23. package/nitrogen/generated/android/c++/JRNSnapshotFormat.hpp +62 -0
  24. package/nitrogen/generated/android/c++/JRNSnapshotOptions.hpp +71 -0
  25. package/nitrogen/generated/android/c++/JRNSnapshotResultType.hpp +59 -0
  26. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/HybridRNGoogleMapsPlusViewSpec.kt +14 -2
  27. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNLatLngBounds.kt +32 -0
  28. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNSize.kt +32 -0
  29. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNSnapshotFormat.kt +22 -0
  30. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNSnapshotOptions.kt +38 -0
  31. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNSnapshotResultType.kt +21 -0
  32. package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Bridge.hpp +57 -0
  33. package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Umbrella.hpp +15 -0
  34. package/nitrogen/generated/ios/c++/HybridRNGoogleMapsPlusViewSpecSwift.hpp +40 -5
  35. package/nitrogen/generated/ios/c++/views/HybridRNGoogleMapsPlusViewComponent.mm +7 -0
  36. package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusViewSpec.swift +5 -2
  37. package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusViewSpec_cxx.swift +58 -4
  38. package/nitrogen/generated/ios/swift/RNLatLngBounds.swift +46 -0
  39. package/nitrogen/generated/ios/swift/RNSize.swift +46 -0
  40. package/nitrogen/generated/ios/swift/RNSnapshotFormat.swift +44 -0
  41. package/nitrogen/generated/ios/swift/RNSnapshotOptions.swift +87 -0
  42. package/nitrogen/generated/ios/swift/RNSnapshotResultType.swift +40 -0
  43. package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusViewSpec.cpp +3 -0
  44. package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusViewSpec.hpp +12 -3
  45. package/nitrogen/generated/shared/c++/RNLatLngBounds.hpp +72 -0
  46. package/nitrogen/generated/shared/c++/RNSize.hpp +71 -0
  47. package/nitrogen/generated/shared/c++/RNSnapshotFormat.hpp +80 -0
  48. package/nitrogen/generated/shared/c++/RNSnapshotOptions.hpp +87 -0
  49. package/nitrogen/generated/shared/c++/RNSnapshotResultType.hpp +76 -0
  50. package/package.json +1 -1
  51. package/src/RNGoogleMapsPlusView.nitro.ts +15 -2
  52. package/src/types.ts +24 -2
@@ -1,8 +1,12 @@
1
1
  package com.rngooglemapsplus
2
2
 
3
3
  import android.annotation.SuppressLint
4
+ import android.graphics.Bitmap
4
5
  import android.location.Location
6
+ import android.util.Base64
7
+ import android.util.Size
5
8
  import android.widget.FrameLayout
9
+ import androidx.core.graphics.scale
6
10
  import com.facebook.react.bridge.LifecycleEventListener
7
11
  import com.facebook.react.bridge.UiThreadUtil
8
12
  import com.facebook.react.uimanager.PixelUtil.dpToPx
@@ -29,11 +33,15 @@ import com.google.android.gms.maps.model.PolylineOptions
29
33
  import com.google.android.gms.maps.model.TileOverlay
30
34
  import com.google.android.gms.maps.model.TileOverlayOptions
31
35
  import com.google.maps.android.data.kml.KmlLayer
36
+ import com.margelo.nitro.core.Promise
32
37
  import com.rngooglemapsplus.extensions.toGooglePriority
33
38
  import com.rngooglemapsplus.extensions.toLocationErrorCode
34
39
  import com.rngooglemapsplus.extensions.toRNIndoorBuilding
35
40
  import com.rngooglemapsplus.extensions.toRNIndoorLevel
36
41
  import java.io.ByteArrayInputStream
42
+ import java.io.ByteArrayOutputStream
43
+ import java.io.File
44
+ import java.io.FileOutputStream
37
45
  import java.nio.charset.StandardCharsets
38
46
 
39
47
  class GoogleMapsViewImpl(
@@ -145,9 +153,9 @@ class GoogleMapsViewImpl(
145
153
  }
146
154
  initLocationCallbacks()
147
155
  applyPending()
156
+ mapReady = true
157
+ onMapReady?.invoke(true)
148
158
  }
149
- mapReady = true
150
- onMapReady?.invoke(true)
151
159
  }
152
160
 
153
161
  override fun onCameraMoveStarted(reason: Int) {
@@ -188,6 +196,8 @@ class GoogleMapsViewImpl(
188
196
  if (cameraPosition == lastSubmittedCameraPosition) {
189
197
  return
190
198
  }
199
+ lastSubmittedCameraPosition = cameraPosition
200
+
191
201
  val isGesture = GoogleMap.OnCameraMoveStartedListener.REASON_GESTURE == cameraMoveReason
192
202
 
193
203
  val latDelta = bounds.northeast.latitude - bounds.southwest.latitude
@@ -207,7 +217,6 @@ class GoogleMapsViewImpl(
207
217
  ),
208
218
  isGesture,
209
219
  )
210
- lastSubmittedCameraPosition = cameraPosition
211
220
  }
212
221
 
213
222
  override fun onCameraIdle() {
@@ -363,6 +372,8 @@ class GoogleMapsViewImpl(
363
372
  }
364
373
  }
365
374
 
375
+ var initialProps: RNInitialProps? = null
376
+
366
377
  var uiSettings: RNMapUiSettings? = null
367
378
  set(value) {
368
379
  field = value
@@ -503,7 +514,7 @@ class GoogleMapsViewImpl(
503
514
  fun setCamera(
504
515
  cameraPosition: CameraPosition,
505
516
  animated: Boolean,
506
- durationMS: Int,
517
+ durationMs: Int,
507
518
  ) {
508
519
  onUi {
509
520
  val current = googleMap?.cameraPosition
@@ -514,7 +525,7 @@ class GoogleMapsViewImpl(
514
525
  val update = CameraUpdateFactory.newCameraPosition(cameraPosition)
515
526
 
516
527
  if (animated) {
517
- googleMap?.animateCamera(update, durationMS, null)
528
+ googleMap?.animateCamera(update, durationMs, null)
518
529
  } else {
519
530
  googleMap?.moveCamera(update)
520
531
  }
@@ -525,7 +536,7 @@ class GoogleMapsViewImpl(
525
536
  coordinates: Array<RNLatLng>,
526
537
  padding: RNMapPadding,
527
538
  animated: Boolean,
528
- durationMS: Int,
539
+ durationMs: Int,
529
540
  ) {
530
541
  if (coordinates.isEmpty()) {
531
542
  return
@@ -583,13 +594,85 @@ class GoogleMapsViewImpl(
583
594
  0,
584
595
  )
585
596
  if (animated) {
586
- googleMap?.animateCamera(update, durationMS, null)
597
+ googleMap?.animateCamera(update, durationMs, null)
587
598
  } else {
588
599
  googleMap?.moveCamera(update)
589
600
  }
590
601
  }
591
602
  }
592
603
 
604
+ fun setCameraBounds(bounds: LatLngBounds?) {
605
+ onUi {
606
+ googleMap?.setLatLngBoundsForCameraTarget(bounds)
607
+ }
608
+ }
609
+
610
+ fun animateToBounds(
611
+ bounds: LatLngBounds,
612
+ padding: Int,
613
+ durationMs: Int,
614
+ lockBounds: Boolean,
615
+ ) {
616
+ onUi {
617
+ if (lockBounds) {
618
+ googleMap?.setLatLngBoundsForCameraTarget(bounds)
619
+ }
620
+ val update =
621
+ CameraUpdateFactory.newLatLngBounds(
622
+ bounds,
623
+ padding,
624
+ )
625
+ googleMap?.animateCamera(update, durationMs, null)
626
+ }
627
+ }
628
+
629
+ fun snapshot(
630
+ size: Size?,
631
+ format: String,
632
+ compressFormat: Bitmap.CompressFormat,
633
+ quality: Double,
634
+ resultIsFile: Boolean,
635
+ ): Promise<String?> {
636
+ val promise = Promise<String?>()
637
+ onUi {
638
+ googleMap?.snapshot { bitmap ->
639
+ try {
640
+ if (bitmap == null) {
641
+ promise.resolve(null)
642
+ return@snapshot
643
+ }
644
+
645
+ val scaledBitmap =
646
+ size?.let {
647
+ bitmap.scale(it.width, it.height)
648
+ } ?: bitmap
649
+
650
+ val output = ByteArrayOutputStream()
651
+ scaledBitmap.compress(compressFormat, (quality * 100).toInt().coerceIn(0, 100), output)
652
+ val bytes = output.toByteArray()
653
+
654
+ if (resultIsFile) {
655
+ val file = File(context.cacheDir, "map_snapshot_${System.currentTimeMillis()}.$format")
656
+ FileOutputStream(file).use { it.write(bytes) }
657
+ promise.resolve(file.absolutePath)
658
+ } else {
659
+ val base64 = Base64.encodeToString(bytes, Base64.NO_WRAP)
660
+ promise.resolve("data:image/$format;base64,$base64")
661
+ }
662
+
663
+ if (scaledBitmap != bitmap) {
664
+ scaledBitmap.recycle()
665
+ }
666
+ bitmap.recycle()
667
+ } catch (e: Exception) {
668
+ promise.resolve(null)
669
+ }
670
+ }
671
+ }
672
+
673
+ return promise
674
+ }
675
+
593
676
  fun addMarker(
594
677
  id: String,
595
678
  opts: MarkerOptions,
@@ -894,6 +977,7 @@ class GoogleMapsViewImpl(
894
977
 
895
978
  fun destroyInternal() {
896
979
  onUi {
980
+ locationHandler.stop()
897
981
  markerBuilder.cancelAllJobs()
898
982
  clearMarkers()
899
983
  clearPolylines()
@@ -901,7 +985,6 @@ class GoogleMapsViewImpl(
901
985
  clearCircles()
902
986
  clearHeatmaps()
903
987
  clearKmlLayer()
904
- locationHandler.stop()
905
988
  googleMap?.apply {
906
989
  setOnCameraMoveStartedListener(null)
907
990
  setOnCameraMoveListener(null)
@@ -922,6 +1005,7 @@ class GoogleMapsViewImpl(
922
1005
  }
923
1006
  super.removeAllViews()
924
1007
  reactContext.removeLifecycleEventListener(this)
1008
+ initialized = false
925
1009
  }
926
1010
  }
927
1011
 
@@ -131,7 +131,6 @@ class LocationHandler(
131
131
 
132
132
  private fun restartLocationUpdates() {
133
133
  stop()
134
- // 4) Google Play Services checken – früh zurückmelden
135
134
  val playServicesStatus =
136
135
  GoogleApiAvailability
137
136
  .getInstance()
@@ -6,16 +6,22 @@ import com.facebook.react.uimanager.ThemedReactContext
6
6
  import com.google.android.gms.maps.model.MapStyleOptions
7
7
  import com.margelo.nitro.core.Promise
8
8
  import com.rngooglemapsplus.extensions.circleEquals
9
+ import com.rngooglemapsplus.extensions.isFileResult
9
10
  import com.rngooglemapsplus.extensions.markerEquals
10
11
  import com.rngooglemapsplus.extensions.polygonEquals
11
12
  import com.rngooglemapsplus.extensions.polylineEquals
12
13
  import com.rngooglemapsplus.extensions.toCameraPosition
14
+ import com.rngooglemapsplus.extensions.toCompressFormat
15
+ import com.rngooglemapsplus.extensions.toFileExtension
16
+ import com.rngooglemapsplus.extensions.toLatLngBounds
13
17
  import com.rngooglemapsplus.extensions.toMapColorScheme
18
+ import com.rngooglemapsplus.extensions.toSize
14
19
 
15
20
  @DoNotStrip
16
21
  class RNGoogleMapsPlusView(
17
22
  val context: ThemedReactContext,
18
23
  ) : HybridRNGoogleMapsPlusViewSpec() {
24
+ private var propsInitialized = false
19
25
  private var currentCustomMapStyle: String? = null
20
26
  private var permissionHandler = PermissionHandler(context)
21
27
  private var locationHandler = LocationHandler(context)
@@ -30,15 +36,23 @@ class RNGoogleMapsPlusView(
30
36
  override val view =
31
37
  GoogleMapsViewImpl(context, locationHandler, playServiceHandler, markerBuilder)
32
38
 
39
+ override fun afterUpdate() {
40
+ super.afterUpdate()
41
+ if (!propsInitialized) {
42
+ propsInitialized = true
43
+ view.initMapView(
44
+ initialProps?.mapId,
45
+ initialProps?.liteMode,
46
+ initialProps?.camera?.toCameraPosition(),
47
+ )
48
+ }
49
+ }
50
+
33
51
  override var initialProps: RNInitialProps? = null
34
52
  set(value) {
35
53
  if (field == value) return
36
54
  field = value
37
- view.initMapView(
38
- value?.mapId,
39
- value?.liteMode,
40
- value?.camera?.toCameraPosition(),
41
- )
55
+ view.initialProps = value
42
56
  }
43
57
 
44
58
  override var uiSettings: RNMapUiSettings? = null
@@ -343,25 +357,54 @@ class RNGoogleMapsPlusView(
343
357
  override fun setCamera(
344
358
  camera: RNCamera,
345
359
  animated: Boolean?,
346
- durationMS: Double?,
360
+ durationMs: Double?,
347
361
  ) {
348
- view.setCamera(camera.toCameraPosition(), animated == true, durationMS?.toInt() ?: 3000)
362
+ view.setCamera(camera.toCameraPosition(), animated == true, durationMs?.toInt() ?: 3000)
349
363
  }
350
364
 
351
365
  override fun setCameraToCoordinates(
352
366
  coordinates: Array<RNLatLng>,
353
367
  padding: RNMapPadding?,
354
368
  animated: Boolean?,
355
- durationMS: Double?,
369
+ durationMs: Double?,
356
370
  ) {
357
371
  view.setCameraToCoordinates(
358
372
  coordinates,
359
373
  padding = padding ?: RNMapPadding(0.0, 0.0, 0.0, 0.0),
360
374
  animated == true,
361
- durationMS?.toInt() ?: 3000,
375
+ durationMs?.toInt() ?: 3000,
376
+ )
377
+ }
378
+
379
+ override fun setCameraBounds(bounds: RNLatLngBounds?) {
380
+ view.setCameraBounds(
381
+ bounds?.toLatLngBounds(),
382
+ )
383
+ }
384
+
385
+ override fun animateToBounds(
386
+ bounds: RNLatLngBounds,
387
+ padding: Double?,
388
+ durationMs: Double?,
389
+ lockBounds: Boolean?,
390
+ ) {
391
+ view.animateToBounds(
392
+ bounds.toLatLngBounds(),
393
+ padding = padding?.toInt() ?: 0,
394
+ durationMs?.toInt() ?: 3000,
395
+ lockBounds = false,
362
396
  )
363
397
  }
364
398
 
399
+ override fun snapshot(options: RNSnapshotOptions): Promise<String?> =
400
+ view.snapshot(
401
+ size = options.size.toSize(),
402
+ format = options.format.toFileExtension(),
403
+ compressFormat = options.format.toCompressFormat(),
404
+ quality = options.quality,
405
+ resultIsFile = options.resultType.isFileResult(),
406
+ )
407
+
365
408
  override fun showLocationDialog() {
366
409
  locationHandler.showLocationDialog()
367
410
  }
@@ -0,0 +1,17 @@
1
+ package com.rngooglemapsplus.extensions
2
+
3
+ import com.google.android.gms.maps.model.LatLng
4
+ import com.google.android.gms.maps.model.LatLngBounds
5
+ import com.rngooglemapsplus.RNLatLngBounds
6
+
7
+ fun RNLatLngBounds.toLatLngBounds(): LatLngBounds =
8
+ LatLngBounds(
9
+ LatLng(
10
+ southWest.latitude,
11
+ southWest.longitude,
12
+ ),
13
+ LatLng(
14
+ northEast.latitude,
15
+ northEast.longitude,
16
+ ),
17
+ )
@@ -0,0 +1,7 @@
1
+ package com.rngooglemapsplus.extensions
2
+
3
+ import android.util.Size
4
+ import com.facebook.react.uimanager.PixelUtil.dpToPx
5
+ import com.rngooglemapsplus.RNSize
6
+
7
+ fun RNSize?.toSize(): Size? = this?.let { Size(width.dpToPx().toInt(), height.dpToPx().toInt()) }
@@ -0,0 +1,16 @@
1
+ package com.rngooglemapsplus.extensions
2
+
3
+ import android.graphics.Bitmap
4
+ import com.rngooglemapsplus.RNSnapshotFormat
5
+
6
+ fun RNSnapshotFormat?.toCompressFormat(): Bitmap.CompressFormat =
7
+ when (this) {
8
+ RNSnapshotFormat.JPG, RNSnapshotFormat.JPEG -> Bitmap.CompressFormat.JPEG
9
+ RNSnapshotFormat.PNG, null -> Bitmap.CompressFormat.PNG
10
+ }
11
+
12
+ fun RNSnapshotFormat?.toFileExtension(): String =
13
+ when (this) {
14
+ RNSnapshotFormat.JPG, RNSnapshotFormat.JPEG -> "jpg"
15
+ RNSnapshotFormat.PNG, null -> "png"
16
+ }
@@ -0,0 +1,9 @@
1
+ package com.rngooglemapsplus.extensions
2
+
3
+ import com.rngooglemapsplus.RNSnapshotResultType
4
+
5
+ fun RNSnapshotResultType?.isFileResult(): Boolean =
6
+ when (this) {
7
+ RNSnapshotResultType.FILE -> true
8
+ RNSnapshotResultType.BASE64, null -> false
9
+ }