react-native-google-maps-plus 1.7.0-dev.9 → 1.8.0
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.
- package/android/build.gradle +1 -1
- package/android/gradle.properties +2 -1
- package/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt +120 -124
- package/android/src/main/java/com/rngooglemapsplus/MapCircleBuilder.kt +2 -3
- package/android/src/main/java/com/rngooglemapsplus/MapMarkerBuilder.kt +83 -53
- package/android/src/main/java/com/rngooglemapsplus/MapPolygonBuilder.kt +6 -23
- package/android/src/main/java/com/rngooglemapsplus/MapPolylineBuilder.kt.kt +12 -39
- package/android/src/main/java/com/rngooglemapsplus/RNGoogleMapsPlusView.kt +30 -12
- package/android/src/main/java/com/rngooglemapsplus/extensions/BitmapExtension.kt +35 -0
- package/android/src/main/java/com/rngooglemapsplus/extensions/LatLngBoundsExtension.kt +31 -0
- package/android/src/main/java/com/rngooglemapsplus/extensions/MapObjectTagExtensions.kt +84 -0
- package/android/src/main/java/com/rngooglemapsplus/extensions/RNLineCapTypeExtension.kt +14 -0
- package/android/src/main/java/com/rngooglemapsplus/extensions/RNLineJoinTypeExtension.kt +12 -0
- package/android/src/main/java/com/rngooglemapsplus/extensions/RNMapCircleExtension.kt +7 -1
- package/android/src/main/java/com/rngooglemapsplus/extensions/RNMarkerExtension.kt +54 -17
- package/android/src/main/java/com/rngooglemapsplus/extensions/RNPolygonExtension.kt +31 -1
- package/android/src/main/java/com/rngooglemapsplus/extensions/RNPolylineExtension.kt +6 -1
- package/ios/GoogleMapViewImpl.swift +81 -64
- package/ios/MapCircleBuilder.swift +2 -3
- package/ios/MapMarkerBuilder.swift +106 -50
- package/ios/MapPolygonBuilder.swift +6 -41
- package/ios/MapPolylineBuilder.swift +2 -10
- package/ios/RNGoogleMapsPlusView.swift +24 -11
- package/ios/extensions/MapObjectTag+Extension.swift +93 -0
- package/ios/extensions/RNCircle+Extension.swift +14 -5
- package/ios/extensions/RNLatLng+Extension.swift +11 -0
- package/ios/extensions/RNLineCapType+Extension.swift +10 -0
- package/ios/extensions/RNLineJoinType+Extension.swift +11 -0
- package/ios/extensions/RNMarker+Extension.swift +43 -12
- package/ios/extensions/RNPolygon+Extension.swift.swift +50 -21
- package/ios/extensions/RNPolyline+Extension.swift.swift +15 -26
- package/ios/extensions/UIImage+Extension.swift +45 -0
- package/lib/module/types.js.map +1 -1
- package/lib/typescript/src/RNGoogleMapsPlusView.nitro.d.ts +12 -10
- package/lib/typescript/src/RNGoogleMapsPlusView.nitro.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +2 -1
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/nitrogen/generated/android/RNGoogleMapsPlusOnLoad.cpp +4 -4
- package/nitrogen/generated/android/c++/JFunc_void_std__string.hpp +75 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__string_RNLatLng.hpp +77 -0
- package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusViewSpec.cpp +100 -92
- package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusViewSpec.hpp +22 -20
- package/nitrogen/generated/android/c++/JRNInitialProps.hpp +7 -3
- package/nitrogen/generated/android/c++/JRNMarker.hpp +7 -7
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/{Func_void_std__optional_std__string_.kt → Func_void_std__string.kt} +12 -12
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/{Func_void_std__optional_std__string__RNLatLng.kt → Func_void_std__string_RNLatLng.kt} +12 -12
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/HybridRNGoogleMapsPlusViewSpec.kt +38 -30
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNInitialProps.kt +6 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNMarker.kt +6 -6
- package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Bridge.cpp +16 -8
- package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Bridge.hpp +58 -36
- package/nitrogen/generated/ios/c++/HybridRNGoogleMapsPlusViewSpecSwift.hpp +32 -20
- package/nitrogen/generated/ios/swift/Func_void_std__optional_std__string_.swift +6 -6
- package/nitrogen/generated/ios/swift/Func_void_std__string.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_std__string_RNLatLng.swift +47 -0
- package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusViewSpec.swift +12 -10
- package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusViewSpec_cxx.swift +142 -180
- package/nitrogen/generated/ios/swift/RNInitialProps.swift +31 -1
- package/nitrogen/generated/ios/swift/RNMarker.swift +24 -31
- package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusViewSpec.cpp +2 -0
- package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusViewSpec.hpp +22 -20
- package/nitrogen/generated/shared/c++/RNInitialProps.hpp +6 -2
- package/nitrogen/generated/shared/c++/RNMarker.hpp +6 -6
- package/nitrogen/generated/shared/c++/views/HybridRNGoogleMapsPlusViewComponent.cpp +20 -20
- package/nitrogen/generated/shared/c++/views/HybridRNGoogleMapsPlusViewComponent.hpp +10 -10
- package/package.json +1 -1
- package/src/RNGoogleMapsPlusView.nitro.ts +14 -10
- package/src/types.ts +2 -1
- package/nitrogen/generated/android/c++/JFunc_void_std__optional_std__string_.hpp +0 -76
- package/nitrogen/generated/android/c++/JFunc_void_std__optional_std__string__RNLatLng.hpp +0 -78
- package/nitrogen/generated/ios/swift/Func_void_std__optional_std__string__RNLatLng.swift +0 -54
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
package com.rngooglemapsplus
|
|
2
2
|
|
|
3
|
+
import MarkerTag
|
|
3
4
|
import android.graphics.Bitmap
|
|
4
5
|
import android.graphics.BitmapFactory
|
|
5
6
|
import android.graphics.Canvas
|
|
6
7
|
import android.graphics.Typeface
|
|
8
|
+
import android.graphics.drawable.PictureDrawable
|
|
7
9
|
import android.util.Base64
|
|
8
10
|
import android.util.LruCache
|
|
11
|
+
import android.widget.ImageView
|
|
12
|
+
import android.widget.LinearLayout
|
|
9
13
|
import androidx.core.graphics.createBitmap
|
|
10
14
|
import com.caverock.androidsvg.SVG
|
|
11
15
|
import com.caverock.androidsvg.SVGExternalFileResolver
|
|
@@ -15,6 +19,10 @@ import com.google.android.gms.maps.model.BitmapDescriptor
|
|
|
15
19
|
import com.google.android.gms.maps.model.BitmapDescriptorFactory
|
|
16
20
|
import com.google.android.gms.maps.model.Marker
|
|
17
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
|
|
18
26
|
import com.rngooglemapsplus.extensions.markerStyleEquals
|
|
19
27
|
import com.rngooglemapsplus.extensions.onUi
|
|
20
28
|
import com.rngooglemapsplus.extensions.styleHash
|
|
@@ -69,7 +77,10 @@ class MapMarkerBuilder(
|
|
|
69
77
|
val height = (svg.documentHeight.takeIf { it > 0 } ?: 128f).toInt()
|
|
70
78
|
|
|
71
79
|
createBitmap(width, height).apply {
|
|
72
|
-
|
|
80
|
+
density = context.resources.displayMetrics.densityDpi
|
|
81
|
+
Canvas(this).also {
|
|
82
|
+
svg.renderToCanvas(it)
|
|
83
|
+
}
|
|
73
84
|
}
|
|
74
85
|
}
|
|
75
86
|
|
|
@@ -90,10 +101,12 @@ class MapMarkerBuilder(
|
|
|
90
101
|
val innerSvg = SVG.getFromString(svgText)
|
|
91
102
|
val w = innerSvg.documentWidth.takeIf { it > 0 } ?: 128f
|
|
92
103
|
val h = innerSvg.documentHeight.takeIf { it > 0 } ?: 128f
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
104
|
+
createBitmap(w.toInt(), h.toInt()).apply {
|
|
105
|
+
density = context.resources.displayMetrics.densityDpi
|
|
106
|
+
Canvas(this).also {
|
|
107
|
+
innerSvg.renderToCanvas(it)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
97
110
|
} else {
|
|
98
111
|
conn.inputStream.use { BitmapFactory.decodeStream(it) }
|
|
99
112
|
}
|
|
@@ -165,51 +178,39 @@ class MapMarkerBuilder(
|
|
|
165
178
|
next: RNMarker,
|
|
166
179
|
marker: Marker,
|
|
167
180
|
) = onUi {
|
|
168
|
-
if (prev.
|
|
169
|
-
prev.coordinate.longitude != next.coordinate.longitude
|
|
170
|
-
) {
|
|
181
|
+
if (!prev.coordinatesEquals(next)) {
|
|
171
182
|
marker.position = next.coordinate.toLatLng()
|
|
172
183
|
}
|
|
173
184
|
|
|
174
185
|
if (!prev.markerStyleEquals(next)) {
|
|
175
|
-
buildIconAsync(
|
|
186
|
+
buildIconAsync(next) { icon ->
|
|
176
187
|
marker.setIcon(icon)
|
|
177
|
-
if (prev.
|
|
178
|
-
prev.infoWindowAnchor?.y != next.infoWindowAnchor?.y
|
|
179
|
-
) {
|
|
180
|
-
marker.setInfoWindowAnchor(
|
|
181
|
-
(next.infoWindowAnchor?.x ?: 0.5f).toFloat(),
|
|
182
|
-
(next.infoWindowAnchor?.y ?: 0f).toFloat(),
|
|
183
|
-
)
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
if (prev.anchor?.x != next.anchor?.x ||
|
|
187
|
-
prev.anchor?.y != next.anchor?.y
|
|
188
|
-
) {
|
|
188
|
+
if (!prev.anchorEquals(next)) {
|
|
189
189
|
marker.setAnchor(
|
|
190
190
|
(next.anchor?.x ?: 0.5f).toFloat(),
|
|
191
191
|
(next.anchor?.y ?: 1.0f).toFloat(),
|
|
192
192
|
)
|
|
193
193
|
}
|
|
194
|
+
if (!prev.infoWindowAnchorEquals(next)) {
|
|
195
|
+
marker.setInfoWindowAnchor(
|
|
196
|
+
(next.infoWindowAnchor?.x ?: 0.5f).toFloat(),
|
|
197
|
+
(next.infoWindowAnchor?.y ?: 0f).toFloat(),
|
|
198
|
+
)
|
|
199
|
+
}
|
|
194
200
|
}
|
|
195
201
|
} else {
|
|
196
|
-
if (prev.
|
|
197
|
-
prev.infoWindowAnchor?.y != next.infoWindowAnchor?.y
|
|
198
|
-
) {
|
|
199
|
-
marker.setInfoWindowAnchor(
|
|
200
|
-
(next.infoWindowAnchor?.x ?: 0.5f).toFloat(),
|
|
201
|
-
(next.infoWindowAnchor?.y ?: 0f).toFloat(),
|
|
202
|
-
)
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
if (prev.anchor?.x != next.anchor?.x ||
|
|
206
|
-
prev.anchor?.y != next.anchor?.y
|
|
207
|
-
) {
|
|
202
|
+
if (!prev.anchorEquals(next)) {
|
|
208
203
|
marker.setAnchor(
|
|
209
204
|
(next.anchor?.x ?: 0.5f).toFloat(),
|
|
210
205
|
(next.anchor?.y ?: 1.0f).toFloat(),
|
|
211
206
|
)
|
|
212
207
|
}
|
|
208
|
+
if (!prev.infoWindowAnchorEquals(next)) {
|
|
209
|
+
marker.setInfoWindowAnchor(
|
|
210
|
+
(next.infoWindowAnchor?.x ?: 0.5f).toFloat(),
|
|
211
|
+
(next.infoWindowAnchor?.y ?: 0f).toFloat(),
|
|
212
|
+
)
|
|
213
|
+
}
|
|
213
214
|
}
|
|
214
215
|
|
|
215
216
|
if (prev.title != next.title) {
|
|
@@ -239,14 +240,17 @@ class MapMarkerBuilder(
|
|
|
239
240
|
if (prev.zIndex != next.zIndex) {
|
|
240
241
|
marker.zIndex = next.zIndex?.toFloat() ?: 0f
|
|
241
242
|
}
|
|
243
|
+
|
|
244
|
+
if (!prev.markerInfoWindowStyleEquals(next)) {
|
|
245
|
+
marker.tag = MarkerTag(id = next.id, iconSvg = next.infoWindowIconSvg)
|
|
246
|
+
}
|
|
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) {
|
|
@@ -296,6 +300,31 @@ class MapMarkerBuilder(
|
|
|
296
300
|
iconCache.evictAll()
|
|
297
301
|
}
|
|
298
302
|
|
|
303
|
+
fun buildInfoWindow(iconSvg: RNMarkerSvg?): ImageView? {
|
|
304
|
+
val iconSvg = iconSvg ?: return null
|
|
305
|
+
|
|
306
|
+
val svgView =
|
|
307
|
+
ImageView(context).apply {
|
|
308
|
+
layoutParams =
|
|
309
|
+
LinearLayout.LayoutParams(
|
|
310
|
+
iconSvg.width.dpToPx().toInt(),
|
|
311
|
+
iconSvg.height.dpToPx().toInt(),
|
|
312
|
+
)
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
try {
|
|
316
|
+
val svg = SVG.getFromString(iconSvg.svgString)
|
|
317
|
+
svg.setDocumentWidth(iconSvg.width.dpToPx())
|
|
318
|
+
svg.setDocumentHeight(iconSvg.height.dpToPx())
|
|
319
|
+
val drawable = PictureDrawable(svg.renderToPicture())
|
|
320
|
+
svgView.setImageDrawable(drawable)
|
|
321
|
+
} catch (e: Exception) {
|
|
322
|
+
return null
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
return svgView
|
|
326
|
+
}
|
|
327
|
+
|
|
299
328
|
private suspend fun renderBitmap(m: RNMarker): Bitmap? {
|
|
300
329
|
m.iconSvg ?: return null
|
|
301
330
|
|
|
@@ -304,27 +333,28 @@ class MapMarkerBuilder(
|
|
|
304
333
|
coroutineContext.ensureActive()
|
|
305
334
|
val svg = SVG.getFromString(m.iconSvg.svgString)
|
|
306
335
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
336
|
+
val wPx =
|
|
337
|
+
m.iconSvg.width
|
|
338
|
+
.dpToPx()
|
|
339
|
+
.toInt()
|
|
340
|
+
val hPx =
|
|
341
|
+
m.iconSvg.height
|
|
342
|
+
.dpToPx()
|
|
343
|
+
.toInt()
|
|
310
344
|
|
|
311
345
|
coroutineContext.ensureActive()
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
m.iconSvg.width
|
|
315
|
-
.dpToPx()
|
|
316
|
-
.toInt(),
|
|
317
|
-
m.iconSvg.height
|
|
318
|
-
.dpToPx()
|
|
319
|
-
.toInt(),
|
|
320
|
-
Bitmap.Config.ARGB_8888,
|
|
321
|
-
)
|
|
346
|
+
svg.setDocumentWidth(wPx.toFloat())
|
|
347
|
+
svg.setDocumentHeight(hPx.toFloat())
|
|
322
348
|
|
|
323
349
|
coroutineContext.ensureActive()
|
|
324
|
-
|
|
325
|
-
|
|
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
|
+
}
|
|
326
357
|
|
|
327
|
-
coroutineContext.ensureActive()
|
|
328
358
|
return bmp
|
|
329
359
|
} catch (t: Throwable) {
|
|
330
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
|
-
|
|
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
|
-
|
|
46
|
-
|
|
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.
|
|
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(
|
|
25
|
-
endCap(
|
|
22
|
+
startCap(it.toMapLineCap())
|
|
23
|
+
endCap(it.toMapLineCap())
|
|
26
24
|
}
|
|
27
|
-
pl.lineJoin?.let { jointType(
|
|
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
|
-
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
|
|
61
|
-
|
|
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
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
package com.rngooglemapsplus
|
|
2
2
|
|
|
3
|
+
import MarkerTag
|
|
3
4
|
import com.facebook.proguard.annotations.DoNotStrip
|
|
4
5
|
import com.facebook.react.uimanager.ThemedReactContext
|
|
5
6
|
import com.google.android.gms.maps.GoogleMapOptions
|
|
@@ -11,6 +12,7 @@ import com.rngooglemapsplus.extensions.markerEquals
|
|
|
11
12
|
import com.rngooglemapsplus.extensions.polygonEquals
|
|
12
13
|
import com.rngooglemapsplus.extensions.polylineEquals
|
|
13
14
|
import com.rngooglemapsplus.extensions.toCameraPosition
|
|
15
|
+
import com.rngooglemapsplus.extensions.toColor
|
|
14
16
|
import com.rngooglemapsplus.extensions.toCompressFormat
|
|
15
17
|
import com.rngooglemapsplus.extensions.toFileExtension
|
|
16
18
|
import com.rngooglemapsplus.extensions.toGoogleMapType
|
|
@@ -47,6 +49,7 @@ class RNGoogleMapsPlusView(
|
|
|
47
49
|
initialProps?.mapId?.let { mapId(it) }
|
|
48
50
|
initialProps?.liteMode?.let { liteMode(it) }
|
|
49
51
|
initialProps?.camera?.let { camera(it.toCameraPosition(current = null)) }
|
|
52
|
+
initialProps?.backgroundColor?.let { backgroundColor(it.toColor()) }
|
|
50
53
|
}
|
|
51
54
|
view.initMapView(options)
|
|
52
55
|
}
|
|
@@ -148,8 +151,15 @@ class RNGoogleMapsPlusView(
|
|
|
148
151
|
val prev = prevById[id]
|
|
149
152
|
when {
|
|
150
153
|
prev == null ->
|
|
151
|
-
markerBuilder.buildIconAsync(
|
|
152
|
-
view.addMarker(
|
|
154
|
+
markerBuilder.buildIconAsync(next) { icon ->
|
|
155
|
+
view.addMarker(
|
|
156
|
+
id,
|
|
157
|
+
markerBuilder.build(next, icon),
|
|
158
|
+
MarkerTag(
|
|
159
|
+
id = id,
|
|
160
|
+
iconSvg = next.infoWindowIconSvg,
|
|
161
|
+
),
|
|
162
|
+
)
|
|
153
163
|
}
|
|
154
164
|
|
|
155
165
|
!prev.markerEquals(next) ->
|
|
@@ -320,7 +330,7 @@ class RNGoogleMapsPlusView(
|
|
|
320
330
|
view.onMapLongPress = cb
|
|
321
331
|
}
|
|
322
332
|
|
|
323
|
-
override var onMarkerPress: ((String
|
|
333
|
+
override var onMarkerPress: ((String) -> Unit)? = null
|
|
324
334
|
set(cb) {
|
|
325
335
|
view.onMarkerPress = cb
|
|
326
336
|
}
|
|
@@ -330,32 +340,32 @@ class RNGoogleMapsPlusView(
|
|
|
330
340
|
view.onPoiPress = cb
|
|
331
341
|
}
|
|
332
342
|
|
|
333
|
-
override var onPolylinePress: ((String
|
|
343
|
+
override var onPolylinePress: ((String) -> Unit)? = null
|
|
334
344
|
set(cb) {
|
|
335
345
|
view.onPolylinePress = cb
|
|
336
346
|
}
|
|
337
347
|
|
|
338
|
-
override var onPolygonPress: ((String
|
|
348
|
+
override var onPolygonPress: ((String) -> Unit)? = null
|
|
339
349
|
set(cb) {
|
|
340
350
|
view.onPolygonPress = cb
|
|
341
351
|
}
|
|
342
352
|
|
|
343
|
-
override var onCirclePress: ((String
|
|
353
|
+
override var onCirclePress: ((String) -> Unit)? = null
|
|
344
354
|
set(cb) {
|
|
345
355
|
view.onCirclePress = cb
|
|
346
356
|
}
|
|
347
357
|
|
|
348
|
-
override var onMarkerDragStart: ((String
|
|
358
|
+
override var onMarkerDragStart: ((String, RNLatLng) -> Unit)? = null
|
|
349
359
|
set(cb) {
|
|
350
360
|
view.onMarkerDragStart = cb
|
|
351
361
|
}
|
|
352
362
|
|
|
353
|
-
override var onMarkerDrag: ((String
|
|
363
|
+
override var onMarkerDrag: ((String, RNLatLng) -> Unit)? = null
|
|
354
364
|
set(cb) {
|
|
355
365
|
view.onMarkerDrag = cb
|
|
356
366
|
}
|
|
357
367
|
|
|
358
|
-
override var onMarkerDragEnd: ((String
|
|
368
|
+
override var onMarkerDragEnd: ((String, RNLatLng) -> Unit)? = null
|
|
359
369
|
set(cb) {
|
|
360
370
|
view.onMarkerDragEnd = cb
|
|
361
371
|
}
|
|
@@ -370,17 +380,17 @@ class RNGoogleMapsPlusView(
|
|
|
370
380
|
view.onIndoorLevelActivated = cb
|
|
371
381
|
}
|
|
372
382
|
|
|
373
|
-
override var onInfoWindowPress: ((String
|
|
383
|
+
override var onInfoWindowPress: ((String) -> Unit)? = null
|
|
374
384
|
set(cb) {
|
|
375
385
|
view.onInfoWindowPress = cb
|
|
376
386
|
}
|
|
377
387
|
|
|
378
|
-
override var onInfoWindowClose: ((String
|
|
388
|
+
override var onInfoWindowClose: ((String) -> Unit)? = null
|
|
379
389
|
set(cb) {
|
|
380
390
|
view.onInfoWindowClose = cb
|
|
381
391
|
}
|
|
382
392
|
|
|
383
|
-
override var onInfoWindowLongPress: ((String
|
|
393
|
+
override var onInfoWindowLongPress: ((String) -> Unit)? = null
|
|
384
394
|
set(cb) {
|
|
385
395
|
view.onInfoWindowLongPress = cb
|
|
386
396
|
}
|
|
@@ -410,6 +420,14 @@ class RNGoogleMapsPlusView(
|
|
|
410
420
|
view.onCameraChangeComplete = cb
|
|
411
421
|
}
|
|
412
422
|
|
|
423
|
+
override fun showMarkerInfoWindow(id: String) {
|
|
424
|
+
view.showMarkerInfoWindow(id)
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
override fun hideMarkerInfoWindow(id: String) {
|
|
428
|
+
view.hideMarkerInfoWindow(id)
|
|
429
|
+
}
|
|
430
|
+
|
|
413
431
|
override fun setCamera(
|
|
414
432
|
camera: RNCamera,
|
|
415
433
|
animated: Boolean?,
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import android.util.Log
|
|
2
|
+
import com.google.android.gms.maps.model.Circle
|
|
3
|
+
import com.google.android.gms.maps.model.Marker
|
|
4
|
+
import com.google.android.gms.maps.model.Polygon
|
|
5
|
+
import com.google.android.gms.maps.model.Polyline
|
|
6
|
+
import com.rngooglemapsplus.RNMarkerSvg
|
|
7
|
+
|
|
8
|
+
sealed class MapObjectTag(
|
|
9
|
+
open val id: String,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
data class MarkerTag(
|
|
13
|
+
override val id: String,
|
|
14
|
+
val iconSvg: RNMarkerSvg? = null,
|
|
15
|
+
) : MapObjectTag(id)
|
|
16
|
+
|
|
17
|
+
data class PolylineTag(
|
|
18
|
+
override val id: String,
|
|
19
|
+
) : MapObjectTag(id)
|
|
20
|
+
|
|
21
|
+
data class PolygonTag(
|
|
22
|
+
override val id: String,
|
|
23
|
+
) : MapObjectTag(id)
|
|
24
|
+
|
|
25
|
+
data class CircleTag(
|
|
26
|
+
override val id: String,
|
|
27
|
+
) : MapObjectTag(id)
|
|
28
|
+
|
|
29
|
+
val Marker.tagData: MarkerTag
|
|
30
|
+
get() =
|
|
31
|
+
(tag as? MarkerTag) ?: run {
|
|
32
|
+
Log.w("MapTag", "Marker without tag detected at $position")
|
|
33
|
+
val fallback = MarkerTag(id = "unknown")
|
|
34
|
+
tag = fallback
|
|
35
|
+
fallback
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
val Marker.idTag: String
|
|
39
|
+
get() = tagData.id
|
|
40
|
+
|
|
41
|
+
var Polyline.tagData: PolylineTag
|
|
42
|
+
get() =
|
|
43
|
+
(tag as? PolylineTag) ?: run {
|
|
44
|
+
Log.w("MapTag", "Polyline without tag detected")
|
|
45
|
+
val fallback = PolylineTag(id = "unknown")
|
|
46
|
+
tag = fallback
|
|
47
|
+
fallback
|
|
48
|
+
}
|
|
49
|
+
set(value) {
|
|
50
|
+
tag = value
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
val Polyline.idTag: String
|
|
54
|
+
get() = tagData.id
|
|
55
|
+
|
|
56
|
+
var Polygon.tagData: PolygonTag
|
|
57
|
+
get() =
|
|
58
|
+
(tag as? PolygonTag) ?: run {
|
|
59
|
+
Log.w("MapTag", "Polygon without tag detected")
|
|
60
|
+
val fallback = PolygonTag(id = "unknown")
|
|
61
|
+
tag = fallback
|
|
62
|
+
fallback
|
|
63
|
+
}
|
|
64
|
+
set(value) {
|
|
65
|
+
tag = value
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
val Polygon.idTag: String
|
|
69
|
+
get() = tagData.id
|
|
70
|
+
|
|
71
|
+
var Circle.tagData: CircleTag
|
|
72
|
+
get() =
|
|
73
|
+
(tag as? CircleTag) ?: run {
|
|
74
|
+
Log.w("MapTag", "Circle without tag detected")
|
|
75
|
+
val fallback = CircleTag(id = "unknown")
|
|
76
|
+
tag = fallback
|
|
77
|
+
fallback
|
|
78
|
+
}
|
|
79
|
+
set(value) {
|
|
80
|
+
tag = value
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
val Circle.idTag: String
|
|
84
|
+
get() = tagData.id
|
|
@@ -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
|
+
}
|