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