Add vector rendering
This commit is contained in:
parent
6258e25669
commit
7771a9b7b9
@ -1,6 +1,8 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
import androidx.compose.desktop.ui.tooling.preview.Preview
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Home
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.window.Window
|
||||
import androidx.compose.ui.window.application
|
||||
@ -18,9 +20,11 @@ fun App() {
|
||||
val pointOne = 55.568548 to 37.568604
|
||||
val pointTwo = 55.929444 to 37.518434
|
||||
val features = buildList<MapFeature> {
|
||||
add(MapCircleFeature(pointOne))
|
||||
// add(MapCircleFeature(pointOne))
|
||||
add(MapCircleFeature(pointTwo))
|
||||
add(MapLineFeature(pointOne, pointTwo))
|
||||
add(MapTextFeature(pointOne.toCoordinates(), "Home"))
|
||||
add(MapVectorImageFeature(pointOne.toCoordinates(), Icons.Filled.Home))
|
||||
}
|
||||
MapView(viewPoint, features = features, cacheDirectory = Path.of("mapCache"))
|
||||
}
|
||||
|
@ -1,14 +1,20 @@
|
||||
package centre.sciprog.maps.compose
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.geometry.Size
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.ImageBitmap
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.graphics.vector.VectorPainter
|
||||
import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
||||
import androidx.compose.ui.unit.IntSize
|
||||
|
||||
//TODO replace zoom range with zoom-based representation change
|
||||
sealed class MapFeature(val zoomRange: ClosedFloatingPointRange<Double>)
|
||||
|
||||
private val defaultZoomRange = 1.0..18.0
|
||||
|
||||
private fun Pair<Double, Double>.toCoordinates() = GeodeticMapCoordinates.ofDegrees(first, second)
|
||||
internal fun Pair<Double, Double>.toCoordinates() = GeodeticMapCoordinates.ofDegrees(first, second)
|
||||
|
||||
class MapCircleFeature(
|
||||
val center: GeodeticMapCoordinates,
|
||||
@ -48,11 +54,30 @@ class MapTextFeature(
|
||||
val text: String,
|
||||
zoomRange: ClosedFloatingPointRange<Double> = defaultZoomRange,
|
||||
val color: Color = Color.Red,
|
||||
): MapFeature(zoomRange)
|
||||
) : MapFeature(zoomRange)
|
||||
|
||||
class MapImageFeature(
|
||||
class MapBitmapImageFeature(
|
||||
val position: GeodeticMapCoordinates,
|
||||
val image: ImageBitmap,
|
||||
val size: IntSize = IntSize(15, 15),
|
||||
zoomRange: ClosedFloatingPointRange<Double> = defaultZoomRange,
|
||||
val color: Color = Color.Red,
|
||||
): MapFeature(zoomRange)
|
||||
) : MapFeature(zoomRange)
|
||||
|
||||
|
||||
class MapVectorImageFeature internal constructor(
|
||||
val position: GeodeticMapCoordinates,
|
||||
val painter: VectorPainter,
|
||||
val size: Size,
|
||||
zoomRange: ClosedFloatingPointRange<Double> = defaultZoomRange,
|
||||
val color: Color = Color.Red,
|
||||
) : MapFeature(zoomRange)
|
||||
|
||||
@Composable
|
||||
fun MapVectorImageFeature(
|
||||
position: GeodeticMapCoordinates,
|
||||
image: ImageVector,
|
||||
size: Size = Size(20f,20f),
|
||||
zoomRange: ClosedFloatingPointRange<Double> = defaultZoomRange,
|
||||
color: Color = Color.Red,
|
||||
): MapVectorImageFeature = MapVectorImageFeature(position, rememberVectorPainter(image), size, zoomRange, color)
|
@ -9,12 +9,10 @@ import androidx.compose.ui.ExperimentalComposeUiApi
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.geometry.Size
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.ImageBitmap
|
||||
import androidx.compose.ui.graphics.*
|
||||
import androidx.compose.ui.graphics.drawscope.clipRect
|
||||
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
|
||||
import androidx.compose.ui.graphics.nativeCanvas
|
||||
import androidx.compose.ui.graphics.toComposeImageBitmap
|
||||
import androidx.compose.ui.graphics.drawscope.translate
|
||||
import androidx.compose.ui.input.pointer.PointerEventType
|
||||
import androidx.compose.ui.input.pointer.PointerInputChange
|
||||
import androidx.compose.ui.input.pointer.onPointerEvent
|
||||
@ -28,7 +26,9 @@ import kotlinx.coroutines.Deferred
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import mu.KotlinLogging
|
||||
import org.jetbrains.skia.Font
|
||||
import org.jetbrains.skia.Image
|
||||
import org.jetbrains.skia.Paint
|
||||
import java.net.URL
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.*
|
||||
@ -93,13 +93,10 @@ private class OsMapCache(val scope: CoroutineScope, val client: HttpClient, priv
|
||||
}
|
||||
}
|
||||
|
||||
private fun Color.toPaint(): org.jetbrains.skia.Paint = org.jetbrains.skia.Paint().setARGB(
|
||||
(alpha * 256).toInt(),
|
||||
(red * 256).toInt(),
|
||||
(green * 256).toInt(),
|
||||
(blue * 256).toInt()
|
||||
)
|
||||
|
||||
private fun Color.toPaint(): Paint = Paint().apply {
|
||||
isAntiAlias = true
|
||||
color = toArgb()
|
||||
}
|
||||
|
||||
private fun Double.toIndex(): Int = floor(this / TILE_SIZE).toInt()
|
||||
private fun Int.toCoordinate(): Double = (this * TILE_SIZE).toDouble()
|
||||
@ -142,7 +139,7 @@ fun MapView(
|
||||
|
||||
for (j in verticalIndices) {
|
||||
for (i in horizontalIndices) {
|
||||
if(z == viewPoint.zoom.toInt() && i in indexRange && j in indexRange) {
|
||||
if (z == viewPoint.zoom.toInt() && i in indexRange && j in indexRange) {
|
||||
val tileId = OsMapTileId(z, i, j)
|
||||
val tile = mapCache.loadTile(tileId)
|
||||
mapTiles.add(tile)
|
||||
@ -211,10 +208,24 @@ fun MapView(
|
||||
center = feature.center.toOffset()
|
||||
)
|
||||
is MapLineFeature -> drawLine(feature.color, feature.a.toOffset(), feature.b.toOffset())
|
||||
is MapImageFeature -> drawImage(feature.image, feature.position.toOffset())
|
||||
is MapTextFeature -> drawIntoCanvas {
|
||||
is MapBitmapImageFeature -> drawImage(feature.image, feature.position.toOffset())
|
||||
is MapVectorImageFeature -> {
|
||||
val offset = feature.position.toOffset()
|
||||
it.nativeCanvas.drawString(feature.text, offset.x, offset.y, null, feature.color.toPaint())
|
||||
translate(offset.x - feature.size.width/2, offset.y - feature.size.height/2) {
|
||||
with(feature.painter) {
|
||||
draw(feature.size)
|
||||
}
|
||||
}
|
||||
}
|
||||
is MapTextFeature -> drawIntoCanvas { canvas ->
|
||||
val offset = feature.position.toOffset()
|
||||
canvas.nativeCanvas.drawString(
|
||||
feature.text,
|
||||
offset.x + 5,
|
||||
offset.y - 5,
|
||||
Font().apply { size = 16f },
|
||||
feature.color.toPaint()
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user