App now finally represents feature for which it was named

This commit is contained in:
Alexey 2025-09-20 21:01:33 +03:00
commit 49cd9c6154
3 changed files with 53 additions and 14 deletions

View file

@ -1,27 +1,61 @@
package com.mirenkov.ktheightmap
import android.content.Context
import android.util.Log
import java.io.DataInputStream
import java.io.FileInputStream
private data class HeightInfo(
val minLon: Float,
val minLat: Float,
val lonPerValue: Float,
val latPerValue: Float,
val width: Int,
val height: Int
)
class KhmParser {
companion object {
fun parse(filePath: String) {
Log.i(TAG, "start")
val dis = DataInputStream(FileInputStream(filePath))
with(dis) {
Log.i(TAG, "start2")
const val HEIGHT_FILE: String = "height.khm"
fun load(filePath: String, ctx: Context) {
if (ctx.getFileStreamPath(HEIGHT_FILE).exists()) {
Log.i(TAG, "height.khm already exists")
return
}
val inp = FileInputStream(filePath)
ctx.openFileOutput(HEIGHT_FILE, Context.MODE_PRIVATE).use {
it.write(inp.readBytes())
Log.i(TAG, "Copied %s to height.khm".format(filePath))
}
}
private fun getOffset(header: HeightInfo, x: Int, y: Int): Int {
Log.i(TAG, "Offset for (%d, %d) = %d".format(x, y, y * header.height + x))
return (x * header.width + y) * 2
}
private fun readHeader(dis: DataInputStream): HeightInfo {
return with(dis) {
val minLon = readFloat()
val minLat = readFloat()
val lonPerPixel = readFloat()
val latPerPixel = readFloat()
val rasterWidth = readInt()
val rasterHeight = readInt()
Log.i(TAG, "mLon: %.6f, mLat: %.6f, pLon: %.6f, pLat: %.6f, w: %d, h: %d".format(
minLon, minLat, lonPerPixel, latPerPixel, rasterWidth, rasterHeight
))
val lonPerValue = readFloat()
val latPerValue = readFloat()
val width = readInt()
val height = readInt()
Log.i(TAG, "Header: %.6f, %.6f, %.6f, %.6f, %d, %d".format(minLon, minLat, lonPerValue, latPerValue, width, height))
HeightInfo( minLon, minLat, lonPerValue, latPerValue, width, height )
}
Log.i(TAG, "end")
}
fun getHeight(lon: Float, lat: Float, ctx: Context): UShort {
val dis = DataInputStream(ctx.openFileInput(HEIGHT_FILE))
val header = readHeader(dis)
val x = ((lon - header.minLon) / header.lonPerValue).toInt()
val y = ((lat - header.minLat) / header.latPerValue).toInt()
val offset = getOffset(header, x, y)
dis.skipBytes(offset)
return dis.readUnsignedShort().toUShort()
}
}
}

View file

@ -175,6 +175,7 @@ fun ToolButton(viewModel: TileViewModel) {
@Suppress("VariableNeverRead", "AssignedValueIsNeverRead")
@Composable
fun SetLocationDialog(vm: TileViewModel, dialogShown: MutableState<Boolean>) {
val ctx = LocalContext.current
var showLocationDialog by dialogShown
if (showLocationDialog) {
var latitudeText by remember { vm.latitudeText }
@ -214,6 +215,7 @@ fun SetLocationDialog(vm: TileViewModel, dialogShown: MutableState<Boolean>) {
Log.i(TAG, "Y = %.6f".format(SphereMercator.mercateLat(latitude, vm.scale.floatValue.toInt(), -TILE_SIZE.toDouble())))
offsetX = SphereMercator.mercateLon(longitude, vm.scale.floatValue.toInt(), -vm.halvedOffsetX!!.toDouble() - TILE_SIZE).toFloat()
offsetY = SphereMercator.mercateLat(latitude, vm.scale.floatValue.toInt(), -vm.halvedOffsetY!!.toDouble() - TILE_SIZE).toFloat()
Log.i(TAG, "%d".format(KhmParser.getHeight(longitude.toFloat(), latitude.toFloat(), ctx).toInt()))
}) {
Text("Confirm".uppercase())
} },

View file

@ -75,6 +75,7 @@ class SettingsActivity : ComponentActivity() {
fun SettingsMain(vm: TileViewModel, launcher: ActivityResultLauncher<DocumentFilePickerConfig?>) {
val coroutineScope = rememberCoroutineScope()
val filePath by remember { SettingsActivity.filePath }
val ctx = LocalContext.current
KtHeightMapTheme {
Column(Modifier.fillMaxSize()
.safeDrawingPadding()) {
@ -100,7 +101,9 @@ fun SettingsMain(vm: TileViewModel, launcher: ActivityResultLauncher<DocumentFil
onClick = { coroutineScope.launch { vm.repository.clearTiles() } },
) { Text(text = "Clear database") }
Button(
onClick = { filePath?.let { KhmParser.parse(it) } },
onClick = { filePath?.let {
KhmParser.load(it, ctx)
} },
) { Text(text = "Load .khm") }
}
}