Compare commits
2 commits
b807e46978
...
4ecdbb1c48
| Author | SHA1 | Date | |
|---|---|---|---|
| 4ecdbb1c48 | |||
| 7a424db8ab |
3 changed files with 81 additions and 29 deletions
|
|
@ -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.Config.Companion.MAP_START_OFFSET_Y
|
||||||
import com.mirenkov.ktheightmap.parser.KhmParser
|
import com.mirenkov.ktheightmap.parser.KhmParser
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
|
import kotlin.math.ceil
|
||||||
import kotlin.math.floor
|
import kotlin.math.floor
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
|
|
@ -257,7 +258,7 @@ fun DrawScope.drawPointInfo(
|
||||||
val latDiff = lat - pointLat
|
val latDiff = lat - pointLat
|
||||||
val lonDiff = lon - pointLon
|
val lonDiff = lon - pointLon
|
||||||
val distance = sqrt((latDiff).pow(2) + (lonDiff).pow(2))
|
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<Pair<Float, Float>> = Array(valuesCount) { step ->
|
val array: Array<Pair<Float, Float>> = Array(valuesCount) { step ->
|
||||||
val interCoef = 1F - step.toFloat() / valuesCount
|
val interCoef = 1F - step.toFloat() / valuesCount
|
||||||
Pair(lon - lonDiff * interCoef, lat - latDiff * interCoef)
|
Pair(lon - lonDiff * interCoef, lat - latDiff * interCoef)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.mirenkov.ktheightmap
|
package com.mirenkov.ktheightmap
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
|
@ -8,16 +9,27 @@ import androidx.activity.compose.setContent
|
||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.enableEdgeToEdge
|
||||||
import androidx.activity.result.ActivityResultLauncher
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.safeDrawingPadding
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.HorizontalDivider
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
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.LocalViewModelStoreOwner
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import com.mirenkov.ktheightmap.parser.KhmParser
|
import com.mirenkov.ktheightmap.parser.KhmParser
|
||||||
|
|
@ -49,41 +61,76 @@ class SettingsActivity : ComponentActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("ShowToast")
|
||||||
@Composable
|
@Composable
|
||||||
fun SettingsMain(vm: TileViewModel, launcher: ActivityResultLauncher<DocumentFilePickerConfig?>) {
|
fun SettingsMain(vm: TileViewModel, launcher: ActivityResultLauncher<DocumentFilePickerConfig?>) {
|
||||||
|
|
||||||
val coroutineScope = rememberCoroutineScope()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
val filePath by remember { FileLoader.filePath }
|
val filePath by remember { FileLoader.filePath }
|
||||||
val ctx = LocalContext.current
|
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 {
|
KtHeightMapTheme {
|
||||||
Column(Modifier.fillMaxSize()
|
Scaffold { paddingValues ->
|
||||||
.safeDrawingPadding()) {
|
Column(Modifier.padding(paddingValues)) {
|
||||||
Button({ launcher.launch(null) }) { Text("Select file") }
|
LabeledSection("Select file:", Modifier.padding(24.dp, 8.dp)) {
|
||||||
Button({
|
fileSelectorRow()
|
||||||
filePath?.let {
|
}
|
||||||
|
LabeledSection("Load file as...", Modifier.padding(24.dp, 8.dp)) {
|
||||||
|
Button({ filePath?.let {
|
||||||
coroutineScope.launch(Dispatchers.IO) {
|
coroutineScope.launch(Dispatchers.IO) {
|
||||||
SasSQLiteParser.processZip(it, vm.repository, ctx)
|
SasSQLiteParser.processZip(it, vm.repository, ctx)
|
||||||
coroutineScope.launch(Dispatchers.Main) { toast.show() }
|
coroutineScope.launch(Dispatchers.Main) { loadToast.show() }
|
||||||
}
|
}
|
||||||
} }
|
} }) { Text("SQLite (.zip)") }
|
||||||
) { Text("Load SQLite") }
|
Button({ filePath?.let {
|
||||||
Button({
|
|
||||||
filePath?.let {
|
|
||||||
coroutineScope.launch(Dispatchers.IO) {
|
coroutineScope.launch(Dispatchers.IO) {
|
||||||
SasJPEGParser.processZip(it, vm.repository)
|
SasJPEGParser.processZip(it, vm.repository)
|
||||||
coroutineScope.launch(Dispatchers.Main) { toast.show() }
|
coroutineScope.launch(Dispatchers.Main) { loadToast.show() }
|
||||||
}
|
}
|
||||||
}
|
} }) { Text("JPEG (.zip)") }
|
||||||
},
|
Button({ filePath?.let {
|
||||||
) { Text("Load JPEG") }
|
|
||||||
Button({
|
|
||||||
filePath?.let {
|
|
||||||
KhmParser.load(it, ctx)
|
KhmParser.load(it, ctx)
|
||||||
toast.show()
|
loadToast.show()
|
||||||
} },
|
} }) { Text("Height data (.khm)") }
|
||||||
) { Text("Load KHM") }
|
}
|
||||||
Button({ coroutineScope.launch { vm.repository.clearTiles() } }) { Text("Clear tiles") }
|
LabeledSection("Clear...", Modifier.padding(24.dp, 8.dp)) {
|
||||||
Button({ KhmParser.clear(ctx) }) { Text("Clear KHM") }
|
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() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -122,10 +122,14 @@ class KhmParser {
|
||||||
|
|
||||||
return Pair(
|
return Pair(
|
||||||
UShortArray(coords.size) { i ->
|
UShortArray(coords.size) { i ->
|
||||||
if (cutOffsets[i] > 0) {
|
when {
|
||||||
dis.skipBytes(cutOffsets[i])
|
(cutOffsets[i] > 0) -> {
|
||||||
dis.readUnsignedShort().toUShort()
|
dis.skipBytes(cutOffsets[i])
|
||||||
} else 0u },
|
dis.readUnsignedShort().toUShort()
|
||||||
|
}
|
||||||
|
(cutOffsets[i] == 0) -> {dis.readUnsignedShort().toUShort()}
|
||||||
|
else -> 0u
|
||||||
|
} },
|
||||||
if (reversed) coords else coords.reversed().toTypedArray())
|
if (reversed) coords else coords.reversed().toTypedArray())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue