react-native-google-maps-plus 1.0.3-dev.1 → 1.1.0-dev.1
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 +122 -29
- package/android/src/main/java/com/rngooglemapsplus/LocationHandler.kt +44 -44
- package/android/src/main/java/com/rngooglemapsplus/{MapCircle.kt → MapCircleBuilder.kt} +2 -12
- package/android/src/main/java/com/rngooglemapsplus/{MapMarker.kt → MapMarkerBuilder.kt} +1 -1
- package/android/src/main/java/com/rngooglemapsplus/{MapPolygon.kt → MapPolygonBuilder.kt} +2 -18
- package/android/src/main/java/com/rngooglemapsplus/{MapPolyline.kt → MapPolylineBuilder.kt.kt} +2 -19
- package/android/src/main/java/com/rngooglemapsplus/RNGoogleMapsPlusView.kt +43 -54
- package/android/src/main/java/com/rngooglemapsplus/extensions/RNCameraExtension.kt +19 -0
- package/android/src/main/java/com/rngooglemapsplus/extensions/RNLocationPriorityExtension.kt +12 -0
- package/android/src/main/java/com/rngooglemapsplus/extensions/RNMapCircleExtension.kt +14 -0
- package/android/src/main/java/com/rngooglemapsplus/extensions/RNPolygonExtension.kt +20 -0
- package/android/src/main/java/com/rngooglemapsplus/extensions/RNPolylineExtension.kt +21 -0
- package/android/src/main/java/com/rngooglemapsplus/extensions/RNUserInterfaceExtension.kt +12 -0
- package/android/src/main/java/com/rngooglemapsplus/{Color.kt → extensions/StringExtension.kt} +1 -1
- package/android/src/main/java/com/rngooglemapsplus/extensions/ThrowableExtension.kt +38 -0
- package/ios/GoogleMapViewImpl.swift +165 -22
- package/ios/LocationHandler.swift +29 -69
- package/ios/MapCircleBuilder.swift +20 -0
- package/ios/{MapMarker.swift → MapMarkerBuilder.swift} +1 -25
- package/ios/MapPolygonBuilder.swift +20 -0
- package/ios/MapPolylineBuilder.swift +24 -0
- package/ios/RNGoogleMapsPlusView.swift +63 -115
- package/ios/extensions/RNCamera+Extension.swift +22 -0
- package/ios/{MapCircle.swift → extensions/RNCircle+Extension.swift} +0 -19
- package/ios/extensions/RNIOSLocationAccuracy+Extensions.swift +19 -0
- package/ios/extensions/RNMarker+Extension.swift +24 -0
- package/ios/{MapPolygon.swift → extensions/RNPolygon+Extension.swift.swift} +0 -19
- package/ios/{MapPolyline.swift → extensions/RNPolyline+Extension.swift.swift} +16 -39
- package/ios/extensions/RNUserInterface+Extension.swift +16 -0
- package/lib/module/types.js +14 -0
- package/lib/module/types.js.map +1 -1
- package/lib/typescript/src/RNGoogleMapsPlusView.nitro.d.ts +5 -1
- package/lib/typescript/src/RNGoogleMapsPlusView.nitro.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +39 -1
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusViewSpec.cpp +60 -0
- package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusViewSpec.hpp +8 -0
- package/nitrogen/generated/android/c++/JRNAndroidLocationConfig.hpp +63 -0
- package/nitrogen/generated/android/c++/JRNAndroidLocationPriority.hpp +65 -0
- package/nitrogen/generated/android/c++/JRNIOSLocationAccuracy.hpp +65 -0
- package/nitrogen/generated/android/c++/JRNIOSLocationConfig.hpp +59 -0
- package/nitrogen/generated/android/c++/JRNInitialProps.hpp +4 -4
- package/nitrogen/generated/android/c++/JRNLocationConfig.hpp +65 -0
- package/nitrogen/generated/android/c++/JRNMapUiSettings.hpp +93 -0
- package/nitrogen/generated/android/c++/views/JHybridRNGoogleMapsPlusViewStateUpdater.cpp +16 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/HybridRNGoogleMapsPlusViewSpec.kt +24 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNAndroidLocationConfig.kt +35 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNAndroidLocationPriority.kt +23 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNIOSLocationAccuracy.kt +23 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNIOSLocationConfig.kt +32 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNInitialProps.kt +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNLocationConfig.kt +32 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNMapUiSettings.kt +59 -0
- package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Bridge.hpp +108 -0
- package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Umbrella.hpp +18 -0
- package/nitrogen/generated/ios/c++/HybridRNGoogleMapsPlusViewSpecSwift.hpp +46 -0
- package/nitrogen/generated/ios/c++/views/HybridRNGoogleMapsPlusViewComponent.mm +20 -0
- package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusViewSpec.swift +4 -0
- package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusViewSpec_cxx.swift +82 -0
- package/nitrogen/generated/ios/swift/RNAndroidLocationConfig.swift +93 -0
- package/nitrogen/generated/ios/swift/RNAndroidLocationPriority.swift +48 -0
- package/nitrogen/generated/ios/swift/RNIOSLocationAccuracy.swift +48 -0
- package/nitrogen/generated/ios/swift/RNIOSLocationConfig.swift +70 -0
- package/nitrogen/generated/ios/swift/RNInitialProps.swift +6 -6
- package/nitrogen/generated/ios/swift/RNLocationConfig.swift +84 -0
- package/nitrogen/generated/ios/swift/RNMapUiSettings.swift +277 -0
- package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusViewSpec.cpp +8 -0
- package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusViewSpec.hpp +14 -0
- package/nitrogen/generated/shared/c++/RNAndroidLocationConfig.hpp +77 -0
- package/nitrogen/generated/shared/c++/RNAndroidLocationPriority.hpp +64 -0
- package/nitrogen/generated/shared/c++/RNIOSLocationAccuracy.hpp +64 -0
- package/nitrogen/generated/shared/c++/RNIOSLocationConfig.hpp +73 -0
- package/nitrogen/generated/shared/c++/RNInitialProps.hpp +5 -5
- package/nitrogen/generated/shared/c++/RNLocationConfig.hpp +76 -0
- package/nitrogen/generated/shared/c++/RNMapUiSettings.hpp +107 -0
- package/nitrogen/generated/shared/c++/views/HybridRNGoogleMapsPlusViewComponent.cpp +48 -0
- package/nitrogen/generated/shared/c++/views/HybridRNGoogleMapsPlusViewComponent.hpp +6 -0
- package/nitrogen/generated/shared/json/RNGoogleMapsPlusViewConfig.json +4 -0
- package/package.json +1 -1
- package/src/RNGoogleMapsPlusView.nitro.ts +6 -0
- package/src/types.ts +44 -1
- /package/ios/{Color.swift → extensions/String+Extensions.swift} +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
package com.rngooglemapsplus
|
|
2
2
|
|
|
3
|
+
import android.annotation.SuppressLint
|
|
3
4
|
import android.location.Location
|
|
4
5
|
import android.widget.FrameLayout
|
|
5
6
|
import com.facebook.react.bridge.LifecycleEventListener
|
|
@@ -24,12 +25,14 @@ import com.google.android.gms.maps.model.Polygon
|
|
|
24
25
|
import com.google.android.gms.maps.model.PolygonOptions
|
|
25
26
|
import com.google.android.gms.maps.model.Polyline
|
|
26
27
|
import com.google.android.gms.maps.model.PolylineOptions
|
|
28
|
+
import com.rngooglemapsplus.extensions.toGooglePriority
|
|
29
|
+
import com.rngooglemapsplus.extensions.toLocationErrorCode
|
|
27
30
|
|
|
28
31
|
class GoogleMapsViewImpl(
|
|
29
32
|
val reactContext: ThemedReactContext,
|
|
30
33
|
val locationHandler: LocationHandler,
|
|
31
34
|
val playServiceHandler: PlayServicesHandler,
|
|
32
|
-
val
|
|
35
|
+
val markerBuilder: MarkerBuilder,
|
|
33
36
|
) : FrameLayout(reactContext),
|
|
34
37
|
GoogleMap.OnCameraMoveStartedListener,
|
|
35
38
|
GoogleMap.OnCameraMoveListener,
|
|
@@ -252,12 +255,37 @@ class GoogleMapsViewImpl(
|
|
|
252
255
|
it.bottom.dpToPx().toInt(),
|
|
253
256
|
)
|
|
254
257
|
}
|
|
258
|
+
|
|
259
|
+
uiSettings?.let { v ->
|
|
260
|
+
googleMap?.uiSettings?.apply {
|
|
261
|
+
v.allGesturesEnabled?.let { setAllGesturesEnabled(it) }
|
|
262
|
+
v.compassEnabled?.let { isCompassEnabled = it }
|
|
263
|
+
v.indoorLevelPickerEnabled?.let { isIndoorLevelPickerEnabled = it }
|
|
264
|
+
v.mapToolbarEnabled?.let { isMapToolbarEnabled = it }
|
|
265
|
+
v.myLocationButtonEnabled?.let {
|
|
266
|
+
googleMap?.setLocationSource(locationHandler)
|
|
267
|
+
isMyLocationButtonEnabled = it
|
|
268
|
+
}
|
|
269
|
+
v.rotateEnabled?.let { isRotateGesturesEnabled = it }
|
|
270
|
+
v.scrollEnabled?.let { isScrollGesturesEnabled = it }
|
|
271
|
+
v.scrollDuringRotateOrZoomEnabled?.let {
|
|
272
|
+
isScrollGesturesEnabledDuringRotateOrZoom = it
|
|
273
|
+
}
|
|
274
|
+
v.tiltEnabled?.let { isTiltGesturesEnabled = it }
|
|
275
|
+
v.zoomControlsEnabled?.let { isZoomControlsEnabled = it }
|
|
276
|
+
v.zoomGesturesEnabled?.let { isZoomGesturesEnabled = it }
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
255
280
|
buildingEnabled?.let {
|
|
256
281
|
googleMap?.isBuildingsEnabled = it
|
|
257
282
|
}
|
|
258
283
|
trafficEnabled?.let {
|
|
259
284
|
googleMap?.isTrafficEnabled = it
|
|
260
285
|
}
|
|
286
|
+
indoorEnabled?.let {
|
|
287
|
+
googleMap?.isIndoorEnabled = it
|
|
288
|
+
}
|
|
261
289
|
googleMap?.setMapStyle(customMapStyle)
|
|
262
290
|
mapType?.let {
|
|
263
291
|
googleMap?.mapType = it
|
|
@@ -273,6 +301,12 @@ class GoogleMapsViewImpl(
|
|
|
273
301
|
}
|
|
274
302
|
}
|
|
275
303
|
|
|
304
|
+
locationConfig?.let {
|
|
305
|
+
locationHandler.priority = it.android?.priority?.toGooglePriority()
|
|
306
|
+
locationHandler.interval = it.android?.interval?.toLong()
|
|
307
|
+
locationHandler.minUpdateInterval = it.android?.minUpdateInterval?.toLong()
|
|
308
|
+
}
|
|
309
|
+
|
|
276
310
|
if (pendingMarkers.isNotEmpty()) {
|
|
277
311
|
pendingMarkers.forEach { (id, opts) ->
|
|
278
312
|
internalAddMarker(id, opts)
|
|
@@ -302,6 +336,69 @@ class GoogleMapsViewImpl(
|
|
|
302
336
|
}
|
|
303
337
|
}
|
|
304
338
|
|
|
339
|
+
var uiSettings: RNMapUiSettings? = null
|
|
340
|
+
set(value) {
|
|
341
|
+
field = value
|
|
342
|
+
onUi {
|
|
343
|
+
value?.let { v ->
|
|
344
|
+
googleMap?.uiSettings?.apply {
|
|
345
|
+
v.allGesturesEnabled?.let { setAllGesturesEnabled(it) }
|
|
346
|
+
v.compassEnabled?.let { isCompassEnabled = it }
|
|
347
|
+
v.indoorLevelPickerEnabled?.let { isIndoorLevelPickerEnabled = it }
|
|
348
|
+
v.mapToolbarEnabled?.let { isMapToolbarEnabled = it }
|
|
349
|
+
v.myLocationButtonEnabled?.let {
|
|
350
|
+
googleMap?.setLocationSource(locationHandler)
|
|
351
|
+
isMyLocationButtonEnabled = it
|
|
352
|
+
}
|
|
353
|
+
v.rotateEnabled?.let { isRotateGesturesEnabled = it }
|
|
354
|
+
v.scrollEnabled?.let { isScrollGesturesEnabled = it }
|
|
355
|
+
v.scrollDuringRotateOrZoomEnabled?.let {
|
|
356
|
+
isScrollGesturesEnabledDuringRotateOrZoom = it
|
|
357
|
+
}
|
|
358
|
+
v.tiltEnabled?.let { isTiltGesturesEnabled = it }
|
|
359
|
+
v.zoomControlsEnabled?.let { isZoomControlsEnabled = it }
|
|
360
|
+
v.zoomGesturesEnabled?.let { isZoomGesturesEnabled = it }
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
?: run {
|
|
364
|
+
googleMap?.uiSettings?.apply {
|
|
365
|
+
setAllGesturesEnabled(true)
|
|
366
|
+
isCompassEnabled = false
|
|
367
|
+
isIndoorLevelPickerEnabled = false
|
|
368
|
+
isMapToolbarEnabled = false
|
|
369
|
+
isMyLocationButtonEnabled = false
|
|
370
|
+
googleMap?.setLocationSource(null)
|
|
371
|
+
isRotateGesturesEnabled = true
|
|
372
|
+
isScrollGesturesEnabled = true
|
|
373
|
+
isScrollGesturesEnabledDuringRotateOrZoom = true
|
|
374
|
+
isTiltGesturesEnabled = true
|
|
375
|
+
isZoomControlsEnabled = false
|
|
376
|
+
isZoomGesturesEnabled = false
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
@SuppressLint("MissingPermission")
|
|
383
|
+
var myLocationEnabled: Boolean? = null
|
|
384
|
+
set(value) {
|
|
385
|
+
onUi {
|
|
386
|
+
try {
|
|
387
|
+
value?.let {
|
|
388
|
+
googleMap?.isMyLocationEnabled = it
|
|
389
|
+
}
|
|
390
|
+
?: run {
|
|
391
|
+
googleMap?.isMyLocationEnabled = false
|
|
392
|
+
}
|
|
393
|
+
} catch (se: SecurityException) {
|
|
394
|
+
onLocationError?.invoke(RNLocationErrorCode.PERMISSION_DENIED)
|
|
395
|
+
} catch (ex: Exception) {
|
|
396
|
+
val error = ex.toLocationErrorCode(context)
|
|
397
|
+
onLocationError?.invoke(error)
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
305
402
|
var buildingEnabled: Boolean? = null
|
|
306
403
|
set(value) {
|
|
307
404
|
field = value
|
|
@@ -327,6 +424,19 @@ class GoogleMapsViewImpl(
|
|
|
327
424
|
}
|
|
328
425
|
}
|
|
329
426
|
|
|
427
|
+
var indoorEnabled: Boolean? = null
|
|
428
|
+
set(value) {
|
|
429
|
+
field = value
|
|
430
|
+
onUi {
|
|
431
|
+
value?.let {
|
|
432
|
+
googleMap?.isIndoorEnabled = it
|
|
433
|
+
}
|
|
434
|
+
?: run {
|
|
435
|
+
googleMap?.isIndoorEnabled = false
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
330
440
|
var customMapStyle: MapStyleOptions? = null
|
|
331
441
|
set(value) {
|
|
332
442
|
field = value
|
|
@@ -400,6 +510,14 @@ class GoogleMapsViewImpl(
|
|
|
400
510
|
}
|
|
401
511
|
}
|
|
402
512
|
|
|
513
|
+
var locationConfig: RNLocationConfig? = null
|
|
514
|
+
set(value) {
|
|
515
|
+
field = value
|
|
516
|
+
locationHandler.priority = value?.android?.priority?.toGooglePriority()
|
|
517
|
+
locationHandler.interval = value?.android?.interval?.toLong()
|
|
518
|
+
locationHandler.minUpdateInterval = value?.android?.minUpdateInterval?.toLong()
|
|
519
|
+
}
|
|
520
|
+
|
|
403
521
|
var onMapError: ((RNMapErrorCode) -> Unit)? = null
|
|
404
522
|
var onMapReady: ((Boolean) -> Unit)? = null
|
|
405
523
|
var onLocationUpdate: ((RNLocation) -> Unit)? = null
|
|
@@ -414,7 +532,7 @@ class GoogleMapsViewImpl(
|
|
|
414
532
|
var onCameraChangeComplete: ((RNRegion, RNCamera, Boolean) -> Unit)? = null
|
|
415
533
|
|
|
416
534
|
fun setCamera(
|
|
417
|
-
|
|
535
|
+
cameraPosition: CameraPosition,
|
|
418
536
|
animated: Boolean,
|
|
419
537
|
durationMS: Int,
|
|
420
538
|
) {
|
|
@@ -423,33 +541,8 @@ class GoogleMapsViewImpl(
|
|
|
423
541
|
if (current == null) {
|
|
424
542
|
return@onUi
|
|
425
543
|
}
|
|
426
|
-
val camPosBuilder =
|
|
427
|
-
CameraPosition.Builder(
|
|
428
|
-
current,
|
|
429
|
-
)
|
|
430
|
-
|
|
431
|
-
camera.center?.let {
|
|
432
|
-
camPosBuilder.target(
|
|
433
|
-
LatLng(
|
|
434
|
-
it.latitude,
|
|
435
|
-
it.longitude,
|
|
436
|
-
),
|
|
437
|
-
)
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
camera.zoom?.let {
|
|
441
|
-
camPosBuilder.zoom(it.toFloat())
|
|
442
|
-
}
|
|
443
|
-
camera.bearing?.let {
|
|
444
|
-
camPosBuilder.bearing(it.toFloat())
|
|
445
|
-
}
|
|
446
|
-
camera.tilt?.let {
|
|
447
|
-
camPosBuilder.tilt(it.toFloat())
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
val camPos = camPosBuilder.build()
|
|
451
544
|
|
|
452
|
-
val update = CameraUpdateFactory.newCameraPosition(
|
|
545
|
+
val update = CameraUpdateFactory.newCameraPosition(cameraPosition)
|
|
453
546
|
|
|
454
547
|
if (animated) {
|
|
455
548
|
googleMap?.animateCamera(update, durationMS, null)
|
|
@@ -746,7 +839,7 @@ class GoogleMapsViewImpl(
|
|
|
746
839
|
|
|
747
840
|
fun destroyInternal() {
|
|
748
841
|
onUi {
|
|
749
|
-
|
|
842
|
+
markerBuilder.cancelAllJobs()
|
|
750
843
|
clearMarkers()
|
|
751
844
|
clearPolylines()
|
|
752
845
|
clearPolygons()
|
|
@@ -10,8 +10,6 @@ import com.facebook.react.bridge.ReactContext
|
|
|
10
10
|
import com.facebook.react.bridge.UiThreadUtil
|
|
11
11
|
import com.google.android.gms.common.ConnectionResult
|
|
12
12
|
import com.google.android.gms.common.GoogleApiAvailability
|
|
13
|
-
import com.google.android.gms.common.api.ApiException
|
|
14
|
-
import com.google.android.gms.common.api.CommonStatusCodes
|
|
15
13
|
import com.google.android.gms.common.api.ResolvableApiException
|
|
16
14
|
import com.google.android.gms.location.FusedLocationProviderClient
|
|
17
15
|
import com.google.android.gms.location.LocationCallback
|
|
@@ -19,22 +17,43 @@ import com.google.android.gms.location.LocationRequest
|
|
|
19
17
|
import com.google.android.gms.location.LocationResult
|
|
20
18
|
import com.google.android.gms.location.LocationServices
|
|
21
19
|
import com.google.android.gms.location.LocationSettingsRequest
|
|
22
|
-
import com.google.android.gms.location.LocationSettingsStatusCodes
|
|
23
20
|
import com.google.android.gms.location.Priority
|
|
21
|
+
import com.google.android.gms.maps.LocationSource
|
|
24
22
|
import com.google.android.gms.tasks.OnSuccessListener
|
|
23
|
+
import com.rngooglemapsplus.extensions.toLocationErrorCode
|
|
25
24
|
|
|
26
25
|
private const val REQ_LOCATION_SETTINGS = 2001
|
|
26
|
+
private const val PRIORITY_DEFAULT = Priority.PRIORITY_BALANCED_POWER_ACCURACY
|
|
27
|
+
private const val INTERVAL_DEFAULT = 600000L
|
|
28
|
+
private const val MIN_UPDATE_INTERVAL = 3600000L
|
|
27
29
|
|
|
28
30
|
class LocationHandler(
|
|
29
31
|
val context: ReactContext,
|
|
30
|
-
) {
|
|
32
|
+
) : LocationSource {
|
|
31
33
|
private val fusedLocationClientProviderClient: FusedLocationProviderClient =
|
|
32
34
|
LocationServices.getFusedLocationProviderClient(context)
|
|
35
|
+
private var listener: LocationSource.OnLocationChangedListener? = null
|
|
33
36
|
private var locationRequest: LocationRequest? = null
|
|
34
37
|
private var locationCallback: LocationCallback? = null
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
|
|
39
|
+
var priority: Int? = PRIORITY_DEFAULT
|
|
40
|
+
set(value) {
|
|
41
|
+
field = value
|
|
42
|
+
start()
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
var interval: Long? = INTERVAL_DEFAULT
|
|
46
|
+
set(value) {
|
|
47
|
+
field = value
|
|
48
|
+
buildLocationRequest()
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
var minUpdateInterval: Long? = MIN_UPDATE_INTERVAL
|
|
52
|
+
set(value) {
|
|
53
|
+
field = value
|
|
54
|
+
buildLocationRequest()
|
|
55
|
+
}
|
|
56
|
+
|
|
38
57
|
var onUpdate: ((Location) -> Unit)? = null
|
|
39
58
|
var onError: ((RNLocationErrorCode) -> Unit)? = null
|
|
40
59
|
|
|
@@ -90,6 +109,10 @@ class LocationHandler(
|
|
|
90
109
|
|
|
91
110
|
@Suppress("deprecation")
|
|
92
111
|
private fun buildLocationRequest() {
|
|
112
|
+
val priority = priority ?: Priority.PRIORITY_BALANCED_POWER_ACCURACY
|
|
113
|
+
val interval = interval ?: INTERVAL_DEFAULT
|
|
114
|
+
val minUpdateInterval = minUpdateInterval ?: MIN_UPDATE_INTERVAL
|
|
115
|
+
|
|
93
116
|
locationRequest =
|
|
94
117
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
|
95
118
|
LocationRequest
|
|
@@ -106,21 +129,6 @@ class LocationHandler(
|
|
|
106
129
|
restartLocationUpdates()
|
|
107
130
|
}
|
|
108
131
|
|
|
109
|
-
fun setPriority(priority: Int) {
|
|
110
|
-
this.priority = priority
|
|
111
|
-
buildLocationRequest()
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
fun setInterval(interval: Int) {
|
|
115
|
-
this.interval = interval.toLong()
|
|
116
|
-
buildLocationRequest()
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
fun setFastestInterval(fastestInterval: Int) {
|
|
120
|
-
this.minUpdateInterval = fastestInterval.toLong()
|
|
121
|
-
buildLocationRequest()
|
|
122
|
-
}
|
|
123
|
-
|
|
124
132
|
private fun restartLocationUpdates() {
|
|
125
133
|
stop()
|
|
126
134
|
// 4) Google Play Services checken – früh zurückmelden
|
|
@@ -146,7 +154,7 @@ class LocationHandler(
|
|
|
146
154
|
}
|
|
147
155
|
},
|
|
148
156
|
).addOnFailureListener { e ->
|
|
149
|
-
val error =
|
|
157
|
+
val error = e.toLocationErrorCode(context)
|
|
150
158
|
onError?.invoke(error)
|
|
151
159
|
}
|
|
152
160
|
locationCallback =
|
|
@@ -154,6 +162,7 @@ class LocationHandler(
|
|
|
154
162
|
override fun onLocationResult(locationResult: LocationResult) {
|
|
155
163
|
val location = locationResult.lastLocation
|
|
156
164
|
if (location != null) {
|
|
165
|
+
listener?.onLocationChanged(location)
|
|
157
166
|
onUpdate?.invoke(location)
|
|
158
167
|
} else {
|
|
159
168
|
onError?.invoke(RNLocationErrorCode.POSITION_UNAVAILABLE)
|
|
@@ -166,40 +175,31 @@ class LocationHandler(
|
|
|
166
175
|
locationCallback!!,
|
|
167
176
|
Looper.getMainLooper(),
|
|
168
177
|
).addOnFailureListener { e ->
|
|
169
|
-
val error =
|
|
178
|
+
val error = e.toLocationErrorCode(context)
|
|
170
179
|
onError?.invoke(error)
|
|
171
180
|
}
|
|
172
181
|
} catch (se: SecurityException) {
|
|
173
182
|
onError?.invoke(RNLocationErrorCode.PERMISSION_DENIED)
|
|
174
183
|
} catch (ex: Exception) {
|
|
175
|
-
val error =
|
|
184
|
+
val error = ex.toLocationErrorCode(context)
|
|
176
185
|
onError?.invoke(error)
|
|
177
186
|
}
|
|
178
187
|
}
|
|
179
188
|
|
|
180
|
-
private fun mapThrowableToCode(t: Throwable): RNLocationErrorCode {
|
|
181
|
-
if (t is SecurityException) return RNLocationErrorCode.PERMISSION_DENIED
|
|
182
|
-
if (t.message?.contains("GoogleApi", ignoreCase = true) == true) {
|
|
183
|
-
val gms = GoogleApiAvailability.getInstance()
|
|
184
|
-
val status = gms.isGooglePlayServicesAvailable(context)
|
|
185
|
-
if (status != ConnectionResult.SUCCESS) return RNLocationErrorCode.PLAY_SERVICE_NOT_AVAILABLE
|
|
186
|
-
}
|
|
187
|
-
if (t is ApiException) {
|
|
188
|
-
when (t.statusCode) {
|
|
189
|
-
CommonStatusCodes.NETWORK_ERROR -> return RNLocationErrorCode.POSITION_UNAVAILABLE
|
|
190
|
-
LocationSettingsStatusCodes.RESOLUTION_REQUIRED,
|
|
191
|
-
LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE,
|
|
192
|
-
-> return RNLocationErrorCode.SETTINGS_NOT_SATISFIED
|
|
193
|
-
}
|
|
194
|
-
return RNLocationErrorCode.INTERNAL_ERROR
|
|
195
|
-
}
|
|
196
|
-
return RNLocationErrorCode.INTERNAL_ERROR
|
|
197
|
-
}
|
|
198
|
-
|
|
199
189
|
fun stop() {
|
|
190
|
+
listener = null
|
|
200
191
|
if (locationCallback != null) {
|
|
201
192
|
fusedLocationClientProviderClient.removeLocationUpdates(locationCallback!!)
|
|
202
193
|
locationCallback = null
|
|
203
194
|
}
|
|
204
195
|
}
|
|
196
|
+
|
|
197
|
+
override fun activate(listener: LocationSource.OnLocationChangedListener) {
|
|
198
|
+
this.listener = listener
|
|
199
|
+
start()
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
override fun deactivate() {
|
|
203
|
+
stop()
|
|
204
|
+
}
|
|
205
205
|
}
|
|
@@ -3,8 +3,9 @@ package com.rngooglemapsplus
|
|
|
3
3
|
import com.facebook.react.uimanager.PixelUtil.dpToPx
|
|
4
4
|
import com.google.android.gms.maps.model.CircleOptions
|
|
5
5
|
import com.google.android.gms.maps.model.LatLng
|
|
6
|
+
import com.rngooglemapsplus.extensions.toColor
|
|
6
7
|
|
|
7
|
-
class
|
|
8
|
+
class MapCircleBuilder {
|
|
8
9
|
fun buildCircleOptions(circle: RNCircle): CircleOptions =
|
|
9
10
|
CircleOptions().apply {
|
|
10
11
|
center(LatLng(circle.center.latitude, circle.center.longitude))
|
|
@@ -16,14 +17,3 @@ class MapCircleOptions {
|
|
|
16
17
|
circle.zIndex?.let { zIndex(it.toFloat()) }
|
|
17
18
|
}
|
|
18
19
|
}
|
|
19
|
-
|
|
20
|
-
fun RNCircle.circleEquals(b: RNCircle): Boolean {
|
|
21
|
-
if (zIndex != b.zIndex) return false
|
|
22
|
-
if (pressable != b.pressable) return false
|
|
23
|
-
if (center != b.center) return false
|
|
24
|
-
if (radius != b.radius) return false
|
|
25
|
-
if (strokeWidth != b.strokeWidth) return false
|
|
26
|
-
if (strokeColor != b.strokeColor) return false
|
|
27
|
-
if (fillColor != b.fillColor) return false
|
|
28
|
-
return true
|
|
29
|
-
}
|
|
@@ -19,7 +19,7 @@ import kotlinx.coroutines.launch
|
|
|
19
19
|
import kotlinx.coroutines.withContext
|
|
20
20
|
import kotlin.coroutines.coroutineContext
|
|
21
21
|
|
|
22
|
-
class
|
|
22
|
+
class MarkerBuilder(
|
|
23
23
|
private val scope: CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Default),
|
|
24
24
|
) {
|
|
25
25
|
private val iconCache =
|
|
@@ -2,8 +2,9 @@ package com.rngooglemapsplus
|
|
|
2
2
|
|
|
3
3
|
import com.facebook.react.uimanager.PixelUtil.dpToPx
|
|
4
4
|
import com.google.android.gms.maps.model.PolygonOptions
|
|
5
|
+
import com.rngooglemapsplus.extensions.toColor
|
|
5
6
|
|
|
6
|
-
class
|
|
7
|
+
class MapPolygonBuilder {
|
|
7
8
|
fun buildPolygonOptions(poly: RNPolygon): PolygonOptions =
|
|
8
9
|
PolygonOptions().apply {
|
|
9
10
|
poly.coordinates.forEach { pt ->
|
|
@@ -19,20 +20,3 @@ class MapPolygonOptions {
|
|
|
19
20
|
poly.zIndex?.let { zIndex(it.toFloat()) }
|
|
20
21
|
}
|
|
21
22
|
}
|
|
22
|
-
|
|
23
|
-
fun RNPolygon.polygonEquals(b: RNPolygon): Boolean {
|
|
24
|
-
if (zIndex != b.zIndex) return false
|
|
25
|
-
if (pressable != b.pressable) return false
|
|
26
|
-
if (strokeWidth != b.strokeWidth) return false
|
|
27
|
-
if (fillColor != b.fillColor) return false
|
|
28
|
-
if (strokeColor != b.strokeColor) return false
|
|
29
|
-
val ac = coordinates
|
|
30
|
-
val bc = b.coordinates
|
|
31
|
-
if (ac.size != bc.size) return false
|
|
32
|
-
for (i in ac.indices) {
|
|
33
|
-
val p = ac[i]
|
|
34
|
-
val q = bc[i]
|
|
35
|
-
if (p.latitude != q.latitude || p.longitude != q.longitude) return false
|
|
36
|
-
}
|
|
37
|
-
return true
|
|
38
|
-
}
|
package/android/src/main/java/com/rngooglemapsplus/{MapPolyline.kt → MapPolylineBuilder.kt.kt}
RENAMED
|
@@ -7,8 +7,9 @@ import com.google.android.gms.maps.model.JointType
|
|
|
7
7
|
import com.google.android.gms.maps.model.PolylineOptions
|
|
8
8
|
import com.google.android.gms.maps.model.RoundCap
|
|
9
9
|
import com.google.android.gms.maps.model.SquareCap
|
|
10
|
+
import com.rngooglemapsplus.extensions.toColor
|
|
10
11
|
|
|
11
|
-
class
|
|
12
|
+
class MapPolylineBuilder {
|
|
12
13
|
fun buildPolylineOptions(pl: RNPolyline): PolylineOptions =
|
|
13
14
|
PolylineOptions().apply {
|
|
14
15
|
pl.coordinates.forEach { pt ->
|
|
@@ -41,21 +42,3 @@ class MapPolylineOptions {
|
|
|
41
42
|
null -> JointType.DEFAULT
|
|
42
43
|
}
|
|
43
44
|
}
|
|
44
|
-
|
|
45
|
-
fun RNPolyline.polylineEquals(b: RNPolyline): Boolean {
|
|
46
|
-
if (zIndex != b.zIndex) return false
|
|
47
|
-
if (pressable != b.pressable) return false
|
|
48
|
-
if ((width ?: 0.0) != (b.width ?: 0.0)) return false
|
|
49
|
-
if (lineCap != b.lineCap) return false
|
|
50
|
-
if (lineJoin != b.lineJoin) return false
|
|
51
|
-
if (color != b.color) return false
|
|
52
|
-
val ac = coordinates
|
|
53
|
-
val bc = b.coordinates
|
|
54
|
-
if (ac.size != bc.size) return false
|
|
55
|
-
for (i in ac.indices) {
|
|
56
|
-
val p = ac[i]
|
|
57
|
-
val q = bc[i]
|
|
58
|
-
if (p.latitude != q.latitude || p.longitude != q.longitude) return false
|
|
59
|
-
}
|
|
60
|
-
return true
|
|
61
|
-
}
|
|
@@ -4,11 +4,15 @@ import com.facebook.proguard.annotations.DoNotStrip
|
|
|
4
4
|
import com.facebook.react.bridge.UiThreadUtil
|
|
5
5
|
import com.facebook.react.uimanager.PixelUtil.dpToPx
|
|
6
6
|
import com.facebook.react.uimanager.ThemedReactContext
|
|
7
|
-
import com.google.android.gms.maps.model.CameraPosition
|
|
8
7
|
import com.google.android.gms.maps.model.LatLng
|
|
9
|
-
import com.google.android.gms.maps.model.MapColorScheme
|
|
10
8
|
import com.google.android.gms.maps.model.MapStyleOptions
|
|
11
9
|
import com.margelo.nitro.core.Promise
|
|
10
|
+
import com.rngooglemapsplus.extensions.circleEquals
|
|
11
|
+
import com.rngooglemapsplus.extensions.polygonEquals
|
|
12
|
+
import com.rngooglemapsplus.extensions.polylineEquals
|
|
13
|
+
import com.rngooglemapsplus.extensions.toCameraPosition
|
|
14
|
+
import com.rngooglemapsplus.extensions.toColor
|
|
15
|
+
import com.rngooglemapsplus.extensions.toMapColorScheme
|
|
12
16
|
|
|
13
17
|
@DoNotStrip
|
|
14
18
|
class RNGoogleMapsPlusView(
|
|
@@ -19,23 +23,33 @@ class RNGoogleMapsPlusView(
|
|
|
19
23
|
private var locationHandler = LocationHandler(context)
|
|
20
24
|
private var playServiceHandler = PlayServicesHandler(context)
|
|
21
25
|
|
|
22
|
-
private val
|
|
23
|
-
private val
|
|
24
|
-
private val
|
|
25
|
-
private val
|
|
26
|
+
private val markerBuilder = MarkerBuilder()
|
|
27
|
+
private val polylineBuilder = MapPolylineBuilder()
|
|
28
|
+
private val polygonBuilder = MapPolygonBuilder()
|
|
29
|
+
private val circleBuilder = MapCircleBuilder()
|
|
26
30
|
|
|
27
31
|
override val view =
|
|
28
|
-
GoogleMapsViewImpl(context, locationHandler, playServiceHandler,
|
|
32
|
+
GoogleMapsViewImpl(context, locationHandler, playServiceHandler, markerBuilder)
|
|
29
33
|
|
|
30
34
|
override var initialProps: RNInitialProps? = null
|
|
31
35
|
set(value) {
|
|
32
36
|
view.initMapView(
|
|
33
37
|
value?.mapId,
|
|
34
38
|
value?.liteMode,
|
|
35
|
-
|
|
39
|
+
value?.camera?.toCameraPosition(),
|
|
36
40
|
)
|
|
37
41
|
}
|
|
38
42
|
|
|
43
|
+
override var uiSettings: RNMapUiSettings? = null
|
|
44
|
+
set(value) {
|
|
45
|
+
view.uiSettings = value
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
override var myLocationEnabled: Boolean? = null
|
|
49
|
+
set(value) {
|
|
50
|
+
view.myLocationEnabled = value
|
|
51
|
+
}
|
|
52
|
+
|
|
39
53
|
override var buildingEnabled: Boolean? = null
|
|
40
54
|
set(value) {
|
|
41
55
|
view.buildingEnabled = value
|
|
@@ -46,6 +60,11 @@ class RNGoogleMapsPlusView(
|
|
|
46
60
|
view.trafficEnabled = value
|
|
47
61
|
}
|
|
48
62
|
|
|
63
|
+
override var indoorEnabled: Boolean? = null
|
|
64
|
+
set(value) {
|
|
65
|
+
view.indoorEnabled = value
|
|
66
|
+
}
|
|
67
|
+
|
|
49
68
|
override var customMapStyle: String? = null
|
|
50
69
|
set(value) {
|
|
51
70
|
currentCustomMapStyle = value
|
|
@@ -56,7 +75,7 @@ class RNGoogleMapsPlusView(
|
|
|
56
75
|
|
|
57
76
|
override var userInterfaceStyle: RNUserInterfaceStyle? = null
|
|
58
77
|
set(value) {
|
|
59
|
-
view.userInterfaceStyle =
|
|
78
|
+
view.userInterfaceStyle = value.toMapColorScheme()
|
|
60
79
|
}
|
|
61
80
|
|
|
62
81
|
override var minZoomLevel: Double? = null
|
|
@@ -87,17 +106,17 @@ class RNGoogleMapsPlusView(
|
|
|
87
106
|
val nextById = value?.associateBy { it.id } ?: emptyMap()
|
|
88
107
|
|
|
89
108
|
(prevById.keys - nextById.keys).forEach { id ->
|
|
90
|
-
|
|
109
|
+
markerBuilder.cancelIconJob(id)
|
|
91
110
|
view.removeMarker(id)
|
|
92
111
|
}
|
|
93
112
|
|
|
94
113
|
nextById.forEach { (id, next) ->
|
|
95
114
|
val prev = prevById[id]
|
|
96
115
|
if (prev == null) {
|
|
97
|
-
|
|
116
|
+
markerBuilder.buildIconAsync(id, next) { icon ->
|
|
98
117
|
view.addMarker(
|
|
99
118
|
id,
|
|
100
|
-
|
|
119
|
+
markerBuilder.build(next, icon),
|
|
101
120
|
)
|
|
102
121
|
}
|
|
103
122
|
} else if (!prev.markerEquals(next)) {
|
|
@@ -113,7 +132,7 @@ class RNGoogleMapsPlusView(
|
|
|
113
132
|
}
|
|
114
133
|
|
|
115
134
|
if (!prev.markerStyleEquals(next)) {
|
|
116
|
-
|
|
135
|
+
markerBuilder.buildIconAsync(id, next) { icon ->
|
|
117
136
|
m.setIcon(icon)
|
|
118
137
|
}
|
|
119
138
|
}
|
|
@@ -140,7 +159,7 @@ class RNGoogleMapsPlusView(
|
|
|
140
159
|
nextById.forEach { (id, next) ->
|
|
141
160
|
val prev = prevById[id]
|
|
142
161
|
if (prev == null) {
|
|
143
|
-
view.addPolyline(id,
|
|
162
|
+
view.addPolyline(id, polylineBuilder.buildPolylineOptions(next))
|
|
144
163
|
} else if (!prev.polylineEquals(next)) {
|
|
145
164
|
view.updatePolyline(id) { gms ->
|
|
146
165
|
onUi {
|
|
@@ -151,11 +170,11 @@ class RNGoogleMapsPlusView(
|
|
|
151
170
|
}
|
|
152
171
|
next.width?.let { gms.width = it.dpToPx() }
|
|
153
172
|
next.lineCap?.let {
|
|
154
|
-
val cap =
|
|
173
|
+
val cap = polylineBuilder.mapLineCap(it)
|
|
155
174
|
gms.startCap = cap
|
|
156
175
|
gms.endCap = cap
|
|
157
176
|
}
|
|
158
|
-
next.lineJoin?.let { gms.jointType =
|
|
177
|
+
next.lineJoin?.let { gms.jointType = polylineBuilder.mapLineJoin(it) }
|
|
159
178
|
next.color?.let { gms.color = it.toColor() }
|
|
160
179
|
next.zIndex?.let { gms.zIndex = it.toFloat() }
|
|
161
180
|
}
|
|
@@ -177,7 +196,7 @@ class RNGoogleMapsPlusView(
|
|
|
177
196
|
nextById.forEach { (id, next) ->
|
|
178
197
|
val prev = prevById[id]
|
|
179
198
|
if (prev == null) {
|
|
180
|
-
view.addPolygon(id,
|
|
199
|
+
view.addPolygon(id, polygonBuilder.buildPolygonOptions(next))
|
|
181
200
|
} else if (!prev.polygonEquals(next)) {
|
|
182
201
|
view.updatePolygon(id) { gmsPoly ->
|
|
183
202
|
onUi {
|
|
@@ -209,7 +228,7 @@ class RNGoogleMapsPlusView(
|
|
|
209
228
|
nextById.forEach { (id, next) ->
|
|
210
229
|
val prev = prevById[id]
|
|
211
230
|
if (prev == null) {
|
|
212
|
-
view.addCircle(id,
|
|
231
|
+
view.addCircle(id, circleBuilder.buildCircleOptions(next))
|
|
213
232
|
} else if (!prev.circleEquals(next)) {
|
|
214
233
|
view.updateCircle(id) { gmsCircle ->
|
|
215
234
|
onUi {
|
|
@@ -226,6 +245,11 @@ class RNGoogleMapsPlusView(
|
|
|
226
245
|
field = value
|
|
227
246
|
}
|
|
228
247
|
|
|
248
|
+
override var locationConfig: RNLocationConfig? = null
|
|
249
|
+
set(value) {
|
|
250
|
+
view.locationConfig = value
|
|
251
|
+
}
|
|
252
|
+
|
|
229
253
|
override var onMapError: ((RNMapErrorCode) -> Unit)? = null
|
|
230
254
|
set(cb) {
|
|
231
255
|
view.onMapError = cb
|
|
@@ -290,7 +314,7 @@ class RNGoogleMapsPlusView(
|
|
|
290
314
|
animated: Boolean?,
|
|
291
315
|
durationMS: Double?,
|
|
292
316
|
) {
|
|
293
|
-
view.setCamera(camera, animated == true, durationMS?.toInt() ?: 3000)
|
|
317
|
+
view.setCamera(camera.toCameraPosition(), animated == true, durationMS?.toInt() ?: 3000)
|
|
294
318
|
}
|
|
295
319
|
|
|
296
320
|
override fun setCameraToCoordinates(
|
|
@@ -318,41 +342,6 @@ class RNGoogleMapsPlusView(
|
|
|
318
342
|
override fun requestLocationPermission(): Promise<RNLocationPermissionResult> = permissionHandler.requestLocationPermission()
|
|
319
343
|
|
|
320
344
|
override fun isGooglePlayServicesAvailable(): Boolean = playServiceHandler.isPlayServicesAvailable()
|
|
321
|
-
|
|
322
|
-
fun userInterfaceStyleToMapColorScheme(value: RNUserInterfaceStyle?): Int? {
|
|
323
|
-
value ?: return null
|
|
324
|
-
return when (value) {
|
|
325
|
-
RNUserInterfaceStyle.LIGHT -> {
|
|
326
|
-
MapColorScheme.LIGHT
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
RNUserInterfaceStyle.DARK -> {
|
|
330
|
-
MapColorScheme.DARK
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
RNUserInterfaceStyle.DEFAULT -> {
|
|
334
|
-
MapColorScheme.FOLLOW_SYSTEM
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
fun mapCameraToCameraPosition(camera: RNCamera?): CameraPosition? {
|
|
340
|
-
camera ?: return null
|
|
341
|
-
val builder = CameraPosition.builder()
|
|
342
|
-
camera.center?.let {
|
|
343
|
-
builder.target(
|
|
344
|
-
com.google.android.gms.maps.model.LatLng(
|
|
345
|
-
camera.center.latitude,
|
|
346
|
-
camera.center.longitude,
|
|
347
|
-
),
|
|
348
|
-
)
|
|
349
|
-
}
|
|
350
|
-
camera.zoom?.let { builder.zoom(it.toFloat()) }
|
|
351
|
-
camera.bearing?.let { builder.bearing(it.toFloat()) }
|
|
352
|
-
camera.tilt?.let { builder.tilt(it.toFloat()) }
|
|
353
|
-
|
|
354
|
-
return builder.build()
|
|
355
|
-
}
|
|
356
345
|
}
|
|
357
346
|
|
|
358
347
|
private inline fun onUi(crossinline block: () -> Unit) {
|