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