react-native-google-maps-plus 1.0.2 → 1.0.3-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/README.md +127 -11
- package/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt +239 -112
- package/android/src/main/java/com/rngooglemapsplus/MapCircle.kt +29 -0
- package/android/src/main/java/com/rngooglemapsplus/MapMarker.kt +6 -5
- package/android/src/main/java/com/rngooglemapsplus/MapPolygon.kt +3 -1
- package/android/src/main/java/com/rngooglemapsplus/MapPolyline.kt +3 -1
- package/android/src/main/java/com/rngooglemapsplus/RNGoogleMapsPlusView.kt +115 -88
- package/ios/Color.swift +20 -20
- package/ios/GoogleMapViewImpl.swift +194 -139
- package/ios/MapCircle.swift +43 -0
- package/ios/MapMarker.swift +10 -17
- package/ios/MapPolygon.swift +9 -6
- package/ios/MapPolyline.swift +9 -7
- package/ios/PermissionHandler.swift +1 -1
- package/ios/RNGoogleMapsPlusModule.swift +1 -1
- package/ios/RNGoogleMapsPlusView.swift +148 -105
- package/lib/module/types.js.map +1 -1
- package/lib/typescript/src/RNGoogleMapsPlusView.nitro.d.ts +17 -12
- package/lib/typescript/src/RNGoogleMapsPlusView.nitro.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +21 -3
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusViewSpec.cpp +173 -69
- package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusViewSpec.hpp +32 -22
- package/nitrogen/generated/android/c++/JRNCircle.hpp +84 -0
- package/nitrogen/generated/android/c++/JRNInitialProps.hpp +66 -0
- package/nitrogen/generated/android/c++/JRNMapType.hpp +68 -0
- package/nitrogen/generated/android/c++/JRNMarker.hpp +4 -4
- package/nitrogen/generated/android/c++/JRNPolygon.hpp +8 -4
- package/nitrogen/generated/android/c++/JRNPolyline.hpp +8 -4
- package/nitrogen/generated/android/c++/views/JHybridRNGoogleMapsPlusViewStateUpdater.cpp +24 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/HybridRNGoogleMapsPlusViewSpec.kt +65 -11
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNCircle.kt +50 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNInitialProps.kt +35 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNMapType.kt +24 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNMarker.kt +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNPolygon.kt +4 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNPolyline.kt +4 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/views/HybridRNGoogleMapsPlusViewManager.kt +7 -1
- package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Bridge.hpp +188 -45
- package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Umbrella.hpp +9 -0
- package/nitrogen/generated/ios/c++/HybridRNGoogleMapsPlusViewSpecSwift.hpp +85 -37
- package/nitrogen/generated/ios/c++/views/HybridRNGoogleMapsPlusViewComponent.mm +41 -16
- package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusViewSpec.swift +16 -11
- package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusViewSpec_cxx.swift +296 -45
- package/nitrogen/generated/ios/swift/RNCircle.swift +198 -0
- package/nitrogen/generated/ios/swift/RNInitialProps.swift +107 -0
- package/nitrogen/generated/ios/swift/RNMapType.swift +52 -0
- package/nitrogen/generated/ios/swift/RNMarker.swift +17 -5
- package/nitrogen/generated/ios/swift/RNPolygon.swift +40 -5
- package/nitrogen/generated/ios/swift/RNPolyline.swift +40 -5
- package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusViewSpec.cpp +12 -2
- package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusViewSpec.hpp +45 -26
- package/nitrogen/generated/shared/c++/RNCircle.hpp +98 -0
- package/nitrogen/generated/shared/c++/RNInitialProps.hpp +78 -0
- package/nitrogen/generated/shared/c++/RNMapType.hpp +88 -0
- package/nitrogen/generated/shared/c++/RNMarker.hpp +6 -6
- package/nitrogen/generated/shared/c++/RNPolygon.hpp +10 -6
- package/nitrogen/generated/shared/c++/RNPolyline.hpp +10 -6
- package/nitrogen/generated/shared/c++/views/HybridRNGoogleMapsPlusViewComponent.cpp +92 -32
- package/nitrogen/generated/shared/c++/views/HybridRNGoogleMapsPlusViewComponent.hpp +21 -13
- package/nitrogen/generated/shared/json/RNGoogleMapsPlusViewConfig.json +6 -1
- package/package.json +5 -5
- package/src/RNGoogleMapsPlusView.nitro.ts +19 -11
- package/src/types.ts +24 -3
package/README.md
CHANGED
|
@@ -1,30 +1,146 @@
|
|
|
1
1
|
# react-native-google-maps-plus
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/react-native-google-maps-plus)
|
|
3
|
+
[](https://www.npmjs.com/package/react-native-google-maps-plus)
|
|
4
|
+
[](https://www.npmjs.com/package/react-native-google-maps-plus)
|
|
4
5
|
[](https://github.com/pinpong/react-native-google-maps-plus/actions/workflows/release.yml)
|
|
5
|
-
[](https://github.com/pinpong/react-native-google-maps-plus/issues)
|
|
6
|
-
[](./LICENSE)
|
|
7
|
-
[](https://prettier.io/)
|
|
8
|
-
[](https://www.typescriptlang.org/)
|
|
9
|
-
[](https://eslint.org/)
|
|
10
|
-
[](https://reactnative.dev/)
|
|
11
|
-
[](https://developer.android.com/)
|
|
12
|
-
[](https://developer.apple.com/ios/)
|
|
6
|
+
[](https://github.com/pinpong/react-native-google-maps-plus/issues)
|
|
7
|
+
[](./LICENSE)
|
|
8
|
+
[](https://prettier.io/)
|
|
9
|
+
[](https://www.typescriptlang.org/)
|
|
10
|
+
[](https://eslint.org/)
|
|
11
|
+
[](https://reactnative.dev/)
|
|
12
|
+
[](https://developer.android.com/)
|
|
13
|
+
[](https://developer.apple.com/ios/)
|
|
13
14
|
|
|
14
15
|
React-native wrapper for android & IOS google maps sdk
|
|
15
16
|
|
|
16
17
|
## Installation
|
|
17
18
|
|
|
19
|
+
`react-native-nitro-modules` is required as this library relies on [Nitro Modules](https://nitro.margelo.com/).
|
|
20
|
+
|
|
18
21
|
```sh
|
|
19
22
|
yarn add react-native-google-maps-plus react-native-nitro-modules
|
|
20
|
-
|
|
21
|
-
> `react-native-nitro-modules` is required as this library relies on [Nitro Modules](https://nitro.margelo.com/).
|
|
22
23
|
```
|
|
23
24
|
|
|
25
|
+
Dependencies
|
|
26
|
+
|
|
27
|
+
This package builds on native SVG rendering libraries:
|
|
28
|
+
|
|
29
|
+
iOS: [SVGKit](https://github.com/SVGKit/SVGKit)
|
|
30
|
+
|
|
31
|
+
Android: [AndroidSVG](https://bigbadaboom.github.io/androidsvg/)
|
|
32
|
+
|
|
33
|
+
These are automatically linked when you install the package, but you may need to clean/rebuild your native projects after first install.
|
|
34
|
+
|
|
35
|
+
## Setup API Key
|
|
36
|
+
|
|
37
|
+
You will need a valid **Google Maps API Key** from the [Google Cloud Console](https://console.cloud.google.com/).
|
|
38
|
+
|
|
39
|
+
### Android
|
|
40
|
+
|
|
41
|
+
It's recommend to use [Secrets Gradle Plugin](https://developers.google.com/maps/documentation/android-sdk/secrets-gradle-plugin) to securely manage your Google Maps API Key.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
### iOS
|
|
46
|
+
|
|
47
|
+
See the official [Google Maps iOS SDK configuration guide](https://developers.google.com/maps/documentation/ios-sdk/config#get-key) for more details.
|
|
48
|
+
|
|
49
|
+
1. Create a `Secrets.xcconfig` file inside the **ios/** folder:
|
|
50
|
+
|
|
51
|
+
```properties
|
|
52
|
+
MAPS_API_KEY=YOUR_IOS_MAPS_API_KEY
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Include it in your project configuration file:
|
|
56
|
+
|
|
57
|
+
```xcconfig
|
|
58
|
+
#include? "Secrets.xcconfig"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
2. Reference the API key in your **Info.plist**:
|
|
62
|
+
|
|
63
|
+
```xml
|
|
64
|
+
<key>MAPS_API_KEY</key>
|
|
65
|
+
<string>$(MAPS_API_KEY)</string>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
3. Provide the key programmatically in **AppDelegate.swift**:
|
|
69
|
+
|
|
70
|
+
```swift
|
|
71
|
+
import GoogleMaps
|
|
72
|
+
|
|
73
|
+
@UIApplicationMain
|
|
74
|
+
class AppDelegate: UIResponder, UIApplicationDelegate {
|
|
75
|
+
func application(_ application: UIApplication,
|
|
76
|
+
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
|
77
|
+
if let apiKey = Bundle.main.object(forInfoDictionaryKey: "MAPS_API_KEY") as? String {
|
|
78
|
+
GMSServices.provideAPIKey(apiKey)
|
|
79
|
+
}
|
|
80
|
+
return true
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
24
87
|
## Usage
|
|
25
88
|
|
|
26
89
|
Checkout the example app in the [example](./example) folder.
|
|
27
90
|
|
|
91
|
+
# Troubleshooting
|
|
92
|
+
|
|
93
|
+
## Android
|
|
94
|
+
|
|
95
|
+
- **API key not found**
|
|
96
|
+
Make sure `secrets.properties` exists under `android/` and contains your `MAPS_API_KEY`.
|
|
97
|
+
Run `./gradlew clean` and rebuild.
|
|
98
|
+
|
|
99
|
+
## iOS
|
|
100
|
+
|
|
101
|
+
- **`GMSServices must be configured before use`**
|
|
102
|
+
Ensure your key is in `Info.plist` and/or provided via `GMSServices.provideAPIKey(...)` in `AppDelegate.swift`.
|
|
103
|
+
|
|
104
|
+
- **Build fails with `Node.h` import error from SVGKit**
|
|
105
|
+
SVGKit uses a header `Node.h` which can conflict with iOS system headers.
|
|
106
|
+
You can patch it automatically in your **Podfile** inside the `post_install` hook:
|
|
107
|
+
|
|
108
|
+
```ruby
|
|
109
|
+
post_install do |installer|
|
|
110
|
+
react_native_post_install(
|
|
111
|
+
installer,
|
|
112
|
+
config[:reactNativePath],
|
|
113
|
+
:mac_catalyst_enabled => false,
|
|
114
|
+
)
|
|
115
|
+
# Force iOS 16+ to avoid deployment target warnings
|
|
116
|
+
installer.pods_project.targets.each do |target|
|
|
117
|
+
target.build_configurations.each do |config|
|
|
118
|
+
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '16.0'
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Patch SVGKit includes to avoid Node.h conflicts
|
|
123
|
+
require 'fileutils'
|
|
124
|
+
svgkit_path = File.join(installer.sandbox.pod_dir('SVGKit'), 'Source')
|
|
125
|
+
Dir.glob(File.join(svgkit_path, '**', '*.{h,m}')).each do |file|
|
|
126
|
+
FileUtils.chmod("u+w", file)
|
|
127
|
+
text = File.read(file)
|
|
128
|
+
new_contents = text.gsub('#import "Node.h"', '#import "SVGKit/Node.h"')
|
|
129
|
+
File.open(file, 'w') { |f| f.write(new_contents) }
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
After applying this, run:
|
|
135
|
+
|
|
136
|
+
```sh
|
|
137
|
+
cd ios && pod install --repo-update
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
- **Maps not rendering**
|
|
141
|
+
- Check that your API key has **Maps SDK for Android/iOS** enabled in Google Cloud Console.
|
|
142
|
+
- Make sure the key is not restricted to wrong bundle IDs or SHA1 fingerprints.
|
|
143
|
+
|
|
28
144
|
## Contributing
|
|
29
145
|
|
|
30
146
|
- [Development workflow](CONTRIBUTING.md#development-workflow)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
package com.rngooglemapsplus
|
|
2
2
|
|
|
3
|
-
import android.annotation.SuppressLint
|
|
4
3
|
import android.location.Location
|
|
4
|
+
import android.widget.FrameLayout
|
|
5
5
|
import com.facebook.react.bridge.LifecycleEventListener
|
|
6
6
|
import com.facebook.react.bridge.UiThreadUtil
|
|
7
7
|
import com.facebook.react.uimanager.PixelUtil.dpToPx
|
|
@@ -9,9 +9,11 @@ import com.facebook.react.uimanager.ThemedReactContext
|
|
|
9
9
|
import com.google.android.gms.common.ConnectionResult
|
|
10
10
|
import com.google.android.gms.maps.CameraUpdateFactory
|
|
11
11
|
import com.google.android.gms.maps.GoogleMap
|
|
12
|
+
import com.google.android.gms.maps.GoogleMapOptions
|
|
12
13
|
import com.google.android.gms.maps.MapView
|
|
13
|
-
import com.google.android.gms.maps.OnMapReadyCallback
|
|
14
14
|
import com.google.android.gms.maps.model.CameraPosition
|
|
15
|
+
import com.google.android.gms.maps.model.Circle
|
|
16
|
+
import com.google.android.gms.maps.model.CircleOptions
|
|
15
17
|
import com.google.android.gms.maps.model.LatLng
|
|
16
18
|
import com.google.android.gms.maps.model.LatLngBounds
|
|
17
19
|
import com.google.android.gms.maps.model.MapColorScheme
|
|
@@ -28,53 +30,46 @@ class GoogleMapsViewImpl(
|
|
|
28
30
|
val locationHandler: LocationHandler,
|
|
29
31
|
val playServiceHandler: PlayServicesHandler,
|
|
30
32
|
val markerOptions: com.rngooglemapsplus.MarkerOptions,
|
|
31
|
-
) :
|
|
33
|
+
) : FrameLayout(reactContext),
|
|
32
34
|
GoogleMap.OnCameraMoveStartedListener,
|
|
33
35
|
GoogleMap.OnCameraMoveListener,
|
|
34
36
|
GoogleMap.OnCameraIdleListener,
|
|
35
37
|
GoogleMap.OnMapClickListener,
|
|
36
|
-
OnMapReadyCallback,
|
|
37
38
|
GoogleMap.OnMarkerClickListener,
|
|
39
|
+
GoogleMap.OnPolylineClickListener,
|
|
40
|
+
GoogleMap.OnPolygonClickListener,
|
|
41
|
+
GoogleMap.OnCircleClickListener,
|
|
38
42
|
LifecycleEventListener {
|
|
43
|
+
private var initialized = false
|
|
44
|
+
private var mapReady = false
|
|
39
45
|
private var googleMap: GoogleMap? = null
|
|
46
|
+
private var mapView: MapView? = null
|
|
40
47
|
|
|
41
|
-
private var pendingBuildingEnabled: Boolean = false
|
|
42
|
-
private var pendingTrafficEnabled: Boolean = false
|
|
43
|
-
private var pendingCustomMapStyle: MapStyleOptions? = null
|
|
44
|
-
private var pendingInitialCamera: CameraPosition =
|
|
45
|
-
CameraPosition
|
|
46
|
-
.builder()
|
|
47
|
-
.target(
|
|
48
|
-
LatLng(
|
|
49
|
-
0.0,
|
|
50
|
-
0.0,
|
|
51
|
-
),
|
|
52
|
-
).zoom(0f)
|
|
53
|
-
.bearing(0f)
|
|
54
|
-
.tilt(0f)
|
|
55
|
-
.build()
|
|
56
|
-
private var pendingUserInterfaceStyle: Int = MapColorScheme.FOLLOW_SYSTEM
|
|
57
|
-
private var pendingMinZoomLevel: Double = 0.0
|
|
58
|
-
private var pendingMaxZoomLevel: Double = 21.0
|
|
59
|
-
private var pendingMapPadding: RNMapPadding = RNMapPadding(0.0, 0.0, 0.0, 0.0)
|
|
60
|
-
private val pendingPolygons = mutableListOf<Pair<String, PolygonOptions>>()
|
|
61
|
-
private val pendingPolylines = mutableListOf<Pair<String, PolylineOptions>>()
|
|
62
48
|
private val pendingMarkers = mutableListOf<Pair<String, MarkerOptions>>()
|
|
63
|
-
private
|
|
49
|
+
private val pendingPolylines = mutableListOf<Pair<String, PolylineOptions>>()
|
|
50
|
+
private val pendingPolygons = mutableListOf<Pair<String, PolygonOptions>>()
|
|
51
|
+
private val pendingCircles = mutableListOf<Pair<String, CircleOptions>>()
|
|
64
52
|
|
|
65
|
-
private val polygonsById = mutableMapOf<String, Polygon>()
|
|
66
|
-
private val polylinesById = mutableMapOf<String, Polyline>()
|
|
67
53
|
private val markersById = mutableMapOf<String, Marker>()
|
|
54
|
+
private val polylinesById = mutableMapOf<String, Polyline>()
|
|
55
|
+
private val polygonsById = mutableMapOf<String, Polygon>()
|
|
56
|
+
private val circlesById = mutableMapOf<String, Circle>()
|
|
68
57
|
|
|
58
|
+
private var cameraMoveReason = -1
|
|
69
59
|
private var lastSubmittedLocation: Location? = null
|
|
70
60
|
private var lastSubmittedCameraPosition: CameraPosition? = null
|
|
71
61
|
|
|
72
62
|
init {
|
|
73
63
|
reactContext.addLifecycleEventListener(this)
|
|
74
|
-
getMap()
|
|
75
64
|
}
|
|
76
65
|
|
|
77
|
-
|
|
66
|
+
fun initMapView(
|
|
67
|
+
mapId: String?,
|
|
68
|
+
liteMode: Boolean?,
|
|
69
|
+
cameraPosition: CameraPosition?,
|
|
70
|
+
) {
|
|
71
|
+
if (initialized) return
|
|
72
|
+
initialized = true
|
|
78
73
|
val result = playServiceHandler.playServicesAvailability()
|
|
79
74
|
|
|
80
75
|
when (result) {
|
|
@@ -103,8 +98,38 @@ class GoogleMapsViewImpl(
|
|
|
103
98
|
onMapError?.invoke(RNMapErrorCode.UNKNOWN)
|
|
104
99
|
}
|
|
105
100
|
|
|
106
|
-
|
|
107
|
-
|
|
101
|
+
mapView =
|
|
102
|
+
MapView(
|
|
103
|
+
reactContext,
|
|
104
|
+
GoogleMapOptions().apply {
|
|
105
|
+
mapId?.let { mapId(it) }
|
|
106
|
+
liteMode?.let { liteMode(it) }
|
|
107
|
+
cameraPosition?.let {
|
|
108
|
+
camera(it)
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
super.addView(mapView)
|
|
114
|
+
|
|
115
|
+
mapView?.onCreate(null)
|
|
116
|
+
mapView?.getMapAsync { map ->
|
|
117
|
+
googleMap = map
|
|
118
|
+
googleMap?.setOnMapLoadedCallback {
|
|
119
|
+
googleMap?.setOnCameraMoveStartedListener(this@GoogleMapsViewImpl)
|
|
120
|
+
googleMap?.setOnCameraMoveListener(this@GoogleMapsViewImpl)
|
|
121
|
+
googleMap?.setOnCameraIdleListener(this@GoogleMapsViewImpl)
|
|
122
|
+
googleMap?.setOnMarkerClickListener(this@GoogleMapsViewImpl)
|
|
123
|
+
googleMap?.setOnPolylineClickListener(this@GoogleMapsViewImpl)
|
|
124
|
+
googleMap?.setOnPolygonClickListener(this@GoogleMapsViewImpl)
|
|
125
|
+
googleMap?.setOnCircleClickListener(this@GoogleMapsViewImpl)
|
|
126
|
+
googleMap?.setOnMapClickListener(this@GoogleMapsViewImpl)
|
|
127
|
+
}
|
|
128
|
+
initLocationCallbacks()
|
|
129
|
+
applyPending()
|
|
130
|
+
}
|
|
131
|
+
mapReady = true
|
|
132
|
+
onMapReady?.invoke(true)
|
|
108
133
|
}
|
|
109
134
|
|
|
110
135
|
override fun onCameraMoveStarted(reason: Int) {
|
|
@@ -195,22 +220,6 @@ class GoogleMapsViewImpl(
|
|
|
195
220
|
)
|
|
196
221
|
}
|
|
197
222
|
|
|
198
|
-
@SuppressLint("PotentialBehaviorOverride")
|
|
199
|
-
override fun onMapReady(map: GoogleMap) {
|
|
200
|
-
googleMap = map
|
|
201
|
-
googleMap?.setOnMapLoadedCallback {
|
|
202
|
-
googleMap?.setOnCameraMoveStartedListener(this)
|
|
203
|
-
googleMap?.setOnCameraMoveListener(this)
|
|
204
|
-
googleMap?.setOnCameraIdleListener(this)
|
|
205
|
-
googleMap?.setOnMarkerClickListener(this)
|
|
206
|
-
googleMap?.setOnMapClickListener(this)
|
|
207
|
-
}
|
|
208
|
-
initLocationCallbacks()
|
|
209
|
-
applyPending()
|
|
210
|
-
|
|
211
|
-
onMapReady?.invoke(true)
|
|
212
|
-
}
|
|
213
|
-
|
|
214
223
|
fun initLocationCallbacks() {
|
|
215
224
|
locationHandler.onUpdate = { location ->
|
|
216
225
|
// / only the coordinated are relevant right now
|
|
@@ -235,27 +244,33 @@ class GoogleMapsViewImpl(
|
|
|
235
244
|
|
|
236
245
|
fun applyPending() {
|
|
237
246
|
onUi {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
pendingInitialCamera.let {
|
|
246
|
-
googleMap?.moveCamera(
|
|
247
|
-
CameraUpdateFactory.newCameraPosition(
|
|
248
|
-
it,
|
|
249
|
-
),
|
|
247
|
+
mapPadding?.let {
|
|
248
|
+
googleMap?.setPadding(
|
|
249
|
+
it.left.dpToPx().toInt(),
|
|
250
|
+
it.top.dpToPx().toInt(),
|
|
251
|
+
it.right.dpToPx().toInt(),
|
|
252
|
+
it.bottom.dpToPx().toInt(),
|
|
250
253
|
)
|
|
251
254
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
googleMap?.
|
|
255
|
+
buildingEnabled?.let {
|
|
256
|
+
googleMap?.isBuildingsEnabled = it
|
|
257
|
+
}
|
|
258
|
+
trafficEnabled?.let {
|
|
259
|
+
googleMap?.isTrafficEnabled = it
|
|
260
|
+
}
|
|
261
|
+
googleMap?.setMapStyle(customMapStyle)
|
|
262
|
+
mapType?.let {
|
|
263
|
+
googleMap?.mapType = it
|
|
264
|
+
}
|
|
265
|
+
userInterfaceStyle?.let {
|
|
266
|
+
googleMap?.mapColorScheme = it
|
|
267
|
+
}
|
|
268
|
+
minZoomLevel?.let {
|
|
269
|
+
googleMap?.setMinZoomPreference(it.toFloat())
|
|
270
|
+
}
|
|
271
|
+
maxZoomLevel?.let {
|
|
272
|
+
googleMap?.setMaxZoomPreference(it.toFloat())
|
|
273
|
+
}
|
|
259
274
|
}
|
|
260
275
|
|
|
261
276
|
if (pendingMarkers.isNotEmpty()) {
|
|
@@ -278,79 +293,110 @@ class GoogleMapsViewImpl(
|
|
|
278
293
|
}
|
|
279
294
|
pendingPolygons.clear()
|
|
280
295
|
}
|
|
296
|
+
|
|
297
|
+
if (pendingCircles.isNotEmpty()) {
|
|
298
|
+
pendingCircles.forEach { (id, opts) ->
|
|
299
|
+
internalAddCircle(id, opts)
|
|
300
|
+
}
|
|
301
|
+
pendingCircles.clear()
|
|
302
|
+
}
|
|
281
303
|
}
|
|
282
304
|
|
|
283
|
-
var buildingEnabled: Boolean
|
|
284
|
-
get() = googleMap?.isBuildingsEnabled ?: pendingBuildingEnabled
|
|
305
|
+
var buildingEnabled: Boolean? = null
|
|
285
306
|
set(value) {
|
|
286
|
-
|
|
307
|
+
field = value
|
|
287
308
|
onUi {
|
|
288
|
-
|
|
309
|
+
value?.let {
|
|
310
|
+
googleMap?.isBuildingsEnabled = it
|
|
311
|
+
}
|
|
312
|
+
?: run {
|
|
313
|
+
googleMap?.isBuildingsEnabled = false
|
|
314
|
+
}
|
|
289
315
|
}
|
|
290
316
|
}
|
|
291
317
|
|
|
292
|
-
var trafficEnabled: Boolean
|
|
293
|
-
get() = googleMap?.isTrafficEnabled ?: pendingTrafficEnabled
|
|
318
|
+
var trafficEnabled: Boolean? = null
|
|
294
319
|
set(value) {
|
|
295
|
-
|
|
320
|
+
field = value
|
|
296
321
|
onUi {
|
|
297
|
-
|
|
322
|
+
value?.let {
|
|
323
|
+
googleMap?.isTrafficEnabled = it
|
|
324
|
+
} ?: run {
|
|
325
|
+
googleMap?.isTrafficEnabled = false
|
|
326
|
+
}
|
|
298
327
|
}
|
|
299
328
|
}
|
|
300
329
|
|
|
301
|
-
var customMapStyle: MapStyleOptions?
|
|
302
|
-
get() = pendingCustomMapStyle
|
|
330
|
+
var customMapStyle: MapStyleOptions? = null
|
|
303
331
|
set(value) {
|
|
304
|
-
|
|
332
|
+
field = value
|
|
305
333
|
onUi {
|
|
306
334
|
googleMap?.setMapStyle(value)
|
|
307
335
|
}
|
|
308
336
|
}
|
|
309
337
|
|
|
310
|
-
var
|
|
311
|
-
get() = pendingInitialCamera
|
|
338
|
+
var userInterfaceStyle: Int? = null
|
|
312
339
|
set(value) {
|
|
313
|
-
|
|
340
|
+
field = value
|
|
341
|
+
onUi {
|
|
342
|
+
value?.let {
|
|
343
|
+
googleMap?.mapColorScheme = it
|
|
344
|
+
} ?: run {
|
|
345
|
+
googleMap?.mapColorScheme = MapColorScheme.FOLLOW_SYSTEM
|
|
346
|
+
}
|
|
347
|
+
}
|
|
314
348
|
}
|
|
315
349
|
|
|
316
|
-
var
|
|
317
|
-
get() = pendingUserInterfaceStyle
|
|
350
|
+
var minZoomLevel: Double? = null
|
|
318
351
|
set(value) {
|
|
319
|
-
|
|
352
|
+
field = value
|
|
320
353
|
onUi {
|
|
321
|
-
|
|
354
|
+
value?.let {
|
|
355
|
+
googleMap?.setMinZoomPreference(it.toFloat())
|
|
356
|
+
} ?: run {
|
|
357
|
+
googleMap?.setMinZoomPreference(2.0f)
|
|
358
|
+
}
|
|
322
359
|
}
|
|
323
360
|
}
|
|
324
361
|
|
|
325
|
-
var
|
|
326
|
-
get() = pendingMinZoomLevel
|
|
362
|
+
var maxZoomLevel: Double? = null
|
|
327
363
|
set(value) {
|
|
328
|
-
|
|
364
|
+
field = value
|
|
329
365
|
onUi {
|
|
330
|
-
|
|
366
|
+
value?.let {
|
|
367
|
+
googleMap?.setMaxZoomPreference(it.toFloat())
|
|
368
|
+
} ?: run {
|
|
369
|
+
googleMap?.setMaxZoomPreference(21.0f)
|
|
370
|
+
}
|
|
331
371
|
}
|
|
332
372
|
}
|
|
333
373
|
|
|
334
|
-
var
|
|
335
|
-
get() = pendingMaxZoomLevel
|
|
374
|
+
var mapPadding: RNMapPadding? = null
|
|
336
375
|
set(value) {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
376
|
+
field = value
|
|
377
|
+
value?.let {
|
|
378
|
+
onUi {
|
|
379
|
+
googleMap?.setPadding(
|
|
380
|
+
it.left.dpToPx().toInt(),
|
|
381
|
+
it.top.dpToPx().toInt(),
|
|
382
|
+
it.right.dpToPx().toInt(),
|
|
383
|
+
it.bottom.dpToPx().toInt(),
|
|
384
|
+
)
|
|
385
|
+
}
|
|
386
|
+
} ?: run {
|
|
387
|
+
googleMap?.setPadding(0, 0, 0, 0)
|
|
340
388
|
}
|
|
341
389
|
}
|
|
342
390
|
|
|
343
|
-
var
|
|
344
|
-
get() = pendingMapPadding
|
|
391
|
+
var mapType: Int? = null
|
|
345
392
|
set(value) {
|
|
346
|
-
|
|
393
|
+
field = value
|
|
347
394
|
onUi {
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
)
|
|
395
|
+
value?.let {
|
|
396
|
+
googleMap?.mapType = it
|
|
397
|
+
} ?: run {
|
|
398
|
+
googleMap?.mapType = 1
|
|
399
|
+
}
|
|
354
400
|
}
|
|
355
401
|
}
|
|
356
402
|
|
|
@@ -360,6 +406,9 @@ class GoogleMapsViewImpl(
|
|
|
360
406
|
var onLocationError: ((RNLocationErrorCode) -> Unit)? = null
|
|
361
407
|
var onMapPress: ((RNLatLng) -> Unit)? = null
|
|
362
408
|
var onMarkerPress: ((String) -> Unit)? = null
|
|
409
|
+
var onPolylinePress: ((String) -> Unit)? = null
|
|
410
|
+
var onPolygonPress: ((String) -> Unit)? = null
|
|
411
|
+
var onCirclePress: ((String) -> Unit)? = null
|
|
363
412
|
var onCameraChangeStart: ((RNRegion, RNCamera, Boolean) -> Unit)? = null
|
|
364
413
|
var onCameraChange: ((RNRegion, RNCamera, Boolean) -> Unit)? = null
|
|
365
414
|
var onCameraChangeComplete: ((RNRegion, RNCamera, Boolean) -> Unit)? = null
|
|
@@ -429,8 +478,8 @@ class GoogleMapsViewImpl(
|
|
|
429
478
|
val latSpan = bounds.northeast.latitude - bounds.southwest.latitude
|
|
430
479
|
val lngSpan = bounds.northeast.longitude - bounds.southwest.longitude
|
|
431
480
|
|
|
432
|
-
val latPerPixel = latSpan / height
|
|
433
|
-
val lngPerPixel = lngSpan / width
|
|
481
|
+
val latPerPixel = latSpan / (mapView?.height ?: 0)
|
|
482
|
+
val lngPerPixel = lngSpan / (mapView?.width ?: 0)
|
|
434
483
|
|
|
435
484
|
builder.include(
|
|
436
485
|
LatLng(
|
|
@@ -459,8 +508,10 @@ class GoogleMapsViewImpl(
|
|
|
459
508
|
|
|
460
509
|
val paddedBounds = builder.build()
|
|
461
510
|
|
|
462
|
-
val adjustedWidth =
|
|
463
|
-
|
|
511
|
+
val adjustedWidth =
|
|
512
|
+
((mapView?.width ?: 0) - padding.left.dpToPx() - padding.right.dpToPx()).toInt()
|
|
513
|
+
val adjustedHeight =
|
|
514
|
+
((mapView?.height ?: 0) - padding.top.dpToPx() - padding.bottom.dpToPx()).toInt()
|
|
464
515
|
|
|
465
516
|
val update =
|
|
466
517
|
CameraUpdateFactory.newLatLngBounds(
|
|
@@ -639,22 +690,86 @@ class GoogleMapsViewImpl(
|
|
|
639
690
|
pendingPolygons.clear()
|
|
640
691
|
}
|
|
641
692
|
|
|
642
|
-
fun
|
|
693
|
+
fun addCircle(
|
|
694
|
+
id: String,
|
|
695
|
+
opts: CircleOptions,
|
|
696
|
+
) {
|
|
697
|
+
if (googleMap == null) {
|
|
698
|
+
pendingCircles.add(id to opts)
|
|
699
|
+
return
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
onUi {
|
|
703
|
+
circlesById.remove(id)?.remove()
|
|
704
|
+
}
|
|
705
|
+
internalAddCircle(id, opts)
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
private fun internalAddCircle(
|
|
709
|
+
id: String,
|
|
710
|
+
opts: CircleOptions,
|
|
711
|
+
) {
|
|
712
|
+
onUi {
|
|
713
|
+
val circle =
|
|
714
|
+
googleMap?.addCircle(opts).also {
|
|
715
|
+
it?.tag = id
|
|
716
|
+
}
|
|
717
|
+
if (circle != null) {
|
|
718
|
+
circlesById[id] = circle
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
fun updateCircle(
|
|
724
|
+
id: String,
|
|
725
|
+
block: (Circle) -> Unit,
|
|
726
|
+
) {
|
|
727
|
+
val circle = circlesById[id] ?: return
|
|
728
|
+
onUi {
|
|
729
|
+
block(circle)
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
fun removeCircle(id: String) {
|
|
734
|
+
onUi {
|
|
735
|
+
circlesById.remove(id)?.remove()
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
fun clearCircles() {
|
|
740
|
+
onUi {
|
|
741
|
+
circlesById.values.forEach { it.remove() }
|
|
742
|
+
}
|
|
743
|
+
circlesById.clear()
|
|
744
|
+
pendingCircles.clear()
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
fun destroyInternal() {
|
|
643
748
|
onUi {
|
|
644
749
|
markerOptions.cancelAllJobs()
|
|
645
750
|
clearMarkers()
|
|
646
751
|
clearPolylines()
|
|
647
752
|
clearPolygons()
|
|
753
|
+
clearCircles()
|
|
648
754
|
locationHandler.stop()
|
|
649
755
|
googleMap?.apply {
|
|
650
756
|
setOnCameraMoveStartedListener(null)
|
|
651
757
|
setOnCameraMoveListener(null)
|
|
652
758
|
setOnCameraIdleListener(null)
|
|
653
759
|
setOnMarkerClickListener(null)
|
|
760
|
+
setOnPolylineClickListener(null)
|
|
761
|
+
setOnPolygonClickListener(null)
|
|
762
|
+
setOnCircleClickListener(null)
|
|
654
763
|
setOnMapClickListener(null)
|
|
655
764
|
}
|
|
656
|
-
this@GoogleMapsViewImpl.onDestroy()
|
|
657
765
|
googleMap = null
|
|
766
|
+
mapView?.apply {
|
|
767
|
+
onPause()
|
|
768
|
+
onStop()
|
|
769
|
+
onDestroy()
|
|
770
|
+
removeAllViews()
|
|
771
|
+
}
|
|
772
|
+
super.removeAllViews()
|
|
658
773
|
reactContext.removeLifecycleEventListener(this)
|
|
659
774
|
}
|
|
660
775
|
}
|
|
@@ -684,19 +799,19 @@ class GoogleMapsViewImpl(
|
|
|
684
799
|
override fun onHostResume() {
|
|
685
800
|
onUi {
|
|
686
801
|
locationHandler.start()
|
|
687
|
-
|
|
802
|
+
mapView?.onResume()
|
|
688
803
|
}
|
|
689
804
|
}
|
|
690
805
|
|
|
691
806
|
override fun onHostPause() {
|
|
692
807
|
onUi {
|
|
693
808
|
locationHandler.stop()
|
|
694
|
-
|
|
809
|
+
mapView?.onPause()
|
|
695
810
|
}
|
|
696
811
|
}
|
|
697
812
|
|
|
698
813
|
override fun onHostDestroy() {
|
|
699
|
-
|
|
814
|
+
destroyInternal()
|
|
700
815
|
}
|
|
701
816
|
|
|
702
817
|
override fun onMarkerClick(marker: Marker): Boolean {
|
|
@@ -704,6 +819,18 @@ class GoogleMapsViewImpl(
|
|
|
704
819
|
return true
|
|
705
820
|
}
|
|
706
821
|
|
|
822
|
+
override fun onPolylineClick(polyline: Polyline) {
|
|
823
|
+
onPolylinePress?.invoke(polyline.tag?.toString() ?: "unknown")
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
override fun onPolygonClick(polygon: Polygon) {
|
|
827
|
+
onPolygonPress?.invoke(polygon.tag?.toString() ?: "unknown")
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
override fun onCircleClick(circle: Circle) {
|
|
831
|
+
onCirclePress?.invoke(circle.tag?.toString() ?: "unknown")
|
|
832
|
+
}
|
|
833
|
+
|
|
707
834
|
override fun onMapClick(coordinates: LatLng) {
|
|
708
835
|
onMapPress?.invoke(
|
|
709
836
|
RNLatLng(coordinates.latitude, coordinates.longitude),
|