API fixes
This commit is contained in:
parent
6278235b51
commit
190834634f
@ -8,7 +8,7 @@ plugins {
|
||||
|
||||
allprojects {
|
||||
group = "center.sciprog"
|
||||
version = "0.2.0-dev-1"
|
||||
version = "0.2.1-dev-1"
|
||||
}
|
||||
|
||||
apiValidation{
|
||||
|
@ -1,9 +1,10 @@
|
||||
kotlin.code.style=official
|
||||
|
||||
compose.version=1.2.2
|
||||
|
||||
agp.version=4.2.2
|
||||
agp.version=7.3.1
|
||||
android.useAndroidX=true
|
||||
org.jetbrains.compose.experimental.jscanvas.enabled=true
|
||||
|
||||
org.gradle.jvmargs=-Xmx4096m
|
||||
|
||||
toolsVersion=0.13.3-kotlin-1.7.20
|
@ -2,7 +2,6 @@ package center.sciprog.maps.compose
|
||||
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import center.sciprog.maps.coordinates.Gmc
|
||||
import center.sciprog.maps.features.*
|
||||
@ -10,8 +9,8 @@ import center.sciprog.maps.features.*
|
||||
|
||||
@Composable
|
||||
public expect fun MapView(
|
||||
mapState: MapViewScope,
|
||||
featuresState: FeatureGroup<Gmc>,
|
||||
viewScope: MapViewScope,
|
||||
features: FeatureGroup<Gmc>,
|
||||
modifier: Modifier = Modifier.fillMaxSize(),
|
||||
)
|
||||
|
||||
@ -21,27 +20,21 @@ public expect fun MapView(
|
||||
@Composable
|
||||
public fun MapView(
|
||||
mapTileProvider: MapTileProvider,
|
||||
initialViewPoint: MapViewPoint? = null,
|
||||
features: FeatureGroup<Gmc>,
|
||||
initialViewPoint: ViewPoint<Gmc>? = null,
|
||||
initialRectangle: Rectangle<Gmc>? = null,
|
||||
featureMap: Map<FeatureId<*>, MapFeature>,
|
||||
config: ViewConfig<Gmc> = ViewConfig(),
|
||||
modifier: Modifier = Modifier.fillMaxSize(),
|
||||
) {
|
||||
|
||||
val featureState = remember(featureMap) {
|
||||
FeatureGroup.build(WebMercatorSpace) {
|
||||
featureMap.forEach { feature(it.key.id, it.value) }
|
||||
}
|
||||
}
|
||||
|
||||
val mapState: MapViewScope = rememberMapState(
|
||||
val mapState: MapViewScope = MapViewScope.remember(
|
||||
mapTileProvider,
|
||||
config,
|
||||
initialViewPoint = initialViewPoint,
|
||||
initialRectangle = initialRectangle ?: featureState.features.computeBoundingBox(WebMercatorSpace, Float.MAX_VALUE),
|
||||
initialRectangle = initialRectangle ?: features.getBoundingBox(Float.MAX_VALUE),
|
||||
)
|
||||
|
||||
MapView(mapState, featureState, modifier)
|
||||
MapView(mapState, features, modifier)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -54,7 +47,7 @@ public fun MapView(
|
||||
@Composable
|
||||
public fun MapView(
|
||||
mapTileProvider: MapTileProvider,
|
||||
initialViewPoint: MapViewPoint? = null,
|
||||
initialViewPoint: ViewPoint<Gmc>? = null,
|
||||
initialRectangle: Rectangle<Gmc>? = null,
|
||||
config: ViewConfig<Gmc> = ViewConfig(),
|
||||
modifier: Modifier = Modifier.fillMaxSize(),
|
||||
@ -63,11 +56,14 @@ public fun MapView(
|
||||
|
||||
val featureState = FeatureGroup.remember(WebMercatorSpace, buildFeatures)
|
||||
|
||||
val mapState: MapViewScope = rememberMapState(
|
||||
val mapState: MapViewScope = MapViewScope.remember(
|
||||
mapTileProvider,
|
||||
config,
|
||||
initialViewPoint = initialViewPoint,
|
||||
initialRectangle = initialRectangle ?: featureState.features.computeBoundingBox(WebMercatorSpace, Float.MAX_VALUE),
|
||||
initialRectangle = initialRectangle ?: featureState.features.computeBoundingBox(
|
||||
WebMercatorSpace,
|
||||
Float.MAX_VALUE
|
||||
),
|
||||
)
|
||||
|
||||
MapView(mapState, featureState, modifier)
|
||||
|
@ -1,13 +1,15 @@
|
||||
package center.sciprog.maps.compose
|
||||
|
||||
import center.sciprog.maps.coordinates.*
|
||||
import center.sciprog.maps.coordinates.GeodeticMapCoordinates
|
||||
import center.sciprog.maps.coordinates.Gmc
|
||||
import center.sciprog.maps.coordinates.WebMercatorProjection
|
||||
import center.sciprog.maps.coordinates.radians
|
||||
import center.sciprog.maps.features.ViewPoint
|
||||
import kotlin.math.pow
|
||||
|
||||
/**
|
||||
* Observable position on the map. Includes observation coordinate and [zoom] factor
|
||||
*/
|
||||
public data class MapViewPoint(
|
||||
internal data class MapViewPoint(
|
||||
override val focus: GeodeticMapCoordinates,
|
||||
override val zoom: Float,
|
||||
) : ViewPoint<Gmc>{
|
||||
@ -17,28 +19,3 @@ public data class MapViewPoint(
|
||||
public val globe: MapViewPoint = MapViewPoint(GeodeticMapCoordinates(0.0.radians, 0.0.radians), 1f)
|
||||
}
|
||||
}
|
||||
|
||||
public fun MapViewPoint.move(delta: GeodeticMapCoordinates): MapViewPoint {
|
||||
val newCoordinates = GeodeticMapCoordinates(
|
||||
(focus.latitude + delta.latitude).coerceIn(
|
||||
-MercatorProjection.MAXIMUM_LATITUDE,
|
||||
MercatorProjection.MAXIMUM_LATITUDE
|
||||
),
|
||||
focus.longitude + delta.longitude
|
||||
)
|
||||
return MapViewPoint(newCoordinates, zoom)
|
||||
}
|
||||
|
||||
public fun MapViewPoint.zoom(
|
||||
zoomDelta: Float,
|
||||
invariant: GeodeticMapCoordinates = focus,
|
||||
): MapViewPoint = if (invariant == focus) {
|
||||
copy(zoom = (zoom + zoomDelta).coerceIn(2f, 18f))
|
||||
} else {
|
||||
val difScale = (1 - 2f.pow(-zoomDelta))
|
||||
val newCenter = GeodeticMapCoordinates(
|
||||
focus.latitude + (invariant.latitude - focus.latitude) * difScale,
|
||||
focus.longitude + (invariant.longitude - focus.longitude) * difScale
|
||||
)
|
||||
MapViewPoint(newCenter, (zoom + zoomDelta).coerceIn(2f, 18f))
|
||||
}
|
@ -60,7 +60,7 @@ public class MapViewScope internal constructor(
|
||||
canvasSize.height.value / rectangle.latitudeDelta.radians.value
|
||||
) * PI / mapTileProvider.tileSize
|
||||
)
|
||||
return MapViewPoint(rectangle.center, zoom.toFloat())
|
||||
return space.ViewPoint(rectangle.center, zoom.toFloat())
|
||||
}
|
||||
|
||||
override fun ViewPoint<Gmc>.moveBy(x: Dp, y: Dp): ViewPoint<Gmc> {
|
||||
@ -73,22 +73,24 @@ public class MapViewScope internal constructor(
|
||||
),
|
||||
focus.longitude + (deltaX / scaleFactor).radians
|
||||
)
|
||||
return MapViewPoint(newCoordinates, zoom)
|
||||
return space.ViewPoint(newCoordinates, zoom)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun rememberMapState(
|
||||
public companion object {
|
||||
@Composable
|
||||
public fun remember(
|
||||
mapTileProvider: MapTileProvider,
|
||||
config: ViewConfig<Gmc>,
|
||||
initialViewPoint: MapViewPoint? = null,
|
||||
config: ViewConfig<Gmc> = ViewConfig(),
|
||||
initialViewPoint: ViewPoint<Gmc>? = null,
|
||||
initialRectangle: Rectangle<Gmc>? = null,
|
||||
): MapViewScope = remember {
|
||||
MapViewScope(mapTileProvider, config).also { mapState->
|
||||
): MapViewScope = remember {
|
||||
MapViewScope(mapTileProvider, config).also { mapState ->
|
||||
if (initialViewPoint != null) {
|
||||
mapState.viewPoint = initialViewPoint
|
||||
} else if (initialRectangle != null) {
|
||||
mapState.viewPoint = mapState.computeViewPoint(initialRectangle)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
package center.sciprog.maps.compose
|
||||
|
||||
import androidx.compose.foundation.Canvas
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
@ -44,11 +43,10 @@ private val logger = KotlinLogging.logger("MapView")
|
||||
*/
|
||||
@Composable
|
||||
public actual fun MapView(
|
||||
mapState: MapViewScope,
|
||||
featuresState: FeatureGroup<Gmc>,
|
||||
viewScope: MapViewScope,
|
||||
features: FeatureGroup<Gmc>,
|
||||
modifier: Modifier,
|
||||
): Unit = with(mapState) {
|
||||
|
||||
): Unit = with(viewScope) {
|
||||
val mapTiles = remember(mapTileProvider) { mutableStateListOf<MapTile>() }
|
||||
|
||||
// Load tiles asynchronously
|
||||
@ -89,13 +87,11 @@ public actual fun MapView(
|
||||
}
|
||||
}
|
||||
}
|
||||
key(viewScope, features) {
|
||||
val painterCache: Map<PainterFeature<Gmc>, Painter> =
|
||||
features.features.filterIsInstance<PainterFeature<Gmc>>().associateWith { it.getPainter() }
|
||||
|
||||
val painterCache: Map<PainterFeature<Gmc>, Painter> = key(featuresState) {
|
||||
featuresState.features.filterIsInstance<PainterFeature<Gmc>>().associateWith { it.getPainter() }
|
||||
}
|
||||
|
||||
|
||||
Canvas(modifier = modifier.mapControls(mapState, featuresState).fillMaxSize()) {
|
||||
Canvas(modifier = modifier.mapControls(viewScope, features)) {
|
||||
|
||||
if (canvasSize != size.toDpSize()) {
|
||||
logger.debug { "Recalculate canvas. Size: $size" }
|
||||
@ -121,10 +117,10 @@ public actual fun MapView(
|
||||
)
|
||||
}
|
||||
|
||||
featuresState.featureMap.values.sortedBy { it.z }
|
||||
features.featureMap.values.sortedBy { it.z }
|
||||
.filter { viewPoint.zoom in it.zoomRange }
|
||||
.forEach { feature ->
|
||||
drawFeature(mapState, painterCache, feature)
|
||||
drawFeature(viewScope, painterCache, feature)
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,5 +138,6 @@ public actual fun MapView(
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,9 @@
|
||||
package center.sciprog.attributes
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import center.sciprog.maps.features.Feature
|
||||
import center.sciprog.maps.features.ZAttribute
|
||||
import kotlin.jvm.JvmInline
|
||||
|
||||
@Stable
|
||||
@JvmInline
|
||||
public value class Attributes internal constructor(internal val map: Map<Attribute<*>, Any>) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
|
@ -23,15 +23,15 @@ private val logger = KotlinLogging.logger("SchemeView")
|
||||
@Composable
|
||||
public fun SchemeView(
|
||||
state: XYViewScope,
|
||||
featuresState: FeatureGroup<XY>,
|
||||
modifier: Modifier = Modifier,
|
||||
) = key(state, featuresState) {
|
||||
features: FeatureGroup<XY>,
|
||||
modifier: Modifier = Modifier.fillMaxSize(),
|
||||
) = key(state, features) {
|
||||
with(state) {
|
||||
//Can't do that inside canvas
|
||||
val painterCache: Map<PainterFeature<XY>, Painter> =
|
||||
featuresState.features.filterIsInstance<PainterFeature<XY>>().associateWith { it.getPainter() }
|
||||
features.features.filterIsInstance<PainterFeature<XY>>().associateWith { it.getPainter() }
|
||||
|
||||
Canvas(modifier = modifier.mapControls(state, featuresState).fillMaxSize()) {
|
||||
Canvas(modifier = modifier.mapControls(state, features)) {
|
||||
|
||||
if (canvasSize != size.toDpSize()) {
|
||||
canvasSize = size.toDpSize()
|
||||
@ -39,7 +39,7 @@ public fun SchemeView(
|
||||
}
|
||||
|
||||
clipRect {
|
||||
featuresState.featureMap.values.sortedBy { it.z }
|
||||
features.featureMap.values.sortedBy { it.z }
|
||||
.filter { viewPoint.zoom in it.zoomRange }
|
||||
.forEach { feature ->
|
||||
drawFeature(state, painterCache, feature)
|
||||
@ -80,30 +80,20 @@ public fun Rectangle<XY>.computeViewPoint(
|
||||
*/
|
||||
@Composable
|
||||
public fun SchemeView(
|
||||
features: FeatureGroup<XY>,
|
||||
initialViewPoint: ViewPoint<XY>? = null,
|
||||
initialRectangle: Rectangle<XY>? = null,
|
||||
featureMap: Map<FeatureId<*>, Feature<XY>>,
|
||||
config: ViewConfig<XY> = ViewConfig(),
|
||||
modifier: Modifier = Modifier.fillMaxSize(),
|
||||
) {
|
||||
|
||||
|
||||
val featureState = key(featureMap) {
|
||||
FeatureGroup.build(XYCoordinateSpace) {
|
||||
featureMap.forEach { feature(it.key.id, it.value) }
|
||||
}
|
||||
}
|
||||
|
||||
val state = XYViewScope.remember(
|
||||
config,
|
||||
initialViewPoint = initialViewPoint,
|
||||
initialRectangle = initialRectangle ?: featureState.features.computeBoundingBox(
|
||||
XYCoordinateSpace,
|
||||
Float.MAX_VALUE
|
||||
),
|
||||
initialRectangle = initialRectangle ?: features.getBoundingBox(Float.MAX_VALUE),
|
||||
)
|
||||
|
||||
SchemeView(state, featureState, modifier)
|
||||
SchemeView(state, features, modifier)
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user