@lugg/maps 0.2.0-alpha.22 → 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.
Files changed (32) hide show
  1. package/README.md +5 -0
  2. package/android/src/main/java/com/luggmaps/LuggMapView.kt +201 -0
  3. package/android/src/main/java/com/luggmaps/{LuggGoogleMapViewManager.kt → LuggMapViewManager.kt} +35 -30
  4. package/android/src/main/java/com/luggmaps/LuggPackage.kt +1 -4
  5. package/android/src/main/java/com/luggmaps/{LuggGoogleMapView.kt → core/GoogleMapProvider.kt} +167 -201
  6. package/android/src/main/java/com/luggmaps/core/MapProviderDelegate.kt +51 -0
  7. package/android/src/main/java/com/luggmaps/core/PolylineAnimator.kt +28 -24
  8. package/ios/LuggMapView.h +9 -0
  9. package/ios/LuggMapView.mm +303 -0
  10. package/ios/core/AppleMapProvider.h +15 -0
  11. package/ios/{LuggAppleMapView.mm → core/AppleMapProvider.mm} +310 -421
  12. package/ios/core/GMSPolylineAnimator.m +16 -4
  13. package/ios/core/GoogleMapProvider.h +13 -0
  14. package/ios/{LuggGoogleMapView.mm → core/GoogleMapProvider.mm} +178 -238
  15. package/ios/core/MapProviderDelegate.h +68 -0
  16. package/lib/module/MapView.js +5 -11
  17. package/lib/module/MapView.js.map +1 -1
  18. package/lib/module/fabric/{LuggGoogleMapViewNativeComponent.ts → LuggMapViewNativeComponent.ts} +2 -1
  19. package/lib/typescript/src/MapView.d.ts +0 -1
  20. package/lib/typescript/src/MapView.d.ts.map +1 -1
  21. package/lib/typescript/src/fabric/{LuggGoogleMapViewNativeComponent.d.ts → LuggMapViewNativeComponent.d.ts} +2 -1
  22. package/lib/typescript/src/fabric/LuggMapViewNativeComponent.d.ts.map +1 -0
  23. package/package.json +3 -4
  24. package/src/MapView.tsx +8 -21
  25. package/src/fabric/{LuggGoogleMapViewNativeComponent.ts → LuggMapViewNativeComponent.ts} +2 -1
  26. package/ios/LuggAppleMapView.h +0 -16
  27. package/ios/LuggGoogleMapView.h +0 -13
  28. package/lib/module/fabric/LuggAppleMapViewNativeComponent.ts +0 -85
  29. package/lib/typescript/src/fabric/LuggAppleMapViewNativeComponent.d.ts +0 -55
  30. package/lib/typescript/src/fabric/LuggAppleMapViewNativeComponent.d.ts.map +0 -1
  31. package/lib/typescript/src/fabric/LuggGoogleMapViewNativeComponent.d.ts.map +0 -1
  32. package/src/fabric/LuggAppleMapViewNativeComponent.ts +0 -85
@@ -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.core.PolylineAnimator
22
-
23
- interface LuggGoogleMapViewEventDelegate {
24
- fun onCameraMove(
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
- @SuppressLint("ViewConstructor")
42
- class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
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 eventDelegate: LuggGoogleMapViewEventDelegate? = null
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 isMapReady = false
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 = 37.78
64
- private var initialLongitude: Double = -122.43
65
- private var initialZoom: Float = 14f
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
@@ -84,79 +67,40 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
84
67
  private var paddingBottom: Int = 0
85
68
  private var paddingRight: Int = 0
86
69
 
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
70
+ // region MapProvider
93
71
 
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
- }
72
+ override fun initializeMap(wrapperView: View, latitude: Double, longitude: Double, zoom: Float) {
73
+ if (mapView != null) return
105
74
 
106
- override fun removeViewAt(index: Int) {
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
- }
75
+ initialLatitude = latitude
76
+ initialLongitude = longitude
77
+ initialZoom = zoom
119
78
 
120
- override fun onAttachedToWindow() {
121
- super.onAttachedToWindow()
122
- if (mapView == null && mapWrapperView != null) {
123
- initializeMap()
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)
124
85
  }
125
86
  }
126
87
 
127
- fun onDropViewInstance() {
88
+ override fun destroy() {
128
89
  pendingMarkerViews.clear()
129
90
  pendingPolylineViews.clear()
130
91
  polylineAnimators.values.forEach { it.destroy() }
131
92
  polylineAnimators.clear()
132
93
  googleMap?.clear()
133
94
  googleMap = null
134
- isMapReady = false
95
+ _isMapReady = false
135
96
  mapView?.onPause()
136
97
  mapView?.onDestroy()
137
98
  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
99
  }
156
100
 
157
101
  override fun onMapReady(map: GoogleMap) {
158
102
  googleMap = map
159
- isMapReady = true
103
+ _isMapReady = true
160
104
 
161
105
  val position = LatLng(initialLatitude, initialLongitude)
162
106
  map.moveCamera(CameraUpdateFactory.newLatLngZoom(position, initialZoom))
@@ -173,9 +117,13 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
173
117
  processPendingMarkers()
174
118
  processPendingPolylines()
175
119
 
176
- eventDelegate?.onReady(this)
120
+ delegate?.mapProviderDidReady()
177
121
  }
178
122
 
123
+ // endregion
124
+
125
+ // region Camera Listeners
126
+
179
127
  override fun onCameraMoveStarted(reason: Int) {
180
128
  isDragging = reason == GoogleMap.OnCameraMoveStartedListener.REASON_GESTURE
181
129
  if (isDragging) {
@@ -186,50 +134,46 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
186
134
  override fun onCameraMove() {
187
135
  val map = googleMap ?: return
188
136
  val position = map.cameraPosition
189
- eventDelegate?.onCameraMove(this, position.target.latitude, position.target.longitude, position.zoom, isDragging)
137
+ delegate?.mapProviderDidMoveCamera(position.target.latitude, position.target.longitude, position.zoom, isDragging)
190
138
  }
191
139
 
192
140
  override fun onCameraIdle() {
193
141
  val map = googleMap ?: return
194
142
  val position = map.cameraPosition
195
- eventDelegate?.onCameraIdle(this, position.target.latitude, position.target.longitude, position.zoom, isDragging)
143
+ delegate?.mapProviderDidIdleCamera(position.target.latitude, position.target.longitude, position.zoom, isDragging)
196
144
  if (isDragging) {
197
145
  polylineAnimators.values.forEach { it.resume() }
198
146
  }
199
147
  isDragging = false
200
148
  }
201
149
 
202
- private fun applyUiSettings() {
203
- googleMap?.uiSettings?.apply {
204
- isZoomGesturesEnabled = zoomEnabled
205
- isScrollGesturesEnabled = scrollEnabled
206
- isRotateGesturesEnabled = rotateEnabled
207
- isTiltGesturesEnabled = pitchEnabled
208
- }
150
+ // endregion
151
+
152
+ // region Props
153
+
154
+ override fun setZoomEnabled(enabled: Boolean) {
155
+ zoomEnabled = enabled
156
+ googleMap?.uiSettings?.isZoomGesturesEnabled = enabled
209
157
  }
210
158
 
211
- private fun applyZoomLimits() {
212
- googleMap?.apply {
213
- minZoom?.let { setMinZoomPreference(it) }
214
- maxZoom?.let { setMaxZoomPreference(it) }
215
- }
159
+ override fun setScrollEnabled(enabled: Boolean) {
160
+ scrollEnabled = enabled
161
+ googleMap?.uiSettings?.isScrollGesturesEnabled = enabled
216
162
  }
217
163
 
218
- private fun applyPadding() {
219
- googleMap?.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom)
164
+ override fun setRotateEnabled(enabled: Boolean) {
165
+ rotateEnabled = enabled
166
+ googleMap?.uiSettings?.isRotateGesturesEnabled = enabled
220
167
  }
221
168
 
222
- private fun applyTheme() {
223
- val colorScheme = when (theme) {
224
- "dark" -> MapColorScheme.DARK
225
- "light" -> MapColorScheme.LIGHT
226
- else -> MapColorScheme.FOLLOW_SYSTEM
227
- }
228
- googleMap?.setMapColorScheme(colorScheme)
169
+ override fun setPitchEnabled(enabled: Boolean) {
170
+ pitchEnabled = enabled
171
+ googleMap?.uiSettings?.isTiltGesturesEnabled = enabled
229
172
  }
230
173
 
231
174
  @SuppressLint("MissingPermission")
232
- private fun applyUserLocation() {
175
+ override fun setUserLocationEnabled(enabled: Boolean) {
176
+ userLocationEnabled = enabled
233
177
  val hasPermission =
234
178
  context.checkSelfPermission(
235
179
  android.Manifest.permission.ACCESS_FINE_LOCATION
@@ -239,12 +183,31 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
239
183
  googleMap?.isMyLocationEnabled = userLocationEnabled && hasPermission
240
184
  }
241
185
 
242
- // endregion
186
+ override fun setTheme(value: String) {
187
+ theme = value
188
+ applyTheme()
189
+ }
243
190
 
244
- // region PolylineViewDelegate
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
+ }
245
197
 
246
- override fun polylineViewDidUpdate(polylineView: LuggPolylineView) {
247
- syncPolylineView(polylineView)
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()
248
211
  }
249
212
 
250
213
  // endregion
@@ -270,8 +233,26 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
270
233
 
271
234
  // endregion
272
235
 
236
+ // region PolylineViewDelegate
237
+
238
+ override fun polylineViewDidUpdate(polylineView: LuggPolylineView) {
239
+ syncPolylineView(polylineView)
240
+ }
241
+
242
+ // endregion
243
+
273
244
  // region Marker Management
274
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
+
275
256
  private fun syncMarkerView(markerView: LuggMarkerView) {
276
257
  if (googleMap == null) {
277
258
  pendingMarkerViews.add(markerView)
@@ -279,7 +260,6 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
279
260
  }
280
261
 
281
262
  if (markerView.marker == null) {
282
- // Custom views need layout first before adding to map
283
263
  if (markerView.hasCustomView) return
284
264
  addMarkerViewToMap(markerView)
285
265
  return
@@ -302,19 +282,14 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
302
282
 
303
283
  private fun processPendingMarkers() {
304
284
  if (googleMap == null) return
305
-
306
285
  pendingMarkerViews.forEach { addMarkerViewToMap(it) }
307
286
  pendingMarkerViews.clear()
308
287
  }
309
288
 
310
289
  private fun addMarkerViewToMap(markerView: LuggMarkerView) {
311
- val map = googleMap ?: run {
312
- RNLog.w(reactContext, "LuggMaps: addMarkerViewToMap called without a map")
313
- return
314
- }
290
+ val map = googleMap ?: return
315
291
 
316
292
  val position = LatLng(markerView.latitude, markerView.longitude)
317
-
318
293
  val options = AdvancedMarkerOptions()
319
294
  .position(position)
320
295
  .title(markerView.title)
@@ -333,6 +308,18 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
333
308
 
334
309
  // region Polyline Management
335
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
+
336
323
  private fun syncPolylineView(polylineView: LuggPolylineView) {
337
324
  if (googleMap == null) {
338
325
  pendingPolylineViews.add(polylineView)
@@ -359,7 +346,6 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
359
346
 
360
347
  private fun processPendingPolylines() {
361
348
  if (googleMap == null) return
362
-
363
349
  pendingPolylineViews.forEach { addPolylineViewToMap(it) }
364
350
  pendingPolylineViews.clear()
365
351
  }
@@ -389,85 +375,21 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
389
375
 
390
376
  // endregion
391
377
 
392
- // region Property Setters
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
- }
378
+ // region Lifecycle
445
379
 
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
- }
380
+ override fun pauseAnimations() {
381
+ polylineAnimators.values.forEach { it.pause() }
451
382
  }
452
383
 
453
- fun setTheme(value: String) {
454
- theme = value
455
- applyTheme()
456
- }
457
-
458
- fun setMapPadding(top: Int, left: Int, bottom: Int, right: Int) {
459
- paddingTop = top
460
- paddingLeft = left
461
- paddingBottom = bottom
462
- paddingRight = right
463
- applyPadding()
384
+ override fun resumeAnimations() {
385
+ polylineAnimators.values.forEach { it.resume() }
464
386
  }
465
387
 
466
388
  // endregion
467
389
 
468
390
  // region Commands
469
391
 
470
- fun moveCamera(latitude: Double, longitude: Double, zoom: Double, duration: Int) {
392
+ override fun moveCamera(latitude: Double, longitude: Double, zoom: Double, duration: Int) {
471
393
  val map = googleMap ?: return
472
394
  val position = LatLng(latitude, longitude)
473
395
  val targetZoom = if (zoom > 0) zoom.toFloat() else map.cameraPosition.zoom
@@ -479,8 +401,8 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
479
401
  }
480
402
  }
481
403
 
482
- fun fitCoordinates(
483
- coordinates: List<LatLng>,
404
+ override fun fitCoordinates(
405
+ coordinates: List<Any>,
484
406
  paddingTop: Int,
485
407
  paddingLeft: Int,
486
408
  paddingBottom: Int,
@@ -490,8 +412,11 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
490
412
  val map = googleMap ?: return
491
413
  if (coordinates.isEmpty()) return
492
414
 
415
+ val latLngs = coordinates.filterIsInstance<LatLng>()
416
+ if (latLngs.isEmpty()) return
417
+
493
418
  val boundsBuilder = com.google.android.gms.maps.model.LatLngBounds.Builder()
494
- coordinates.forEach { boundsBuilder.include(it) }
419
+ latLngs.forEach { boundsBuilder.include(it) }
495
420
  val bounds = boundsBuilder.build()
496
421
 
497
422
  val top = paddingTop.toFloat().dpToPx().toInt()
@@ -499,7 +424,6 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
499
424
  val bottom = paddingBottom.toFloat().dpToPx().toInt()
500
425
  val right = paddingRight.toFloat().dpToPx().toInt()
501
426
 
502
- // Set padding before camera update, then restore after
503
427
  map.setPadding(
504
428
  this.paddingLeft + left,
505
429
  this.paddingTop + top,
@@ -515,14 +439,56 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
515
439
  else -> map.moveCamera(cameraUpdate)
516
440
  }
517
441
 
518
- // Restore base padding
519
442
  map.setPadding(this.paddingLeft, this.paddingTop, this.paddingRight, this.paddingBottom)
520
443
  }
521
444
 
522
445
  // endregion
523
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
+
524
491
  companion object {
525
- private const val TAG = "Lugg"
526
492
  const val DEMO_MAP_ID = "DEMO_MAP_ID"
527
493
  }
528
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
+ }