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
@@ -15,7 +15,6 @@ final class MapMarkerBuilder {
15
15
  let marker = GMSMarker(
16
16
  position: m.coordinate.toCLLocationCoordinate2D()
17
17
  )
18
- marker.tracksViewChanges = true
19
18
  marker.icon = icon
20
19
  m.title.map { marker.title = $0 }
21
20
  m.snippet.map { marker.snippet = $0 }
@@ -42,107 +41,122 @@ final class MapMarkerBuilder {
42
41
  iconSvg: m.infoWindowIconSvg
43
42
  )
44
43
 
45
- onMainAsync { [weak marker] in
46
- try? await Task.sleep(nanoseconds: 250_000_000)
47
- marker?.tracksViewChanges = false
48
- }
49
-
50
44
  return marker
51
45
  }
52
46
 
53
47
  @MainActor
54
48
  func update(_ prev: RNMarker, _ next: RNMarker, _ m: GMSMarker) {
55
- if prev.coordinate.latitude != next.coordinate.latitude
56
- || prev.coordinate.longitude != next.coordinate.longitude {
57
- m.position = next.coordinate.toCLLocationCoordinate2D()
58
- }
59
-
60
- if prev.title != next.title {
61
- m.title = next.title
62
- }
63
-
64
- if prev.snippet != next.snippet {
65
- m.snippet = next.snippet
66
- }
67
-
68
- if prev.opacity != next.opacity {
69
- let opacity = Float(next.opacity ?? 1)
70
- m.opacity = opacity
71
- m.iconView?.alpha = CGFloat(opacity)
72
- }
73
-
74
- if prev.flat != next.flat {
75
- m.isFlat = next.flat ?? false
76
- }
77
-
78
- if prev.draggable != next.draggable {
79
- m.isDraggable = next.draggable ?? false
80
- }
49
+ withCATransaction(disableActions: true) {
81
50
 
82
- if prev.rotation != next.rotation {
83
- m.rotation = next.rotation ?? 0
84
- }
85
-
86
- if prev.zIndex != next.zIndex {
87
- m.zIndex = Int32(next.zIndex ?? 0)
88
- }
51
+ var tracksViewChanges = false
52
+ var tracksInfoWindowChanges = false
89
53
 
90
- if !prev.markerStyleEquals(next) {
91
- buildIconAsync(next.id, next) { img in
92
- m.tracksViewChanges = true
93
- m.icon = img
54
+ if !prev.coordinateEquals(next) {
55
+ m.position = next.coordinate.toCLLocationCoordinate2D()
56
+ }
94
57
 
95
- if prev.anchor?.x != next.anchor?.x || prev.anchor?.y != next.anchor?.y {
58
+ if !prev.markerStyleEquals(next) {
59
+ self.buildIconAsync(next) { img in
60
+ tracksViewChanges = true
61
+ m.icon = img
62
+
63
+ if !prev.anchorEquals(next) {
64
+ m.groundAnchor = CGPoint(
65
+ x: next.anchor?.x ?? 0.5,
66
+ y: next.anchor?.y ?? 1
67
+ )
68
+ }
69
+
70
+ if !prev.infoWindowAnchorEquals(next) {
71
+ m.infoWindowAnchor = CGPoint(
72
+ x: next.infoWindowAnchor?.x ?? 0.5,
73
+ y: next.infoWindowAnchor?.y ?? 0
74
+ )
75
+ }
76
+ }
77
+ } else {
78
+ if !prev.anchorEquals(next) {
96
79
  m.groundAnchor = CGPoint(
97
80
  x: next.anchor?.x ?? 0.5,
98
81
  y: next.anchor?.y ?? 1
99
82
  )
100
83
  }
101
84
 
102
- if prev.infoWindowAnchor?.x != next.infoWindowAnchor?.x
103
- || prev.infoWindowAnchor?.y != next.infoWindowAnchor?.y {
85
+ if !prev.infoWindowAnchorEquals(next) {
104
86
  m.infoWindowAnchor = CGPoint(
105
87
  x: next.infoWindowAnchor?.x ?? 0.5,
106
88
  y: next.infoWindowAnchor?.y ?? 0
107
89
  )
108
90
  }
91
+ }
109
92
 
110
- onMainAsync { [weak m] in
111
- try? await Task.sleep(nanoseconds: 250_000_000)
112
- m?.tracksViewChanges = false
113
- }
93
+ if prev.title != next.title {
94
+ tracksInfoWindowChanges = true
95
+ m.title = next.title
114
96
  }
115
- } else {
116
- if prev.anchor?.x != next.anchor?.x || prev.anchor?.y != next.anchor?.y {
117
- m.groundAnchor = CGPoint(
118
- x: next.anchor?.x ?? 0.5,
119
- y: next.anchor?.y ?? 1
120
- )
97
+
98
+ if prev.snippet != next.snippet {
99
+ tracksInfoWindowChanges = true
100
+ m.snippet = next.snippet
101
+ }
102
+
103
+ if prev.opacity != next.opacity {
104
+ let opacity = Float(next.opacity ?? 1)
105
+ m.opacity = opacity
106
+ m.iconView?.alpha = CGFloat(opacity)
107
+ }
108
+
109
+ if prev.flat != next.flat {
110
+ m.isFlat = next.flat ?? false
121
111
  }
122
112
 
123
- if prev.infoWindowAnchor?.x != next.infoWindowAnchor?.x
124
- || prev.infoWindowAnchor?.y != next.infoWindowAnchor?.y {
125
- m.infoWindowAnchor = CGPoint(
126
- x: next.infoWindowAnchor?.x ?? 0.5,
127
- y: next.infoWindowAnchor?.y ?? 0
113
+ if prev.draggable != next.draggable {
114
+ m.isDraggable = next.draggable ?? false
115
+ }
116
+
117
+ if prev.rotation != next.rotation {
118
+ m.rotation = next.rotation ?? 0
119
+ }
120
+
121
+ if prev.zIndex != next.zIndex {
122
+ m.zIndex = Int32(next.zIndex ?? 0)
123
+ }
124
+
125
+ if !prev.markerInfoWindowStyleEquals(next) {
126
+ m.tagData = MarkerTag(
127
+ id: next.id,
128
+ iconSvg: next.infoWindowIconSvg
128
129
  )
129
130
  }
130
131
 
131
- m.tagData = MarkerTag(
132
- id: next.id,
133
- iconSvg: next.infoWindowIconSvg
134
- )
132
+ if tracksViewChanges {
133
+ m.tracksViewChanges = tracksViewChanges
134
+ }
135
+ if tracksInfoWindowChanges {
136
+ m.tracksInfoWindowChanges = tracksInfoWindowChanges
137
+ }
138
+
139
+ if tracksViewChanges || tracksInfoWindowChanges {
140
+ onMain { [weak m] in
141
+ guard let m = m else { return }
135
142
 
143
+ if tracksViewChanges {
144
+ m.tracksViewChanges = false
145
+ }
146
+
147
+ if tracksInfoWindowChanges {
148
+ m.tracksInfoWindowChanges = false
149
+ }
150
+ }
151
+ }
136
152
  }
137
153
  }
138
154
 
139
- @MainActor
140
155
  func buildIconAsync(
141
- _ id: String,
142
156
  _ m: RNMarker,
143
157
  onReady: @escaping (UIImage?) -> Void
144
158
  ) {
145
- tasks[id]?.cancel()
159
+ tasks[m.id]?.cancel()
146
160
 
147
161
  if m.iconSvg == nil {
148
162
  onReady(nil)
@@ -155,12 +169,15 @@ final class MapMarkerBuilder {
155
169
  return
156
170
  }
157
171
 
172
+ let scale = UIScreen.main.scale
173
+
158
174
  let task = Task(priority: .userInitiated) { [weak self] in
159
175
  guard let self else { return }
160
- defer { self.tasks.removeValue(forKey: id) }
176
+ defer {
177
+ Task { @MainActor in self.tasks.removeValue(forKey: m.id) }
178
+ }
161
179
 
162
- let scale = UIScreen.main.scale
163
- let img = await self.renderUIImage(m, scale)
180
+ let img = self.renderUIImage(m, scale)
164
181
  guard let img, !Task.isCancelled else { return }
165
182
 
166
183
  self.iconCache.setObject(img, forKey: key)
@@ -171,7 +188,7 @@ final class MapMarkerBuilder {
171
188
  }
172
189
  }
173
190
 
174
- tasks[id] = task
191
+ tasks[m.id] = task
175
192
  }
176
193
 
177
194
  @MainActor
@@ -209,18 +226,11 @@ final class MapMarkerBuilder {
209
226
 
210
227
  svgImg.size = size
211
228
 
212
- guard let base = svgImg.uiImage else {
229
+ guard let finalImage = SVGKExporterUIImage.export(asUIImage: svgImg) else {
230
+ svgImg.clear()
213
231
  return nil
214
232
  }
215
-
216
- let fmt = UIGraphicsImageRendererFormat.default()
217
- fmt.opaque = false
218
- fmt.scale = UIScreen.main.scale
219
- let renderer = UIGraphicsImageRenderer(size: size, format: fmt)
220
-
221
- let finalImage = renderer.image { _ in
222
- base.draw(in: CGRect(origin: .zero, size: size))
223
- }
233
+ svgImg.clear()
224
234
 
225
235
  let imageView = UIImageView(image: finalImage)
226
236
  imageView.frame = CGRect(origin: .zero, size: size)
@@ -230,10 +240,10 @@ final class MapMarkerBuilder {
230
240
  return imageView
231
241
  }
232
242
 
233
- @MainActor
234
- private func renderUIImage(_ m: RNMarker, _ scale: CGFloat) async -> UIImage? {
235
- guard let iconSvg = m.iconSvg,
236
- let data = iconSvg.svgString.data(using: .utf8)
243
+ private func renderUIImage(_ m: RNMarker, _ scale: CGFloat) -> UIImage? {
244
+ guard
245
+ let iconSvg = m.iconSvg,
246
+ let data = iconSvg.svgString.data(using: .utf8)
237
247
  else { return nil }
238
248
 
239
249
  let size = CGSize(
@@ -241,28 +251,21 @@ final class MapMarkerBuilder {
241
251
  height: max(1, CGFloat(iconSvg.height))
242
252
  )
243
253
 
244
- return await Task.detached(priority: .userInitiated) {
245
- autoreleasepool {
246
- guard let svgImg = SVGKImage(data: data) else { return nil }
247
- svgImg.size = size
254
+ return autoreleasepool { () -> UIImage? in
255
+ guard !Task.isCancelled else { return nil }
256
+ guard let svgImg = SVGKImage(data: data) else { return nil }
248
257
 
249
- guard !Task.isCancelled else { return nil }
250
- guard let base = svgImg.uiImage else { return nil }
258
+ svgImg.size = size
251
259
 
252
- if let cg = base.cgImage {
253
- return UIImage(cgImage: cg, scale: scale, orientation: .up)
254
- }
255
- guard !Task.isCancelled else { return nil }
256
- let fmt = UIGraphicsImageRendererFormat.default()
257
- fmt.opaque = false
258
- fmt.scale = scale
259
- guard !Task.isCancelled else { return nil }
260
- let renderer = UIGraphicsImageRenderer(size: size, format: fmt)
261
- return renderer.image { _ in
262
- base.draw(in: CGRect(origin: .zero, size: size))
263
- }
260
+ guard !Task.isCancelled else {
261
+ svgImg.clear()
262
+ return nil
264
263
  }
265
- }.value
264
+
265
+ let uiImage = SVGKExporterUIImage.export(asUIImage: svgImg)
266
+ svgImg.clear()
267
+ return uiImage
268
+ }
266
269
  }
267
270
 
268
271
  }
@@ -3,13 +3,7 @@ import GoogleMaps
3
3
  final class MapPolygonBuilder {
4
4
  @MainActor
5
5
  func build(_ p: RNPolygon) -> GMSPolygon {
6
- let path = GMSMutablePath()
7
- p.coordinates.forEach {
8
- path.add(
9
- $0.toCLLocationCoordinate2D()
10
- )
11
- }
12
-
6
+ let path = p.coordinates.toGMSPath()
13
7
  let pg = GMSPolygon(path: path)
14
8
 
15
9
  p.fillColor.map { pg.fillColor = $0.toUIColor() }
@@ -17,13 +11,7 @@ final class MapPolygonBuilder {
17
11
  p.strokeWidth.map { pg.strokeWidth = CGFloat($0) }
18
12
  p.pressable.map { pg.isTappable = $0 }
19
13
  p.geodesic.map { pg.geodesic = $0 }
20
- p.holes.map {
21
- pg.holes = $0.map { hole in
22
- let path = GMSMutablePath()
23
- hole.coordinates.forEach { path.add($0.toCLLocationCoordinate2D()) }
24
- return path
25
- }
26
- }
14
+ pg.holes = p.holes.toMapPolygonHoles()
27
15
  p.zIndex.map { pg.zIndex = Int32($0) }
28
16
 
29
17
  return pg
@@ -31,35 +19,12 @@ final class MapPolygonBuilder {
31
19
 
32
20
  @MainActor
33
21
  func update(_ prev: RNPolygon, _ next: RNPolygon, _ pg: GMSPolygon) {
34
- let coordsChanged =
35
- prev.coordinates.count != next.coordinates.count
36
- || !zip(prev.coordinates, next.coordinates).allSatisfy {
37
- $0.latitude == $1.latitude && $0.longitude == $1.longitude
38
- }
39
-
40
- if coordsChanged {
41
- let path = GMSMutablePath()
42
- next.coordinates.forEach { path.add($0.toCLLocationCoordinate2D()) }
43
- pg.path = path
22
+ if !prev.coordinatesEquals(next) {
23
+ pg.path = next.coordinates.toGMSPath()
44
24
  }
45
25
 
46
- let prevHoles = prev.holes ?? []
47
- let nextHoles = next.holes ?? []
48
- let holesChanged =
49
- prevHoles.count != nextHoles.count
50
- || !zip(prevHoles, nextHoles).allSatisfy { a, b in
51
- a.coordinates.count == b.coordinates.count
52
- && zip(a.coordinates, b.coordinates).allSatisfy {
53
- $0.latitude == $1.latitude && $0.longitude == $1.longitude
54
- }
55
- }
56
-
57
- if holesChanged {
58
- pg.holes = nextHoles.map { hole in
59
- let path = GMSMutablePath()
60
- hole.coordinates.forEach { path.add($0.toCLLocationCoordinate2D()) }
61
- return path
62
- }
26
+ if !prev.holesEquals(next) {
27
+ pg.holes = next.holes.toMapPolygonHoles()
63
28
  }
64
29
 
65
30
  if prev.fillColor != next.fillColor {
@@ -25,16 +25,8 @@ final class MapPolylineBuilder {
25
25
 
26
26
  @MainActor
27
27
  func update(_ prev: RNPolyline, _ next: RNPolyline, _ pl: GMSPolyline) {
28
- let coordsChanged =
29
- prev.coordinates.count != next.coordinates.count
30
- || !zip(prev.coordinates, next.coordinates).allSatisfy {
31
- $0.latitude == $1.latitude && $0.longitude == $1.longitude
32
- }
33
-
34
- if coordsChanged {
35
- let path = GMSMutablePath()
36
- next.coordinates.forEach { path.add($0.toCLLocationCoordinate2D()) }
37
- pl.path = path
28
+ if !prev.coordinatesEquals(next) {
29
+ pl.path = next.coordinates.toGMSPath()
38
30
  }
39
31
 
40
32
  if prev.width != next.width {
@@ -41,6 +41,9 @@ final class RNGoogleMapsPlusView: HybridRNGoogleMapsPlusViewSpec {
41
41
  initialProps?.camera.map {
42
42
  options.camera = $0.toGMSCameraPosition(current: nil)
43
43
  }
44
+ initialProps?.backgroundColor.map {
45
+ options.backgroundColor = $0.toUIColor()
46
+ }
44
47
  impl.initMapView(googleMapOptions: options)
45
48
  }
46
49
  }
@@ -128,26 +131,26 @@ final class RNGoogleMapsPlusView: HybridRNGoogleMapsPlusViewSpec {
128
131
  )
129
132
 
130
133
  let removed = Set(prevById.keys).subtracting(nextById.keys)
131
- withCATransaction(disableActions: true) {
132
134
 
133
- removed.forEach {
134
- self.impl.removeMarker(id: $0)
135
- self.markerBuilder.cancelIconTask($0)
136
- }
135
+ removed.forEach {
136
+ self.impl.removeMarker(id: $0)
137
+ self.markerBuilder.cancelIconTask($0)
138
+ }
137
139
 
138
- for (id, next) in nextById {
139
- if let prev = prevById[id] {
140
- if !prev.markerEquals(next) {
141
- self.impl.updateMarker(id: id) { m in
142
- self.markerBuilder.update(prev, next, m)
143
- }
144
- }
145
- } else {
146
- self.markerBuilder.buildIconAsync(next.id, next) { icon in
147
- let marker = self.markerBuilder.build(next, icon: icon)
148
- self.impl.addMarker(id: id, marker: marker)
140
+ for (id, next) in nextById {
141
+ if let prev = prevById[id] {
142
+ if !prev.markerEquals(next) {
143
+ self.impl.updateMarker(id: id) { [weak self] m in
144
+ guard let self else { return }
145
+ self.markerBuilder.update(prev, next, m)
149
146
  }
150
147
  }
148
+ } else {
149
+ self.markerBuilder.buildIconAsync(next) { [weak self] icon in
150
+ guard let self else { return }
151
+ let marker = self.markerBuilder.build(next, icon: icon)
152
+ self.impl.addMarker(id: id, marker: marker)
153
+ }
151
154
  }
152
155
  }
153
156
  }
@@ -171,7 +174,8 @@ final class RNGoogleMapsPlusView: HybridRNGoogleMapsPlusViewSpec {
171
174
  for (id, next) in nextById {
172
175
  if let prev = prevById[id] {
173
176
  if !prev.polylineEquals(next) {
174
- impl.updatePolyline(id: id) { pl in
177
+ impl.updatePolyline(id: id) { [weak self] pl in
178
+ guard let self else { return }
175
179
  self.polylineBuilder.update(prev, next, pl)
176
180
  }
177
181
  }
@@ -203,7 +207,8 @@ final class RNGoogleMapsPlusView: HybridRNGoogleMapsPlusViewSpec {
203
207
  for (id, next) in nextById {
204
208
  if let prev = prevById[id] {
205
209
  if !prev.polygonEquals(next) {
206
- impl.updatePolygon(id: id) { pg in
210
+ impl.updatePolygon(id: id) { [weak self] pg in
211
+ guard let self else { return }
207
212
  self.polygonBuilder.update(prev, next, pg)
208
213
  }
209
214
  }
@@ -232,7 +237,8 @@ final class RNGoogleMapsPlusView: HybridRNGoogleMapsPlusViewSpec {
232
237
  for (id, next) in nextById {
233
238
  if let prev = prevById[id] {
234
239
  if !prev.circleEquals(next) {
235
- impl.updateCircle(id: id) { circle in
240
+ impl.updateCircle(id: id) { [weak self] circle in
241
+ guard let self else { return }
236
242
  self.circleBuilder.update(prev, next, circle)
237
243
  }
238
244
  }
@@ -419,16 +425,16 @@ final class RNGoogleMapsPlusView: HybridRNGoogleMapsPlusViewSpec {
419
425
 
420
426
  @MainActor
421
427
  func showMarkerInfoWindow(id: String) {
422
- impl.showMarkerInfoWindow(id: id);
428
+ impl.showMarkerInfoWindow(id: id)
423
429
  }
424
430
 
425
431
  @MainActor
426
432
  func hideMarkerInfoWindow(id: String) {
427
- impl.hideMarkerInfoWindow(id: id);
433
+ impl.hideMarkerInfoWindow(id: id)
428
434
  }
429
435
 
430
436
  @MainActor
431
- func setCamera(camera: RNCamera, animated: Bool?, durationMs: Double?) {
437
+ func setCamera(camera: RNCameraUpdate, animated: Bool?, durationMs: Double?) {
432
438
  let cam = camera.toGMSCameraPosition(current: impl.currentCamera)
433
439
  impl.setCamera(
434
440
  camera: cam,
@@ -1,7 +1,7 @@
1
1
  import CoreLocation
2
2
  import GoogleMaps
3
3
 
4
- extension RNCamera {
4
+ extension RNCameraUpdate {
5
5
  func toGMSCameraPosition(current: GMSCameraPosition?) -> GMSCameraPosition {
6
6
  let center = CLLocationCoordinate2D(
7
7
  latitude: center?.latitude ?? current?.target.latitude ?? 0.0,
@@ -2,10 +2,19 @@ import GoogleMaps
2
2
 
3
3
  extension RNCircle {
4
4
  func circleEquals(_ b: RNCircle) -> Bool {
5
- zIndex == b.zIndex && pressable == b.pressable
6
- && center.latitude == b.center.latitude
7
- && center.longitude == b.center.longitude && radius == b.radius
8
- && strokeWidth == b.strokeWidth && strokeColor == b.strokeColor
9
- && fillColor == b.fillColor
5
+ if zIndex != b.zIndex { return false }
6
+ if pressable != b.pressable { return false }
7
+ if !centerEquals(b) { return false }
8
+ if radius != b.radius { return false }
9
+ if strokeWidth != b.strokeWidth { return false }
10
+ if strokeColor != b.strokeColor { return false }
11
+ if fillColor != b.fillColor { return false }
12
+ return true
13
+ }
14
+
15
+ func centerEquals(_ b: RNCircle) -> Bool {
16
+ if center.latitude != b.center.latitude { return false }
17
+ if center.longitude != b.center.longitude { return false }
18
+ return true
10
19
  }
11
20
  }
@@ -1,7 +1,18 @@
1
1
  import CoreLocation
2
+ import GoogleMaps
2
3
 
3
4
  extension RNLatLng {
4
5
  func toCLLocationCoordinate2D() -> CLLocationCoordinate2D {
5
6
  CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
6
7
  }
7
8
  }
9
+
10
+ extension Array where Element == RNLatLng {
11
+ func toGMSPath() -> GMSPath {
12
+ let path = GMSMutablePath()
13
+ for coord in self {
14
+ path.add(coord.toCLLocationCoordinate2D())
15
+ }
16
+ return path
17
+ }
18
+ }
@@ -0,0 +1,10 @@
1
+ extension RNLineCapType {
2
+ func toCGLineCap() -> CGLineCap {
3
+ switch self {
4
+ case .round: return .round
5
+ case .square: return .square
6
+ default: return .butt
7
+ }
8
+ }
9
+ }
10
+
@@ -0,0 +1,11 @@
1
+ extension RNLineJoinType {
2
+ func toCGLineJoin() -> CGLineJoin {
3
+ switch self {
4
+ case .round: return .round
5
+ case .bevel: return .bevel
6
+ default: return .miter
7
+ }
8
+ }
9
+
10
+ }
11
+
@@ -2,21 +2,52 @@ import GoogleMaps
2
2
 
3
3
  extension RNMarker {
4
4
  func markerEquals(_ b: RNMarker) -> Bool {
5
- id == b.id && zIndex == b.zIndex
6
- && coordinate.latitude == b.coordinate.latitude
7
- && coordinate.longitude == b.coordinate.longitude
8
- && anchor?.x == b.anchor?.x && anchor?.y == b.anchor?.y
9
- && showInfoWindow == b.showInfoWindow && title == b.title
10
- && snippet == b.snippet && opacity == b.opacity && flat == b.flat
11
- && draggable == b.draggable && rotation == b.rotation
12
- && infoWindowAnchor?.x == b.infoWindowAnchor?.x
13
- && infoWindowAnchor?.y == b.infoWindowAnchor?.y
14
- && markerStyleEquals(b)
5
+ if id != b.id { return false }
6
+ if zIndex != b.zIndex { return false }
7
+ if !coordinateEquals(b) { return false }
8
+ if !anchorEquals(b) { return false }
9
+ if title != b.title { return false }
10
+ if snippet != b.snippet { return false }
11
+ if opacity != b.opacity { return false }
12
+ if flat != b.flat { return false }
13
+ if draggable != b.draggable { return false }
14
+ if rotation != b.rotation { return false }
15
+ if !infoWindowAnchorEquals(b) { return false }
16
+ if !markerInfoWindowStyleEquals(b) { return false }
17
+ if !markerStyleEquals(b) { return false }
18
+ return true
19
+ }
20
+
21
+ func coordinateEquals(_ b: RNMarker) -> Bool {
22
+ if coordinate.latitude != b.coordinate.latitude { return false }
23
+ if coordinate.longitude != b.coordinate.longitude { return false }
24
+ return true
25
+ }
26
+
27
+ func anchorEquals(_ b: RNMarker) -> Bool {
28
+ if anchor?.x != b.anchor?.x { return false }
29
+ if anchor?.y != b.anchor?.y { return false }
30
+ return true
31
+ }
32
+
33
+ func infoWindowAnchorEquals(_ b: RNMarker) -> Bool {
34
+ if infoWindowAnchor?.x != b.infoWindowAnchor?.x { return false }
35
+ if infoWindowAnchor?.y != b.infoWindowAnchor?.y { return false }
36
+ return true
37
+ }
38
+
39
+ func markerInfoWindowStyleEquals(_ b: RNMarker) -> Bool {
40
+ if infoWindowIconSvg?.width != b.infoWindowIconSvg?.width { return false }
41
+ if infoWindowIconSvg?.height != b.infoWindowIconSvg?.height { return false }
42
+ if infoWindowIconSvg?.svgString != b.infoWindowIconSvg?.svgString { return false }
43
+ return true
15
44
  }
16
45
 
17
46
  func markerStyleEquals(_ b: RNMarker) -> Bool {
18
- iconSvg?.width == b.iconSvg?.width && iconSvg?.height == b.iconSvg?.height
19
- && iconSvg?.svgString == b.iconSvg?.svgString
47
+ if iconSvg?.width != b.iconSvg?.width { return false }
48
+ if iconSvg?.height != b.iconSvg?.height { return false }
49
+ if iconSvg?.svgString != b.iconSvg?.svgString { return false }
50
+ return true
20
51
  }
21
52
 
22
53
  func styleHash() -> NSNumber {