Almost done tiles processing

This commit is contained in:
Alexey 2025-08-07 15:21:04 +03:00
commit 8bec8e4b16
3 changed files with 69 additions and 32 deletions

View file

@ -50,6 +50,8 @@ dependencies {
implementation("io.github.chochanaresh:filepicker:0.6.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.2")
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)

View file

@ -40,10 +40,14 @@ import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner
import androidx.lifecycle.viewmodel.compose.viewModel
import com.mirenkov.ktheightmap.ui.theme.KtHeightMapTheme
import java.util.Base64
const val TAG = "KtHeightMap"
const val TILE_SIZE: Float = 256F
fun ByteArray.toBase64(): String =
String(Base64.getEncoder().encode(this))
class TileViewModelFactory(val application: Application):
ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
@ -58,7 +62,6 @@ class MainActivity : ComponentActivity() {
enableEdgeToEdge()
setContent {
val owner = LocalViewModelStoreOwner.current
owner?.let {
val viewModel: TileViewModel = viewModel(
it,

View file

@ -1,65 +1,97 @@
package com.mirenkov.ktheightmap
import android.graphics.BitmapFactory
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.safeDrawingPadding
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import com.mirenkov.ktheightmap.ui.theme.KtHeightMapTheme
import com.nareshchocha.filepickerlibrary.FilePickerResultContracts
import com.nareshchocha.filepickerlibrary.models.PickerData
import com.nareshchocha.filepickerlibrary.models.PopUpConfig
import com.nareshchocha.filepickerlibrary.models.FilePickerResult
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import java.io.FileInputStream
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream
class SettingsActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val launcher = registerForActivityResult(FilePickerResultContracts.PickDocumentFile()) { result ->
var filePath: String? = null
fun filePickerResult(result: FilePickerResult): String? {
if (result.errorMessage != null) {
Log.e("Picker", result.errorMessage ?: "")
Log.e(TAG, result.errorMessage ?: "")
return null
} else {
val filePath = result.selectedFilePath
filePath?.let {
if (!it.endsWith(".zip"))
return@let
ZipInputStream(FileInputStream(it)).use { zipInputStream ->
var entry = zipInputStream.nextEntry
while (entry != null) {
with(entry.name) {
if (count { it == '/' } == 4 && endsWith(".jpg"))
processEntry(entry)
}
entry = zipInputStream.nextEntry
}
}
if (it.endsWith(".zip"))
return filePath
}
return null
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val launcher = registerForActivityResult(FilePickerResultContracts.PickDocumentFile(),
{ result -> filePath = filePickerResult(result) }
)
enableEdgeToEdge()
setContent {
val coroutineScope = rememberCoroutineScope()
KtHeightMapTheme {
Column(Modifier.fillMaxSize()
.safeDrawingPadding()) {
Button(onClick = {
launcher.launch(null)
}) { Text(text = "Load database") }
}) { Text(text = "Select database") }
Button(onClick = { coroutineScope.launch { processZip(filePath) } }) {
Text(text = "Load database")
}
}
}
}
}
}
fun processEntry(entry: ZipEntry) {
suspend fun processZip(filePath: String?) = coroutineScope {
filePath?.let {
ZipInputStream(FileInputStream(it)).use { zipInputStream ->
var entry = zipInputStream.nextEntry
while (true) {
if (entry.name.endsWith(".jpg")) {
Log.i(TAG, entry.name)
processEntry(zipInputStream, entry)
}
entry = zipInputStream.nextEntry
if (entry == null)
break
}
}
}
}
fun processEntry(zis: ZipInputStream, entry: ZipEntry) {
val ba = ByteArray(entry.size.toInt())
var offset = 0
var size = zis.read(ba, 0, ba.size)
while (size > 0) {
offset += size
size = zis.read(ba, offset, ba.size - offset)
}
val regex = Regex("(?<=z)(\\d+)|(?<=x)(\\d+)|(?<=y)(\\d+)")
val ( level, x, y ) = regex.findAll(entry.name).map { it.value.toInt() }.toList()
val base64 = ba.toBase64()
val tile = Tile(x, y, level, base64)
}