Skip to content

Commit 0d36df2

Browse files
committed
fmt
1 parent e8a2644 commit 0d36df2

File tree

5 files changed

+122
-117
lines changed

5 files changed

+122
-117
lines changed

demo-app/src/commonMain/kotlin/org/maplibre/compose/demoapp/DemoStyle.kt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ enum class Protomaps(override val isDark: Boolean = false) : DemoStyle {
2121
override val displayName = name
2222

2323
override val base =
24-
BaseStyle.Uri(
25-
"https://api.protomaps.com/styles/v5/${name.lowercase()}/en.json?key=73c45a97eddd43fb"
26-
)
24+
BaseStyle.Uri(
25+
"https://api.protomaps.com/styles/v5/${name.lowercase()}/en.json?key=73c45a97eddd43fb"
26+
)
2727

2828
override val anchorBelowSymbols = Anchor.Below("address_label")
2929
}
@@ -53,14 +53,14 @@ enum class Versatiles(override val isDark: Boolean = false) : DemoStyle {
5353
}
5454

5555
enum class OtherStyles(
56-
override val displayName: String,
57-
override val base: BaseStyle,
58-
override val isDark: Boolean = false,
59-
override val anchorBelowSymbols: Anchor = Anchor.Top,
56+
override val displayName: String,
57+
override val base: BaseStyle,
58+
override val isDark: Boolean = false,
59+
override val anchorBelowSymbols: Anchor = Anchor.Top,
6060
) : DemoStyle {
6161
OpenStreetMaps(
62-
displayName = "OpenStreetMaps Carto",
63-
base = BaseStyle.Uri(Res.getUri("files/styles/osm-raster.json")),
62+
displayName = "OpenStreetMaps Carto",
63+
base = BaseStyle.Uri(Res.getUri("files/styles/osm-raster.json")),
6464
),
6565
Americana(displayName = "Americana", base = BaseStyle.Uri("https://americanamap.org/style.json")),
6666
}
Lines changed: 70 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package org.maplibre.compose.location
22

3+
import android.Manifest
34
import android.content.Context
45
import android.content.Context.SENSOR_SERVICE
56
import android.hardware.Sensor
67
import android.hardware.SensorEvent
78
import android.hardware.SensorEventListener
89
import android.hardware.SensorManager
10+
import androidx.annotation.RequiresPermission
911
import androidx.compose.runtime.Composable
1012
import androidx.compose.runtime.remember
1113
import androidx.compose.runtime.rememberCoroutineScope
@@ -23,8 +25,8 @@ import kotlinx.coroutines.flow.stateIn
2325
* A [LocationProvider] that enhances an existing [LocationProvider] with bearing information
2426
* derived from the device's rotation vector sensor.
2527
*
26-
* This class listens to the `Sensor.TYPE_ROTATION_VECTOR` to get the device's orientation.
27-
* It then combines this sensor-derived bearing with the location data from the wrapped [locationProvider].
28+
* This class listens to the `Sensor.TYPE_ROTATION_VECTOR` to get the device's orientation. It then
29+
* combines this sensor-derived bearing with the location data from the wrapped [locationProvider].
2830
*
2931
* The sensor-based bearing is only used if its accuracy is better than the bearing accuracy
3032
* provided by the original location provider.
@@ -33,106 +35,109 @@ import kotlinx.coroutines.flow.stateIn
3335
* @param locationProvider The underlying [LocationProvider] to be enhanced.
3436
* @param coroutineScope The [CoroutineScope] in which the location and bearing flows are combined.
3537
* @param sharingStarted The strategy for starting and stopping the collection of the location flow.
36-
* Defaults to [SharingStarted.WhileSubscribed] with a 1-second stop timeout.
38+
* Defaults to [SharingStarted.WhileSubscribed] with a 1-second stop timeout.
3739
* @throws IllegalStateException if the rotation vector sensor is not available on the device.
3840
*/
3941
public class AndroidSensorEnhancedLocationProvider(
40-
context: Context,
41-
locationProvider: LocationProvider,
42-
coroutineScope: CoroutineScope,
43-
sharingStarted: SharingStarted = SharingStarted.WhileSubscribed(stopTimeoutMillis = 1000),
42+
context: Context,
43+
locationProvider: LocationProvider,
44+
coroutineScope: CoroutineScope,
45+
sharingStarted: SharingStarted = SharingStarted.WhileSubscribed(stopTimeoutMillis = 1000),
4446
) : LocationProvider {
4547
private val sensorManager = context.getSystemService(SENSOR_SERVICE) as SensorManager
4648

47-
private fun accuracyToDegrees(accuracy: Int): Double = when (accuracy) {
48-
SensorManager.SENSOR_STATUS_ACCURACY_HIGH -> 5.0
49-
SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM -> 15.0
50-
SensorManager.SENSOR_STATUS_ACCURACY_LOW -> 45.0
51-
SensorManager.SENSOR_STATUS_UNRELIABLE -> 180.0
52-
else -> 180.0
53-
}
49+
private fun accuracyToDegrees(accuracy: Int): Double =
50+
when (accuracy) {
51+
SensorManager.SENSOR_STATUS_ACCURACY_HIGH -> 5.0
52+
SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM -> 15.0
53+
SensorManager.SENSOR_STATUS_ACCURACY_LOW -> 45.0
54+
SensorManager.SENSOR_STATUS_UNRELIABLE -> 180.0
55+
else -> 180.0
56+
}
5457

5558
private val bearing: Flow<Pair<Double, Double>> = callbackFlow {
5659
val rotationMatrix = FloatArray(9)
5760
val orientationAngles = FloatArray(3)
5861
var accuracyDegrees = accuracyToDegrees(SensorManager.SENSOR_STATUS_UNRELIABLE)
5962

60-
val listener = object : SensorEventListener {
61-
override fun onSensorChanged(event: SensorEvent?) {
62-
if (event?.sensor?.type == Sensor.TYPE_ROTATION_VECTOR) {
63-
SensorManager.getRotationMatrixFromVector(
64-
rotationMatrix,
65-
event.values
66-
)
67-
SensorManager.getOrientation(
68-
rotationMatrix,
69-
orientationAngles
70-
)
63+
val listener =
64+
object : SensorEventListener {
65+
override fun onSensorChanged(event: SensorEvent?) {
66+
if (event?.sensor?.type == Sensor.TYPE_ROTATION_VECTOR) {
67+
SensorManager.getRotationMatrixFromVector(rotationMatrix, event.values)
68+
SensorManager.getOrientation(rotationMatrix, orientationAngles)
7169

72-
trySend(
73-
Math.toDegrees(orientationAngles[0].toDouble()) to accuracyDegrees
74-
)
75-
}
76-
}
70+
trySend(Math.toDegrees(orientationAngles[0].toDouble()) to accuracyDegrees)
71+
}
72+
}
7773

78-
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
79-
accuracyDegrees = accuracyToDegrees(accuracy)
80-
}
81-
}
74+
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
75+
accuracyDegrees = accuracyToDegrees(accuracy)
76+
}
77+
}
8278

83-
val sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR)
84-
?: throw IllegalStateException("Rotation vector sensor is not available")
79+
val sensor =
80+
sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR)
81+
?: throw IllegalStateException("Rotation vector sensor is not available")
8582

8683
sensorManager.registerListener(
87-
listener,
88-
sensor,
89-
SensorManager.SENSOR_DELAY_NORMAL,
84+
listener,
85+
sensor,
86+
SensorManager.SENSOR_DELAY_NORMAL,
9087
)
9188

92-
awaitClose {
93-
sensorManager.unregisterListener(listener)
94-
}
89+
awaitClose { sensorManager.unregisterListener(listener) }
9590
}
9691

9792
override val location: StateFlow<Location?> =
98-
locationProvider.location.combine(bearing) { location, (sensorBearing, sensorAccuracy) ->
99-
val bearingAccuracy = location?.bearingAccuracy
100-
if (bearingAccuracy != null && bearingAccuracy > sensorAccuracy) {
101-
location.copy(bearing = sensorBearing, accuracy = sensorAccuracy)
102-
} else {
103-
location
104-
}
105-
}.stateIn(coroutineScope, sharingStarted, null)
93+
locationProvider.location
94+
.combine(bearing) { location, (sensorBearing, sensorAccuracy) ->
95+
val bearingAccuracy = location?.bearingAccuracy
96+
if (bearingAccuracy != null && bearingAccuracy > sensorAccuracy) {
97+
location.copy(bearing = sensorBearing, accuracy = sensorAccuracy)
98+
} else {
99+
location
100+
}
101+
}
102+
.stateIn(coroutineScope, sharingStarted, null)
106103
}
107104

108105
@Composable
106+
@RequiresPermission(
107+
anyOf = [Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION]
108+
)
109109
public actual fun rememberSensorEnhancedLocationProvider(
110-
locationProvider: LocationProvider,
110+
locationProvider: LocationProvider,
111111
): LocationProvider {
112112
return rememberAndroidSensorEnhancedLocationProvider(locationProvider = locationProvider)
113113
}
114114

115-
/** Create and remember an [AndroidSensorEnhancedLocationProvider], a [LocationProvider] that enhances an existing [LocationProvider] with bearing information
116-
* derived from the device's rotation vector sensor.
115+
/**
116+
* Create and remember an [AndroidSensorEnhancedLocationProvider], a [LocationProvider] that
117+
* enhances an existing [LocationProvider] with bearing information derived from the device's
118+
* rotation vector sensor.
117119
*/
118120
@Composable
121+
@RequiresPermission(
122+
anyOf = [Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION]
123+
)
119124
public fun rememberAndroidSensorEnhancedLocationProvider(
120-
locationProvider: LocationProvider,
121-
context: Context = LocalContext.current,
122-
coroutineScope: CoroutineScope = rememberCoroutineScope(),
123-
sharingStarted: SharingStarted = SharingStarted.WhileSubscribed(stopTimeoutMillis = 1000),
125+
locationProvider: LocationProvider,
126+
context: Context = LocalContext.current,
127+
coroutineScope: CoroutineScope = rememberCoroutineScope(),
128+
sharingStarted: SharingStarted = SharingStarted.WhileSubscribed(stopTimeoutMillis = 1000),
124129
): AndroidSensorEnhancedLocationProvider {
125130
return remember(
126-
context,
127-
locationProvider,
128-
coroutineScope,
129-
sharingStarted,
131+
context,
132+
locationProvider,
133+
coroutineScope,
134+
sharingStarted,
130135
) {
131136
AndroidSensorEnhancedLocationProvider(
132-
context = context,
133-
locationProvider = locationProvider,
134-
coroutineScope = coroutineScope,
135-
sharingStarted = sharingStarted,
137+
context = context,
138+
locationProvider = locationProvider,
139+
coroutineScope = coroutineScope,
140+
sharingStarted = sharingStarted,
136141
)
137142
}
138143
}

lib/maplibre-compose/src/commonMain/kotlin/org/maplibre/compose/location/LocationProvider.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,9 @@ public class PermissionException : Exception()
100100
*/
101101
@Composable
102102
public expect fun rememberDefaultLocationProvider(
103-
updateInterval: Duration = 1.seconds,
104-
desiredAccuracy: DesiredAccuracy = DesiredAccuracy.High,
105-
minDistanceMeters: Double = 1.0,
103+
updateInterval: Duration = 1.seconds,
104+
desiredAccuracy: DesiredAccuracy = DesiredAccuracy.High,
105+
minDistanceMeters: Double = 1.0,
106106
): LocationProvider
107107

108108
/**
@@ -125,5 +125,5 @@ public fun rememberNullLocationProvider(): LocationProvider {
125125
*/
126126
@Composable
127127
public expect fun rememberSensorEnhancedLocationProvider(
128-
locationProvider: LocationProvider = rememberDefaultLocationProvider()
128+
locationProvider: LocationProvider = rememberDefaultLocationProvider()
129129
): LocationProvider

lib/maplibre-compose/src/iosMain/kotlin/org/maplibre/compose/location/IosLocationProvider.kt

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -34,45 +34,45 @@ import platform.darwin.NSObject
3434
* @param sharingStarted parameter for [stateIn] call of [location]
3535
*/
3636
public class IosLocationProvider(
37-
private val minDistanceMeters: Double,
38-
private val desiredAccuracy: DesiredAccuracy,
39-
coroutineScope: CoroutineScope,
40-
sharingStarted: SharingStarted,
37+
private val minDistanceMeters: Double,
38+
private val desiredAccuracy: DesiredAccuracy,
39+
coroutineScope: CoroutineScope,
40+
sharingStarted: SharingStarted,
4141
) : LocationProvider {
4242
private val locationManager = CLLocationManager()
4343

4444
init {
4545
if (
46-
locationManager.authorizationStatus != kCLAuthorizationStatusAuthorizedAlways &&
47-
locationManager.authorizationStatus != kCLAuthorizationStatusAuthorizedWhenInUse
46+
locationManager.authorizationStatus != kCLAuthorizationStatusAuthorizedAlways &&
47+
locationManager.authorizationStatus != kCLAuthorizationStatusAuthorizedWhenInUse
4848
) {
4949
throw PermissionException()
5050
}
5151
}
5252

5353
override val location: StateFlow<Location?> =
54-
callbackFlow {
55-
locationManager.delegate = Delegate(channel)
54+
callbackFlow {
55+
locationManager.delegate = Delegate(channel)
5656

57-
locationManager.desiredAccuracy =
58-
when (desiredAccuracy) {
59-
DesiredAccuracy.Highest -> kCLLocationAccuracyBestForNavigation
60-
DesiredAccuracy.High -> kCLLocationAccuracyBest
61-
DesiredAccuracy.Balanced -> kCLLocationAccuracyHundredMeters
62-
DesiredAccuracy.Low -> kCLLocationAccuracyKilometer
63-
DesiredAccuracy.Lowest -> kCLLocationAccuracyReduced
64-
}
65-
locationManager.distanceFilter = minDistanceMeters
57+
locationManager.desiredAccuracy =
58+
when (desiredAccuracy) {
59+
DesiredAccuracy.Highest -> kCLLocationAccuracyBestForNavigation
60+
DesiredAccuracy.High -> kCLLocationAccuracyBest
61+
DesiredAccuracy.Balanced -> kCLLocationAccuracyHundredMeters
62+
DesiredAccuracy.Low -> kCLLocationAccuracyKilometer
63+
DesiredAccuracy.Lowest -> kCLLocationAccuracyReduced
64+
}
65+
locationManager.distanceFilter = minDistanceMeters
6666

67-
locationManager.stopUpdatingLocation()
68-
locationManager.startUpdatingLocation()
67+
locationManager.stopUpdatingLocation()
68+
locationManager.startUpdatingLocation()
6969

70-
awaitClose { locationManager.stopUpdatingLocation() }
71-
}
72-
.stateIn(coroutineScope, sharingStarted, null)
70+
awaitClose { locationManager.stopUpdatingLocation() }
71+
}
72+
.stateIn(coroutineScope, sharingStarted, null)
7373

7474
private inner class Delegate(private val channel: SendChannel<Location?>) :
75-
NSObject(), CLLocationManagerDelegateProtocol {
75+
NSObject(), CLLocationManagerDelegateProtocol {
7676
override fun locationManager(manager: CLLocationManager, didUpdateLocations: List<*>) {
7777
@Suppress("UNCHECKED_CAST") val locations = didUpdateLocations as? List<CLLocation>
7878

@@ -85,33 +85,33 @@ public class IosLocationProvider(
8585

8686
@Composable
8787
public actual fun rememberDefaultLocationProvider(
88-
updateInterval: Duration,
89-
desiredAccuracy: DesiredAccuracy,
90-
minDistanceMeters: Double,
88+
updateInterval: Duration,
89+
desiredAccuracy: DesiredAccuracy,
90+
minDistanceMeters: Double,
9191
): LocationProvider {
9292
return rememberIosLocationProvider(minDistanceMeters, desiredAccuracy)
9393
}
9494

9595
@Composable
9696
public fun rememberIosLocationProvider(
97-
minDistanceMeters: Double = 1.0,
98-
desiredAccuracy: DesiredAccuracy = DesiredAccuracy.High,
99-
coroutineScope: CoroutineScope = rememberCoroutineScope(),
100-
sharingStarted: SharingStarted = SharingStarted.WhileSubscribed(stopTimeoutMillis = 1000),
97+
minDistanceMeters: Double = 1.0,
98+
desiredAccuracy: DesiredAccuracy = DesiredAccuracy.High,
99+
coroutineScope: CoroutineScope = rememberCoroutineScope(),
100+
sharingStarted: SharingStarted = SharingStarted.WhileSubscribed(stopTimeoutMillis = 1000),
101101
): IosLocationProvider {
102102
return remember(minDistanceMeters, desiredAccuracy, coroutineScope, sharingStarted) {
103103
IosLocationProvider(
104-
minDistanceMeters = minDistanceMeters,
105-
desiredAccuracy = desiredAccuracy,
106-
coroutineScope = coroutineScope,
107-
sharingStarted = sharingStarted,
104+
minDistanceMeters = minDistanceMeters,
105+
desiredAccuracy = desiredAccuracy,
106+
coroutineScope = coroutineScope,
107+
sharingStarted = sharingStarted,
108108
)
109109
}
110110
}
111111

112112
@Composable
113113
public actual fun rememberSensorEnhancedLocationProvider(
114-
locationProvider: LocationProvider
114+
locationProvider: LocationProvider
115115
): LocationProvider {
116116
// TODO: Implement sensor enhanced location provider
117117
return locationProvider

lib/maplibre-compose/src/jsMain/kotlin/org/maplibre/compose/location/WebLocationProvider.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@ import kotlin.time.Duration
55

66
@Composable
77
public actual fun rememberDefaultLocationProvider(
8-
updateInterval: Duration,
9-
desiredAccuracy: DesiredAccuracy,
10-
minDistanceMeters: Double,
8+
updateInterval: Duration,
9+
desiredAccuracy: DesiredAccuracy,
10+
minDistanceMeters: Double,
1111
): LocationProvider {
1212
throw NotImplementedError("no default implementation for web")
1313
}
1414

1515
@Composable
1616
public actual fun rememberSensorEnhancedLocationProvider(
17-
locationProvider: LocationProvider
17+
locationProvider: LocationProvider
1818
): LocationProvider {
1919
TODO()
2020
}

0 commit comments

Comments
 (0)