react-native-google-maps-plus 1.7.0-dev.14 → 1.7.0-dev.16

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.
@@ -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
@@ -77,7 +77,10 @@ class MapMarkerBuilder(
77
77
  val height = (svg.documentHeight.takeIf { it > 0 } ?: 128f).toInt()
78
78
 
79
79
  createBitmap(width, height).apply {
80
- Canvas(this).also(svg::renderToCanvas)
80
+ density = context.resources.displayMetrics.densityDpi
81
+ Canvas(this).also {
82
+ svg.renderToCanvas(it)
83
+ }
81
84
  }
82
85
  }
83
86
 
@@ -98,10 +101,12 @@ class MapMarkerBuilder(
98
101
  val innerSvg = SVG.getFromString(svgText)
99
102
  val w = innerSvg.documentWidth.takeIf { it > 0 } ?: 128f
100
103
  val h = innerSvg.documentHeight.takeIf { it > 0 } ?: 128f
101
- val bmp = createBitmap(w.toInt(), h.toInt())
102
- val canvas = Canvas(bmp)
103
- innerSvg.renderToCanvas(canvas)
104
- bmp
104
+ createBitmap(w.toInt(), h.toInt()).apply {
105
+ density = context.resources.displayMetrics.densityDpi
106
+ Canvas(this).also {
107
+ innerSvg.renderToCanvas(it)
108
+ }
109
+ }
105
110
  } else {
106
111
  conn.inputStream.use { BitmapFactory.decodeStream(it) }
107
112
  }
@@ -178,7 +183,7 @@ class MapMarkerBuilder(
178
183
  }
179
184
 
180
185
  if (!prev.markerStyleEquals(next)) {
181
- buildIconAsync(marker.id, next) { icon ->
186
+ buildIconAsync(next) { icon ->
182
187
  marker.setIcon(icon)
183
188
  if (!prev.anchorEquals(next)) {
184
189
  marker.setAnchor(
@@ -242,11 +247,10 @@ class MapMarkerBuilder(
242
247
  }
243
248
 
244
249
  fun buildIconAsync(
245
- id: String,
246
250
  m: RNMarker,
247
251
  onReady: (BitmapDescriptor?) -> Unit,
248
252
  ) {
249
- jobsById[id]?.cancel()
253
+ jobsById[m.id]?.cancel()
250
254
 
251
255
  m.iconSvg ?: return onReady(null)
252
256
 
@@ -275,11 +279,11 @@ class MapMarkerBuilder(
275
279
  iconCache.evictAll()
276
280
  } catch (_: Throwable) {
277
281
  } finally {
278
- jobsById.remove(id)
282
+ jobsById.remove(m.id)
279
283
  }
280
284
  }
281
285
 
282
- jobsById[id] = job
286
+ jobsById[m.id] = job
283
287
  }
284
288
 
285
289
  fun cancelIconJob(id: String) {
@@ -329,27 +333,28 @@ class MapMarkerBuilder(
329
333
  coroutineContext.ensureActive()
330
334
  val svg = SVG.getFromString(m.iconSvg.svgString)
331
335
 
332
- coroutineContext.ensureActive()
333
- svg.setDocumentWidth(m.iconSvg.width.dpToPx())
334
- 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()
335
344
 
336
345
  coroutineContext.ensureActive()
337
- bmp =
338
- createBitmap(
339
- m.iconSvg.width
340
- .dpToPx()
341
- .toInt(),
342
- m.iconSvg.height
343
- .dpToPx()
344
- .toInt(),
345
- Bitmap.Config.ARGB_8888,
346
- )
346
+ svg.setDocumentWidth(wPx.toFloat())
347
+ svg.setDocumentHeight(hPx.toFloat())
347
348
 
348
349
  coroutineContext.ensureActive()
349
- val canvas = Canvas(bmp)
350
- 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
+ }
351
357
 
352
- coroutineContext.ensureActive()
353
358
  return bmp
354
359
  } catch (t: Throwable) {
355
360
  try {
@@ -151,7 +151,7 @@ class RNGoogleMapsPlusView(
151
151
  val prev = prevById[id]
152
152
  when {
153
153
  prev == null ->
154
- markerBuilder.buildIconAsync(id, next) { icon ->
154
+ markerBuilder.buildIconAsync(next) { icon ->
155
155
  view.addMarker(
156
156
  id,
157
157
  markerBuilder.build(next, icon),
@@ -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
@@ -51,8 +51,7 @@ final class MapMarkerBuilder {
51
51
  }
52
52
 
53
53
  if !prev.markerStyleEquals(next) {
54
- buildIconAsync(next.id, next) { img in
55
- m.tracksViewChanges = true
54
+ buildIconAsync(next) { img in
56
55
  m.icon = img
57
56
 
58
57
  if !prev.anchorEquals(next) {
@@ -69,9 +68,9 @@ final class MapMarkerBuilder {
69
68
  )
70
69
  }
71
70
 
72
- onMainAsync { [weak m] in
73
- try? await Task.sleep(nanoseconds: 250_000_000)
74
- m?.tracksViewChanges = false
71
+ m.tracksViewChanges = true
72
+ DispatchQueue.main.async {
73
+ m.tracksViewChanges = false
75
74
  }
76
75
  }
77
76
  } else {
@@ -102,11 +101,10 @@ final class MapMarkerBuilder {
102
101
  m.snippet = next.snippet
103
102
  }
104
103
 
105
- if(tracksInfoWindowChanges) {
104
+ if tracksInfoWindowChanges {
106
105
  m.tracksInfoWindowChanges = true
107
- onMainAsync { [weak m] in
108
- try? await Task.sleep(nanoseconds: 250_000_000)
109
- m?.tracksInfoWindowChanges = false
106
+ DispatchQueue.main.async {
107
+ m.tracksInfoWindowChanges = false
110
108
  }
111
109
  }
112
110
 
@@ -140,13 +138,11 @@ final class MapMarkerBuilder {
140
138
  }
141
139
  }
142
140
 
143
- @MainActor
144
141
  func buildIconAsync(
145
- _ id: String,
146
142
  _ m: RNMarker,
147
143
  onReady: @escaping (UIImage?) -> Void
148
144
  ) {
149
- tasks[id]?.cancel()
145
+ tasks[m.id]?.cancel()
150
146
 
151
147
  if m.iconSvg == nil {
152
148
  onReady(nil)
@@ -159,23 +155,29 @@ final class MapMarkerBuilder {
159
155
  return
160
156
  }
161
157
 
158
+ let scale = UIScreen.main.scale
159
+
162
160
  let task = Task(priority: .userInitiated) { [weak self] in
163
161
  guard let self else { return }
164
- defer { self.tasks.removeValue(forKey: id) }
162
+ defer {
163
+ Task { @MainActor in self.tasks.removeValue(forKey: m.id) }
164
+ }
165
165
 
166
- let scale = UIScreen.main.scale
167
- let img = await self.renderUIImage(m, scale)
166
+ let img = self.renderUIImage(m, scale)
168
167
  guard let img, !Task.isCancelled else { return }
169
168
 
170
169
  self.iconCache.setObject(img, forKey: key)
171
170
 
172
171
  await MainActor.run {
173
172
  guard !Task.isCancelled else { return }
173
+ }
174
+
175
+ Task { @MainActor in
174
176
  onReady(img)
175
177
  }
176
178
  }
177
179
 
178
- tasks[id] = task
180
+ tasks[m.id] = task
179
181
  }
180
182
 
181
183
  @MainActor
@@ -213,18 +215,11 @@ final class MapMarkerBuilder {
213
215
 
214
216
  svgImg.size = size
215
217
 
216
- guard let base = svgImg.uiImage else {
218
+ guard let finalImage = SVGKExporterUIImage.export(asUIImage: svgImg) else {
219
+ svgImg.clear()
217
220
  return nil
218
221
  }
219
-
220
- let fmt = UIGraphicsImageRendererFormat.default()
221
- fmt.opaque = false
222
- fmt.scale = UIScreen.main.scale
223
- let renderer = UIGraphicsImageRenderer(size: size, format: fmt)
224
-
225
- let finalImage = renderer.image { _ in
226
- base.draw(in: CGRect(origin: .zero, size: size))
227
- }
222
+ svgImg.clear()
228
223
 
229
224
  let imageView = UIImageView(image: finalImage)
230
225
  imageView.frame = CGRect(origin: .zero, size: size)
@@ -234,10 +229,10 @@ final class MapMarkerBuilder {
234
229
  return imageView
235
230
  }
236
231
 
237
- @MainActor
238
- private func renderUIImage(_ m: RNMarker, _ scale: CGFloat) async -> UIImage? {
239
- guard let iconSvg = m.iconSvg,
240
- let data = iconSvg.svgString.data(using: .utf8)
232
+ private func renderUIImage(_ m: RNMarker, _ scale: CGFloat) -> UIImage? {
233
+ guard
234
+ let iconSvg = m.iconSvg,
235
+ let data = iconSvg.svgString.data(using: .utf8)
241
236
  else { return nil }
242
237
 
243
238
  let size = CGSize(
@@ -245,28 +240,21 @@ final class MapMarkerBuilder {
245
240
  height: max(1, CGFloat(iconSvg.height))
246
241
  )
247
242
 
248
- return await Task.detached(priority: .userInitiated) {
249
- autoreleasepool {
250
- guard let svgImg = SVGKImage(data: data) else { return nil }
251
- svgImg.size = size
243
+ return autoreleasepool { () -> UIImage? in
244
+ guard !Task.isCancelled else { return nil }
245
+ guard let svgImg = SVGKImage(data: data) else { return nil }
252
246
 
253
- guard !Task.isCancelled else { return nil }
254
- guard let base = svgImg.uiImage else { return nil }
247
+ svgImg.size = size
255
248
 
256
- if let cg = base.cgImage {
257
- return UIImage(cgImage: cg, scale: scale, orientation: .up)
258
- }
259
- guard !Task.isCancelled else { return nil }
260
- let fmt = UIGraphicsImageRendererFormat.default()
261
- fmt.opaque = false
262
- fmt.scale = scale
263
- guard !Task.isCancelled else { return nil }
264
- let renderer = UIGraphicsImageRenderer(size: size, format: fmt)
265
- return renderer.image { _ in
266
- base.draw(in: CGRect(origin: .zero, size: size))
267
- }
249
+ guard !Task.isCancelled else {
250
+ svgImg.clear()
251
+ return nil
268
252
  }
269
- }.value
253
+
254
+ let uiImage = SVGKExporterUIImage.export(asUIImage: svgImg)
255
+ svgImg.clear()
256
+ return uiImage
257
+ }
270
258
  }
271
259
 
272
260
  }
@@ -141,12 +141,14 @@ final class RNGoogleMapsPlusView: HybridRNGoogleMapsPlusViewSpec {
141
141
  for (id, next) in nextById {
142
142
  if let prev = prevById[id] {
143
143
  if !prev.markerEquals(next) {
144
- self.impl.updateMarker(id: id) { m in
144
+ self.impl.updateMarker(id: id) { [weak self] m in
145
+ guard let self else { return }
145
146
  self.markerBuilder.update(prev, next, m)
146
147
  }
147
148
  }
148
149
  } else {
149
- self.markerBuilder.buildIconAsync(next.id, next) { icon in
150
+ self.markerBuilder.buildIconAsync(next) { [weak self] icon in
151
+ guard let self else { return }
150
152
  let marker = self.markerBuilder.build(next, icon: icon)
151
153
  self.impl.addMarker(id: id, marker: marker)
152
154
  }
@@ -174,7 +176,8 @@ final class RNGoogleMapsPlusView: HybridRNGoogleMapsPlusViewSpec {
174
176
  for (id, next) in nextById {
175
177
  if let prev = prevById[id] {
176
178
  if !prev.polylineEquals(next) {
177
- impl.updatePolyline(id: id) { pl in
179
+ impl.updatePolyline(id: id) { [weak self] pl in
180
+ guard let self else { return }
178
181
  self.polylineBuilder.update(prev, next, pl)
179
182
  }
180
183
  }
@@ -206,7 +209,8 @@ final class RNGoogleMapsPlusView: HybridRNGoogleMapsPlusViewSpec {
206
209
  for (id, next) in nextById {
207
210
  if let prev = prevById[id] {
208
211
  if !prev.polygonEquals(next) {
209
- impl.updatePolygon(id: id) { pg in
212
+ impl.updatePolygon(id: id) { [weak self] pg in
213
+ guard let self else { return }
210
214
  self.polygonBuilder.update(prev, next, pg)
211
215
  }
212
216
  }
@@ -235,7 +239,8 @@ final class RNGoogleMapsPlusView: HybridRNGoogleMapsPlusViewSpec {
235
239
  for (id, next) in nextById {
236
240
  if let prev = prevById[id] {
237
241
  if !prev.circleEquals(next) {
238
- impl.updateCircle(id: id) { circle in
242
+ impl.updateCircle(id: id) { [weak self] circle in
243
+ guard let self else { return }
239
244
  self.circleBuilder.update(prev, next, circle)
240
245
  }
241
246
  }
@@ -422,12 +427,12 @@ final class RNGoogleMapsPlusView: HybridRNGoogleMapsPlusViewSpec {
422
427
 
423
428
  @MainActor
424
429
  func showMarkerInfoWindow(id: String) {
425
- impl.showMarkerInfoWindow(id: id);
430
+ impl.showMarkerInfoWindow(id: id)
426
431
  }
427
432
 
428
433
  @MainActor
429
434
  func hideMarkerInfoWindow(id: String) {
430
- impl.hideMarkerInfoWindow(id: id);
435
+ impl.hideMarkerInfoWindow(id: id)
431
436
  }
432
437
 
433
438
  @MainActor
@@ -0,0 +1,22 @@
1
+ import SVGKit
2
+
3
+ extension SVGKImage {
4
+ @inline(__always)
5
+ func clear() {
6
+ caLayerTree?.sublayers?.forEach { $0.removeFromSuperlayer() }
7
+ if let layer = caLayerTree {
8
+ layer.sublayers?.forEach { $0.removeFromSuperlayer() }
9
+ layer.removeFromSuperlayer()
10
+ }
11
+
12
+ if let dom = domDocument {
13
+ dom.childNodes = nil
14
+ }
15
+
16
+ if let root = domTree {
17
+ root.childNodes = nil
18
+ }
19
+
20
+ caLayerTree.sublayers?.removeAll()
21
+ }
22
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-google-maps-plus",
3
- "version": "1.7.0-dev.14",
3
+ "version": "1.7.0-dev.16",
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",