Layers are added to place features below or on top of others

This commit is contained in:
a.kalmakhanov 2022-09-01 15:11:26 +09:00
parent 491a4e6000
commit 5247ce10ab
4 changed files with 56 additions and 27 deletions

View File

@ -87,11 +87,14 @@ fun App() {
centerCoordinates = pointTwo,
)
draw(position = pointThree) {
drawLine(start = Offset(-10f, -10f), end = Offset(10f, 10f), color = Color.Red)
drawLine(start = Offset(-10f, 10f), end = Offset(10f, -10f), color = Color.Red)
}
circle(pointThree, layer = -1, color = Color.Blue)
arc(pointOne, Distance(10.0), 0f, PI)
line(pointOne, pointTwo, id = "line")

View File

@ -17,7 +17,7 @@ import kotlin.math.floor
public interface MapFeature {
public val zoomRange: IntRange
public fun getBoundingBox(zoom: Double): GmcRectangle?
public val layer: Int
}
public interface DraggableMapFeature : MapFeature {
@ -36,6 +36,7 @@ internal val defaultZoomRange = 1..18
*/
public class MapFeatureSelector(
public val selector: (zoom: Int) -> MapFeature,
override val layer: Int
) : MapFeature {
override val zoomRange: IntRange get() = defaultZoomRange
@ -46,6 +47,7 @@ public class MapDrawFeature(
public val position: GeodeticMapCoordinates,
override val zoomRange: IntRange = defaultZoomRange,
public val drawFeature: DrawScope.() -> Unit,
override val layer: Int
) : DraggableMapFeature {
override fun getBoundingBox(zoom: Double): GmcRectangle {
//TODO add box computation
@ -53,7 +55,7 @@ public class MapDrawFeature(
}
override fun withCoordinates(newCoordinates: GeodeticMapCoordinates): MapFeature =
MapDrawFeature(newCoordinates, zoomRange, drawFeature)
MapDrawFeature(newCoordinates, zoomRange, drawFeature, layer)
}
public class MapPointsFeature(
@ -62,6 +64,7 @@ public class MapPointsFeature(
public val stroke: Float = 2f,
public val color: Color = Color.Red,
public val pointMode: PointMode = PointMode.Points,
override val layer: Int
) : MapFeature {
override fun getBoundingBox(zoom: Double): GmcRectangle {
return GmcRectangle(points.first(), points.last())
@ -73,14 +76,15 @@ public class MapCircleFeature(
override val zoomRange: IntRange = defaultZoomRange,
public val size: Float = 5f,
public val color: Color = Color.Red,
override val layer: Int
) : DraggableMapFeature {
override fun getBoundingBox(zoom: Double): GmcRectangle {
val scale = WebMercatorProjection.scaleFactor(zoom)
return GmcRectangle.square(center, (size/scale).radians, (size/scale).radians)
return GmcRectangle.square(center, (size / scale).radians, (size / scale).radians)
}
override fun withCoordinates(newCoordinates: GeodeticMapCoordinates): MapFeature =
MapCircleFeature(newCoordinates, zoomRange, size, color)
MapCircleFeature(newCoordinates, zoomRange, size, color, layer)
}
public class MapRectangleFeature(
@ -88,14 +92,15 @@ public class MapRectangleFeature(
override val zoomRange: IntRange = defaultZoomRange,
public val size: DpSize = DpSize(5.dp, 5.dp),
public val color: Color = Color.Red,
override val layer: Int
) : DraggableMapFeature {
override fun getBoundingBox(zoom: Double): GmcRectangle {
val scale = WebMercatorProjection.scaleFactor(zoom)
return GmcRectangle.square(center, (size.height.value/scale).radians, (size.width.value/scale).radians)
return GmcRectangle.square(center, (size.height.value / scale).radians, (size.width.value / scale).radians)
}
override fun withCoordinates(newCoordinates: GeodeticMapCoordinates): MapFeature =
MapRectangleFeature(newCoordinates, zoomRange, size, color)
MapRectangleFeature(newCoordinates, zoomRange, size, color, layer)
}
public class MapLineFeature(
@ -103,6 +108,7 @@ public class MapLineFeature(
public val b: GeodeticMapCoordinates,
override val zoomRange: IntRange = defaultZoomRange,
public val color: Color = Color.Red,
override val layer: Int
) : MapFeature {
override fun getBoundingBox(zoom: Double): GmcRectangle = GmcRectangle(a, b)
}
@ -113,6 +119,7 @@ public class MapArcFeature(
public val endAngle: Float,
override val zoomRange: IntRange = defaultZoomRange,
public val color: Color = Color.Red,
override val layer: Int
) : MapFeature {
override fun getBoundingBox(zoom: Double): GmcRectangle = oval
}
@ -122,11 +129,12 @@ public class MapBitmapImageFeature(
public val image: ImageBitmap,
public val size: IntSize = IntSize(15, 15),
override val zoomRange: IntRange = defaultZoomRange,
override val layer: Int
) : DraggableMapFeature {
override fun getBoundingBox(zoom: Double): GmcRectangle = GmcRectangle(position, position)
override fun withCoordinates(newCoordinates: GeodeticMapCoordinates): MapFeature =
MapBitmapImageFeature(newCoordinates, image, size, zoomRange)
MapBitmapImageFeature(newCoordinates, image, size, zoomRange, layer)
}
public class MapVectorImageFeature(
@ -134,11 +142,12 @@ public class MapVectorImageFeature(
public val painter: Painter,
public val size: DpSize,
override val zoomRange: IntRange = defaultZoomRange,
) : DraggableMapFeature{
override val layer: Int
) : DraggableMapFeature {
override fun getBoundingBox(zoom: Double): GmcRectangle = GmcRectangle(position, position)
override fun withCoordinates(newCoordinates: GeodeticMapCoordinates): MapFeature =
MapVectorImageFeature(newCoordinates,painter, size, zoomRange)
MapVectorImageFeature(newCoordinates, painter, size, zoomRange, layer)
}
@Composable
@ -147,7 +156,8 @@ public fun MapVectorImageFeature(
image: ImageVector,
size: DpSize = DpSize(20.dp, 20.dp),
zoomRange: IntRange = defaultZoomRange,
): MapVectorImageFeature = MapVectorImageFeature(position, rememberVectorPainter(image), size, zoomRange)
layer: Int
): MapVectorImageFeature = MapVectorImageFeature(position, rememberVectorPainter(image), size, zoomRange, layer)
/**
* A group of other features
@ -155,6 +165,7 @@ public fun MapVectorImageFeature(
public class MapFeatureGroup(
public val children: Map<FeatureId, MapFeature>,
override val zoomRange: IntRange = defaultZoomRange,
override val layer: Int
) : MapFeature {
override fun getBoundingBox(zoom: Double): GmcRectangle? =
children.values.mapNotNull { it.getBoundingBox(zoom) }.wrapAll()
@ -166,9 +177,10 @@ public class MapTextFeature(
override val zoomRange: IntRange = defaultZoomRange,
public val color: Color,
public val fontConfig: MapTextFeatureFont.() -> Unit,
) : DraggableMapFeature{
override val layer: Int
) : DraggableMapFeature {
override fun getBoundingBox(zoom: Double): GmcRectangle = GmcRectangle(position, position)
override fun withCoordinates(newCoordinates: GeodeticMapCoordinates): MapFeature =
MapTextFeature(newCoordinates, text, zoomRange, color, fontConfig)
MapTextFeature(newCoordinates, text, zoomRange, color, fontConfig, layer)
}

View File

@ -70,8 +70,9 @@ public fun MapFeatureBuilder.circle(
size: Float = 5f,
color: Color = Color.Red,
id: FeatureId? = null,
layer: Int = 0
): FeatureId = addFeature(
id, MapCircleFeature(center, zoomRange, size, color)
id, MapCircleFeature(center, zoomRange, size, color, layer)
)
public fun MapFeatureBuilder.circle(
@ -80,8 +81,9 @@ public fun MapFeatureBuilder.circle(
size: Float = 5f,
color: Color = Color.Red,
id: FeatureId? = null,
layer: Int = 0
): FeatureId = addFeature(
id, MapCircleFeature(centerCoordinates.toCoordinates(), zoomRange, size, color)
id, MapCircleFeature(centerCoordinates.toCoordinates(), zoomRange, size, color, layer)
)
public fun MapFeatureBuilder.rectangle(
@ -90,16 +92,18 @@ public fun MapFeatureBuilder.rectangle(
size: DpSize = DpSize(5.dp, 5.dp),
color: Color = Color.Red,
id: FeatureId? = null,
layer: Int = 0
): FeatureId = addFeature(
id, MapRectangleFeature(centerCoordinates.toCoordinates(), zoomRange, size, color)
id, MapRectangleFeature(centerCoordinates.toCoordinates(), zoomRange, size, color, layer)
)
public fun MapFeatureBuilder.draw(
position: Pair<Double, Double>,
zoomRange: IntRange = defaultZoomRange,
id: FeatureId? = null,
drawFeature: DrawScope.() -> Unit,
): FeatureId = addFeature(id, MapDrawFeature(position.toCoordinates(), zoomRange, drawFeature))
layer: Int = 0,
drawFeature: DrawScope.() -> Unit
): FeatureId = addFeature(id, MapDrawFeature(position.toCoordinates(), zoomRange, drawFeature, layer))
public fun MapFeatureBuilder.line(
aCoordinates: Pair<Double, Double>,
@ -107,9 +111,10 @@ public fun MapFeatureBuilder.line(
zoomRange: IntRange = defaultZoomRange,
color: Color = Color.Red,
id: FeatureId? = null,
layer: Int = 0
): FeatureId = addFeature(
id,
MapLineFeature(aCoordinates.toCoordinates(), bCoordinates.toCoordinates(), zoomRange, color)
MapLineFeature(aCoordinates.toCoordinates(), bCoordinates.toCoordinates(), zoomRange, color, layer)
)
public fun MapFeatureBuilder.arc(
@ -119,9 +124,10 @@ public fun MapFeatureBuilder.arc(
zoomRange: IntRange = defaultZoomRange,
color: Color = Color.Red,
id: FeatureId? = null,
layer: Int = 0
): FeatureId = addFeature(
id,
MapArcFeature(oval, startAngle.toFloat(), endAngle.toFloat(), zoomRange, color)
MapArcFeature(oval, startAngle.toFloat(), endAngle.toFloat(), zoomRange, color, layer)
)
public fun MapFeatureBuilder.arc(
@ -132,6 +138,7 @@ public fun MapFeatureBuilder.arc(
zoomRange: IntRange = defaultZoomRange,
color: Color = Color.Red,
id: FeatureId? = null,
layer: Int = 0
): FeatureId = addFeature(
id,
MapArcFeature(
@ -139,7 +146,8 @@ public fun MapFeatureBuilder.arc(
startAngle.toFloat(),
endAngle.toFloat(),
zoomRange,
color
color,
layer
)
)
@ -150,7 +158,9 @@ public fun MapFeatureBuilder.points(
color: Color = Color.Red,
pointMode: PointMode = PointMode.Points,
id: FeatureId? = null,
): FeatureId = addFeature(id, MapPointsFeature(points.map { it.toCoordinates() }, zoomRange, stroke, color, pointMode))
layer: Int = 0
): FeatureId =
addFeature(id, MapPointsFeature(points.map { it.toCoordinates() }, zoomRange, stroke, color, pointMode, layer))
@Composable
public fun MapFeatureBuilder.image(
@ -159,15 +169,17 @@ public fun MapFeatureBuilder.image(
size: DpSize = DpSize(20.dp, 20.dp),
zoomRange: IntRange = defaultZoomRange,
id: FeatureId? = null,
): FeatureId = addFeature(id, MapVectorImageFeature(position.toCoordinates(), image, size, zoomRange))
layer: Int = 0
): FeatureId = addFeature(id, MapVectorImageFeature(position.toCoordinates(), image, size, zoomRange, layer))
public fun MapFeatureBuilder.group(
zoomRange: IntRange = defaultZoomRange,
id: FeatureId? = null,
builder: MapFeatureBuilder.() -> Unit,
layer: Int = 0,
builder: MapFeatureBuilder.() -> Unit
): FeatureId {
val map = MapFeatureBuilderImpl(mutableStateMapOf()).apply(builder).features
val feature = MapFeatureGroup(map, zoomRange)
val feature = MapFeatureGroup(map, zoomRange, layer)
return addFeature(id, feature)
}
@ -178,7 +190,8 @@ public fun MapFeatureBuilder.text(
color: Color = Color.Red,
font: MapTextFeatureFont.() -> Unit = { size = 16f },
id: FeatureId? = null,
): FeatureId = addFeature(id, MapTextFeature(position, text, zoomRange, color, font))
layer: Int = 0
): FeatureId = addFeature(id, MapTextFeature(position, text, zoomRange, color, font, layer))
public fun MapFeatureBuilder.text(
position: Pair<Double, Double>,
@ -187,4 +200,5 @@ public fun MapFeatureBuilder.text(
color: Color = Color.Red,
font: MapTextFeatureFont.() -> Unit = { size = 16f },
id: FeatureId? = null,
): FeatureId = addFeature(id, MapTextFeature(position.toCoordinates(), text, zoomRange, color, font))
layer: Int = 0
): FeatureId = addFeature(id, MapTextFeature(position.toCoordinates(), text, zoomRange, color, font, layer))

View File

@ -351,7 +351,7 @@ public actual fun MapView(
dstSize = tileSize
)
}
features.values.filter { zoom in it.zoomRange }.forEach { feature ->
features.values.filter { zoom in it.zoomRange }.sortedBy { it.layer }.forEach { feature ->
drawFeature(zoom, feature)
}
}