diff --git a/demo-app/src/commonMain/kotlin/dev/sargunv/maplibrecompose/demoapp/app.kt b/demo-app/src/commonMain/kotlin/dev/sargunv/maplibrecompose/demoapp/app.kt index df98ad6b..1f78652f 100644 --- a/demo-app/src/commonMain/kotlin/dev/sargunv/maplibrecompose/demoapp/app.kt +++ b/demo-app/src/commonMain/kotlin/dev/sargunv/maplibrecompose/demoapp/app.kt @@ -157,7 +157,7 @@ fun DemoMapControls( if (Platform.supportsBlending) { Box(modifier = modifier.fillMaxSize().padding(8.dp)) { DisappearingScaleBar( - lengthPerDp = cameraState.lengthPerDpAtTarget, + scale = cameraState.scaleAtTarget, zoom = cameraState.position.zoom, modifier = Modifier.align(Alignment.TopStart), ) diff --git a/demo-app/src/commonMain/kotlin/dev/sargunv/maplibrecompose/demoapp/demos/CameraStateDemo.kt b/demo-app/src/commonMain/kotlin/dev/sargunv/maplibrecompose/demoapp/demos/CameraStateDemo.kt index a4a32040..1d95314a 100644 --- a/demo-app/src/commonMain/kotlin/dev/sargunv/maplibrecompose/demoapp/demos/CameraStateDemo.kt +++ b/demo-app/src/commonMain/kotlin/dev/sargunv/maplibrecompose/demoapp/demos/CameraStateDemo.kt @@ -53,7 +53,7 @@ object CameraStateDemo : Demo { Row(modifier = Modifier.safeDrawingPadding().wrapContentSize(Alignment.Center)) { val pos = cameraState.position - val scale = cameraState.lengthPerDpAtTarget + val scale = cameraState.scaleAtTarget Cell("Latitude", pos.target.latitude.format(3), Modifier.weight(1.4f)) Cell("Longitude", pos.target.longitude.format(3), Modifier.weight(1.4f)) diff --git a/demo-app/src/commonMain/kotlin/dev/sargunv/maplibrecompose/demoapp/docs/Material3.kt b/demo-app/src/commonMain/kotlin/dev/sargunv/maplibrecompose/demoapp/docs/Material3.kt index 10029c3b..343d1005 100644 --- a/demo-app/src/commonMain/kotlin/dev/sargunv/maplibrecompose/demoapp/docs/Material3.kt +++ b/demo-app/src/commonMain/kotlin/dev/sargunv/maplibrecompose/demoapp/docs/Material3.kt @@ -33,7 +33,7 @@ fun Material3() { ) Box(modifier = Modifier.fillMaxSize().padding(8.dp)) { - ScaleBar(cameraState.lengthPerDpAtTarget, modifier = Modifier.align(Alignment.TopStart)) + ScaleBar(cameraState.scaleAtTarget, modifier = Modifier.align(Alignment.TopStart)) CompassButton(cameraState, modifier = Modifier.align(Alignment.TopEnd)) AttributionButton(styleState, modifier = Modifier.align(Alignment.BottomEnd)) } @@ -50,7 +50,7 @@ fun Material3() { Box(modifier = Modifier.fillMaxSize().padding(8.dp)) { DisappearingScaleBar( - lengthPerDp = cameraState.lengthPerDpAtTarget, + scale = cameraState.scaleAtTarget, zoom = cameraState.position.zoom, modifier = Modifier.align(Alignment.TopStart), ) // (1)! diff --git a/lib/maplibre-compose-material3/src/commonMain/kotlin/dev/sargunv/maplibrecompose/material3/controls/DisappearingScaleBar.kt b/lib/maplibre-compose-material3/src/commonMain/kotlin/dev/sargunv/maplibrecompose/material3/controls/DisappearingScaleBar.kt index 0cac6988..d40bbb7e 100644 --- a/lib/maplibre-compose-material3/src/commonMain/kotlin/dev/sargunv/maplibrecompose/material3/controls/DisappearingScaleBar.kt +++ b/lib/maplibre-compose-material3/src/commonMain/kotlin/dev/sargunv/maplibrecompose/material3/controls/DisappearingScaleBar.kt @@ -15,8 +15,8 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.TextStyle +import dev.sargunv.maplibrecompose.core.util.MapScale import dev.sargunv.maplibrecompose.material3.defaultScaleBarMeasures -import io.github.kevincianfarini.alchemist.type.Length import kotlin.time.Duration import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.delay @@ -25,9 +25,8 @@ import kotlinx.coroutines.delay * An animated scale bar that appears when the [zoom] level of the map changes, and then disappears * after [visibilityDuration]. This composable wraps [ScaleBar] with visibility animations. * - * @param lengthPerDp the real world distance in one device independent pixel (dp), i.e. the scale. - * See - * [CameraState.lengthPerDpAtTarget][dev.sargunv.maplibrecompose.compose.CameraState.lengthPerDpAtTarget] + * @param scale the ratio of real world distance [Length] to [Dp], i.e. the scale. See + * [CameraState.scaleAtTarget][dev.sargunv.maplibrecompose.compose.CameraState.scaleAtTarget] * @param zoom zoom level of the map * @param modifier the [Modifier] to be applied to this layout node * @param measures which measures to show on the scale bar. If `null`, measures will be selected @@ -43,7 +42,7 @@ import kotlinx.coroutines.delay */ @Composable public fun DisappearingScaleBar( - lengthPerDp: Length, + scale: MapScale, zoom: Double, modifier: Modifier = Modifier, measures: ScaleBarMeasures = defaultScaleBarMeasures(), @@ -72,7 +71,7 @@ public fun DisappearingScaleBar( exit = exitTransition, ) { ScaleBar( - lengthPerDp = lengthPerDp, + scale = scale, measures = measures, haloColor = haloColor, color = color, diff --git a/lib/maplibre-compose-material3/src/commonMain/kotlin/dev/sargunv/maplibrecompose/material3/controls/ScaleBar.kt b/lib/maplibre-compose-material3/src/commonMain/kotlin/dev/sargunv/maplibrecompose/material3/controls/ScaleBar.kt index 2aee813d..1b28a385 100644 --- a/lib/maplibre-compose-material3/src/commonMain/kotlin/dev/sargunv/maplibrecompose/material3/controls/ScaleBar.kt +++ b/lib/maplibre-compose-material3/src/commonMain/kotlin/dev/sargunv/maplibrecompose/material3/controls/ScaleBar.kt @@ -20,6 +20,8 @@ import androidx.compose.ui.text.rememberTextMeasurer import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.toSize +import dev.sargunv.maplibrecompose.core.util.MapScale +import dev.sargunv.maplibrecompose.core.util.div import dev.sargunv.maplibrecompose.material3.defaultScaleBarMeasures import dev.sargunv.maplibrecompose.material3.drawPathsWithHalo import dev.sargunv.maplibrecompose.material3.drawTextWithHalo @@ -38,9 +40,8 @@ public data class ScaleBarMeasures( * A scale bar composable that shows the current scale of the map in feet, yards, or meters when * zoomed in to the map, changing to miles and kilometers when zooming out. * - * @param lengthPerDp the real world distance in one device independent pixel (dp), i.e. the scale. - * See - * [CameraState.lengthPerDpAtTarget][dev.sargunv.maplibrecompose.compose.CameraState.lengthPerDpAtTarget] + * @param scale the ratio of real world distance [Length] to [Dp], i.e. the scale. See + * [CameraState.scaleAtTarget][dev.sargunv.maplibrecompose.compose.CameraState.scaleAtTarget] * @param modifier the [Modifier] to be applied to this layout node * @param measures which measures to show on the scale bar. If `null`, measures will be selected * based on the system settings or otherwise the user's locale. @@ -52,7 +53,7 @@ public data class ScaleBarMeasures( */ @Composable public fun ScaleBar( - lengthPerDp: Length, + scale: MapScale, modifier: Modifier = Modifier, measures: ScaleBarMeasures = defaultScaleBarMeasures(), haloColor: Color = MaterialTheme.colorScheme.surface, @@ -61,6 +62,7 @@ public fun ScaleBar( alignment: Alignment.Horizontal = Alignment.Start, ) { val textMeasurer = rememberTextMeasurer() + // longest possible text val maxTextSizePx = remember(textMeasurer, textStyle) { textMeasurer.measure("5000 km", textStyle).size } @@ -87,8 +89,8 @@ public fun ScaleBar( // scale bar start/end should not overlap horizontally with canvas bounds val maxBarLength = maxWidth - fullStrokeWidth - val params1 = scaleBarParameters(measures.primary, lengthPerDp, maxBarLength) - val params2 = measures.secondary?.let { scaleBarParameters(it, lengthPerDp, maxBarLength) } + val params1 = scaleBarParameters(measures.primary, scale, maxBarLength) + val params2 = measures.secondary?.let { scaleBarParameters(it, scale, maxBarLength) } Canvas(modifier.fillMaxSize()) { val fullStrokeWidthPx = fullStrokeWidth.toPx() @@ -187,12 +189,12 @@ private data class ScaleBarParams(val barWidth: Dp, val text: String) @Composable private fun scaleBarParameters( measure: ScaleBarMeasure, - lengthPerDp: Length, + scale: MapScale, maxBarLength: Dp, ): ScaleBarParams { - val max = lengthPerDp * maxBarLength.value.toDouble() + val max = scale * maxBarLength val stop = findStop(max, measure.stops) - return ScaleBarParams(barWidth = (stop / lengthPerDp).dp, text = measure.getText(stop)) + return ScaleBarParams(barWidth = (stop / scale), text = measure.getText(stop)) } /** diff --git a/lib/maplibre-compose/src/androidMain/kotlin/dev/sargunv/maplibrecompose/core/AndroidMap.kt b/lib/maplibre-compose/src/androidMain/kotlin/dev/sargunv/maplibrecompose/core/AndroidMap.kt index 5e48fba8..ec163421 100644 --- a/lib/maplibre-compose/src/androidMain/kotlin/dev/sargunv/maplibrecompose/core/AndroidMap.kt +++ b/lib/maplibre-compose/src/androidMain/kotlin/dev/sargunv/maplibrecompose/core/AndroidMap.kt @@ -10,7 +10,9 @@ import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.coerceAtLeast import androidx.compose.ui.unit.dp import co.touchlab.kermit.Logger +import dev.sargunv.maplibrecompose.core.util.MapScale import dev.sargunv.maplibrecompose.core.util.correctedAndroidUri +import dev.sargunv.maplibrecompose.core.util.div import dev.sargunv.maplibrecompose.core.util.toBoundingBox import dev.sargunv.maplibrecompose.core.util.toGravity import dev.sargunv.maplibrecompose.core.util.toLatLng @@ -25,7 +27,6 @@ import io.github.dellisd.spatialk.geojson.BoundingBox import io.github.dellisd.spatialk.geojson.Feature import io.github.dellisd.spatialk.geojson.Position import io.github.kevincianfarini.alchemist.scalar.toLength -import io.github.kevincianfarini.alchemist.type.Length import io.github.kevincianfarini.alchemist.unit.LengthUnit.International.Meter import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine @@ -338,9 +339,9 @@ internal class AndroidMap( .map { Feature.fromJson(it.toJson()) } } - override fun lengthPerDpAtLatitude(latitude: Double): Length { + override fun scaleAtLatitude(latitude: Double): MapScale { // https://github.com/kevincianfarini/alchemist/issues/54 - return map.projection.getMetersPerPixelAtLatitude(latitude).toLength(Meter) + return map.projection.getMetersPerPixelAtLatitude(latitude).toLength(Meter) / 1.dp } } diff --git a/lib/maplibre-compose/src/commonMain/kotlin/dev/sargunv/maplibrecompose/compose/CameraState.kt b/lib/maplibre-compose/src/commonMain/kotlin/dev/sargunv/maplibrecompose/compose/CameraState.kt index be805662..1d449ea8 100644 --- a/lib/maplibre-compose/src/commonMain/kotlin/dev/sargunv/maplibrecompose/compose/CameraState.kt +++ b/lib/maplibre-compose/src/commonMain/kotlin/dev/sargunv/maplibrecompose/compose/CameraState.kt @@ -5,11 +5,14 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.unit.DpOffset import androidx.compose.ui.unit.DpRect +import androidx.compose.ui.unit.dp import dev.sargunv.maplibrecompose.core.CameraMoveReason import dev.sargunv.maplibrecompose.core.CameraPosition import dev.sargunv.maplibrecompose.core.MaplibreMap import dev.sargunv.maplibrecompose.core.StandardMaplibreMap import dev.sargunv.maplibrecompose.core.VisibleRegion +import dev.sargunv.maplibrecompose.core.util.MapScale +import dev.sargunv.maplibrecompose.core.util.div import dev.sargunv.maplibrecompose.expressions.ExpressionContext import dev.sargunv.maplibrecompose.expressions.ast.Expression import dev.sargunv.maplibrecompose.expressions.dsl.const @@ -18,7 +21,6 @@ import io.github.dellisd.spatialk.geojson.BoundingBox import io.github.dellisd.spatialk.geojson.Feature import io.github.dellisd.spatialk.geojson.Position import io.github.kevincianfarini.alchemist.scalar.toLength -import io.github.kevincianfarini.alchemist.type.Length import io.github.kevincianfarini.alchemist.unit.LengthUnit.International.Meter import kotlin.time.Duration import kotlin.time.Duration.Companion.milliseconds @@ -46,7 +48,7 @@ public class CameraState internal constructor(firstPosition: CameraPosition) { internal val positionState = mutableStateOf(firstPosition) internal val moveReasonState = mutableStateOf(CameraMoveReason.NONE) // https://github.com/kevincianfarini/alchemist/issues/54 - internal val lengthPerDpAtTargetState = mutableStateOf(0.toLength(Meter)) + internal val scaleAtTargetState = mutableStateOf(0.toLength(Meter) / 1.dp) /** how the camera is oriented towards the map */ // if the map is not yet initialized, we store the value to apply it later @@ -62,8 +64,8 @@ public class CameraState internal constructor(firstPosition: CameraPosition) { get() = moveReasonState.value /** real world distance per dp at the target position */ - public val lengthPerDpAtTarget: Length - get() = lengthPerDpAtTargetState.value + public val scaleAtTarget: MapScale + get() = scaleAtTargetState.value /** suspends until the map has been initialized */ public suspend fun awaitInitialized() { diff --git a/lib/maplibre-compose/src/commonMain/kotlin/dev/sargunv/maplibrecompose/compose/MaplibreMap.kt b/lib/maplibre-compose/src/commonMain/kotlin/dev/sargunv/maplibrecompose/compose/MaplibreMap.kt index dc4babf3..0d1664e2 100644 --- a/lib/maplibre-compose/src/commonMain/kotlin/dev/sargunv/maplibrecompose/compose/MaplibreMap.kt +++ b/lib/maplibre-compose/src/commonMain/kotlin/dev/sargunv/maplibrecompose/compose/MaplibreMap.kt @@ -115,8 +115,8 @@ public fun MaplibreMap( map as StandardMaplibreMap styleState.attach(style) rememberedStyle = style - cameraState.lengthPerDpAtTargetState.value = - map.lengthPerDpAtLatitude(map.getCameraPosition().target.latitude) + cameraState.scaleAtTargetState.value = + map.scaleAtLatitude(map.getCameraPosition().target.latitude) } override fun onCameraMoveStarted(map: MaplibreMap, reason: CameraMoveReason) { @@ -126,8 +126,8 @@ public fun MaplibreMap( override fun onCameraMoved(map: MaplibreMap) { map as StandardMaplibreMap cameraState.positionState.value = map.getCameraPosition() - cameraState.lengthPerDpAtTargetState.value = - map.lengthPerDpAtLatitude(map.getCameraPosition().target.latitude) + cameraState.scaleAtTargetState.value = + map.scaleAtLatitude(map.getCameraPosition().target.latitude) } override fun onCameraMoveEnded(map: MaplibreMap) {} diff --git a/lib/maplibre-compose/src/commonMain/kotlin/dev/sargunv/maplibrecompose/core/MaplibreMap.kt b/lib/maplibre-compose/src/commonMain/kotlin/dev/sargunv/maplibrecompose/core/MaplibreMap.kt index c46d84fe..2f77b3d9 100644 --- a/lib/maplibre-compose/src/commonMain/kotlin/dev/sargunv/maplibrecompose/core/MaplibreMap.kt +++ b/lib/maplibre-compose/src/commonMain/kotlin/dev/sargunv/maplibrecompose/core/MaplibreMap.kt @@ -2,12 +2,12 @@ package dev.sargunv.maplibrecompose.core import androidx.compose.ui.unit.DpOffset import androidx.compose.ui.unit.DpRect +import dev.sargunv.maplibrecompose.core.util.MapScale import dev.sargunv.maplibrecompose.expressions.ast.CompiledExpression import dev.sargunv.maplibrecompose.expressions.value.BooleanValue import io.github.dellisd.spatialk.geojson.BoundingBox import io.github.dellisd.spatialk.geojson.Feature import io.github.dellisd.spatialk.geojson.Position -import io.github.kevincianfarini.alchemist.type.Length import kotlin.time.Duration internal interface MaplibreMap { @@ -55,7 +55,7 @@ internal interface MaplibreMap { predicate: CompiledExpression? = null, ): List - suspend fun asyncLengthPerDpAtLatitude(latitude: Double): Length + suspend fun asyncScaleAtLatitude(latitude: Double): MapScale interface Callbacks { fun onStyleChanged(map: MaplibreMap, style: Style?) @@ -121,8 +121,7 @@ internal interface StandardMaplibreMap : MaplibreMap { predicate: CompiledExpression?, ): List = queryRenderedFeatures(rect, layerIds, predicate) - override suspend fun asyncLengthPerDpAtLatitude(latitude: Double): Length = - lengthPerDpAtLatitude(latitude) + override suspend fun asyncScaleAtLatitude(latitude: Double): MapScale = scaleAtLatitude(latitude) fun setStyleUri(styleUri: String) @@ -166,5 +165,5 @@ internal interface StandardMaplibreMap : MaplibreMap { predicate: CompiledExpression? = null, ): List - fun lengthPerDpAtLatitude(latitude: Double): Length + fun scaleAtLatitude(latitude: Double): MapScale } diff --git a/lib/maplibre-compose/src/commonMain/kotlin/dev/sargunv/maplibrecompose/core/util/MapScale.kt b/lib/maplibre-compose/src/commonMain/kotlin/dev/sargunv/maplibrecompose/core/util/MapScale.kt new file mode 100644 index 00000000..7c175f01 --- /dev/null +++ b/lib/maplibre-compose/src/commonMain/kotlin/dev/sargunv/maplibrecompose/core/util/MapScale.kt @@ -0,0 +1,49 @@ +package dev.sargunv.maplibrecompose.core.util + +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import io.github.kevincianfarini.alchemist.scalar.toLength +import io.github.kevincianfarini.alchemist.type.Length +import io.github.kevincianfarini.alchemist.unit.LengthUnit.International.Nanometer +import kotlin.jvm.JvmInline +import kotlin.math.roundToLong + +public inline operator fun Length.div(dp: Dp): MapScale = + MapScale((this.toLong(Nanometer) / dp.value).roundToLong().toLength(Nanometer)) + +public inline operator fun Length.div(scale: MapScale): Dp = (this / scale.lengthPerDp).dp + +public inline operator fun Dp.times(scale: MapScale): Length = scale * this + +public inline operator fun Number.times(scale: MapScale): MapScale = scale * this + +/** + * Represents a map scale: a ratio of real-world distance ([Length]) to device-independent pixels + * ([Dp]). + */ +@JvmInline +public value class MapScale +@PublishedApi +internal constructor(@PublishedApi internal val lengthPerDp: Length) : Comparable { + + public operator fun times(dp: Dp): Length = + (lengthPerDp.toLong(Nanometer) * dp.value).roundToLong().toLength(Nanometer) + + public operator fun div(other: MapScale): Double { + return lengthPerDp / other.lengthPerDp + } + + public operator fun div(other: Number): MapScale = + MapScale((lengthPerDp.toLong(Nanometer) / other.toDouble()).roundToLong().toLength(Nanometer)) + + public operator fun unaryMinus(): MapScale = MapScale(-lengthPerDp) + + public operator fun times(other: Number): MapScale = + MapScale((lengthPerDp.toLong(Nanometer) * other.toDouble()).roundToLong().toLength(Nanometer)) + + override fun toString(): String { + return "$lengthPerDp/dp" + } + + override fun compareTo(other: MapScale): Int = lengthPerDp.compareTo(other.lengthPerDp) +} diff --git a/lib/maplibre-compose/src/desktopMain/kotlin/dev/sargunv/maplibrecompose/core/WebviewMap.kt b/lib/maplibre-compose/src/desktopMain/kotlin/dev/sargunv/maplibrecompose/core/WebviewMap.kt index 8c051a13..22593873 100644 --- a/lib/maplibre-compose/src/desktopMain/kotlin/dev/sargunv/maplibrecompose/core/WebviewMap.kt +++ b/lib/maplibre-compose/src/desktopMain/kotlin/dev/sargunv/maplibrecompose/core/WebviewMap.kt @@ -3,13 +3,15 @@ package dev.sargunv.maplibrecompose.core import androidx.compose.ui.unit.DpOffset import androidx.compose.ui.unit.DpRect import androidx.compose.ui.unit.LayoutDirection +import androidx.compose.ui.unit.dp +import dev.sargunv.maplibrecompose.core.util.MapScale +import dev.sargunv.maplibrecompose.core.util.div import dev.sargunv.maplibrecompose.expressions.ast.CompiledExpression import dev.sargunv.maplibrecompose.expressions.value.BooleanValue import io.github.dellisd.spatialk.geojson.BoundingBox import io.github.dellisd.spatialk.geojson.Feature import io.github.dellisd.spatialk.geojson.Position import io.github.kevincianfarini.alchemist.scalar.toLength -import io.github.kevincianfarini.alchemist.type.Length import io.github.kevincianfarini.alchemist.unit.LengthUnit.International.Meter import kotlin.time.Duration @@ -142,8 +144,8 @@ internal class WebviewMap(private val bridge: WebviewBridge) : MaplibreMap { return emptyList() } - override suspend fun asyncLengthPerDpAtLatitude(latitude: Double): Length { + override suspend fun asyncScaleAtLatitude(latitude: Double): MapScale { // https://github.com/kevincianfarini/alchemist/issues/54 - return 0.0.toLength(Meter) + return 0.0.toLength(Meter) / 1.dp } } diff --git a/lib/maplibre-compose/src/iosMain/kotlin/dev/sargunv/maplibrecompose/core/IosMap.kt b/lib/maplibre-compose/src/iosMain/kotlin/dev/sargunv/maplibrecompose/core/IosMap.kt index d5431187..44469379 100644 --- a/lib/maplibre-compose/src/iosMain/kotlin/dev/sargunv/maplibrecompose/core/IosMap.kt +++ b/lib/maplibre-compose/src/iosMain/kotlin/dev/sargunv/maplibrecompose/core/IosMap.kt @@ -42,6 +42,7 @@ import cocoapods.MapLibre.MLNOrnamentPositionTopRight import cocoapods.MapLibre.MLNStyle import cocoapods.MapLibre.MLNZoomLevelForAltitude import cocoapods.MapLibre.allowsTilting +import dev.sargunv.maplibrecompose.core.util.div import dev.sargunv.maplibrecompose.core.util.toBoundingBox import dev.sargunv.maplibrecompose.core.util.toCGPoint import dev.sargunv.maplibrecompose.core.util.toCGRect @@ -475,6 +476,6 @@ internal class IosMap( ) .map { (it as MLNFeatureProtocol).toFeature() } - override fun lengthPerDpAtLatitude(latitude: Double) = - mapView.metersPerPointAtLatitude(latitude).meters + override fun scaleAtLatitude(latitude: Double) = + mapView.metersPerPointAtLatitude(latitude).meters / 1.dp } diff --git a/lib/maplibre-compose/src/jsMain/kotlin/dev/sargunv/maplibrecompose/core/JsMap.kt b/lib/maplibre-compose/src/jsMain/kotlin/dev/sargunv/maplibrecompose/core/JsMap.kt index b23ad424..60e59df4 100644 --- a/lib/maplibre-compose/src/jsMain/kotlin/dev/sargunv/maplibrecompose/core/JsMap.kt +++ b/lib/maplibre-compose/src/jsMain/kotlin/dev/sargunv/maplibrecompose/core/JsMap.kt @@ -4,7 +4,10 @@ import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.DpOffset import androidx.compose.ui.unit.DpRect import androidx.compose.ui.unit.LayoutDirection +import androidx.compose.ui.unit.dp import co.touchlab.kermit.Logger +import dev.sargunv.maplibrecompose.core.util.MapScale +import dev.sargunv.maplibrecompose.core.util.div import dev.sargunv.maplibrecompose.core.util.toBoundingBox import dev.sargunv.maplibrecompose.core.util.toControlPosition import dev.sargunv.maplibrecompose.core.util.toDpOffset @@ -33,7 +36,6 @@ import io.github.dellisd.spatialk.geojson.BoundingBox import io.github.dellisd.spatialk.geojson.Feature import io.github.dellisd.spatialk.geojson.Position import io.github.kevincianfarini.alchemist.scalar.meters -import io.github.kevincianfarini.alchemist.type.Length import kotlin.time.Duration import kotlin.time.DurationUnit import kotlin.time.TimeSource @@ -298,8 +300,9 @@ internal class JsMap( .map { Feature.fromJson(JSON.stringify(it)) } } - override fun lengthPerDpAtLatitude(latitude: Double): Length { + override fun scaleAtLatitude(latitude: Double): MapScale { val point = impl.project(LngLat(impl.getCenter().lng, latitude)) - return impl.unproject(point).distanceTo(impl.unproject(Point(point.x + 1, point.y))).meters + return impl.unproject(point).distanceTo(impl.unproject(Point(point.x + 1, point.y))).meters / + 1.dp } }