From 7a424db8ab2e93671b5d8cd65c123a818f1ad1b5 Mon Sep 17 00:00:00 2001 From: 2ndbeam <2ndbeam@disroot.org> Date: Tue, 11 Nov 2025 12:53:15 +0300 Subject: [PATCH 1/2] Updated Settings Activity UI --- .../mirenkov/ktheightmap/SettingsActivity.kt | 95 ++++++++++++++----- 1 file changed, 71 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/com/mirenkov/ktheightmap/SettingsActivity.kt b/app/src/main/java/com/mirenkov/ktheightmap/SettingsActivity.kt index b868ad0..dc7c39e 100644 --- a/app/src/main/java/com/mirenkov/ktheightmap/SettingsActivity.kt +++ b/app/src/main/java/com/mirenkov/ktheightmap/SettingsActivity.kt @@ -1,5 +1,6 @@ package com.mirenkov.ktheightmap +import android.annotation.SuppressLint import android.app.Application import android.os.Bundle import android.widget.Toast @@ -8,16 +9,27 @@ import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.activity.result.ActivityResultLauncher import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.safeDrawingPadding +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding import androidx.compose.material3.Button +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.text.AnnotatedString +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.withStyle +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner import androidx.lifecycle.viewmodel.compose.viewModel import com.mirenkov.ktheightmap.parser.KhmParser @@ -49,41 +61,76 @@ class SettingsActivity : ComponentActivity() { } } +@SuppressLint("ShowToast") @Composable fun SettingsMain(vm: TileViewModel, launcher: ActivityResultLauncher) { + val coroutineScope = rememberCoroutineScope() val filePath by remember { FileLoader.filePath } val ctx = LocalContext.current - val toast = Toast.makeText(ctx, "File parsed.", Toast.LENGTH_LONG) + val loadToast = Toast.makeText(ctx, "File successfully loaded.", Toast.LENGTH_LONG) + val clearTilesToast = Toast.makeText(ctx, "Tiles removed from database.", Toast.LENGTH_LONG) + val clearHeightToast = Toast.makeText(ctx, "Height data removed.", Toast.LENGTH_LONG) + val fileSelectorRow = @Composable () { + Row(Modifier.fillMaxWidth()) { + Button({ launcher.launch(null) }) { Text("Select") } + Text("Selected file: none", Modifier.padding(8.dp, 0.dp).align(Alignment.CenterVertically)) + } + } KtHeightMapTheme { - Column(Modifier.fillMaxSize() - .safeDrawingPadding()) { - Button({ launcher.launch(null) }) { Text("Select file") } - Button({ - filePath?.let { + Scaffold { paddingValues -> + Column(Modifier.padding(paddingValues)) { + LabeledSection("Select file:", Modifier.padding(24.dp, 8.dp)) { + fileSelectorRow() + } + LabeledSection("Load file as...", Modifier.padding(24.dp, 8.dp)) { + Button({ filePath?.let { coroutineScope.launch(Dispatchers.IO) { SasSQLiteParser.processZip(it, vm.repository, ctx) - coroutineScope.launch(Dispatchers.Main) { toast.show() } + coroutineScope.launch(Dispatchers.Main) { loadToast.show() } } - } } - ) { Text("Load SQLite") } - Button({ - filePath?.let { + } }) { Text("SQLite (.zip)") } + Button({ filePath?.let { coroutineScope.launch(Dispatchers.IO) { SasJPEGParser.processZip(it, vm.repository) - coroutineScope.launch(Dispatchers.Main) { toast.show() } + coroutineScope.launch(Dispatchers.Main) { loadToast.show() } } - } - }, - ) { Text("Load JPEG") } - Button({ - filePath?.let { + } }) { Text("JPEG (.zip)") } + Button({ filePath?.let { KhmParser.load(it, ctx) - toast.show() - } }, - ) { Text("Load KHM") } - Button({ coroutineScope.launch { vm.repository.clearTiles() } }) { Text("Clear tiles") } - Button({ KhmParser.clear(ctx) }) { Text("Clear KHM") } + loadToast.show() + } }) { Text("Height data (.khm)") } + } + LabeledSection("Clear...", Modifier.padding(24.dp, 8.dp)) { + Button({ coroutineScope.launch { + vm.repository.clearTiles() + clearTilesToast.show() + } }) { Text("Tile data") } + Button({ + KhmParser.clear(ctx) + clearHeightToast.show() + }) { Text("Height data") } + } + } } } +} + +fun labelString(text: String): AnnotatedString { + return buildAnnotatedString { + withStyle(SpanStyle(fontWeight = FontWeight.Bold, fontSize = 24.sp)) { + append(text) + } + } +} + +@Composable +fun LabeledSection(text: String, modifier: Modifier = Modifier, content: @Composable () -> Unit) { + Column(modifier) { + Text(labelString(text)) + HorizontalDivider() + Column( + modifier = modifier.fillMaxWidth() + ) { content() } + } } \ No newline at end of file From 4ecdbb1c48ddb2525996654d2f730cace2a9a401 Mon Sep 17 00:00:00 2001 From: 2ndbeam <2ndbeam@disroot.org> Date: Tue, 11 Nov 2025 13:04:45 +0300 Subject: [PATCH 2/2] Improved GetHeightsMul algorithm --- .../main/java/com/mirenkov/ktheightmap/MapCanvas.kt | 3 ++- .../com/mirenkov/ktheightmap/parser/KhmParser.kt | 12 ++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/mirenkov/ktheightmap/MapCanvas.kt b/app/src/main/java/com/mirenkov/ktheightmap/MapCanvas.kt index 905ec07..d691183 100644 --- a/app/src/main/java/com/mirenkov/ktheightmap/MapCanvas.kt +++ b/app/src/main/java/com/mirenkov/ktheightmap/MapCanvas.kt @@ -33,6 +33,7 @@ import com.mirenkov.ktheightmap.Config.Companion.MAP_START_OFFSET_X import com.mirenkov.ktheightmap.Config.Companion.MAP_START_OFFSET_Y import com.mirenkov.ktheightmap.parser.KhmParser import kotlin.math.absoluteValue +import kotlin.math.ceil import kotlin.math.floor import kotlin.math.min import kotlin.math.pow @@ -257,7 +258,7 @@ fun DrawScope.drawPointInfo( val latDiff = lat - pointLat val lonDiff = lon - pointLon val distance = sqrt((latDiff).pow(2) + (lonDiff).pow(2)) - val valuesCount = min(floor(distance / valueDistance).toInt(),1000) + val valuesCount = min(ceil(distance / valueDistance).toInt(), 1000) val array: Array> = Array(valuesCount) { step -> val interCoef = 1F - step.toFloat() / valuesCount Pair(lon - lonDiff * interCoef, lat - latDiff * interCoef) diff --git a/app/src/main/java/com/mirenkov/ktheightmap/parser/KhmParser.kt b/app/src/main/java/com/mirenkov/ktheightmap/parser/KhmParser.kt index efc8bc9..35801e8 100644 --- a/app/src/main/java/com/mirenkov/ktheightmap/parser/KhmParser.kt +++ b/app/src/main/java/com/mirenkov/ktheightmap/parser/KhmParser.kt @@ -122,10 +122,14 @@ class KhmParser { return Pair( UShortArray(coords.size) { i -> - if (cutOffsets[i] > 0) { - dis.skipBytes(cutOffsets[i]) - dis.readUnsignedShort().toUShort() - } else 0u }, + when { + (cutOffsets[i] > 0) -> { + dis.skipBytes(cutOffsets[i]) + dis.readUnsignedShort().toUShort() + } + (cutOffsets[i] == 0) -> {dis.readUnsignedShort().toUShort()} + else -> 0u + } }, if (reversed) coords else coords.reversed().toTypedArray()) } }