diff --git a/app/src/main/java/com/mirenkov/ktheightmap/KhmParser.kt b/app/src/main/java/com/mirenkov/ktheightmap/KhmParser.kt index 2de27b4..2734176 100644 --- a/app/src/main/java/com/mirenkov/ktheightmap/KhmParser.kt +++ b/app/src/main/java/com/mirenkov/ktheightmap/KhmParser.kt @@ -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() } } } \ No newline at end of file diff --git a/app/src/main/java/com/mirenkov/ktheightmap/MainActivity.kt b/app/src/main/java/com/mirenkov/ktheightmap/MainActivity.kt index 79f2f15..53d6a6b 100644 --- a/app/src/main/java/com/mirenkov/ktheightmap/MainActivity.kt +++ b/app/src/main/java/com/mirenkov/ktheightmap/MainActivity.kt @@ -175,6 +175,7 @@ fun ToolButton(viewModel: TileViewModel) { @Suppress("VariableNeverRead", "AssignedValueIsNeverRead") @Composable fun SetLocationDialog(vm: TileViewModel, dialogShown: MutableState) { + 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) { 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()) } }, diff --git a/app/src/main/java/com/mirenkov/ktheightmap/SettingsActivity.kt b/app/src/main/java/com/mirenkov/ktheightmap/SettingsActivity.kt index f8e0c89..1bfed6c 100644 --- a/app/src/main/java/com/mirenkov/ktheightmap/SettingsActivity.kt +++ b/app/src/main/java/com/mirenkov/ktheightmap/SettingsActivity.kt @@ -75,6 +75,7 @@ class SettingsActivity : ComponentActivity() { fun SettingsMain(vm: TileViewModel, launcher: ActivityResultLauncher) { 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