react-native-google-maps-plus 1.7.0-dev.1 → 1.7.0-dev.11
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/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt +457 -451
- package/android/src/main/java/com/rngooglemapsplus/LocationHandler.kt +3 -8
- package/android/src/main/java/com/rngooglemapsplus/MapCircleBuilder.kt +2 -1
- package/android/src/main/java/com/rngooglemapsplus/MapHeatmapBuilder.kt +1 -1
- package/android/src/main/java/com/rngooglemapsplus/MapHelper.kt +22 -0
- package/android/src/main/java/com/rngooglemapsplus/MapMarkerBuilder.kt +103 -2
- package/android/src/main/java/com/rngooglemapsplus/MapPolygonBuilder.kt +2 -1
- package/android/src/main/java/com/rngooglemapsplus/MapPolylineBuilder.kt.kt +2 -1
- package/android/src/main/java/com/rngooglemapsplus/MapUrlTileOverlayBuilder.kt +40 -0
- package/android/src/main/java/com/rngooglemapsplus/RNGoogleMapsPlusView.kt +84 -34
- package/android/src/main/java/com/rngooglemapsplus/extensions/LatLngBoundsExtension.kt +10 -0
- package/android/src/main/java/com/rngooglemapsplus/extensions/MapObjectTagExtensions.kt +84 -0
- package/android/src/main/java/com/rngooglemapsplus/extensions/RNLatLngBoundsExtension.kt +2 -8
- package/android/src/main/java/com/rngooglemapsplus/extensions/RNMapTypeExtension.kt +13 -0
- package/android/src/main/java/com/rngooglemapsplus/extensions/VisibleRegionExtension.kt +13 -0
- package/ios/GoogleMapViewImpl.swift +164 -48
- package/ios/MapCircleBuilder.swift +2 -0
- package/ios/MapHeatmapBuilder.swift +2 -1
- package/ios/MapMarkerBuilder.swift +54 -1
- package/ios/MapPolygonBuilder.swift +2 -0
- package/ios/MapPolylineBuilder.swift +2 -0
- package/ios/MapUrlTileOverlayBuilder.swift +24 -0
- package/ios/RNGoogleMapsPlusView.swift +68 -11
- package/ios/extensions/GMSCoordinateBounds+Extension.swift +4 -13
- package/ios/extensions/GMSVisibleRegion+Extension.swift +14 -0
- package/ios/extensions/MapObjectTag+Extension.swift +93 -0
- package/ios/extensions/RNLatLngBounds+Extension.swift +4 -4
- package/ios/extensions/RNMapType+Extension.swift +18 -0
- package/lib/module/types.js.map +1 -1
- package/lib/nitrogen/generated/shared/json/RNGoogleMapsPlusViewConfig.json +7 -0
- package/lib/typescript/src/RNGoogleMapsPlusView.nitro.d.ts +18 -9
- package/lib/typescript/src/RNGoogleMapsPlusView.nitro.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +18 -5
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/nitrogen/generated/android/RNGoogleMapsPlusOnLoad.cpp +8 -4
- package/nitrogen/generated/android/c++/JFunc_void_RNRegion_RNCamera.hpp +83 -0
- package/nitrogen/generated/android/c++/JFunc_void_RNRegion_RNCamera_bool.hpp +2 -0
- 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++/JFunc_void_std__string_std__string_RNLatLng.hpp +77 -0
- package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusViewSpec.cpp +237 -83
- package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusViewSpec.hpp +32 -16
- package/nitrogen/generated/android/c++/JRNLatLngBounds.hpp +8 -8
- package/nitrogen/generated/android/c++/JRNMapUiSettings.hpp +11 -3
- package/nitrogen/generated/android/c++/JRNMarker.hpp +7 -3
- package/nitrogen/generated/android/c++/JRNRegion.hpp +23 -13
- package/nitrogen/generated/android/c++/JRNUrlTileOverlay.hpp +78 -0
- package/nitrogen/generated/android/c++/views/JHybridRNGoogleMapsPlusViewStateUpdater.cpp +28 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/Func_void_RNRegion_RNCamera.kt +81 -0
- 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/Func_void_std__string_std__string_RNLatLng.kt +81 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/HybridRNGoogleMapsPlusViewSpec.kt +122 -24
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNLatLngBounds.kt +4 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNMapUiSettings.kt +9 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNMarker.kt +6 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNRegion.kt +11 -5
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNUrlTileOverlay.kt +52 -0
- package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Bridge.cpp +32 -8
- package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Bridge.hpp +168 -43
- package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Umbrella.hpp +3 -0
- package/nitrogen/generated/ios/c++/HybridRNGoogleMapsPlusViewSpecSwift.hpp +86 -22
- package/nitrogen/generated/ios/c++/views/HybridRNGoogleMapsPlusViewComponent.mm +35 -0
- package/nitrogen/generated/ios/swift/Func_void_RNRegion_RNCamera.swift +47 -0
- 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/Func_void_std__string_std__string_RNLatLng.swift +47 -0
- package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusViewSpec.swift +17 -8
- package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusViewSpec_cxx.swift +340 -138
- package/nitrogen/generated/ios/swift/RNLatLngBounds.swift +8 -8
- package/nitrogen/generated/ios/swift/RNMapUiSettings.swift +61 -1
- package/nitrogen/generated/ios/swift/RNMarker.swift +24 -1
- package/nitrogen/generated/ios/swift/RNRegion.swift +33 -11
- package/nitrogen/generated/ios/swift/RNUrlTileOverlay.swift +133 -0
- package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusViewSpec.cpp +16 -0
- package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusViewSpec.hpp +41 -22
- package/nitrogen/generated/shared/c++/RNLatLngBounds.hpp +9 -9
- package/nitrogen/generated/shared/c++/RNMapUiSettings.hpp +10 -2
- package/nitrogen/generated/shared/c++/RNMarker.hpp +6 -2
- package/nitrogen/generated/shared/c++/RNRegion.hpp +24 -13
- package/nitrogen/generated/shared/c++/RNUrlTileOverlay.hpp +96 -0
- package/nitrogen/generated/shared/c++/views/HybridRNGoogleMapsPlusViewComponent.cpp +100 -16
- package/nitrogen/generated/shared/c++/views/HybridRNGoogleMapsPlusViewComponent.hpp +18 -10
- package/nitrogen/generated/shared/json/RNGoogleMapsPlusViewConfig.json +7 -0
- package/package.json +4 -2
- package/src/RNGoogleMapsPlusView.nitro.ts +20 -8
- package/src/types.ts +19 -5
- package/android/src/main/java/com/rngooglemapsplus/extensions/LatLngBounds.kt +0 -15
- 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
- /package/android/src/main/java/com/rngooglemapsplus/extensions/{RNSize.kt → RNSizeExtension.kt} +0 -0
- /package/android/src/main/java/com/rngooglemapsplus/extensions/{RNSnapshotFormat.kt → RNSnapshotFormatExtension.kt} +0 -0
- /package/android/src/main/java/com/rngooglemapsplus/extensions/{RNSnapshotResultType.kt → RNSnapshotResultTypeExtension.kt} +0 -0
|
@@ -38,7 +38,6 @@ class LocationHandler(
|
|
|
38
38
|
private var priority: Int = PRIORITY_DEFAULT
|
|
39
39
|
private var interval: Long = INTERVAL_DEFAULT
|
|
40
40
|
private var minUpdateInterval: Long = MIN_UPDATE_INTERVAL
|
|
41
|
-
private var lastSubmittedLocation: Location? = null
|
|
42
41
|
private var isActive = false
|
|
43
42
|
|
|
44
43
|
var onUpdate: ((Location) -> Unit)? = null
|
|
@@ -145,9 +144,8 @@ class LocationHandler(
|
|
|
145
144
|
fusedLocationClientProviderClient.lastLocation
|
|
146
145
|
.addOnSuccessListener(
|
|
147
146
|
OnSuccessListener { location ->
|
|
148
|
-
if (location != null
|
|
147
|
+
if (location != null) {
|
|
149
148
|
onUpdate?.invoke(location)
|
|
150
|
-
lastSubmittedLocation = location
|
|
151
149
|
}
|
|
152
150
|
},
|
|
153
151
|
).addOnFailureListener { e ->
|
|
@@ -159,11 +157,8 @@ class LocationHandler(
|
|
|
159
157
|
override fun onLocationResult(locationResult: LocationResult) {
|
|
160
158
|
val location = locationResult.lastLocation
|
|
161
159
|
if (location != null) {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
listener?.onLocationChanged(location)
|
|
165
|
-
onUpdate?.invoke(location)
|
|
166
|
-
}
|
|
160
|
+
listener?.onLocationChanged(location)
|
|
161
|
+
onUpdate?.invoke(location)
|
|
167
162
|
} else {
|
|
168
163
|
onError?.invoke(RNLocationErrorCode.POSITION_UNAVAILABLE)
|
|
169
164
|
}
|
|
@@ -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.onUi
|
|
7
8
|
import com.rngooglemapsplus.extensions.toColor
|
|
8
9
|
import com.rngooglemapsplus.extensions.toLatLng
|
|
9
10
|
|
|
@@ -23,7 +24,7 @@ class MapCircleBuilder {
|
|
|
23
24
|
prev: RNCircle,
|
|
24
25
|
next: RNCircle,
|
|
25
26
|
circle: Circle,
|
|
26
|
-
) {
|
|
27
|
+
) = onUi {
|
|
27
28
|
if (prev.center.latitude != next.center.latitude ||
|
|
28
29
|
prev.center.longitude != next.center.longitude
|
|
29
30
|
) {
|
|
@@ -19,7 +19,7 @@ class MapHeatmapBuilder {
|
|
|
19
19
|
heatmap.gradient?.let {
|
|
20
20
|
val colors = it.colors.map { c -> c.toColor() }.toIntArray()
|
|
21
21
|
val startPoints = it.startPoints.map { p -> p.toFloat() }.toFloatArray()
|
|
22
|
-
gradient(Gradient(colors, startPoints))
|
|
22
|
+
gradient(Gradient(colors, startPoints, it.colorMapSize.toInt()))
|
|
23
23
|
}
|
|
24
24
|
}.build()
|
|
25
25
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
package com.rngooglemapsplus.extensions
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.UiThreadUtil
|
|
4
|
+
import kotlinx.coroutines.CompletableDeferred
|
|
5
|
+
import kotlinx.coroutines.runBlocking
|
|
6
|
+
|
|
7
|
+
inline fun onUi(crossinline block: () -> Unit) {
|
|
8
|
+
if (UiThreadUtil.isOnUiThread()) {
|
|
9
|
+
block()
|
|
10
|
+
} else {
|
|
11
|
+
UiThreadUtil.runOnUiThread { block() }
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
inline fun <T> onUiSync(crossinline block: () -> T): T {
|
|
16
|
+
if (UiThreadUtil.isOnUiThread()) return block()
|
|
17
|
+
val result = CompletableDeferred<T>()
|
|
18
|
+
UiThreadUtil.runOnUiThread {
|
|
19
|
+
runCatching(block).onSuccess(result::complete).onFailure(result::completeExceptionally)
|
|
20
|
+
}
|
|
21
|
+
return runBlocking { result.await() }
|
|
22
|
+
}
|
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
package com.rngooglemapsplus
|
|
2
2
|
|
|
3
|
+
import MarkerTag
|
|
3
4
|
import android.graphics.Bitmap
|
|
5
|
+
import android.graphics.BitmapFactory
|
|
4
6
|
import android.graphics.Canvas
|
|
7
|
+
import android.graphics.Typeface
|
|
8
|
+
import android.graphics.drawable.PictureDrawable
|
|
5
9
|
import android.util.Base64
|
|
6
10
|
import android.util.LruCache
|
|
11
|
+
import android.widget.ImageView
|
|
12
|
+
import android.widget.LinearLayout
|
|
7
13
|
import androidx.core.graphics.createBitmap
|
|
8
14
|
import com.caverock.androidsvg.SVG
|
|
9
15
|
import com.caverock.androidsvg.SVGExternalFileResolver
|
|
10
16
|
import com.facebook.react.uimanager.PixelUtil.dpToPx
|
|
17
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
11
18
|
import com.google.android.gms.maps.model.BitmapDescriptor
|
|
12
19
|
import com.google.android.gms.maps.model.BitmapDescriptorFactory
|
|
13
20
|
import com.google.android.gms.maps.model.Marker
|
|
14
21
|
import com.google.android.gms.maps.model.MarkerOptions
|
|
15
22
|
import com.rngooglemapsplus.extensions.markerStyleEquals
|
|
23
|
+
import com.rngooglemapsplus.extensions.onUi
|
|
16
24
|
import com.rngooglemapsplus.extensions.styleHash
|
|
17
25
|
import com.rngooglemapsplus.extensions.toLatLng
|
|
18
26
|
import kotlinx.coroutines.CoroutineScope
|
|
@@ -22,10 +30,14 @@ import kotlinx.coroutines.SupervisorJob
|
|
|
22
30
|
import kotlinx.coroutines.ensureActive
|
|
23
31
|
import kotlinx.coroutines.launch
|
|
24
32
|
import kotlinx.coroutines.withContext
|
|
33
|
+
import java.net.HttpURLConnection
|
|
34
|
+
import java.net.URL
|
|
25
35
|
import java.net.URLDecoder
|
|
36
|
+
import java.util.concurrent.ConcurrentHashMap
|
|
26
37
|
import kotlin.coroutines.coroutineContext
|
|
27
38
|
|
|
28
39
|
class MapMarkerBuilder(
|
|
40
|
+
val context: ThemedReactContext,
|
|
29
41
|
private val scope: CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Default),
|
|
30
42
|
) {
|
|
31
43
|
private val iconCache =
|
|
@@ -36,9 +48,10 @@ class MapMarkerBuilder(
|
|
|
36
48
|
): Int = 1
|
|
37
49
|
}
|
|
38
50
|
|
|
39
|
-
private val jobsById =
|
|
51
|
+
private val jobsById = ConcurrentHashMap<String, Job>()
|
|
40
52
|
|
|
41
53
|
init {
|
|
54
|
+
// / TODO: refactor with androidsvg 1.5 release
|
|
42
55
|
SVG.registerExternalFileResolver(
|
|
43
56
|
object : SVGExternalFileResolver() {
|
|
44
57
|
override fun resolveImage(filename: String?): Bitmap? {
|
|
@@ -64,11 +77,70 @@ class MapMarkerBuilder(
|
|
|
64
77
|
}
|
|
65
78
|
}
|
|
66
79
|
|
|
80
|
+
filename.startsWith("http://") || filename.startsWith("https://") -> {
|
|
81
|
+
val conn =
|
|
82
|
+
(URL(filename).openConnection() as HttpURLConnection).apply {
|
|
83
|
+
connectTimeout = 5000
|
|
84
|
+
readTimeout = 5000
|
|
85
|
+
requestMethod = "GET"
|
|
86
|
+
instanceFollowRedirects = true
|
|
87
|
+
}
|
|
88
|
+
conn.connect()
|
|
89
|
+
|
|
90
|
+
val contentType = conn.contentType ?: ""
|
|
91
|
+
val result =
|
|
92
|
+
if (contentType.contains("svg") || filename.endsWith(".svg")) {
|
|
93
|
+
val svgText = conn.inputStream.bufferedReader().use { it.readText() }
|
|
94
|
+
val innerSvg = SVG.getFromString(svgText)
|
|
95
|
+
val w = innerSvg.documentWidth.takeIf { it > 0 } ?: 128f
|
|
96
|
+
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
|
|
101
|
+
} else {
|
|
102
|
+
conn.inputStream.use { BitmapFactory.decodeStream(it) }
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
conn.disconnect()
|
|
106
|
+
result
|
|
107
|
+
}
|
|
108
|
+
|
|
67
109
|
else -> null
|
|
68
110
|
}
|
|
69
111
|
}.getOrNull()
|
|
70
112
|
}
|
|
71
113
|
|
|
114
|
+
override fun resolveFont(
|
|
115
|
+
fontFamily: String?,
|
|
116
|
+
fontWeight: Int,
|
|
117
|
+
fontStyle: String?,
|
|
118
|
+
): Typeface? {
|
|
119
|
+
if (fontFamily.isNullOrBlank()) return null
|
|
120
|
+
|
|
121
|
+
return runCatching {
|
|
122
|
+
val assetManager = context.assets
|
|
123
|
+
|
|
124
|
+
val candidates =
|
|
125
|
+
listOf(
|
|
126
|
+
"fonts/$fontFamily.ttf",
|
|
127
|
+
"fonts/$fontFamily.otf",
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
for (path in candidates) {
|
|
131
|
+
try {
|
|
132
|
+
return Typeface.createFromAsset(assetManager, path)
|
|
133
|
+
} catch (_: Throwable) {
|
|
134
|
+
// / ignore
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
Typeface.create(fontFamily, Typeface.NORMAL)
|
|
139
|
+
}.getOrElse {
|
|
140
|
+
Typeface.create(fontFamily, fontWeight)
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
72
144
|
override fun isFormatSupported(mimeType: String?): Boolean = mimeType?.startsWith("image/") == true
|
|
73
145
|
},
|
|
74
146
|
)
|
|
@@ -96,7 +168,7 @@ class MapMarkerBuilder(
|
|
|
96
168
|
prev: RNMarker,
|
|
97
169
|
next: RNMarker,
|
|
98
170
|
marker: Marker,
|
|
99
|
-
) {
|
|
171
|
+
) = onUi {
|
|
100
172
|
if (prev.coordinate.latitude != next.coordinate.latitude ||
|
|
101
173
|
prev.coordinate.longitude != next.coordinate.longitude
|
|
102
174
|
) {
|
|
@@ -171,6 +243,10 @@ class MapMarkerBuilder(
|
|
|
171
243
|
if (prev.zIndex != next.zIndex) {
|
|
172
244
|
marker.zIndex = next.zIndex?.toFloat() ?: 0f
|
|
173
245
|
}
|
|
246
|
+
|
|
247
|
+
if (prev.infoWindowIconSvg != next.infoWindowIconSvg) {
|
|
248
|
+
marker.tag = MarkerTag(id = next.id, iconSvg = next.infoWindowIconSvg)
|
|
249
|
+
}
|
|
174
250
|
}
|
|
175
251
|
|
|
176
252
|
fun buildIconAsync(
|
|
@@ -228,6 +304,31 @@ class MapMarkerBuilder(
|
|
|
228
304
|
iconCache.evictAll()
|
|
229
305
|
}
|
|
230
306
|
|
|
307
|
+
fun buildInfoWindow(iconSvg: RNMarkerSvg?): ImageView? {
|
|
308
|
+
val iconSvg = iconSvg ?: return null
|
|
309
|
+
|
|
310
|
+
val svgView =
|
|
311
|
+
ImageView(context).apply {
|
|
312
|
+
layoutParams =
|
|
313
|
+
LinearLayout.LayoutParams(
|
|
314
|
+
iconSvg.width.dpToPx().toInt(),
|
|
315
|
+
iconSvg.height.dpToPx().toInt(),
|
|
316
|
+
)
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
try {
|
|
320
|
+
val svg = SVG.getFromString(iconSvg.svgString)
|
|
321
|
+
svg.setDocumentWidth(iconSvg.width.dpToPx())
|
|
322
|
+
svg.setDocumentHeight(iconSvg.height.dpToPx())
|
|
323
|
+
val drawable = PictureDrawable(svg.renderToPicture())
|
|
324
|
+
svgView.setImageDrawable(drawable)
|
|
325
|
+
} catch (e: Exception) {
|
|
326
|
+
return null
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
return svgView
|
|
330
|
+
}
|
|
331
|
+
|
|
231
332
|
private suspend fun renderBitmap(m: RNMarker): Bitmap? {
|
|
232
333
|
m.iconSvg ?: return null
|
|
233
334
|
|
|
@@ -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.Polygon
|
|
6
6
|
import com.google.android.gms.maps.model.PolygonOptions
|
|
7
|
+
import com.rngooglemapsplus.extensions.onUi
|
|
7
8
|
import com.rngooglemapsplus.extensions.toColor
|
|
8
9
|
import com.rngooglemapsplus.extensions.toLatLng
|
|
9
10
|
|
|
@@ -30,7 +31,7 @@ class MapPolygonBuilder {
|
|
|
30
31
|
prev: RNPolygon,
|
|
31
32
|
next: RNPolygon,
|
|
32
33
|
poly: Polygon,
|
|
33
|
-
) {
|
|
34
|
+
) = onUi {
|
|
34
35
|
val coordsChanged =
|
|
35
36
|
prev.coordinates.size != next.coordinates.size ||
|
|
36
37
|
!prev.coordinates.zip(next.coordinates).all { (a, b) ->
|
|
@@ -9,6 +9,7 @@ import com.google.android.gms.maps.model.Polyline
|
|
|
9
9
|
import com.google.android.gms.maps.model.PolylineOptions
|
|
10
10
|
import com.google.android.gms.maps.model.RoundCap
|
|
11
11
|
import com.google.android.gms.maps.model.SquareCap
|
|
12
|
+
import com.rngooglemapsplus.extensions.onUi
|
|
12
13
|
import com.rngooglemapsplus.extensions.toColor
|
|
13
14
|
import com.rngooglemapsplus.extensions.toLatLng
|
|
14
15
|
|
|
@@ -34,7 +35,7 @@ class MapPolylineBuilder {
|
|
|
34
35
|
prev: RNPolyline,
|
|
35
36
|
next: RNPolyline,
|
|
36
37
|
polyline: Polyline,
|
|
37
|
-
) {
|
|
38
|
+
) = onUi {
|
|
38
39
|
val coordsChanged =
|
|
39
40
|
prev.coordinates.size != next.coordinates.size ||
|
|
40
41
|
!prev.coordinates.zip(next.coordinates).all { (a, b) ->
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
package com.rngooglemapsplus
|
|
2
|
+
|
|
3
|
+
import com.google.android.gms.maps.model.TileOverlayOptions
|
|
4
|
+
import com.google.android.gms.maps.model.UrlTileProvider
|
|
5
|
+
import java.net.URL
|
|
6
|
+
|
|
7
|
+
class MapUrlTileOverlayBuilder {
|
|
8
|
+
fun build(t: RNUrlTileOverlay): TileOverlayOptions {
|
|
9
|
+
val provider =
|
|
10
|
+
object : UrlTileProvider(
|
|
11
|
+
t.tileSize.toInt(),
|
|
12
|
+
t.tileSize.toInt(),
|
|
13
|
+
) {
|
|
14
|
+
override fun getTileUrl(
|
|
15
|
+
x: Int,
|
|
16
|
+
y: Int,
|
|
17
|
+
zoom: Int,
|
|
18
|
+
): URL? {
|
|
19
|
+
val url =
|
|
20
|
+
t.url
|
|
21
|
+
.replace("{x}", x.toString())
|
|
22
|
+
.replace("{y}", y.toString())
|
|
23
|
+
.replace("{z}", zoom.toString())
|
|
24
|
+
|
|
25
|
+
return try {
|
|
26
|
+
URL(url)
|
|
27
|
+
} catch (e: Exception) {
|
|
28
|
+
null
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
val opts = TileOverlayOptions().tileProvider(provider)
|
|
34
|
+
|
|
35
|
+
t.fadeIn?.let { opts.fadeIn(it) }
|
|
36
|
+
t.zIndex?.let { opts.zIndex(it.toFloat()) }
|
|
37
|
+
t.opacity?.let { opts.transparency(1f - it.toFloat()) }
|
|
38
|
+
return opts
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
package com.rngooglemapsplus
|
|
2
2
|
|
|
3
|
+
import MarkerTag
|
|
3
4
|
import com.facebook.proguard.annotations.DoNotStrip
|
|
4
|
-
import com.facebook.react.bridge.UiThreadUtil
|
|
5
5
|
import com.facebook.react.uimanager.ThemedReactContext
|
|
6
6
|
import com.google.android.gms.maps.GoogleMapOptions
|
|
7
7
|
import com.google.android.gms.maps.model.MapStyleOptions
|
|
@@ -14,6 +14,7 @@ import com.rngooglemapsplus.extensions.polylineEquals
|
|
|
14
14
|
import com.rngooglemapsplus.extensions.toCameraPosition
|
|
15
15
|
import com.rngooglemapsplus.extensions.toCompressFormat
|
|
16
16
|
import com.rngooglemapsplus.extensions.toFileExtension
|
|
17
|
+
import com.rngooglemapsplus.extensions.toGoogleMapType
|
|
17
18
|
import com.rngooglemapsplus.extensions.toLatLngBounds
|
|
18
19
|
import com.rngooglemapsplus.extensions.toMapColorScheme
|
|
19
20
|
import com.rngooglemapsplus.extensions.toSize
|
|
@@ -28,11 +29,12 @@ class RNGoogleMapsPlusView(
|
|
|
28
29
|
private var locationHandler = LocationHandler(context)
|
|
29
30
|
private var playServiceHandler = PlayServicesHandler(context)
|
|
30
31
|
|
|
31
|
-
private val markerBuilder = MapMarkerBuilder()
|
|
32
|
+
private val markerBuilder = MapMarkerBuilder(context)
|
|
32
33
|
private val polylineBuilder = MapPolylineBuilder()
|
|
33
34
|
private val polygonBuilder = MapPolygonBuilder()
|
|
34
35
|
private val circleBuilder = MapCircleBuilder()
|
|
35
36
|
private val heatmapBuilder = MapHeatmapBuilder()
|
|
37
|
+
private val urlTileOverlayBuilder = MapUrlTileOverlayBuilder()
|
|
36
38
|
|
|
37
39
|
override val view =
|
|
38
40
|
GoogleMapsViewImpl(context, locationHandler, playServiceHandler, markerBuilder)
|
|
@@ -128,9 +130,7 @@ class RNGoogleMapsPlusView(
|
|
|
128
130
|
set(value) {
|
|
129
131
|
if (field == value) return
|
|
130
132
|
field = value
|
|
131
|
-
value?.
|
|
132
|
-
view.mapType = it.value
|
|
133
|
-
}
|
|
133
|
+
view.mapType = value?.toGoogleMapType()
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
override var markers: Array<RNMarker>? = null
|
|
@@ -150,12 +150,19 @@ class RNGoogleMapsPlusView(
|
|
|
150
150
|
when {
|
|
151
151
|
prev == null ->
|
|
152
152
|
markerBuilder.buildIconAsync(id, next) { icon ->
|
|
153
|
-
view.addMarker(
|
|
153
|
+
view.addMarker(
|
|
154
|
+
id,
|
|
155
|
+
markerBuilder.build(next, icon),
|
|
156
|
+
MarkerTag(
|
|
157
|
+
id = id,
|
|
158
|
+
iconSvg = next.infoWindowIconSvg,
|
|
159
|
+
),
|
|
160
|
+
)
|
|
154
161
|
}
|
|
155
162
|
|
|
156
163
|
!prev.markerEquals(next) ->
|
|
157
164
|
view.updateMarker(id) { marker ->
|
|
158
|
-
|
|
165
|
+
markerBuilder.update(prev, next, marker)
|
|
159
166
|
}
|
|
160
167
|
}
|
|
161
168
|
}
|
|
@@ -179,7 +186,7 @@ class RNGoogleMapsPlusView(
|
|
|
179
186
|
|
|
180
187
|
!prev.polylineEquals(next) ->
|
|
181
188
|
view.updatePolyline(id) { polyline ->
|
|
182
|
-
|
|
189
|
+
polylineBuilder.update(prev, next, polyline)
|
|
183
190
|
}
|
|
184
191
|
}
|
|
185
192
|
}
|
|
@@ -204,7 +211,7 @@ class RNGoogleMapsPlusView(
|
|
|
204
211
|
|
|
205
212
|
!prev.polygonEquals(next) ->
|
|
206
213
|
view.updatePolygon(id) { polygon ->
|
|
207
|
-
|
|
214
|
+
polygonBuilder.update(prev, next, polygon)
|
|
208
215
|
}
|
|
209
216
|
}
|
|
210
217
|
}
|
|
@@ -229,7 +236,7 @@ class RNGoogleMapsPlusView(
|
|
|
229
236
|
|
|
230
237
|
!prev.circleEquals(next) ->
|
|
231
238
|
view.updateCircle(id) { circle ->
|
|
232
|
-
|
|
239
|
+
circleBuilder.update(prev, next, circle)
|
|
233
240
|
}
|
|
234
241
|
}
|
|
235
242
|
}
|
|
@@ -264,6 +271,21 @@ class RNGoogleMapsPlusView(
|
|
|
264
271
|
}
|
|
265
272
|
}
|
|
266
273
|
|
|
274
|
+
override var urlTileOverlays: Array<RNUrlTileOverlay>? = null
|
|
275
|
+
set(value) {
|
|
276
|
+
if (field.contentEquals(value)) return
|
|
277
|
+
val prevById = field?.associateBy { it.id } ?: emptyMap()
|
|
278
|
+
val nextById = value?.associateBy { it.id } ?: emptyMap()
|
|
279
|
+
field = value
|
|
280
|
+
(prevById.keys - nextById.keys).forEach { id ->
|
|
281
|
+
view.removeUrlTileOverlay(id)
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
nextById.forEach { (id, next) ->
|
|
285
|
+
view.addUrlTileOverlay(id, urlTileOverlayBuilder.build(next))
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
267
289
|
override var locationConfig: RNLocationConfig? = null
|
|
268
290
|
set(value) {
|
|
269
291
|
if (field == value) return
|
|
@@ -281,7 +303,7 @@ class RNGoogleMapsPlusView(
|
|
|
281
303
|
view.onMapReady = cb
|
|
282
304
|
}
|
|
283
305
|
|
|
284
|
-
override var onMapLoaded: ((
|
|
306
|
+
override var onMapLoaded: ((RNRegion, RNCamera) -> Unit)? = null
|
|
285
307
|
set(cb) {
|
|
286
308
|
view.onMapLoaded = cb
|
|
287
309
|
}
|
|
@@ -306,37 +328,42 @@ class RNGoogleMapsPlusView(
|
|
|
306
328
|
view.onMapLongPress = cb
|
|
307
329
|
}
|
|
308
330
|
|
|
309
|
-
override var onMarkerPress: ((String
|
|
331
|
+
override var onMarkerPress: ((String) -> Unit)? = null
|
|
310
332
|
set(cb) {
|
|
311
333
|
view.onMarkerPress = cb
|
|
312
334
|
}
|
|
313
335
|
|
|
314
|
-
override var
|
|
336
|
+
override var onPoiPress: ((String, String, RNLatLng) -> Unit)? = null
|
|
337
|
+
set(cb) {
|
|
338
|
+
view.onPoiPress = cb
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
override var onPolylinePress: ((String) -> Unit)? = null
|
|
315
342
|
set(cb) {
|
|
316
343
|
view.onPolylinePress = cb
|
|
317
344
|
}
|
|
318
345
|
|
|
319
|
-
override var onPolygonPress: ((String
|
|
346
|
+
override var onPolygonPress: ((String) -> Unit)? = null
|
|
320
347
|
set(cb) {
|
|
321
348
|
view.onPolygonPress = cb
|
|
322
349
|
}
|
|
323
350
|
|
|
324
|
-
override var onCirclePress: ((String
|
|
351
|
+
override var onCirclePress: ((String) -> Unit)? = null
|
|
325
352
|
set(cb) {
|
|
326
353
|
view.onCirclePress = cb
|
|
327
354
|
}
|
|
328
355
|
|
|
329
|
-
override var onMarkerDragStart: ((String
|
|
356
|
+
override var onMarkerDragStart: ((String, RNLatLng) -> Unit)? = null
|
|
330
357
|
set(cb) {
|
|
331
358
|
view.onMarkerDragStart = cb
|
|
332
359
|
}
|
|
333
360
|
|
|
334
|
-
override var onMarkerDrag: ((String
|
|
361
|
+
override var onMarkerDrag: ((String, RNLatLng) -> Unit)? = null
|
|
335
362
|
set(cb) {
|
|
336
363
|
view.onMarkerDrag = cb
|
|
337
364
|
}
|
|
338
365
|
|
|
339
|
-
override var onMarkerDragEnd: ((String
|
|
366
|
+
override var onMarkerDragEnd: ((String, RNLatLng) -> Unit)? = null
|
|
340
367
|
set(cb) {
|
|
341
368
|
view.onMarkerDragEnd = cb
|
|
342
369
|
}
|
|
@@ -351,6 +378,31 @@ class RNGoogleMapsPlusView(
|
|
|
351
378
|
view.onIndoorLevelActivated = cb
|
|
352
379
|
}
|
|
353
380
|
|
|
381
|
+
override var onInfoWindowPress: ((String) -> Unit)? = null
|
|
382
|
+
set(cb) {
|
|
383
|
+
view.onInfoWindowPress = cb
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
override var onInfoWindowClose: ((String) -> Unit)? = null
|
|
387
|
+
set(cb) {
|
|
388
|
+
view.onInfoWindowClose = cb
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
override var onInfoWindowLongPress: ((String) -> Unit)? = null
|
|
392
|
+
set(cb) {
|
|
393
|
+
view.onInfoWindowLongPress = cb
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
override var onMyLocationPress: ((RNLocation) -> Unit)? = null
|
|
397
|
+
set(cb) {
|
|
398
|
+
view.onMyLocationPress = cb
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
override var onMyLocationButtonPress: ((Boolean) -> Unit)? = null
|
|
402
|
+
set(cb) {
|
|
403
|
+
view.onMyLocationButtonPress = cb
|
|
404
|
+
}
|
|
405
|
+
|
|
354
406
|
override var onCameraChangeStart: ((RNRegion, RNCamera, Boolean) -> Unit)? = null
|
|
355
407
|
set(cb) {
|
|
356
408
|
view.onCameraChangeStart = cb
|
|
@@ -366,19 +418,25 @@ class RNGoogleMapsPlusView(
|
|
|
366
418
|
view.onCameraChangeComplete = cb
|
|
367
419
|
}
|
|
368
420
|
|
|
421
|
+
override fun showMarkerInfoWindow(id: String) {
|
|
422
|
+
view.showMarkerInfoWindow(id)
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
override fun hideMarkerInfoWindow(id: String) {
|
|
426
|
+
view.hideMarkerInfoWindow(id)
|
|
427
|
+
}
|
|
428
|
+
|
|
369
429
|
override fun setCamera(
|
|
370
430
|
camera: RNCamera,
|
|
371
431
|
animated: Boolean?,
|
|
372
432
|
durationMs: Double?,
|
|
373
433
|
) {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
)
|
|
381
|
-
}
|
|
434
|
+
val current = view.currentCamera
|
|
435
|
+
view.setCamera(
|
|
436
|
+
camera.toCameraPosition(current),
|
|
437
|
+
animated == true,
|
|
438
|
+
durationMs?.toInt() ?: 3000,
|
|
439
|
+
)
|
|
382
440
|
}
|
|
383
441
|
|
|
384
442
|
override fun setCameraToCoordinates(
|
|
@@ -436,11 +494,3 @@ class RNGoogleMapsPlusView(
|
|
|
436
494
|
|
|
437
495
|
override fun isGooglePlayServicesAvailable(): Boolean = playServiceHandler.isPlayServicesAvailable()
|
|
438
496
|
}
|
|
439
|
-
|
|
440
|
-
private inline fun onUi(crossinline block: () -> Unit) {
|
|
441
|
-
if (UiThreadUtil.isOnUiThread()) {
|
|
442
|
-
block()
|
|
443
|
-
} else {
|
|
444
|
-
UiThreadUtil.runOnUiThread { block() }
|
|
445
|
-
}
|
|
446
|
-
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
package com.rngooglemapsplus.extensions
|
|
2
|
+
|
|
3
|
+
import com.google.android.gms.maps.model.LatLngBounds
|
|
4
|
+
import com.rngooglemapsplus.RNLatLngBounds
|
|
5
|
+
|
|
6
|
+
fun LatLngBounds.toRnLatLngBounds(): RNLatLngBounds =
|
|
7
|
+
RNLatLngBounds(
|
|
8
|
+
northeast = northeast.toRnLatLng(),
|
|
9
|
+
southwest = southwest.toRnLatLng(),
|
|
10
|
+
)
|
|
@@ -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
|
|
@@ -6,12 +6,6 @@ import com.rngooglemapsplus.RNLatLngBounds
|
|
|
6
6
|
|
|
7
7
|
fun RNLatLngBounds.toLatLngBounds(): LatLngBounds =
|
|
8
8
|
LatLngBounds(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
southWest.longitude,
|
|
12
|
-
),
|
|
13
|
-
LatLng(
|
|
14
|
-
northEast.latitude,
|
|
15
|
-
northEast.longitude,
|
|
16
|
-
),
|
|
9
|
+
southwest.toLatLng(),
|
|
10
|
+
northeast.toLatLng(),
|
|
17
11
|
)
|