Generalize feature draw logic
This commit is contained in:
parent
5b95adc649
commit
8a94438dfd
@ -11,21 +11,23 @@ internal class MapState internal constructor(
|
||||
config: ViewConfig<Gmc>,
|
||||
canvasSize: DpSize,
|
||||
viewPoint: ViewPoint<Gmc>,
|
||||
public val tileSize: Int,
|
||||
val tileSize: Int,
|
||||
) : CoordinateViewState<Gmc>(config, canvasSize, viewPoint) {
|
||||
override val space: CoordinateSpace<Gmc> get() = GmcCoordinateSpace
|
||||
|
||||
public val scaleFactor: Double
|
||||
get() = WebMercatorProjection.scaleFactor(viewPoint.zoom)
|
||||
|
||||
val intZoom: Int get() = floor(zoom).toInt()
|
||||
|
||||
public val centerCoordinates: WebMercatorCoordinates
|
||||
get() = WebMercatorProjection.toMercator(viewPoint.focus, zoom)
|
||||
get() = WebMercatorProjection.toMercator(viewPoint.focus, intZoom)
|
||||
|
||||
internal val tileScale: Double
|
||||
get() = 2.0.pow(viewPoint.zoom - zoom)
|
||||
get() = 2.0.pow(viewPoint.zoom - floor(viewPoint.zoom))
|
||||
|
||||
private fun DpOffset.toMercator(): WebMercatorCoordinates = WebMercatorCoordinates(
|
||||
floor(zoom).toInt(),
|
||||
intZoom,
|
||||
(x - canvasSize.width / 2).value / tileScale + centerCoordinates.x,
|
||||
(y - canvasSize.height / 2).value / tileScale + centerCoordinates.y,
|
||||
)
|
||||
@ -42,7 +44,7 @@ internal class MapState internal constructor(
|
||||
)
|
||||
|
||||
override fun Gmc.toDpOffset(): DpOffset =
|
||||
WebMercatorProjection.toMercator(this, zoom).toOffset()
|
||||
WebMercatorProjection.toMercator(this, intZoom).toOffset()
|
||||
|
||||
override fun Rectangle<Gmc>.toDpRect(): DpRect {
|
||||
val topLeft = topLeft.toDpOffset()
|
||||
|
@ -20,7 +20,10 @@ import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.supervisorScope
|
||||
import mu.KotlinLogging
|
||||
import org.jetbrains.skia.Paint
|
||||
import kotlin.math.*
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
import kotlin.math.pow
|
||||
|
||||
|
||||
private fun Color.toPaint(): Paint = Paint().apply {
|
||||
@ -57,7 +60,7 @@ public actual fun MapView(
|
||||
// Load tiles asynchronously
|
||||
LaunchedEffect(viewPoint, canvasSize) {
|
||||
with(mapTileProvider) {
|
||||
val indexRange = 0 until 2.0.pow(zoom).toInt()
|
||||
val indexRange = 0 until 2.0.pow(intZoom).toInt()
|
||||
|
||||
val left = centerCoordinates.x - canvasSize.width.value / 2 / tileScale
|
||||
val right = centerCoordinates.x + canvasSize.width.value / 2 / tileScale
|
||||
@ -71,7 +74,7 @@ public actual fun MapView(
|
||||
|
||||
for (j in verticalIndices) {
|
||||
for (i in horizontalIndices) {
|
||||
val id = TileId(floor(zoom).toInt(), i, j)
|
||||
val id = TileId(intZoom, i, j)
|
||||
//ensure that failed tiles do not fail the application
|
||||
supervisorScope {
|
||||
//start all
|
||||
|
@ -26,12 +26,12 @@ public object WebMercatorProjection {
|
||||
/**
|
||||
* https://en.wikipedia.org/wiki/Web_Mercator_projection#Formulas
|
||||
*/
|
||||
public fun toMercator(gmc: GeodeticMapCoordinates, zoom: Double): WebMercatorCoordinates {
|
||||
public fun toMercator(gmc: GeodeticMapCoordinates, zoom: Int): WebMercatorCoordinates {
|
||||
require(abs(gmc.latitude) <= MercatorProjection.MAXIMUM_LATITUDE) { "Latitude exceeds the maximum latitude for mercator coordinates" }
|
||||
|
||||
val scaleFactor = scaleFactor(zoom)
|
||||
val scaleFactor = scaleFactor(zoom.toDouble())
|
||||
return WebMercatorCoordinates(
|
||||
zoom = floor(zoom).toInt(),
|
||||
zoom = zoom,
|
||||
x = scaleFactor * (gmc.longitude.radians.value + PI),
|
||||
y = scaleFactor * (PI - ln(tan(PI / 4 + gmc.latitude.radians.value / 2)))
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user