@lugg/maps 0.2.0-alpha.3 → 0.2.0-alpha.30
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 +21 -3
- package/android/src/main/java/com/luggmaps/LuggMapView.kt +265 -0
- package/android/src/main/java/com/luggmaps/{LuggGoogleMapViewManager.kt → LuggMapViewManager.kt} +75 -36
- package/android/src/main/java/com/luggmaps/LuggMapWrapperView.kt +6 -5
- package/android/src/main/java/com/luggmaps/LuggMarkerView.kt +136 -14
- package/android/src/main/java/com/luggmaps/LuggMarkerViewManager.kt +21 -0
- package/android/src/main/java/com/luggmaps/LuggPackage.kt +1 -4
- package/android/src/main/java/com/luggmaps/LuggPolylineView.kt +16 -0
- package/android/src/main/java/com/luggmaps/LuggPolylineViewManager.kt +22 -0
- package/android/src/main/java/com/luggmaps/{LuggGoogleMapView.kt → core/GoogleMapProvider.kt} +251 -241
- package/android/src/main/java/com/luggmaps/core/MapProviderDelegate.kt +55 -0
- package/android/src/main/java/com/luggmaps/core/PolylineAnimator.kt +163 -52
- package/ios/LuggMapView.h +9 -0
- package/ios/LuggMapView.mm +312 -0
- package/ios/LuggMarkerView.h +9 -0
- package/ios/LuggMarkerView.mm +79 -0
- package/ios/LuggPolylineView.h +4 -0
- package/ios/LuggPolylineView.mm +23 -0
- package/ios/core/AppleMapProvider.h +15 -0
- package/ios/core/AppleMapProvider.mm +664 -0
- package/ios/core/GMSPolylineAnimator.h +3 -0
- package/ios/core/GMSPolylineAnimator.m +175 -40
- package/ios/core/GoogleMapProvider.h +13 -0
- package/ios/core/GoogleMapProvider.mm +513 -0
- package/ios/core/MKPolylineAnimator.h +4 -0
- package/ios/core/MKPolylineAnimator.m +224 -68
- package/ios/core/MapProviderDelegate.h +72 -0
- package/ios/core/PolylineAnimatorBase.h +24 -1
- package/ios/core/PolylineAnimatorBase.m +82 -19
- package/ios/extensions/MKMapView+Zoom.h +2 -0
- package/ios/extensions/MKMapView+Zoom.m +14 -4
- package/lib/module/MapProvider.js +13 -0
- package/lib/module/MapProvider.js.map +1 -0
- package/lib/module/MapProvider.types.js +4 -0
- package/lib/module/MapProvider.types.js.map +1 -0
- package/lib/module/MapProvider.web.js +20 -0
- package/lib/module/MapProvider.web.js.map +1 -0
- package/lib/module/MapView.js +29 -16
- package/lib/module/MapView.js.map +1 -1
- package/lib/module/MapView.web.js +290 -0
- package/lib/module/MapView.web.js.map +1 -0
- package/lib/module/components/Marker.js +19 -2
- package/lib/module/components/Marker.js.map +1 -1
- package/lib/module/components/Marker.web.js +33 -0
- package/lib/module/components/Marker.web.js.map +1 -0
- package/lib/module/components/Polyline.js +17 -4
- package/lib/module/components/Polyline.js.map +1 -1
- package/lib/module/components/Polyline.web.js +229 -0
- package/lib/module/components/Polyline.web.js.map +1 -0
- package/lib/module/components/index.js +2 -2
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/components/index.web.js +5 -0
- package/lib/module/components/index.web.js.map +1 -0
- package/lib/module/fabric/{LuggGoogleMapViewNativeComponent.ts → LuggMapViewNativeComponent.ts} +19 -7
- package/lib/module/fabric/LuggMarkerViewNativeComponent.ts +7 -1
- package/lib/module/fabric/LuggPolylineViewNativeComponent.ts +8 -0
- package/lib/module/index.js +4 -2
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +7 -0
- package/lib/module/index.web.js.map +1 -0
- package/lib/typescript/src/MapProvider.d.ts +8 -0
- package/lib/typescript/src/MapProvider.d.ts.map +1 -0
- package/lib/typescript/src/MapProvider.types.d.ts +16 -0
- package/lib/typescript/src/MapProvider.types.d.ts.map +1 -0
- package/lib/typescript/src/MapProvider.web.d.ts +11 -0
- package/lib/typescript/src/MapProvider.web.d.ts.map +1 -0
- package/lib/typescript/src/MapView.d.ts +4 -4
- package/lib/typescript/src/MapView.d.ts.map +1 -1
- package/lib/typescript/src/MapView.types.d.ts +23 -7
- package/lib/typescript/src/MapView.types.d.ts.map +1 -1
- package/lib/typescript/src/MapView.web.d.ts +3 -0
- package/lib/typescript/src/MapView.web.d.ts.map +1 -0
- package/lib/typescript/src/components/Marker.d.ts +25 -1
- package/lib/typescript/src/components/Marker.d.ts.map +1 -1
- package/lib/typescript/src/components/Marker.web.d.ts +3 -0
- package/lib/typescript/src/components/Marker.web.d.ts.map +1 -0
- package/lib/typescript/src/components/Polyline.d.ts +36 -1
- package/lib/typescript/src/components/Polyline.d.ts.map +1 -1
- package/lib/typescript/src/components/Polyline.web.d.ts +3 -0
- package/lib/typescript/src/components/Polyline.web.d.ts.map +1 -0
- package/lib/typescript/src/components/index.d.ts +4 -2
- package/lib/typescript/src/components/index.d.ts.map +1 -1
- package/lib/typescript/src/components/index.web.d.ts +5 -0
- package/lib/typescript/src/components/index.web.d.ts.map +1 -0
- package/lib/typescript/src/fabric/{LuggGoogleMapViewNativeComponent.d.ts → LuggMapViewNativeComponent.d.ts} +8 -4
- package/lib/typescript/src/fabric/LuggMapViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/fabric/LuggMarkerViewNativeComponent.d.ts +4 -1
- package/lib/typescript/src/fabric/LuggMarkerViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/fabric/LuggPolylineViewNativeComponent.d.ts +7 -0
- package/lib/typescript/src/fabric/LuggPolylineViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +8 -3
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/index.web.d.ts +10 -0
- package/lib/typescript/src/index.web.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +4 -0
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/package.json +17 -3
- package/src/MapProvider.tsx +10 -0
- package/src/MapProvider.types.ts +16 -0
- package/src/MapProvider.web.tsx +14 -0
- package/src/MapView.tsx +28 -26
- package/src/MapView.types.ts +24 -7
- package/src/MapView.web.tsx +364 -0
- package/src/components/Marker.tsx +50 -4
- package/src/components/Marker.web.tsx +33 -0
- package/src/components/Polyline.tsx +51 -2
- package/src/components/Polyline.web.tsx +287 -0
- package/src/components/index.ts +8 -2
- package/src/components/index.web.ts +4 -0
- package/src/fabric/{LuggGoogleMapViewNativeComponent.ts → LuggMapViewNativeComponent.ts} +19 -7
- package/src/fabric/LuggMarkerViewNativeComponent.ts +7 -1
- package/src/fabric/LuggPolylineViewNativeComponent.ts +8 -0
- package/src/index.ts +18 -2
- package/src/index.web.ts +20 -0
- package/src/types.ts +5 -0
- package/ios/LuggAppleMapView.h +0 -16
- package/ios/LuggAppleMapView.mm +0 -580
- package/ios/LuggGoogleMapView.h +0 -13
- package/ios/LuggGoogleMapView.mm +0 -454
- package/lib/module/fabric/LuggAppleMapViewNativeComponent.ts +0 -83
- package/lib/typescript/src/fabric/LuggAppleMapViewNativeComponent.d.ts +0 -54
- package/lib/typescript/src/fabric/LuggAppleMapViewNativeComponent.d.ts.map +0 -1
- package/lib/typescript/src/fabric/LuggGoogleMapViewNativeComponent.d.ts.map +0 -1
- package/src/fabric/LuggAppleMapViewNativeComponent.ts +0 -83
package/android/src/main/java/com/luggmaps/{LuggGoogleMapView.kt → core/GoogleMapProvider.kt}
RENAMED
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
package com.luggmaps
|
|
1
|
+
package com.luggmaps.core
|
|
2
2
|
|
|
3
3
|
import android.annotation.SuppressLint
|
|
4
|
-
import android.
|
|
4
|
+
import android.content.Context
|
|
5
5
|
import android.view.View
|
|
6
|
-
import android.view.ViewGroup
|
|
7
6
|
import com.facebook.react.uimanager.PixelUtil.dpToPx
|
|
8
|
-
import com.facebook.react.uimanager.ThemedReactContext
|
|
9
7
|
import com.facebook.react.util.RNLog
|
|
10
|
-
import com.facebook.react.views.view.ReactViewGroup
|
|
11
8
|
import com.google.android.gms.maps.CameraUpdateFactory
|
|
12
9
|
import com.google.android.gms.maps.GoogleMap
|
|
13
10
|
import com.google.android.gms.maps.GoogleMapOptions
|
|
@@ -15,32 +12,16 @@ import com.google.android.gms.maps.MapView
|
|
|
15
12
|
import com.google.android.gms.maps.OnMapReadyCallback
|
|
16
13
|
import com.google.android.gms.maps.model.AdvancedMarker
|
|
17
14
|
import com.google.android.gms.maps.model.AdvancedMarkerOptions
|
|
18
|
-
import com.google.android.gms.maps.model.AdvancedMarkerOptions.CollisionBehavior
|
|
19
15
|
import com.google.android.gms.maps.model.LatLng
|
|
16
|
+
import com.google.android.gms.maps.model.MapColorScheme
|
|
20
17
|
import com.google.android.gms.maps.model.PolylineOptions
|
|
21
|
-
import com.luggmaps.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
view: LuggGoogleMapView,
|
|
26
|
-
latitude: Double,
|
|
27
|
-
longitude: Double,
|
|
28
|
-
zoom: Float,
|
|
29
|
-
gesture: Boolean
|
|
30
|
-
)
|
|
31
|
-
fun onCameraIdle(
|
|
32
|
-
view: LuggGoogleMapView,
|
|
33
|
-
latitude: Double,
|
|
34
|
-
longitude: Double,
|
|
35
|
-
zoom: Float,
|
|
36
|
-
gesture: Boolean
|
|
37
|
-
)
|
|
38
|
-
fun onReady(view: LuggGoogleMapView)
|
|
39
|
-
}
|
|
18
|
+
import com.luggmaps.LuggMarkerView
|
|
19
|
+
import com.luggmaps.LuggMarkerViewDelegate
|
|
20
|
+
import com.luggmaps.LuggPolylineView
|
|
21
|
+
import com.luggmaps.LuggPolylineViewDelegate
|
|
40
22
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
ReactViewGroup(reactContext),
|
|
23
|
+
class GoogleMapProvider(private val context: Context) :
|
|
24
|
+
MapProvider,
|
|
44
25
|
OnMapReadyCallback,
|
|
45
26
|
LuggMarkerViewDelegate,
|
|
46
27
|
LuggPolylineViewDelegate,
|
|
@@ -48,21 +29,23 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
|
|
|
48
29
|
GoogleMap.OnCameraMoveListener,
|
|
49
30
|
GoogleMap.OnCameraIdleListener {
|
|
50
31
|
|
|
51
|
-
var
|
|
32
|
+
override var delegate: MapProviderDelegate? = null
|
|
33
|
+
override val isMapReady: Boolean get() = _isMapReady
|
|
34
|
+
|
|
35
|
+
var mapId: String = DEMO_MAP_ID
|
|
36
|
+
|
|
52
37
|
private var mapView: MapView? = null
|
|
53
|
-
private var mapWrapperView: LuggMapWrapperView? = null
|
|
54
38
|
private var googleMap: GoogleMap? = null
|
|
55
|
-
private var
|
|
39
|
+
private var _isMapReady = false
|
|
56
40
|
private var isDragging = false
|
|
57
|
-
private
|
|
58
|
-
private val
|
|
59
|
-
private val pendingPolylineViews = mutableListOf<LuggPolylineView>()
|
|
41
|
+
private val pendingMarkerViews = mutableSetOf<LuggMarkerView>()
|
|
42
|
+
private val pendingPolylineViews = mutableSetOf<LuggPolylineView>()
|
|
60
43
|
private val polylineAnimators = mutableMapOf<LuggPolylineView, PolylineAnimator>()
|
|
61
44
|
|
|
62
45
|
// Initial camera settings
|
|
63
|
-
private var initialLatitude: Double =
|
|
64
|
-
private var initialLongitude: Double =
|
|
65
|
-
private var initialZoom: Float =
|
|
46
|
+
private var initialLatitude: Double = 0.0
|
|
47
|
+
private var initialLongitude: Double = 0.0
|
|
48
|
+
private var initialZoom: Float = 10f
|
|
66
49
|
|
|
67
50
|
// UI settings
|
|
68
51
|
private var zoomEnabled: Boolean = true
|
|
@@ -70,95 +53,55 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
|
|
|
70
53
|
private var rotateEnabled: Boolean = true
|
|
71
54
|
private var pitchEnabled: Boolean = true
|
|
72
55
|
private var userLocationEnabled: Boolean = false
|
|
56
|
+
private var userLocationButtonEnabled: Boolean = false
|
|
73
57
|
|
|
74
58
|
// Zoom limits
|
|
75
59
|
private var minZoom: Float? = null
|
|
76
60
|
private var maxZoom: Float? = null
|
|
77
61
|
|
|
78
|
-
//
|
|
79
|
-
private var
|
|
80
|
-
private var paddingLeft: Int = 0
|
|
81
|
-
private var paddingBottom: Int = 0
|
|
82
|
-
private var paddingRight: Int = 0
|
|
62
|
+
// Theme
|
|
63
|
+
private var theme: String = "system"
|
|
83
64
|
|
|
84
|
-
//
|
|
65
|
+
// Edge Insets
|
|
66
|
+
private var edgeInsets: EdgeInsets = EdgeInsets()
|
|
85
67
|
|
|
86
|
-
|
|
87
|
-
super.addView(child, index)
|
|
88
|
-
when (child) {
|
|
89
|
-
is LuggMapWrapperView -> mapWrapperView = child
|
|
68
|
+
// region MapProvider
|
|
90
69
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
syncMarkerView(child)
|
|
94
|
-
}
|
|
70
|
+
override fun initializeMap(wrapperView: View, latitude: Double, longitude: Double, zoom: Float) {
|
|
71
|
+
if (mapView != null) return
|
|
95
72
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
override fun removeViewAt(index: Int) {
|
|
104
|
-
val view = getChildAt(index)
|
|
105
|
-
if (view is LuggMarkerView) {
|
|
106
|
-
Log.d(TAG, "removing markerView: ${view.name}")
|
|
107
|
-
view.marker?.remove()
|
|
108
|
-
view.marker = null
|
|
109
|
-
} else if (view is LuggPolylineView) {
|
|
110
|
-
polylineAnimators[view]?.destroy()
|
|
111
|
-
polylineAnimators.remove(view)
|
|
112
|
-
view.polyline?.remove()
|
|
113
|
-
view.polyline = null
|
|
114
|
-
}
|
|
115
|
-
super.removeViewAt(index)
|
|
116
|
-
}
|
|
73
|
+
initialLatitude = latitude
|
|
74
|
+
initialLongitude = longitude
|
|
75
|
+
initialZoom = zoom
|
|
117
76
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
77
|
+
val options = GoogleMapOptions().mapId(mapId)
|
|
78
|
+
mapView = MapView(context, options).also { view ->
|
|
79
|
+
view.onCreate(null)
|
|
80
|
+
view.onResume()
|
|
81
|
+
view.getMapAsync(this)
|
|
82
|
+
(wrapperView as android.view.ViewGroup).addView(view)
|
|
122
83
|
}
|
|
123
84
|
}
|
|
124
85
|
|
|
125
|
-
fun
|
|
126
|
-
Log.d(TAG, "dropping mapView instance")
|
|
86
|
+
override fun destroy() {
|
|
127
87
|
pendingMarkerViews.clear()
|
|
128
88
|
pendingPolylineViews.clear()
|
|
129
89
|
polylineAnimators.values.forEach { it.destroy() }
|
|
130
90
|
polylineAnimators.clear()
|
|
91
|
+
googleMap?.setOnCameraMoveStartedListener(null)
|
|
92
|
+
googleMap?.setOnCameraMoveListener(null)
|
|
93
|
+
googleMap?.setOnCameraIdleListener(null)
|
|
131
94
|
googleMap?.clear()
|
|
132
95
|
googleMap = null
|
|
133
|
-
|
|
96
|
+
_isMapReady = false
|
|
134
97
|
mapView?.onPause()
|
|
135
98
|
mapView?.onDestroy()
|
|
136
99
|
mapView = null
|
|
137
|
-
mapWrapperView = null
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// endregion
|
|
141
|
-
|
|
142
|
-
// region Map Initialization
|
|
143
|
-
|
|
144
|
-
private fun initializeMap() {
|
|
145
|
-
if (mapView != null || mapWrapperView == null) return
|
|
146
|
-
|
|
147
|
-
val options = GoogleMapOptions().mapId(mapId)
|
|
148
|
-
mapView = MapView(context, options).also { view ->
|
|
149
|
-
view.onCreate(null)
|
|
150
|
-
view.onResume()
|
|
151
|
-
view.getMapAsync(this)
|
|
152
|
-
mapWrapperView?.addView(
|
|
153
|
-
view,
|
|
154
|
-
LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
|
|
155
|
-
)
|
|
156
|
-
}
|
|
157
100
|
}
|
|
158
101
|
|
|
159
102
|
override fun onMapReady(map: GoogleMap) {
|
|
160
103
|
googleMap = map
|
|
161
|
-
|
|
104
|
+
_isMapReady = true
|
|
162
105
|
|
|
163
106
|
val position = LatLng(initialLatitude, initialLongitude)
|
|
164
107
|
map.moveCamera(CameraUpdateFactory.newLatLngZoom(position, initialZoom))
|
|
@@ -169,53 +112,69 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
|
|
|
169
112
|
|
|
170
113
|
applyUiSettings()
|
|
171
114
|
applyZoomLimits()
|
|
172
|
-
|
|
115
|
+
applyEdgeInsets()
|
|
116
|
+
applyTheme()
|
|
173
117
|
applyUserLocation()
|
|
174
118
|
processPendingMarkers()
|
|
175
119
|
processPendingPolylines()
|
|
176
120
|
|
|
177
|
-
|
|
121
|
+
delegate?.mapProviderDidReady()
|
|
178
122
|
}
|
|
179
123
|
|
|
124
|
+
// endregion
|
|
125
|
+
|
|
126
|
+
// region Camera Listeners
|
|
127
|
+
|
|
180
128
|
override fun onCameraMoveStarted(reason: Int) {
|
|
181
129
|
isDragging = reason == GoogleMap.OnCameraMoveStartedListener.REASON_GESTURE
|
|
130
|
+
if (isDragging) {
|
|
131
|
+
polylineAnimators.values.forEach { it.pause() }
|
|
132
|
+
}
|
|
182
133
|
}
|
|
183
134
|
|
|
184
135
|
override fun onCameraMove() {
|
|
185
136
|
val map = googleMap ?: return
|
|
186
137
|
val position = map.cameraPosition
|
|
187
|
-
|
|
138
|
+
delegate?.mapProviderDidMoveCamera(position.target.latitude, position.target.longitude, position.zoom, isDragging)
|
|
188
139
|
}
|
|
189
140
|
|
|
190
141
|
override fun onCameraIdle() {
|
|
191
142
|
val map = googleMap ?: return
|
|
192
143
|
val position = map.cameraPosition
|
|
193
|
-
|
|
144
|
+
delegate?.mapProviderDidIdleCamera(position.target.latitude, position.target.longitude, position.zoom, isDragging)
|
|
145
|
+
if (isDragging) {
|
|
146
|
+
polylineAnimators.values.forEach { it.resume() }
|
|
147
|
+
}
|
|
194
148
|
isDragging = false
|
|
195
149
|
}
|
|
196
150
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
151
|
+
// endregion
|
|
152
|
+
|
|
153
|
+
// region Props
|
|
154
|
+
|
|
155
|
+
override fun setZoomEnabled(enabled: Boolean) {
|
|
156
|
+
zoomEnabled = enabled
|
|
157
|
+
googleMap?.uiSettings?.isZoomGesturesEnabled = enabled
|
|
204
158
|
}
|
|
205
159
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
maxZoom?.let { setMaxZoomPreference(it) }
|
|
210
|
-
}
|
|
160
|
+
override fun setScrollEnabled(enabled: Boolean) {
|
|
161
|
+
scrollEnabled = enabled
|
|
162
|
+
googleMap?.uiSettings?.isScrollGesturesEnabled = enabled
|
|
211
163
|
}
|
|
212
164
|
|
|
213
|
-
|
|
214
|
-
|
|
165
|
+
override fun setRotateEnabled(enabled: Boolean) {
|
|
166
|
+
rotateEnabled = enabled
|
|
167
|
+
googleMap?.uiSettings?.isRotateGesturesEnabled = enabled
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
override fun setPitchEnabled(enabled: Boolean) {
|
|
171
|
+
pitchEnabled = enabled
|
|
172
|
+
googleMap?.uiSettings?.isTiltGesturesEnabled = enabled
|
|
215
173
|
}
|
|
216
174
|
|
|
217
175
|
@SuppressLint("MissingPermission")
|
|
218
|
-
|
|
176
|
+
override fun setUserLocationEnabled(enabled: Boolean) {
|
|
177
|
+
userLocationEnabled = enabled
|
|
219
178
|
val hasPermission =
|
|
220
179
|
context.checkSelfPermission(
|
|
221
180
|
android.Manifest.permission.ACCESS_FINE_LOCATION
|
|
@@ -225,12 +184,59 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
|
|
|
225
184
|
googleMap?.isMyLocationEnabled = userLocationEnabled && hasPermission
|
|
226
185
|
}
|
|
227
186
|
|
|
228
|
-
|
|
187
|
+
override fun setUserLocationButtonEnabled(enabled: Boolean) {
|
|
188
|
+
userLocationButtonEnabled = enabled
|
|
189
|
+
googleMap?.uiSettings?.isMyLocationButtonEnabled = enabled
|
|
190
|
+
}
|
|
229
191
|
|
|
230
|
-
|
|
192
|
+
override fun setTheme(value: String) {
|
|
193
|
+
theme = value
|
|
194
|
+
applyTheme()
|
|
195
|
+
}
|
|
231
196
|
|
|
232
|
-
override fun
|
|
233
|
-
|
|
197
|
+
override fun setMinZoom(zoom: Double) {
|
|
198
|
+
minZoom = if (zoom > 0) zoom.toFloat() else null
|
|
199
|
+
googleMap?.let { map ->
|
|
200
|
+
minZoom?.let { map.setMinZoomPreference(it) } ?: map.resetMinMaxZoomPreference()
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
override fun setMaxZoom(zoom: Double) {
|
|
205
|
+
maxZoom = if (zoom > 0) zoom.toFloat() else null
|
|
206
|
+
googleMap?.let { map ->
|
|
207
|
+
maxZoom?.let { map.setMaxZoomPreference(it) } ?: map.resetMinMaxZoomPreference()
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
override fun setEdgeInsets(edgeInsets: EdgeInsets) {
|
|
212
|
+
val oldInsets = this.edgeInsets
|
|
213
|
+
this.edgeInsets = edgeInsets
|
|
214
|
+
applyEdgeInsets()
|
|
215
|
+
|
|
216
|
+
val map = googleMap
|
|
217
|
+
if (map != null && oldInsets != edgeInsets) {
|
|
218
|
+
mapView?.post {
|
|
219
|
+
setEdgeInsets(edgeInsets, 0)
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
override fun setEdgeInsets(edgeInsets: EdgeInsets, duration: Int) {
|
|
225
|
+
val map = googleMap
|
|
226
|
+
val oldInsets = this.edgeInsets
|
|
227
|
+
this.edgeInsets = edgeInsets
|
|
228
|
+
|
|
229
|
+
if (map != null && oldInsets != edgeInsets) {
|
|
230
|
+
val cameraUpdate = CameraUpdateFactory.newCameraPosition(map.cameraPosition)
|
|
231
|
+
applyEdgeInsets()
|
|
232
|
+
when {
|
|
233
|
+
duration < 0 -> map.animateCamera(cameraUpdate)
|
|
234
|
+
duration > 0 -> map.animateCamera(cameraUpdate, duration, null)
|
|
235
|
+
else -> map.moveCamera(cameraUpdate)
|
|
236
|
+
}
|
|
237
|
+
} else {
|
|
238
|
+
applyEdgeInsets()
|
|
239
|
+
}
|
|
234
240
|
}
|
|
235
241
|
|
|
236
242
|
// endregion
|
|
@@ -239,16 +245,12 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
|
|
|
239
245
|
|
|
240
246
|
override fun markerViewDidLayout(markerView: LuggMarkerView) {
|
|
241
247
|
if (googleMap == null) {
|
|
242
|
-
|
|
243
|
-
pendingMarkerViews.add(markerView)
|
|
244
|
-
}
|
|
248
|
+
pendingMarkerViews.add(markerView)
|
|
245
249
|
return
|
|
246
250
|
}
|
|
247
251
|
|
|
248
252
|
if (markerView.hasCustomView) {
|
|
249
|
-
|
|
250
|
-
markerView.marker?.remove()
|
|
251
|
-
addMarkerViewToMap(markerView)
|
|
253
|
+
markerView.updateIcon { addMarkerViewToMap(markerView) }
|
|
252
254
|
} else {
|
|
253
255
|
syncMarkerView(markerView)
|
|
254
256
|
}
|
|
@@ -260,18 +262,33 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
|
|
|
260
262
|
|
|
261
263
|
// endregion
|
|
262
264
|
|
|
265
|
+
// region PolylineViewDelegate
|
|
266
|
+
|
|
267
|
+
override fun polylineViewDidUpdate(polylineView: LuggPolylineView) {
|
|
268
|
+
syncPolylineView(polylineView)
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// endregion
|
|
272
|
+
|
|
263
273
|
// region Marker Management
|
|
264
274
|
|
|
275
|
+
override fun addMarkerView(markerView: LuggMarkerView) {
|
|
276
|
+
markerView.delegate = this
|
|
277
|
+
syncMarkerView(markerView)
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
override fun removeMarkerView(markerView: LuggMarkerView) {
|
|
281
|
+
markerView.marker?.remove()
|
|
282
|
+
markerView.marker = null
|
|
283
|
+
}
|
|
284
|
+
|
|
265
285
|
private fun syncMarkerView(markerView: LuggMarkerView) {
|
|
266
286
|
if (googleMap == null) {
|
|
267
|
-
|
|
268
|
-
pendingMarkerViews.add(markerView)
|
|
269
|
-
}
|
|
287
|
+
pendingMarkerViews.add(markerView)
|
|
270
288
|
return
|
|
271
289
|
}
|
|
272
290
|
|
|
273
291
|
if (markerView.marker == null) {
|
|
274
|
-
// Custom views need layout first before adding to map
|
|
275
292
|
if (markerView.hasCustomView) return
|
|
276
293
|
addMarkerViewToMap(markerView)
|
|
277
294
|
return
|
|
@@ -282,57 +299,59 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
|
|
|
282
299
|
title = markerView.title
|
|
283
300
|
snippet = markerView.description
|
|
284
301
|
setAnchor(markerView.anchorX, markerView.anchorY)
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
302
|
+
zIndex = markerView.zIndex
|
|
303
|
+
rotation = markerView.rotate
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
if (markerView.hasCustomView && markerView.scaleChanged) {
|
|
307
|
+
markerView.applyScaleToMarker()
|
|
308
|
+
markerView.clearScaleChanged()
|
|
288
309
|
}
|
|
289
310
|
}
|
|
290
311
|
|
|
291
312
|
private fun processPendingMarkers() {
|
|
292
313
|
if (googleMap == null) return
|
|
293
|
-
|
|
294
|
-
Log.d(TAG, "processing pending markers ${pendingMarkerViews.size}")
|
|
295
314
|
pendingMarkerViews.forEach { addMarkerViewToMap(it) }
|
|
296
315
|
pendingMarkerViews.clear()
|
|
297
316
|
}
|
|
298
317
|
|
|
299
318
|
private fun addMarkerViewToMap(markerView: LuggMarkerView) {
|
|
300
|
-
val map = googleMap ?:
|
|
301
|
-
RNLog.w(reactContext, "Lugg: addMarkerViewToMap called without a map")
|
|
302
|
-
return
|
|
303
|
-
}
|
|
319
|
+
val map = googleMap ?: return
|
|
304
320
|
|
|
305
321
|
val position = LatLng(markerView.latitude, markerView.longitude)
|
|
306
|
-
val iconView = markerView.iconView
|
|
307
|
-
|
|
308
|
-
(iconView.parent as? ViewGroup)?.removeView(iconView)
|
|
309
|
-
|
|
310
322
|
val options = AdvancedMarkerOptions()
|
|
311
323
|
.position(position)
|
|
312
324
|
.title(markerView.title)
|
|
313
325
|
.snippet(markerView.description)
|
|
314
|
-
.collisionBehavior(CollisionBehavior.REQUIRED)
|
|
315
|
-
|
|
316
|
-
Log.d(TAG, "adding marker: ${markerView.name} customview: ${markerView.hasCustomView}")
|
|
317
|
-
if (markerView.hasCustomView) {
|
|
318
|
-
options.iconView(iconView)
|
|
319
|
-
}
|
|
320
326
|
|
|
321
327
|
val marker = map.addMarker(options) as AdvancedMarker
|
|
322
328
|
marker.setAnchor(markerView.anchorX, markerView.anchorY)
|
|
329
|
+
marker.zIndex = markerView.zIndex
|
|
330
|
+
marker.rotation = markerView.rotate
|
|
323
331
|
|
|
324
332
|
markerView.marker = marker
|
|
333
|
+
markerView.applyIconToMarker()
|
|
325
334
|
}
|
|
326
335
|
|
|
327
336
|
// endregion
|
|
328
337
|
|
|
329
338
|
// region Polyline Management
|
|
330
339
|
|
|
340
|
+
override fun addPolylineView(polylineView: LuggPolylineView) {
|
|
341
|
+
polylineView.delegate = this
|
|
342
|
+
syncPolylineView(polylineView)
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
override fun removePolylineView(polylineView: LuggPolylineView) {
|
|
346
|
+
polylineAnimators[polylineView]?.destroy()
|
|
347
|
+
polylineAnimators.remove(polylineView)
|
|
348
|
+
polylineView.polyline?.remove()
|
|
349
|
+
polylineView.polyline = null
|
|
350
|
+
}
|
|
351
|
+
|
|
331
352
|
private fun syncPolylineView(polylineView: LuggPolylineView) {
|
|
332
353
|
if (googleMap == null) {
|
|
333
|
-
|
|
334
|
-
pendingPolylineViews.add(polylineView)
|
|
335
|
-
}
|
|
354
|
+
pendingPolylineViews.add(polylineView)
|
|
336
355
|
return
|
|
337
356
|
}
|
|
338
357
|
|
|
@@ -342,11 +361,13 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
|
|
|
342
361
|
}
|
|
343
362
|
|
|
344
363
|
polylineView.polyline?.width = polylineView.strokeWidth.dpToPx()
|
|
364
|
+
polylineView.polyline?.zIndex = polylineView.zIndex
|
|
345
365
|
|
|
346
366
|
polylineAnimators[polylineView]?.apply {
|
|
347
367
|
coordinates = polylineView.coordinates
|
|
348
368
|
strokeColors = polylineView.strokeColors
|
|
349
369
|
strokeWidth = polylineView.strokeWidth.dpToPx()
|
|
370
|
+
animatedOptions = polylineView.animatedOptions
|
|
350
371
|
animated = polylineView.animated
|
|
351
372
|
update()
|
|
352
373
|
}
|
|
@@ -354,7 +375,6 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
|
|
|
354
375
|
|
|
355
376
|
private fun processPendingPolylines() {
|
|
356
377
|
if (googleMap == null) return
|
|
357
|
-
|
|
358
378
|
pendingPolylineViews.forEach { addPolylineViewToMap(it) }
|
|
359
379
|
pendingPolylineViews.clear()
|
|
360
380
|
}
|
|
@@ -364,6 +384,7 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
|
|
|
364
384
|
|
|
365
385
|
val options = PolylineOptions()
|
|
366
386
|
.width(polylineView.strokeWidth.dpToPx())
|
|
387
|
+
.zIndex(polylineView.zIndex)
|
|
367
388
|
|
|
368
389
|
val polyline = map.addPolyline(options)
|
|
369
390
|
polylineView.polyline = polyline
|
|
@@ -373,6 +394,7 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
|
|
|
373
394
|
coordinates = polylineView.coordinates
|
|
374
395
|
strokeColors = polylineView.strokeColors
|
|
375
396
|
strokeWidth = polylineView.strokeWidth.dpToPx()
|
|
397
|
+
animatedOptions = polylineView.animatedOptions
|
|
376
398
|
animated = polylineView.animated
|
|
377
399
|
update()
|
|
378
400
|
}
|
|
@@ -382,83 +404,25 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
|
|
|
382
404
|
|
|
383
405
|
// endregion
|
|
384
406
|
|
|
385
|
-
// region
|
|
386
|
-
|
|
387
|
-
fun setMapId(value: String?) {
|
|
388
|
-
if (value.isNullOrEmpty()) return
|
|
389
|
-
|
|
390
|
-
if (mapView != null) {
|
|
391
|
-
RNLog.w(reactContext, "Lugg: mapId cannot be changed after map is initialized")
|
|
392
|
-
return
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
mapId = value
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
fun setInitialCoordinate(latitude: Double, longitude: Double) {
|
|
399
|
-
initialLatitude = latitude
|
|
400
|
-
initialLongitude = longitude
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
fun setInitialZoom(zoom: Double) {
|
|
404
|
-
initialZoom = zoom.toFloat()
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
fun setZoomEnabled(enabled: Boolean) {
|
|
408
|
-
zoomEnabled = enabled
|
|
409
|
-
googleMap?.uiSettings?.isZoomGesturesEnabled = enabled
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
fun setScrollEnabled(enabled: Boolean) {
|
|
413
|
-
scrollEnabled = enabled
|
|
414
|
-
googleMap?.uiSettings?.isScrollGesturesEnabled = enabled
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
fun setRotateEnabled(enabled: Boolean) {
|
|
418
|
-
rotateEnabled = enabled
|
|
419
|
-
googleMap?.uiSettings?.isRotateGesturesEnabled = enabled
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
fun setPitchEnabled(enabled: Boolean) {
|
|
423
|
-
pitchEnabled = enabled
|
|
424
|
-
googleMap?.uiSettings?.isTiltGesturesEnabled = enabled
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
fun setUserLocationEnabled(enabled: Boolean) {
|
|
428
|
-
userLocationEnabled = enabled
|
|
429
|
-
applyUserLocation()
|
|
430
|
-
}
|
|
407
|
+
// region Lifecycle
|
|
431
408
|
|
|
432
|
-
fun
|
|
433
|
-
|
|
434
|
-
googleMap?.let { map ->
|
|
435
|
-
minZoom?.let { map.setMinZoomPreference(it) } ?: map.resetMinMaxZoomPreference()
|
|
436
|
-
}
|
|
409
|
+
override fun pauseAnimations() {
|
|
410
|
+
polylineAnimators.values.forEach { it.pause() }
|
|
437
411
|
}
|
|
438
412
|
|
|
439
|
-
fun
|
|
440
|
-
|
|
441
|
-
googleMap?.let { map ->
|
|
442
|
-
maxZoom?.let { map.setMaxZoomPreference(it) } ?: map.resetMinMaxZoomPreference()
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
fun setMapPadding(top: Int, left: Int, bottom: Int, right: Int) {
|
|
447
|
-
paddingTop = top
|
|
448
|
-
paddingLeft = left
|
|
449
|
-
paddingBottom = bottom
|
|
450
|
-
paddingRight = right
|
|
451
|
-
applyPadding()
|
|
413
|
+
override fun resumeAnimations() {
|
|
414
|
+
polylineAnimators.values.forEach { it.resume() }
|
|
452
415
|
}
|
|
453
416
|
|
|
454
417
|
// endregion
|
|
455
418
|
|
|
456
419
|
// region Commands
|
|
457
420
|
|
|
458
|
-
fun moveCamera(latitude: Double, longitude: Double, zoom: Double, duration: Int) {
|
|
421
|
+
override fun moveCamera(latitude: Double, longitude: Double, zoom: Double, duration: Int) {
|
|
459
422
|
val map = googleMap ?: return
|
|
460
423
|
val position = LatLng(latitude, longitude)
|
|
461
|
-
val
|
|
424
|
+
val targetZoom = if (zoom > 0) zoom.toFloat() else map.cameraPosition.zoom
|
|
425
|
+
val cameraUpdate = CameraUpdateFactory.newLatLngZoom(position, targetZoom)
|
|
462
426
|
when {
|
|
463
427
|
duration < 0 -> map.animateCamera(cameraUpdate)
|
|
464
428
|
duration > 0 -> map.animateCamera(cameraUpdate, duration, null)
|
|
@@ -466,32 +430,34 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
|
|
|
466
430
|
}
|
|
467
431
|
}
|
|
468
432
|
|
|
469
|
-
fun fitCoordinates(
|
|
470
|
-
coordinates: List<
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
433
|
+
override fun fitCoordinates(
|
|
434
|
+
coordinates: List<Any>,
|
|
435
|
+
edgeInsetsTop: Int,
|
|
436
|
+
edgeInsetsLeft: Int,
|
|
437
|
+
edgeInsetsBottom: Int,
|
|
438
|
+
edgeInsetsRight: Int,
|
|
475
439
|
duration: Int
|
|
476
440
|
) {
|
|
477
441
|
val map = googleMap ?: return
|
|
478
442
|
if (coordinates.isEmpty()) return
|
|
479
443
|
|
|
444
|
+
val latLngs = coordinates.filterIsInstance<LatLng>()
|
|
445
|
+
if (latLngs.isEmpty()) return
|
|
446
|
+
|
|
480
447
|
val boundsBuilder = com.google.android.gms.maps.model.LatLngBounds.Builder()
|
|
481
|
-
|
|
448
|
+
latLngs.forEach { boundsBuilder.include(it) }
|
|
482
449
|
val bounds = boundsBuilder.build()
|
|
483
450
|
|
|
484
|
-
val top =
|
|
485
|
-
val left =
|
|
486
|
-
val bottom =
|
|
487
|
-
val right =
|
|
451
|
+
val top = edgeInsetsTop.toFloat().dpToPx().toInt()
|
|
452
|
+
val left = edgeInsetsLeft.toFloat().dpToPx().toInt()
|
|
453
|
+
val bottom = edgeInsetsBottom.toFloat().dpToPx().toInt()
|
|
454
|
+
val right = edgeInsetsRight.toFloat().dpToPx().toInt()
|
|
488
455
|
|
|
489
|
-
// Set padding before camera update, then restore after
|
|
490
456
|
map.setPadding(
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
457
|
+
edgeInsets.left + left,
|
|
458
|
+
edgeInsets.top + top,
|
|
459
|
+
edgeInsets.right + right,
|
|
460
|
+
edgeInsets.bottom + bottom
|
|
495
461
|
)
|
|
496
462
|
|
|
497
463
|
val cameraUpdate = CameraUpdateFactory.newLatLngBounds(bounds, 0)
|
|
@@ -502,14 +468,58 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
|
|
|
502
468
|
else -> map.moveCamera(cameraUpdate)
|
|
503
469
|
}
|
|
504
470
|
|
|
505
|
-
|
|
506
|
-
|
|
471
|
+
map.setPadding(edgeInsets.left, edgeInsets.top, edgeInsets.right, edgeInsets.bottom)
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// endregion
|
|
475
|
+
|
|
476
|
+
// region Private
|
|
477
|
+
|
|
478
|
+
private fun applyUiSettings() {
|
|
479
|
+
googleMap?.uiSettings?.apply {
|
|
480
|
+
isZoomGesturesEnabled = zoomEnabled
|
|
481
|
+
isScrollGesturesEnabled = scrollEnabled
|
|
482
|
+
isRotateGesturesEnabled = rotateEnabled
|
|
483
|
+
isTiltGesturesEnabled = pitchEnabled
|
|
484
|
+
isMyLocationButtonEnabled = userLocationButtonEnabled
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
private fun applyZoomLimits() {
|
|
489
|
+
googleMap?.apply {
|
|
490
|
+
minZoom?.let { setMinZoomPreference(it) }
|
|
491
|
+
maxZoom?.let { setMaxZoomPreference(it) }
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
private fun applyEdgeInsets() {
|
|
496
|
+
googleMap?.setPadding(edgeInsets.left, edgeInsets.top, edgeInsets.right, edgeInsets.bottom)
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
private fun applyTheme() {
|
|
500
|
+
val colorScheme = when (theme) {
|
|
501
|
+
"dark" -> MapColorScheme.DARK
|
|
502
|
+
"light" -> MapColorScheme.LIGHT
|
|
503
|
+
else -> MapColorScheme.FOLLOW_SYSTEM
|
|
504
|
+
}
|
|
505
|
+
googleMap?.setMapColorScheme(colorScheme)
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
@SuppressLint("MissingPermission")
|
|
509
|
+
private fun applyUserLocation() {
|
|
510
|
+
val hasPermission =
|
|
511
|
+
context.checkSelfPermission(
|
|
512
|
+
android.Manifest.permission.ACCESS_FINE_LOCATION
|
|
513
|
+
) == android.content.pm.PackageManager.PERMISSION_GRANTED ||
|
|
514
|
+
context.checkSelfPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) ==
|
|
515
|
+
android.content.pm.PackageManager.PERMISSION_GRANTED
|
|
516
|
+
googleMap?.isMyLocationEnabled = userLocationEnabled && hasPermission
|
|
517
|
+
googleMap?.uiSettings?.isMyLocationButtonEnabled = userLocationButtonEnabled
|
|
507
518
|
}
|
|
508
519
|
|
|
509
520
|
// endregion
|
|
510
521
|
|
|
511
522
|
companion object {
|
|
512
|
-
private const val TAG = "Lugg"
|
|
513
523
|
const val DEMO_MAP_ID = "DEMO_MAP_ID"
|
|
514
524
|
}
|
|
515
525
|
}
|