2022-07-23 10:58:16 +03:00
|
|
|
package center.sciprog.maps.compose
|
2022-07-11 09:36:43 +03:00
|
|
|
|
|
|
|
import androidx.compose.foundation.layout.fillMaxSize
|
|
|
|
import androidx.compose.runtime.Composable
|
|
|
|
import androidx.compose.ui.Modifier
|
2022-07-14 20:19:57 +03:00
|
|
|
import androidx.compose.ui.unit.DpSize
|
2022-07-23 11:24:37 +03:00
|
|
|
import center.sciprog.maps.coordinates.*
|
2022-07-14 20:19:57 +03:00
|
|
|
import kotlin.math.PI
|
|
|
|
import kotlin.math.log2
|
|
|
|
import kotlin.math.min
|
2022-07-11 09:36:43 +03:00
|
|
|
|
2022-07-13 11:36:02 +03:00
|
|
|
|
2022-07-19 12:31:09 +03:00
|
|
|
//TODO consider replacing by modifier
|
2022-07-13 11:36:02 +03:00
|
|
|
data class MapViewConfig(
|
|
|
|
val zoomSpeed: Double = 1.0 / 3.0,
|
2022-07-19 12:31:09 +03:00
|
|
|
val inferViewBoxFromFeatures: Boolean = false,
|
|
|
|
val onClick: MapViewPoint.() -> Unit = {},
|
|
|
|
val onViewChange: MapViewPoint.() -> Unit = {},
|
|
|
|
val onSelect: (GmcBox) -> Unit = {},
|
|
|
|
val zoomOnSelect: Boolean = true
|
2022-07-13 11:36:02 +03:00
|
|
|
)
|
|
|
|
|
2022-07-11 09:36:43 +03:00
|
|
|
@Composable
|
|
|
|
expect fun MapView(
|
|
|
|
mapTileProvider: MapTileProvider,
|
2022-07-14 20:19:57 +03:00
|
|
|
computeViewPoint: (canvasSize: DpSize) -> MapViewPoint,
|
2022-07-11 18:43:05 +03:00
|
|
|
features: Map<FeatureId, MapFeature>,
|
2022-07-13 11:36:02 +03:00
|
|
|
config: MapViewConfig = MapViewConfig(),
|
2022-07-11 18:32:36 +03:00
|
|
|
modifier: Modifier = Modifier.fillMaxSize(),
|
|
|
|
)
|
|
|
|
|
|
|
|
@Composable
|
|
|
|
fun MapView(
|
2022-07-14 20:19:57 +03:00
|
|
|
mapTileProvider: MapTileProvider,
|
2022-07-11 18:32:36 +03:00
|
|
|
initialViewPoint: MapViewPoint,
|
2022-07-14 20:19:57 +03:00
|
|
|
features: Map<FeatureId, MapFeature> = emptyMap(),
|
|
|
|
config: MapViewConfig = MapViewConfig(),
|
|
|
|
modifier: Modifier = Modifier.fillMaxSize(),
|
|
|
|
buildFeatures: @Composable (FeatureBuilder.() -> Unit) = {},
|
|
|
|
) {
|
|
|
|
val featuresBuilder = MapFeatureBuilder(features)
|
|
|
|
featuresBuilder.buildFeatures()
|
2022-07-19 12:31:09 +03:00
|
|
|
MapView(
|
|
|
|
mapTileProvider,
|
|
|
|
{ initialViewPoint },
|
|
|
|
featuresBuilder.build(),
|
|
|
|
config,
|
|
|
|
modifier
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2022-07-23 09:59:14 +03:00
|
|
|
internal fun GmcBox.computeViewPoint(mapTileProvider: MapTileProvider): (canvasSize: DpSize) -> MapViewPoint = { canvasSize ->
|
2022-07-19 12:31:09 +03:00
|
|
|
val zoom = log2(
|
|
|
|
min(
|
|
|
|
canvasSize.width.value / width,
|
|
|
|
canvasSize.height.value / height
|
|
|
|
) * PI / mapTileProvider.tileSize
|
|
|
|
)
|
|
|
|
MapViewPoint(center, zoom)
|
2022-07-14 20:19:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
@Composable
|
2022-07-23 11:24:37 +03:00
|
|
|
public fun MapView(
|
2022-07-14 20:19:57 +03:00
|
|
|
mapTileProvider: MapTileProvider,
|
|
|
|
box: GmcBox,
|
|
|
|
features: Map<FeatureId, MapFeature> = emptyMap(),
|
|
|
|
config: MapViewConfig = MapViewConfig(),
|
|
|
|
modifier: Modifier = Modifier.fillMaxSize(),
|
|
|
|
buildFeatures: @Composable (FeatureBuilder.() -> Unit) = {},
|
|
|
|
) {
|
|
|
|
val featuresBuilder = MapFeatureBuilder(features)
|
|
|
|
featuresBuilder.buildFeatures()
|
2022-07-19 12:31:09 +03:00
|
|
|
MapView(
|
|
|
|
mapTileProvider,
|
2022-07-23 09:59:14 +03:00
|
|
|
box.computeViewPoint(mapTileProvider),
|
2022-07-19 12:31:09 +03:00
|
|
|
featuresBuilder.build(),
|
|
|
|
config,
|
|
|
|
modifier
|
|
|
|
)
|
2022-07-11 18:32:36 +03:00
|
|
|
}
|