react-native-google-maps-plus 1.7.0 → 1.8.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 (66) hide show
  1. package/android/build.gradle +1 -1
  2. package/android/gradle.properties +2 -1
  3. package/android/src/main/java/com/rngooglemapsplus/MapCircleBuilder.kt +2 -3
  4. package/android/src/main/java/com/rngooglemapsplus/MapMarkerBuilder.kt +51 -54
  5. package/android/src/main/java/com/rngooglemapsplus/MapPolygonBuilder.kt +6 -23
  6. package/android/src/main/java/com/rngooglemapsplus/MapPolylineBuilder.kt.kt +12 -39
  7. package/android/src/main/java/com/rngooglemapsplus/RNGoogleMapsPlusView.kt +4 -2
  8. package/android/src/main/java/com/rngooglemapsplus/extensions/{RNCameraExtension.kt → RNCameraUpdateExtension.kt} +2 -2
  9. package/android/src/main/java/com/rngooglemapsplus/extensions/RNLineCapTypeExtension.kt +14 -0
  10. package/android/src/main/java/com/rngooglemapsplus/extensions/RNLineJoinTypeExtension.kt +12 -0
  11. package/android/src/main/java/com/rngooglemapsplus/extensions/RNMapCircleExtension.kt +7 -1
  12. package/android/src/main/java/com/rngooglemapsplus/extensions/RNMarkerExtension.kt +54 -17
  13. package/android/src/main/java/com/rngooglemapsplus/extensions/RNPolygonExtension.kt +31 -1
  14. package/android/src/main/java/com/rngooglemapsplus/extensions/RNPolylineExtension.kt +6 -1
  15. package/ios/GoogleMapViewImpl.swift +4 -1
  16. package/ios/LocationHandler.swift +3 -1
  17. package/ios/MapCircleBuilder.swift +2 -3
  18. package/ios/MapHelper.swift +3 -5
  19. package/ios/MapMarkerBuilder.swift +108 -105
  20. package/ios/MapPolygonBuilder.swift +6 -41
  21. package/ios/MapPolylineBuilder.swift +2 -10
  22. package/ios/RNGoogleMapsPlusView.swift +28 -22
  23. package/ios/extensions/{RNCamera+Extension.swift → RNCameraUpdate+Extension.swift} +1 -1
  24. package/ios/extensions/RNCircle+Extension.swift +14 -5
  25. package/ios/extensions/RNLatLng+Extension.swift +11 -0
  26. package/ios/extensions/RNLineCapType+Extension.swift +10 -0
  27. package/ios/extensions/RNLineJoinType+Extension.swift +11 -0
  28. package/ios/extensions/RNMarker+Extension.swift +43 -12
  29. package/ios/extensions/RNPolygon+Extension.swift.swift +50 -21
  30. package/ios/extensions/RNPolyline+Extension.swift.swift +15 -26
  31. package/ios/extensions/SVGKImage+Extension.swift +22 -0
  32. package/lib/module/types.js.map +1 -1
  33. package/lib/typescript/src/RNGoogleMapsPlusView.nitro.d.ts +2 -2
  34. package/lib/typescript/src/RNGoogleMapsPlusView.nitro.d.ts.map +1 -1
  35. package/lib/typescript/src/types.d.ts +8 -2
  36. package/lib/typescript/src/types.d.ts.map +1 -1
  37. package/nitrogen/generated/android/c++/JFunc_void_RNRegion_RNCamera.hpp +0 -1
  38. package/nitrogen/generated/android/c++/JFunc_void_RNRegion_RNCamera_bool.hpp +0 -1
  39. package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusViewSpec.cpp +11 -7
  40. package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusViewSpec.hpp +1 -1
  41. package/nitrogen/generated/android/c++/JRNCamera.hpp +15 -16
  42. package/nitrogen/generated/android/c++/JRNCameraUpdate.hpp +71 -0
  43. package/nitrogen/generated/android/c++/JRNInitialProps.hpp +11 -7
  44. package/nitrogen/generated/android/c++/JRNMarker.hpp +1 -5
  45. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/HybridRNGoogleMapsPlusViewSpec.kt +1 -1
  46. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNCamera.kt +5 -5
  47. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNCameraUpdate.kt +46 -0
  48. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNInitialProps.kt +6 -3
  49. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNMarker.kt +2 -5
  50. package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Bridge.hpp +10 -7
  51. package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Umbrella.hpp +3 -0
  52. package/nitrogen/generated/ios/c++/HybridRNGoogleMapsPlusViewSpecSwift.hpp +7 -4
  53. package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusViewSpec.swift +1 -1
  54. package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusViewSpec_cxx.swift +1 -1
  55. package/nitrogen/generated/ios/swift/RNCamera.swift +14 -62
  56. package/nitrogen/generated/ios/swift/RNCameraUpdate.swift +116 -0
  57. package/nitrogen/generated/ios/swift/RNInitialProps.swift +36 -6
  58. package/nitrogen/generated/ios/swift/RNMarker.swift +1 -31
  59. package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusViewSpec.hpp +4 -1
  60. package/nitrogen/generated/shared/c++/RNCamera.hpp +17 -18
  61. package/nitrogen/generated/shared/c++/RNCameraUpdate.hpp +89 -0
  62. package/nitrogen/generated/shared/c++/RNInitialProps.hpp +12 -8
  63. package/nitrogen/generated/shared/c++/RNMarker.hpp +1 -5
  64. package/package.json +1 -1
  65. package/src/RNGoogleMapsPlusView.nitro.ts +6 -1
  66. package/src/types.ts +9 -2
@@ -136,6 +136,6 @@ dependencies {
136
136
  implementation "com.google.android.gms:play-services-base:${getExtOrDefault('googlePlayServicesBaseVersion')}"
137
137
  implementation "com.google.android.gms:play-services-maps:${getExtOrDefault('googlePlayServicesMapsVersion')}"
138
138
  implementation "com.google.android.gms:play-services-location:${getExtOrDefault('googlePlayServicesLocationVersion')}"
139
- implementation 'com.google.maps.android:android-maps-utils:3.10.0'
139
+ implementation "com.google.maps.android:android-maps-utils:${getExtOrDefault('mapsUtilsVersion')}"
140
140
  implementation 'com.caverock:androidsvg-aar:1.4'
141
141
  }
@@ -3,6 +3,7 @@ RNGoogleMapsPlus_minSdkVersion=26
3
3
  RNGoogleMapsPlus_targetSdkVersion=36
4
4
  RNGoogleMapsPlus_compileSdkVersion=36
5
5
  RNGoogleMapsPlus_ndkVersion=27.1.12297006
6
- RNGoogleMapsPlus_googlePlayServicesBaseVersion=18.8.0
6
+ RNGoogleMapsPlus_googlePlayServicesBaseVersion=18.9.0
7
7
  RNGoogleMapsPlus_googlePlayServicesMapsVersion=19.2.0
8
8
  RNGoogleMapsPlus_googlePlayServicesLocationVersion=21.3.0
9
+ RNGoogleMapsPlus_mapsUtilsVersion=3.19.0
@@ -4,6 +4,7 @@ import android.graphics.Color
4
4
  import com.facebook.react.uimanager.PixelUtil.dpToPx
5
5
  import com.google.android.gms.maps.model.Circle
6
6
  import com.google.android.gms.maps.model.CircleOptions
7
+ import com.rngooglemapsplus.extensions.centerEquals
7
8
  import com.rngooglemapsplus.extensions.onUi
8
9
  import com.rngooglemapsplus.extensions.toColor
9
10
  import com.rngooglemapsplus.extensions.toLatLng
@@ -25,9 +26,7 @@ class MapCircleBuilder {
25
26
  next: RNCircle,
26
27
  circle: Circle,
27
28
  ) = onUi {
28
- if (prev.center.latitude != next.center.latitude ||
29
- prev.center.longitude != next.center.longitude
30
- ) {
29
+ if (!prev.centerEquals(next)) {
31
30
  circle.center = next.center.toLatLng()
32
31
  }
33
32
 
@@ -19,6 +19,10 @@ import com.google.android.gms.maps.model.BitmapDescriptor
19
19
  import com.google.android.gms.maps.model.BitmapDescriptorFactory
20
20
  import com.google.android.gms.maps.model.Marker
21
21
  import com.google.android.gms.maps.model.MarkerOptions
22
+ import com.rngooglemapsplus.extensions.anchorEquals
23
+ import com.rngooglemapsplus.extensions.coordinatesEquals
24
+ import com.rngooglemapsplus.extensions.infoWindowAnchorEquals
25
+ import com.rngooglemapsplus.extensions.markerInfoWindowStyleEquals
22
26
  import com.rngooglemapsplus.extensions.markerStyleEquals
23
27
  import com.rngooglemapsplus.extensions.onUi
24
28
  import com.rngooglemapsplus.extensions.styleHash
@@ -73,7 +77,10 @@ class MapMarkerBuilder(
73
77
  val height = (svg.documentHeight.takeIf { it > 0 } ?: 128f).toInt()
74
78
 
75
79
  createBitmap(width, height).apply {
76
- Canvas(this).also(svg::renderToCanvas)
80
+ density = context.resources.displayMetrics.densityDpi
81
+ Canvas(this).also {
82
+ svg.renderToCanvas(it)
83
+ }
77
84
  }
78
85
  }
79
86
 
@@ -94,10 +101,12 @@ class MapMarkerBuilder(
94
101
  val innerSvg = SVG.getFromString(svgText)
95
102
  val w = innerSvg.documentWidth.takeIf { it > 0 } ?: 128f
96
103
  val h = innerSvg.documentHeight.takeIf { it > 0 } ?: 128f
97
- val bmp = createBitmap(w.toInt(), h.toInt())
98
- val canvas = Canvas(bmp)
99
- innerSvg.renderToCanvas(canvas)
100
- bmp
104
+ createBitmap(w.toInt(), h.toInt()).apply {
105
+ density = context.resources.displayMetrics.densityDpi
106
+ Canvas(this).also {
107
+ innerSvg.renderToCanvas(it)
108
+ }
109
+ }
101
110
  } else {
102
111
  conn.inputStream.use { BitmapFactory.decodeStream(it) }
103
112
  }
@@ -169,51 +178,39 @@ class MapMarkerBuilder(
169
178
  next: RNMarker,
170
179
  marker: Marker,
171
180
  ) = onUi {
172
- if (prev.coordinate.latitude != next.coordinate.latitude ||
173
- prev.coordinate.longitude != next.coordinate.longitude
174
- ) {
181
+ if (!prev.coordinatesEquals(next)) {
175
182
  marker.position = next.coordinate.toLatLng()
176
183
  }
177
184
 
178
185
  if (!prev.markerStyleEquals(next)) {
179
- buildIconAsync(marker.id, next) { icon ->
186
+ buildIconAsync(next) { icon ->
180
187
  marker.setIcon(icon)
181
- if (prev.infoWindowAnchor?.x != next.infoWindowAnchor?.x ||
182
- prev.infoWindowAnchor?.y != next.infoWindowAnchor?.y
183
- ) {
184
- marker.setInfoWindowAnchor(
185
- (next.infoWindowAnchor?.x ?: 0.5f).toFloat(),
186
- (next.infoWindowAnchor?.y ?: 0f).toFloat(),
187
- )
188
- }
189
-
190
- if (prev.anchor?.x != next.anchor?.x ||
191
- prev.anchor?.y != next.anchor?.y
192
- ) {
188
+ if (!prev.anchorEquals(next)) {
193
189
  marker.setAnchor(
194
190
  (next.anchor?.x ?: 0.5f).toFloat(),
195
191
  (next.anchor?.y ?: 1.0f).toFloat(),
196
192
  )
197
193
  }
194
+ if (!prev.infoWindowAnchorEquals(next)) {
195
+ marker.setInfoWindowAnchor(
196
+ (next.infoWindowAnchor?.x ?: 0.5f).toFloat(),
197
+ (next.infoWindowAnchor?.y ?: 0f).toFloat(),
198
+ )
199
+ }
198
200
  }
199
201
  } else {
200
- if (prev.infoWindowAnchor?.x != next.infoWindowAnchor?.x ||
201
- prev.infoWindowAnchor?.y != next.infoWindowAnchor?.y
202
- ) {
203
- marker.setInfoWindowAnchor(
204
- (next.infoWindowAnchor?.x ?: 0.5f).toFloat(),
205
- (next.infoWindowAnchor?.y ?: 0f).toFloat(),
206
- )
207
- }
208
-
209
- if (prev.anchor?.x != next.anchor?.x ||
210
- prev.anchor?.y != next.anchor?.y
211
- ) {
202
+ if (!prev.anchorEquals(next)) {
212
203
  marker.setAnchor(
213
204
  (next.anchor?.x ?: 0.5f).toFloat(),
214
205
  (next.anchor?.y ?: 1.0f).toFloat(),
215
206
  )
216
207
  }
208
+ if (!prev.infoWindowAnchorEquals(next)) {
209
+ marker.setInfoWindowAnchor(
210
+ (next.infoWindowAnchor?.x ?: 0.5f).toFloat(),
211
+ (next.infoWindowAnchor?.y ?: 0f).toFloat(),
212
+ )
213
+ }
217
214
  }
218
215
 
219
216
  if (prev.title != next.title) {
@@ -244,17 +241,16 @@ class MapMarkerBuilder(
244
241
  marker.zIndex = next.zIndex?.toFloat() ?: 0f
245
242
  }
246
243
 
247
- if (prev.infoWindowIconSvg != next.infoWindowIconSvg) {
244
+ if (!prev.markerInfoWindowStyleEquals(next)) {
248
245
  marker.tag = MarkerTag(id = next.id, iconSvg = next.infoWindowIconSvg)
249
246
  }
250
247
  }
251
248
 
252
249
  fun buildIconAsync(
253
- id: String,
254
250
  m: RNMarker,
255
251
  onReady: (BitmapDescriptor?) -> Unit,
256
252
  ) {
257
- jobsById[id]?.cancel()
253
+ jobsById[m.id]?.cancel()
258
254
 
259
255
  m.iconSvg ?: return onReady(null)
260
256
 
@@ -283,11 +279,11 @@ class MapMarkerBuilder(
283
279
  iconCache.evictAll()
284
280
  } catch (_: Throwable) {
285
281
  } finally {
286
- jobsById.remove(id)
282
+ jobsById.remove(m.id)
287
283
  }
288
284
  }
289
285
 
290
- jobsById[id] = job
286
+ jobsById[m.id] = job
291
287
  }
292
288
 
293
289
  fun cancelIconJob(id: String) {
@@ -337,27 +333,28 @@ class MapMarkerBuilder(
337
333
  coroutineContext.ensureActive()
338
334
  val svg = SVG.getFromString(m.iconSvg.svgString)
339
335
 
340
- coroutineContext.ensureActive()
341
- svg.setDocumentWidth(m.iconSvg.width.dpToPx())
342
- svg.setDocumentHeight(m.iconSvg.height.dpToPx())
336
+ val wPx =
337
+ m.iconSvg.width
338
+ .dpToPx()
339
+ .toInt()
340
+ val hPx =
341
+ m.iconSvg.height
342
+ .dpToPx()
343
+ .toInt()
343
344
 
344
345
  coroutineContext.ensureActive()
345
- bmp =
346
- createBitmap(
347
- m.iconSvg.width
348
- .dpToPx()
349
- .toInt(),
350
- m.iconSvg.height
351
- .dpToPx()
352
- .toInt(),
353
- Bitmap.Config.ARGB_8888,
354
- )
346
+ svg.setDocumentWidth(wPx.toFloat())
347
+ svg.setDocumentHeight(hPx.toFloat())
355
348
 
356
349
  coroutineContext.ensureActive()
357
- val canvas = Canvas(bmp)
358
- svg.renderToCanvas(canvas)
350
+ bmp =
351
+ createBitmap(wPx, hPx, Bitmap.Config.ARGB_8888).apply {
352
+ density = context.resources.displayMetrics.densityDpi
353
+ Canvas(this).also {
354
+ svg.renderToCanvas(it)
355
+ }
356
+ }
359
357
 
360
- coroutineContext.ensureActive()
361
358
  return bmp
362
359
  } catch (t: Throwable) {
363
360
  try {
@@ -4,9 +4,12 @@ import android.graphics.Color
4
4
  import com.facebook.react.uimanager.PixelUtil.dpToPx
5
5
  import com.google.android.gms.maps.model.Polygon
6
6
  import com.google.android.gms.maps.model.PolygonOptions
7
+ import com.rngooglemapsplus.extensions.coordinatesEquals
8
+ import com.rngooglemapsplus.extensions.holesEquals
7
9
  import com.rngooglemapsplus.extensions.onUi
8
10
  import com.rngooglemapsplus.extensions.toColor
9
11
  import com.rngooglemapsplus.extensions.toLatLng
12
+ import com.rngooglemapsplus.extensions.toMapsPolygonHoles
10
13
 
11
14
  class MapPolygonBuilder {
12
15
  fun build(poly: RNPolygon): PolygonOptions =
@@ -32,32 +35,12 @@ class MapPolygonBuilder {
32
35
  next: RNPolygon,
33
36
  poly: Polygon,
34
37
  ) = onUi {
35
- val coordsChanged =
36
- prev.coordinates.size != next.coordinates.size ||
37
- !prev.coordinates.zip(next.coordinates).all { (a, b) ->
38
- a.latitude == b.latitude && a.longitude == b.longitude
39
- }
40
-
41
- if (coordsChanged) {
38
+ if (!prev.coordinatesEquals(next)) {
42
39
  poly.points = next.coordinates.map { it.toLatLng() }
43
40
  }
44
41
 
45
- val prevHoles = prev.holes?.toList() ?: emptyList()
46
- val nextHoles = next.holes?.toList() ?: emptyList()
47
- val holesChanged =
48
- prevHoles.size != nextHoles.size ||
49
- !prevHoles.zip(nextHoles).all { (ha, hb) ->
50
- ha.coordinates.size == hb.coordinates.size &&
51
- ha.coordinates.zip(hb.coordinates).all { (a, b) ->
52
- a.latitude == b.latitude && a.longitude == b.longitude
53
- }
54
- }
55
-
56
- if (holesChanged) {
57
- poly.holes =
58
- nextHoles.map { hole ->
59
- hole.coordinates.map { it.toLatLng() }
60
- }
42
+ if (!prev.holesEquals(next)) {
43
+ poly.holes = next.holes?.toMapsPolygonHoles() ?: emptyList()
61
44
  }
62
45
 
63
46
  if (prev.fillColor != next.fillColor) {
@@ -2,16 +2,14 @@ package com.rngooglemapsplus
2
2
 
3
3
  import android.graphics.Color
4
4
  import com.facebook.react.uimanager.PixelUtil.dpToPx
5
- import com.google.android.gms.maps.model.ButtCap
6
- import com.google.android.gms.maps.model.Cap
7
- import com.google.android.gms.maps.model.JointType
8
5
  import com.google.android.gms.maps.model.Polyline
9
6
  import com.google.android.gms.maps.model.PolylineOptions
10
- import com.google.android.gms.maps.model.RoundCap
11
- import com.google.android.gms.maps.model.SquareCap
7
+ import com.rngooglemapsplus.extensions.coordinatesEquals
12
8
  import com.rngooglemapsplus.extensions.onUi
13
9
  import com.rngooglemapsplus.extensions.toColor
14
10
  import com.rngooglemapsplus.extensions.toLatLng
11
+ import com.rngooglemapsplus.extensions.toMapJointType
12
+ import com.rngooglemapsplus.extensions.toMapLineCap
15
13
 
16
14
  class MapPolylineBuilder {
17
15
  fun build(pl: RNPolyline): PolylineOptions =
@@ -21,10 +19,10 @@ class MapPolylineBuilder {
21
19
  }
22
20
  pl.width?.let { width(it.dpToPx()) }
23
21
  pl.lineCap?.let {
24
- startCap(mapLineCap(it))
25
- endCap(mapLineCap(it))
22
+ startCap(it.toMapLineCap())
23
+ endCap(it.toMapLineCap())
26
24
  }
27
- pl.lineJoin?.let { jointType(mapLineJoin(it)) }
25
+ pl.lineJoin?.let { jointType(it.toMapJointType()) }
28
26
  pl.color?.let { color(it.toColor()) }
29
27
  pl.geodesic?.let { geodesic(it) }
30
28
  pl.pressable?.let { clickable(it) }
@@ -36,13 +34,7 @@ class MapPolylineBuilder {
36
34
  next: RNPolyline,
37
35
  polyline: Polyline,
38
36
  ) = onUi {
39
- val coordsChanged =
40
- prev.coordinates.size != next.coordinates.size ||
41
- !prev.coordinates.zip(next.coordinates).all { (a, b) ->
42
- a.latitude == b.latitude && a.longitude == b.longitude
43
- }
44
-
45
- if (coordsChanged) {
37
+ if (!prev.coordinatesEquals(next)) {
46
38
  polyline.points = next.coordinates.map { it.toLatLng() }
47
39
  }
48
40
 
@@ -50,17 +42,13 @@ class MapPolylineBuilder {
50
42
  polyline.width = next.width?.dpToPx() ?: 1f
51
43
  }
52
44
 
53
- val newCap = mapLineCap(next.lineCap ?: RNLineCapType.BUTT)
54
- val prevCap = mapLineCap(prev.lineCap ?: RNLineCapType.BUTT)
55
- if (newCap != prevCap) {
56
- polyline.startCap = newCap
57
- polyline.endCap = newCap
45
+ if (prev.lineCap != next.lineCap) {
46
+ polyline.startCap = next.lineCap.toMapLineCap()
47
+ polyline.endCap = next.lineCap.toMapLineCap()
58
48
  }
59
49
 
60
- val newJoin = mapLineJoin(next.lineJoin ?: RNLineJoinType.MITER)
61
- val prevJoin = mapLineJoin(prev.lineJoin ?: RNLineJoinType.MITER)
62
- if (newJoin != prevJoin) {
63
- polyline.jointType = newJoin
50
+ if (prev.lineJoin != next.lineJoin) {
51
+ polyline.jointType = next.lineJoin.toMapJointType()
64
52
  }
65
53
 
66
54
  if (prev.color != next.color) {
@@ -79,19 +67,4 @@ class MapPolylineBuilder {
79
67
  polyline.zIndex = next.zIndex?.toFloat() ?: 0f
80
68
  }
81
69
  }
82
-
83
- private fun mapLineCap(type: RNLineCapType?): Cap =
84
- when (type) {
85
- RNLineCapType.ROUND -> RoundCap()
86
- RNLineCapType.SQUARE -> SquareCap()
87
- else -> ButtCap()
88
- }
89
-
90
- private fun mapLineJoin(type: RNLineJoinType?): Int =
91
- when (type) {
92
- RNLineJoinType.ROUND -> JointType.ROUND
93
- RNLineJoinType.BEVEL -> JointType.BEVEL
94
- RNLineJoinType.MITER -> JointType.DEFAULT
95
- null -> JointType.DEFAULT
96
- }
97
70
  }
@@ -12,6 +12,7 @@ import com.rngooglemapsplus.extensions.markerEquals
12
12
  import com.rngooglemapsplus.extensions.polygonEquals
13
13
  import com.rngooglemapsplus.extensions.polylineEquals
14
14
  import com.rngooglemapsplus.extensions.toCameraPosition
15
+ import com.rngooglemapsplus.extensions.toColor
15
16
  import com.rngooglemapsplus.extensions.toCompressFormat
16
17
  import com.rngooglemapsplus.extensions.toFileExtension
17
18
  import com.rngooglemapsplus.extensions.toGoogleMapType
@@ -48,6 +49,7 @@ class RNGoogleMapsPlusView(
48
49
  initialProps?.mapId?.let { mapId(it) }
49
50
  initialProps?.liteMode?.let { liteMode(it) }
50
51
  initialProps?.camera?.let { camera(it.toCameraPosition(current = null)) }
52
+ initialProps?.backgroundColor?.let { backgroundColor(it.toColor()) }
51
53
  }
52
54
  view.initMapView(options)
53
55
  }
@@ -149,7 +151,7 @@ class RNGoogleMapsPlusView(
149
151
  val prev = prevById[id]
150
152
  when {
151
153
  prev == null ->
152
- markerBuilder.buildIconAsync(id, next) { icon ->
154
+ markerBuilder.buildIconAsync(next) { icon ->
153
155
  view.addMarker(
154
156
  id,
155
157
  markerBuilder.build(next, icon),
@@ -427,7 +429,7 @@ class RNGoogleMapsPlusView(
427
429
  }
428
430
 
429
431
  override fun setCamera(
430
- camera: RNCamera,
432
+ camera: RNCameraUpdate,
431
433
  animated: Boolean?,
432
434
  durationMs: Double?,
433
435
  ) {
@@ -2,9 +2,9 @@ package com.rngooglemapsplus.extensions
2
2
 
3
3
  import com.google.android.gms.maps.model.CameraPosition
4
4
  import com.google.android.gms.maps.model.LatLng
5
- import com.rngooglemapsplus.RNCamera
5
+ import com.rngooglemapsplus.RNCameraUpdate
6
6
 
7
- fun RNCamera.toCameraPosition(current: CameraPosition?) =
7
+ fun RNCameraUpdate.toCameraPosition(current: CameraPosition?) =
8
8
  CameraPosition
9
9
  .builder()
10
10
  .target(center?.toLatLng() ?: current?.target ?: LatLng(0.0, 0.0))
@@ -0,0 +1,14 @@
1
+ package com.rngooglemapsplus.extensions
2
+
3
+ import com.google.android.gms.maps.model.ButtCap
4
+ import com.google.android.gms.maps.model.Cap
5
+ import com.google.android.gms.maps.model.RoundCap
6
+ import com.google.android.gms.maps.model.SquareCap
7
+ import com.rngooglemapsplus.RNLineCapType
8
+
9
+ fun RNLineCapType?.toMapLineCap(): Cap =
10
+ when (this) {
11
+ RNLineCapType.ROUND -> RoundCap()
12
+ RNLineCapType.SQUARE -> SquareCap()
13
+ else -> ButtCap()
14
+ }
@@ -0,0 +1,12 @@
1
+ package com.rngooglemapsplus.extensions
2
+
3
+ import com.google.android.gms.maps.model.JointType
4
+ import com.rngooglemapsplus.RNLineJoinType
5
+
6
+ fun RNLineJoinType?.toMapJointType(): Int =
7
+ when (this) {
8
+ RNLineJoinType.ROUND -> JointType.ROUND
9
+ RNLineJoinType.BEVEL -> JointType.BEVEL
10
+ RNLineJoinType.MITER -> JointType.DEFAULT
11
+ null -> JointType.DEFAULT
12
+ }
@@ -3,12 +3,18 @@ package com.rngooglemapsplus.extensions
3
3
  import com.rngooglemapsplus.RNCircle
4
4
 
5
5
  fun RNCircle.circleEquals(b: RNCircle): Boolean {
6
+ if (!centerEquals(b)) return false
6
7
  if (zIndex != b.zIndex) return false
7
8
  if (pressable != b.pressable) return false
8
- if (center != b.center) return false
9
9
  if (radius != b.radius) return false
10
10
  if (strokeWidth != b.strokeWidth) return false
11
11
  if (strokeColor != b.strokeColor) return false
12
12
  if (fillColor != b.fillColor) return false
13
13
  return true
14
14
  }
15
+
16
+ fun RNCircle.centerEquals(b: RNCircle): Boolean {
17
+ if (center.latitude != b.center.latitude) return false
18
+ if (center.longitude != b.center.longitude) return false
19
+ return true
20
+ }
@@ -2,24 +2,61 @@ package com.rngooglemapsplus.extensions
2
2
 
3
3
  import com.rngooglemapsplus.RNMarker
4
4
 
5
- fun RNMarker.markerEquals(b: RNMarker): Boolean =
6
- id == b.id &&
7
- zIndex == b.zIndex &&
8
- coordinate == b.coordinate &&
9
- anchor == b.anchor &&
10
- showInfoWindow == b.showInfoWindow &&
11
- title == b.title &&
12
- snippet == b.snippet &&
13
- opacity == b.opacity &&
14
- flat == b.flat &&
15
- draggable == b.draggable &&
16
- rotation == b.rotation &&
17
- infoWindowAnchor == b.infoWindowAnchor &&
18
- markerStyleEquals(b)
19
-
20
- fun RNMarker.markerStyleEquals(b: RNMarker): Boolean = iconSvg == b.iconSvg
5
+ fun RNMarker.markerEquals(b: RNMarker): Boolean {
6
+ if (id != b.id) return false
7
+ if (zIndex != b.zIndex) return false
8
+ if (!coordinatesEquals(b)) return false
9
+ if (!anchorEquals(b)) return false
10
+ if (!infoWindowAnchorEquals(b)) return false
11
+ if (title != b.title) return false
12
+ if (snippet != b.snippet) return false
13
+ if (opacity != b.opacity) return false
14
+ if (flat != b.flat) return false
15
+ if (draggable != b.draggable) return false
16
+ if (rotation != b.rotation) return false
17
+ if (!markerInfoWindowStyleEquals(b)) return false
18
+ if (!markerStyleEquals(b)) return false
19
+
20
+ return true
21
+ }
22
+
23
+ fun RNMarker.coordinatesEquals(b: RNMarker): Boolean {
24
+ if (coordinate.latitude != b.coordinate.latitude) return false
25
+ if (coordinate.longitude != b.coordinate.longitude) return false
26
+ return true
27
+ }
28
+
29
+ fun RNMarker.anchorEquals(b: RNMarker): Boolean {
30
+ if (anchor?.x != b.anchor?.x) return false
31
+ if (anchor?.y != b.anchor?.y) return false
32
+ return true
33
+ }
34
+
35
+ fun RNMarker.infoWindowAnchorEquals(b: RNMarker): Boolean {
36
+ if (infoWindowAnchor?.x != b.infoWindowAnchor?.x) return false
37
+ if (infoWindowAnchor?.y != b.infoWindowAnchor?.y) return false
38
+ return true
39
+ }
40
+
41
+ fun RNMarker.markerInfoWindowStyleEquals(b: RNMarker): Boolean {
42
+ if (infoWindowIconSvg?.width != b.infoWindowIconSvg?.width) return false
43
+ if (infoWindowIconSvg?.height != b.infoWindowIconSvg?.height) return false
44
+ if (infoWindowIconSvg?.svgString != b.infoWindowIconSvg?.svgString) return false
45
+
46
+ return true
47
+ }
48
+
49
+ fun RNMarker.markerStyleEquals(b: RNMarker): Boolean {
50
+ if (iconSvg?.width != b.iconSvg?.width) return false
51
+ if (iconSvg?.height != b.iconSvg?.height) return false
52
+ if (iconSvg?.svgString != b.iconSvg?.svgString) return false
53
+
54
+ return true
55
+ }
21
56
 
22
57
  fun RNMarker.styleHash(): Int =
23
58
  arrayOf<Any?>(
24
- iconSvg,
59
+ iconSvg?.width,
60
+ iconSvg?.height,
61
+ iconSvg?.svgString,
25
62
  ).contentHashCode()
@@ -1,6 +1,8 @@
1
1
  package com.rngooglemapsplus.extensions
2
2
 
3
+ import com.google.android.gms.maps.model.LatLng
3
4
  import com.rngooglemapsplus.RNPolygon
5
+ import com.rngooglemapsplus.RNPolygonHole
4
6
 
5
7
  fun RNPolygon.polygonEquals(b: RNPolygon): Boolean {
6
8
  if (zIndex != b.zIndex) return false
@@ -9,7 +11,12 @@ fun RNPolygon.polygonEquals(b: RNPolygon): Boolean {
9
11
  if (fillColor != b.fillColor) return false
10
12
  if (strokeColor != b.strokeColor) return false
11
13
  if (geodesic != b.geodesic) return false
12
- if (!holes.contentEquals(b.holes)) return false
14
+ if (!coordinatesEquals(b)) return false
15
+ if (!holesEquals(b)) return false
16
+ return true
17
+ }
18
+
19
+ fun RNPolygon.coordinatesEquals(b: RNPolygon): Boolean {
13
20
  val ac = coordinates
14
21
  val bc = b.coordinates
15
22
  if (ac.size != bc.size) return false
@@ -20,3 +27,26 @@ fun RNPolygon.polygonEquals(b: RNPolygon): Boolean {
20
27
  }
21
28
  return true
22
29
  }
30
+
31
+ fun RNPolygon.holesEquals(b: RNPolygon): Boolean {
32
+ if (holes?.size != b.holes?.size) return false
33
+ if (holes != null && b.holes != null) {
34
+ for (i in holes.indices) {
35
+ val ah = holes[i]
36
+ val bh = b.holes[i]
37
+
38
+ if (ah.coordinates.size != bh.coordinates.size) return false
39
+ for (j in ah.coordinates.indices) {
40
+ val p = ah.coordinates[j]
41
+ val q = bh.coordinates[j]
42
+ if (p.latitude != q.latitude || p.longitude != q.longitude) return false
43
+ }
44
+ }
45
+ }
46
+ return true
47
+ }
48
+
49
+ fun Array<RNPolygonHole>.toMapsPolygonHoles(): List<List<LatLng>> =
50
+ this.map { hole ->
51
+ hole.coordinates.map { it.toLatLng() }
52
+ }
@@ -5,11 +5,16 @@ import com.rngooglemapsplus.RNPolyline
5
5
  fun RNPolyline.polylineEquals(b: RNPolyline): Boolean {
6
6
  if (zIndex != b.zIndex) return false
7
7
  if (pressable != b.pressable) return false
8
- if ((width ?: 0.0) != (b.width ?: 0.0)) return false
8
+ if (width != b.width) return false
9
9
  if (lineCap != b.lineCap) return false
10
10
  if (lineJoin != b.lineJoin) return false
11
11
  if (geodesic != b.geodesic) return false
12
12
  if (color != b.color) return false
13
+ if (!coordinatesEquals(b)) return false
14
+ return true
15
+ }
16
+
17
+ fun RNPolyline.coordinatesEquals(b: RNPolyline): Boolean {
13
18
  val ac = coordinates
14
19
  val bc = b.coordinates
15
20
  if (ac.size != bc.size) return false
@@ -444,7 +444,10 @@ GMSIndoorDisplayDelegate {
444
444
 
445
445
  @MainActor
446
446
  func removeMarker(id: String) {
447
- markersById.removeValue(forKey: id).map { $0.map = nil }
447
+ markersById.removeValue(forKey: id).map {
448
+ $0.icon = nil
449
+ $0.map = nil
450
+ }
448
451
  }
449
452
 
450
453
  @MainActor
@@ -35,6 +35,8 @@ final class LocationHandler: NSObject, CLLocationManagerDelegate {
35
35
 
36
36
  func showLocationDialog() {
37
37
  onMainAsync { [weak self] in
38
+ guard let self = self else { return }
39
+
38
40
  guard let vc = Self.topMostViewController() else { return }
39
41
  let title =
40
42
  Bundle.main.object(forInfoDictionaryKey: "LocationNotAvailableTitle")
@@ -61,7 +63,7 @@ final class LocationHandler: NSObject, CLLocationManagerDelegate {
61
63
  title: openLocationSettingsButton ?? "Open settings",
62
64
  style: .default
63
65
  ) { _ in
64
- self?.openLocationSettings()
66
+ self.openLocationSettings()
65
67
  }
66
68
  )
67
69
  vc.present(alert, animated: true, completion: nil)
@@ -17,13 +17,12 @@ final class MapCircleBuilder {
17
17
 
18
18
  @MainActor
19
19
  func update(_ prev: RNCircle, _ next: RNCircle, _ c: GMSCircle) {
20
- if prev.center.latitude != next.center.latitude
21
- || prev.center.longitude != next.center.longitude {
20
+ if !prev.centerEquals(next) {
22
21
  c.position = next.center.toCLLocationCoordinate2D()
23
22
  }
24
23
 
25
24
  if prev.radius != next.radius {
26
- c.radius = next.radius ?? 0
25
+ c.radius = next.radius
27
26
  }
28
27
 
29
28
  if prev.fillColor != next.fillColor {
@@ -32,11 +32,9 @@ func onMain(_ block: @escaping @MainActor () -> Void) {
32
32
 
33
33
  @inline(__always)
34
34
  func onMainAsync(
35
- _ block: @MainActor @escaping () async -> Void
35
+ _ block: @escaping @MainActor () async -> Void
36
36
  ) {
37
- if Thread.isMainThread {
38
- Task { @MainActor in await block() }
39
- } else {
40
- Task { @MainActor in await block() }
37
+ Task { @MainActor in
38
+ await block()
41
39
  }
42
40
  }