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

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.
@@ -7,7 +7,6 @@ import PolylineTag
7
7
  import android.annotation.SuppressLint
8
8
  import android.graphics.Bitmap
9
9
  import android.location.Location
10
- import android.util.Base64
11
10
  import android.util.Size
12
11
  import android.view.View
13
12
  import android.widget.FrameLayout
@@ -38,6 +37,7 @@ import com.google.android.gms.maps.model.TileOverlay
38
37
  import com.google.android.gms.maps.model.TileOverlayOptions
39
38
  import com.google.maps.android.data.kml.KmlLayer
40
39
  import com.margelo.nitro.core.Promise
40
+ import com.rngooglemapsplus.extensions.encode
41
41
  import com.rngooglemapsplus.extensions.onUi
42
42
  import com.rngooglemapsplus.extensions.onUiSync
43
43
  import com.rngooglemapsplus.extensions.toGooglePriority
@@ -50,12 +50,10 @@ import com.rngooglemapsplus.extensions.toRnCamera
50
50
  import com.rngooglemapsplus.extensions.toRnLatLng
51
51
  import com.rngooglemapsplus.extensions.toRnLocation
52
52
  import com.rngooglemapsplus.extensions.toRnRegion
53
+ import com.rngooglemapsplus.extensions.withPaddingPixels
53
54
  import idTag
54
55
  import tagData
55
56
  import java.io.ByteArrayInputStream
56
- import java.io.ByteArrayOutputStream
57
- import java.io.File
58
- import java.io.FileOutputStream
59
57
  import java.nio.charset.StandardCharsets
60
58
 
61
59
  class GoogleMapsViewImpl(
@@ -427,56 +425,23 @@ class GoogleMapsViewImpl(
427
425
  durationMs: Int,
428
426
  ) = onUi {
429
427
  if (coordinates.isEmpty()) return@onUi
430
- val builder = LatLngBounds.Builder()
428
+
429
+ val w = mapView?.width ?: 0
430
+ val h = mapView?.height ?: 0
431
+
432
+ val builder = LatLngBounds.builder()
431
433
  coordinates.forEach { coord -> builder.include(coord.toLatLng()) }
432
- val bounds = builder.build()
433
-
434
- val latSpan = bounds.northeast.latitude - bounds.southwest.latitude
435
- val lngSpan = bounds.northeast.longitude - bounds.southwest.longitude
436
-
437
- val h = (mapView?.height ?: 0)
438
- val w = (mapView?.width ?: 0)
439
- val latPerPixel = if (h != 0) latSpan / h else 0.0
440
- val lngPerPixel = if (w != 0) lngSpan / w else 0.0
441
-
442
- builder.include(
443
- LatLng(
444
- bounds.northeast.latitude + (padding.top.dpToPx() * latPerPixel),
445
- bounds.northeast.longitude,
446
- ),
447
- )
448
- builder.include(
449
- LatLng(
450
- bounds.southwest.latitude - (padding.bottom.dpToPx() * latPerPixel),
451
- bounds.southwest.longitude,
452
- ),
453
- )
454
- builder.include(
455
- LatLng(
456
- bounds.northeast.latitude,
457
- bounds.northeast.longitude + (padding.right.dpToPx() * lngPerPixel),
458
- ),
459
- )
460
- builder.include(
461
- LatLng(
462
- bounds.southwest.latitude,
463
- bounds.southwest.longitude - (padding.left.dpToPx() * lngPerPixel),
464
- ),
465
- )
466
-
467
- val paddedBounds = builder.build()
434
+
435
+ val baseBounds = builder.build()
436
+ val paddedBounds = baseBounds.withPaddingPixels(w, h, padding)
437
+
468
438
  val adjustedWidth =
469
439
  (w - padding.left.dpToPx() - padding.right.dpToPx()).toInt().coerceAtLeast(0)
470
440
  val adjustedHeight =
471
441
  (h - padding.top.dpToPx() - padding.bottom.dpToPx()).toInt().coerceAtLeast(0)
472
442
 
473
- val update =
474
- CameraUpdateFactory.newLatLngBounds(
475
- paddedBounds,
476
- adjustedWidth,
477
- adjustedHeight,
478
- 0,
479
- )
443
+ val update = CameraUpdateFactory.newLatLngBounds(paddedBounds, adjustedWidth, adjustedHeight, 0)
444
+
480
445
  if (animated) {
481
446
  googleMap?.animateCamera(update, durationMs, null)
482
447
  } else {
@@ -512,30 +477,9 @@ class GoogleMapsViewImpl(
512
477
  val promise = Promise<String?>()
513
478
  onUi {
514
479
  googleMap?.snapshot { bitmap ->
515
- try {
516
- if (bitmap == null) {
517
- promise.resolve(null)
518
- return@snapshot
519
- }
520
- val scaledBitmap = size?.let { bitmap.scale(it.width, it.height) } ?: bitmap
521
- val output = ByteArrayOutputStream()
522
- scaledBitmap.compress(compressFormat, (quality * 100).toInt().coerceIn(0, 100), output)
523
- val bytes = output.toByteArray()
524
-
525
- if (resultIsFile) {
526
- val file = File(context.cacheDir, "map_snapshot_${System.currentTimeMillis()}.$format")
527
- FileOutputStream(file).use { it.write(bytes) }
528
- promise.resolve(file.absolutePath)
529
- } else {
530
- val base64 = Base64.encodeToString(bytes, Base64.NO_WRAP)
531
- promise.resolve("data:image/$format;base64,$base64")
532
- }
533
-
534
- if (scaledBitmap !== bitmap) scaledBitmap.recycle()
535
- bitmap.recycle()
536
- } catch (_: Exception) {
537
- promise.resolve(null)
538
- }
480
+ bitmap
481
+ ?.encode(context, size, format, compressFormat, quality, resultIsFile)
482
+ ?.let(promise::resolve) ?: promise.resolve(null)
539
483
  }
540
484
  }
541
485
  return promise
@@ -0,0 +1,35 @@
1
+ package com.rngooglemapsplus.extensions
2
+
3
+ import android.content.Context
4
+ import android.graphics.Bitmap
5
+ import android.util.Base64
6
+ import android.util.Size
7
+ import androidx.core.graphics.scale
8
+ import java.io.ByteArrayOutputStream
9
+ import java.io.File
10
+ import java.io.FileOutputStream
11
+
12
+ fun Bitmap.encode(
13
+ context: Context,
14
+ targetSize: Size?,
15
+ format: String,
16
+ compressFormat: Bitmap.CompressFormat,
17
+ quality: Double,
18
+ asFile: Boolean,
19
+ ): String? =
20
+ try {
21
+ targetSize?.let { scale(it.width, it.height) }
22
+ val output = ByteArrayOutputStream()
23
+ compress(compressFormat, (quality * 100).toInt().coerceIn(0, 100), output)
24
+ val bytes = output.toByteArray()
25
+
26
+ if (asFile) {
27
+ val file = File(context.cacheDir, "snapshot_${System.currentTimeMillis()}.$format")
28
+ FileOutputStream(file).use { it.write(bytes) }
29
+ file.absolutePath
30
+ } else {
31
+ "data:image/$format;base64," + Base64.encodeToString(bytes, Base64.NO_WRAP)
32
+ }
33
+ } catch (_: Exception) {
34
+ null
35
+ }
@@ -1,10 +1,41 @@
1
1
  package com.rngooglemapsplus.extensions
2
2
 
3
+ import com.facebook.react.uimanager.PixelUtil.dpToPx
4
+ import com.google.android.gms.maps.model.LatLng
3
5
  import com.google.android.gms.maps.model.LatLngBounds
4
6
  import com.rngooglemapsplus.RNLatLngBounds
7
+ import com.rngooglemapsplus.RNMapPadding
5
8
 
6
9
  fun LatLngBounds.toRnLatLngBounds(): RNLatLngBounds =
7
10
  RNLatLngBounds(
8
11
  northeast = northeast.toRnLatLng(),
9
12
  southwest = southwest.toRnLatLng(),
10
13
  )
14
+
15
+ fun LatLngBounds.withPaddingPixels(
16
+ mapWidthPx: Int,
17
+ mapHeightPx: Int,
18
+ padding: RNMapPadding,
19
+ ): LatLngBounds {
20
+ val latSpan = northeast.latitude - southwest.latitude
21
+ val lngSpan = northeast.longitude - southwest.longitude
22
+ if (latSpan == 0.0 && lngSpan == 0.0) return this
23
+
24
+ val latPerPixel = if (mapHeightPx != 0) latSpan / mapHeightPx else 0.0
25
+ val lngPerPixel = if (mapWidthPx != 0) lngSpan / mapWidthPx else 0.0
26
+
27
+ val builder = LatLngBounds.builder()
28
+ builder.include(
29
+ LatLng(
30
+ northeast.latitude + (padding.top.dpToPx() * latPerPixel),
31
+ northeast.longitude + (padding.right.dpToPx() * lngPerPixel),
32
+ ),
33
+ )
34
+ builder.include(
35
+ LatLng(
36
+ southwest.latitude - (padding.bottom.dpToPx() * latPerPixel),
37
+ southwest.longitude - (padding.left.dpToPx() * lngPerPixel),
38
+ ),
39
+ )
40
+ return builder.build()
41
+ }
@@ -288,7 +288,7 @@ GMSIndoorDisplayDelegate {
288
288
  @MainActor
289
289
  func showMarkerInfoWindow(id: String) {
290
290
  onMain {
291
- guard let marker = self.markersById[id] else { return }
291
+ guard let marker = self.markersById[id] else { return }
292
292
  self.mapView?.selectedMarker = nil
293
293
  self.mapView?.selectedMarker = marker
294
294
  }
@@ -399,42 +399,16 @@ GMSIndoorDisplayDelegate {
399
399
  mapView.layer.render(in: ctx.cgContext)
400
400
  }
401
401
 
402
- var finalImage = image
403
-
404
- size.map {
405
- UIGraphicsBeginImageContextWithOptions($0, false, 0.0)
406
- image.draw(in: CGRect(origin: .zero, size: $0))
407
- finalImage = UIGraphicsGetImageFromCurrentImageContext() ?? image
408
- UIGraphicsEndImageContext()
409
- }
410
-
411
- let data: Data?
412
- switch imageFormat {
413
- case .jpeg:
414
- data = finalImage.jpegData(compressionQuality: quality)
415
- case .png:
416
- data = finalImage.pngData()
417
- }
418
-
419
- guard let imageData = data else {
420
- promise.resolve(withResult: nil)
421
- return
422
- }
423
-
424
- if resultIsFile {
425
- let filename =
426
- "map_snapshot_\(Int(Date().timeIntervalSince1970)).\(format)"
427
- let fileURL = URL(fileURLWithPath: NSTemporaryDirectory())
428
- .appendingPathComponent(filename)
429
- do {
430
- try imageData.write(to: fileURL)
431
- promise.resolve(withResult: fileURL.path)
432
- } catch {
433
- promise.resolve(withResult: nil)
434
- }
402
+ if let result = image.encode(
403
+ targetSize: size,
404
+ format: format,
405
+ imageFormat: imageFormat,
406
+ quality: quality,
407
+ resultIsFile: resultIsFile
408
+ ) {
409
+ promise.resolve(withResult: result)
435
410
  } else {
436
- let base64 = imageData.base64EncodedString()
437
- promise.resolve(withResult: "data:image/\(format);base64,\(base64)")
411
+ promise.resolve(withResult: nil)
438
412
  }
439
413
  }
440
414
 
@@ -0,0 +1,45 @@
1
+ import UIKit
2
+
3
+ extension UIImage {
4
+ func encode(
5
+ targetSize: CGSize? = nil,
6
+ format: String = "png",
7
+ imageFormat: ImageFormat = .png,
8
+ quality: CGFloat = 1.0,
9
+ resultIsFile: Bool = false
10
+ ) -> String? {
11
+ var imageToEncode = self
12
+
13
+ if let targetSize = targetSize {
14
+ UIGraphicsBeginImageContextWithOptions(targetSize, false, 0.0)
15
+ self.draw(in: CGRect(origin: .zero, size: targetSize))
16
+ imageToEncode = UIGraphicsGetImageFromCurrentImageContext() ?? self
17
+ UIGraphicsEndImageContext()
18
+ }
19
+
20
+ let data: Data?
21
+ switch imageFormat {
22
+ case .jpeg:
23
+ data = imageToEncode.jpegData(compressionQuality: quality)
24
+ case .png:
25
+ data = imageToEncode.pngData()
26
+ }
27
+
28
+ guard let imageData = data else { return nil }
29
+
30
+ if resultIsFile {
31
+ let filename = "snapshot_\(Int(Date().timeIntervalSince1970)).\(format)"
32
+ let fileURL = FileManager.default.temporaryDirectory
33
+ .appendingPathComponent(filename)
34
+ do {
35
+ try imageData.write(to: fileURL)
36
+ return fileURL.path
37
+ } catch {
38
+ return nil
39
+ }
40
+ } else {
41
+ let base64 = imageData.base64EncodedString()
42
+ return "data:image/\(format);base64,\(base64)"
43
+ }
44
+ }
45
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-google-maps-plus",
3
- "version": "1.7.0-dev.10",
3
+ "version": "1.7.0-dev.12",
4
4
  "description": "React Native wrapper for Android & iOS Google Maps SDK",
5
5
  "main": "./lib/module/index.js",
6
6
  "module": "./lib/module/index.js",