Changed multiple heights parsing

This commit is contained in:
Alexey 2025-09-23 16:39:53 +03:00
commit 71f012dc6b
2 changed files with 50 additions and 6 deletions

View file

@ -2,10 +2,12 @@ package com.mirenkov.ktheightmap
import android.content.Context
import android.util.Log
import java.io.DataInput
import java.io.DataInputStream
import java.io.FileInputStream
import kotlin.math.max
import kotlin.math.min
import kotlin.math.sign
private data class HeightInfo(
val minLon: Float,
@ -20,6 +22,7 @@ class KhmParser {
companion object {
private var header: HeightInfo? = null
const val HEIGHT_FILE: String = "height.khm"
fun load(filePath: String, ctx: Context) {
if (ctx.getFileStreamPath(HEIGHT_FILE).exists()) {
return
@ -77,6 +80,42 @@ class KhmParser {
}
}
@OptIn(ExperimentalUnsignedTypes::class)
fun getHeightsMul(ctx: Context, coords: Array<Pair<Float, Float>>): Pair<UShortArray, Array<Pair<Float, Float>>> {
if (coords.isEmpty()) return Pair(ushortArrayOf(), coords)
val dis = DataInputStream(ctx.openFileInput(HEIGHT_FILE))
dis.use {
val header = readHeader(dis)
val glist: Array<Pair<Pair<Float, Float>, Int>> = Array(coords.size) { i ->
val x = ((coords[i].first - header.minLon) / header.lonPerValue).toInt()
val y = ((coords[i].second - header.minLat) / header.latPerValue).toInt()
val offset = getOffset(header, x, y)
Pair(coords[i], offset)
}
glist.sortBy {
it.second
}
coords.sortBy { oit ->
glist.find { it.first == oit }!!.second
}
val cutOffsets = IntArray(glist.size)
cutOffsets[0] = glist[0].second
for (i in 1 until glist.size) {
cutOffsets[i] = glist[i].second - glist[i-1].second - 2
assert(cutOffsets[i] >= 0)
}
return Pair(UShortArray(coords.size) { i ->
dis.skipBytes(cutOffsets[i])
dis.readUnsignedShort().toUShort()
}, coords)
}
}
fun getLonPerValue(): Float {
return header?.lonPerValue ?: 0F
}

View file

@ -24,11 +24,11 @@ import androidx.compose.ui.text.rememberTextMeasurer
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle
import kotlin.math.absoluteValue
import kotlin.math.ceil
import kotlin.math.floor
import kotlin.math.pow
import kotlin.math.sqrt
@OptIn(ExperimentalUnsignedTypes::class)
@Composable
fun MapCanvas(
viewModel: TileViewModel,
@ -200,15 +200,20 @@ fun MapCanvas(
val lonDiff = lon - pointLon
val distance = sqrt((latDiff).pow(2) + (lonDiff).pow(2))
val valuesCount = floor(distance / valueDistance).toInt()
for (step in 0 .. valuesCount) {
val array: Array<Pair<Float, Float>> = Array(valuesCount) { step ->
val interCoef = 1F - step.toFloat() / valuesCount
val stepLat = lat - latDiff * interCoef
val stepLon = lon - lonDiff * interCoef
Pair(lon - lonDiff * interCoef, lat - latDiff * interCoef)
}
val heightPair = KhmParser.getHeightsMul(ctx, array)
val heights = heightPair.first
val coords = heightPair.second
for (step in 0 until coords.size) {
val stepLat = coords[step].second
val stepLon = coords[step].first
val stepOffsetX = SphereMercator.mercateLon(stepLon.toDouble(), level, -TILE_SIZE.toDouble()).toFloat() - offsetX
val stepOffsetY = SphereMercator.mercateLat(stepLat.toDouble(), level, -TILE_SIZE.toDouble()).toFloat() - offsetY
val height = KhmParser.getHeight(stepLon, stepLat, ctx)
drawRect(
color = if (height > startHeight) Color.Red else Color.Green,
color = if (heights[step] > startHeight) Color.Red else Color.Green,
size = Size(8F, 8F),
topLeft = Offset(stepOffsetX - 4, stepOffsetY - 4)
)