I push my tiles into my database

This commit is contained in:
Alexey 2025-08-07 16:48:06 +03:00
commit c0644b4c70
5 changed files with 81 additions and 32 deletions

13
.idea/deviceManager.xml generated Normal file
View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DeviceTable">
<option name="columnSorters">
<list>
<ColumnSorterState>
<option name="column" value="Name" />
<option name="order" value="ASCENDING" />
</ColumnSorterState>
</list>
</option>
</component>
</project>

View file

@ -3,15 +3,11 @@ package com.mirenkov.ktheightmap
import android.app.Application
import android.content.Intent
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.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.absoluteOffset
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
@ -24,7 +20,6 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme.colorScheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Slider
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableFloatStateOf
@ -76,7 +71,7 @@ class MainActivity : ComponentActivity() {
@Composable
fun Main(vm: TileViewModel = viewModel()) {
var sliderValue = rememberSaveable { mutableFloatStateOf(1F) }
val sliderValue = rememberSaveable { mutableFloatStateOf(1F) }
KtHeightMapTheme {
Box(modifier = Modifier.background(color = colorScheme.background)) {
Scaffold(

View file

@ -1,22 +1,27 @@
package com.mirenkov.ktheightmap
import android.graphics.BitmapFactory
import android.app.Application
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
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.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner
import androidx.lifecycle.viewmodel.compose.viewModel
import com.mirenkov.ktheightmap.ui.theme.KtHeightMapTheme
import com.nareshchocha.filepickerlibrary.FilePickerResultContracts
import com.nareshchocha.filepickerlibrary.models.DocumentFilePickerConfig
import com.nareshchocha.filepickerlibrary.models.FilePickerResult
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import java.io.FileInputStream
@ -25,7 +30,10 @@ import java.util.zip.ZipInputStream
class SettingsActivity : ComponentActivity() {
companion object {
var filePath: String? = null
}
fun filePickerResult(result: FilePickerResult): String? {
if (result.errorMessage != null) {
Log.e(TAG, result.errorMessage ?: "")
@ -41,47 +49,72 @@ class SettingsActivity : ComponentActivity() {
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val launcher = registerForActivityResult(FilePickerResultContracts.PickDocumentFile(),
val launcher = registerForActivityResult(FilePickerResultContracts.PickDocumentFile())
{ result -> filePath = filePickerResult(result) }
)
enableEdgeToEdge()
setContent {
val coroutineScope = rememberCoroutineScope()
val owner = LocalViewModelStoreOwner.current
owner?.let {
val viewModel: TileViewModel = viewModel(
it,
"TileViewModel2",
TileViewModelFactory(LocalContext.current.applicationContext as Application)
)
SettingsMain(viewModel, launcher)
}
}
}
}
@Composable
fun SettingsMain(vm: TileViewModel, launcher: ActivityResultLauncher<DocumentFilePickerConfig?>) {
val coroutineScope = rememberCoroutineScope()
KtHeightMapTheme {
Column(Modifier.fillMaxSize()
.safeDrawingPadding()) {
Button(onClick = {
launcher.launch(null)
}) { Text(text = "Select database") }
Button(onClick = { coroutineScope.launch { processZip(filePath) } }) {
Text(text = "Load database")
}
Button(onClick = { coroutineScope.launch {
processZip(SettingsActivity.filePath).forEach {
with(vm.repository) {
val t = getTile(it.x, it.y, it.level)
if (t == null) {
pushTile(it)
Log.i(TAG, "pushed to db: %d, %d, %d".format(it.level, it.x, it.y))
}
else
Log.i(TAG, "found in db: %d, %d, %d".format(t.level, t.x, t.y))
}
}
} }) { Text(text = "Load database") }
}
}
}
suspend fun processZip(filePath: String?) = coroutineScope {
suspend fun processZip(filePath: String?): List<Tile> = coroutineScope {
val list: MutableList<Tile> = mutableListOf()
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)
val tile = processEntry(zipInputStream, entry)
list.add(tile)
}
entry = zipInputStream.nextEntry
if (entry == null)
break
}
Log.i(TAG, "got list")
}
}
return@coroutineScope list
}
fun processEntry(zis: ZipInputStream, entry: ZipEntry) {
fun processEntry(zis: ZipInputStream, entry: ZipEntry): Tile {
val ba = ByteArray(entry.size.toInt())
var offset = 0
var size = zis.read(ba, 0, ba.size)
@ -93,5 +126,5 @@ fun processEntry(zis: ZipInputStream, entry: ZipEntry) {
val ( level, x, y ) = regex.findAll(entry.name).map { it.value.toInt() }.toList()
val base64 = ba.toBase64()
val tile = Tile(x, y, level, base64)
return Tile(x, y, level, base64)
}

View file

@ -1,20 +1,28 @@
package com.mirenkov.ktheightmap
import android.util.Log
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
class TileRepository(private val tileDao: TileDao) {
private val coroutineScope = CoroutineScope(Dispatchers.Main)
fun pushTile(tile: Tile) {
tileDao.pushTile(tile)
coroutineScope.launch(Dispatchers.IO) { tileDao.pushTile(tile) }
}
fun getTile(x: Int, y: Int, level: Int): Tile? {
return tileDao.getTile(x, y, level)
@OptIn(ExperimentalCoroutinesApi::class)
suspend fun getTile(x: Int, y: Int, level: Int): Tile? {
val tileDeferred = coroutineScope.async(Dispatchers.IO) {
tileDao.getTile(x, y, level)
}
return tileDeferred.await()
}
fun clearTiles() {
tileDao.clearTiles()
coroutineScope.launch(Dispatchers.IO) { tileDao.clearTiles() }
}
}

View file

@ -5,7 +5,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
class TileViewModel(application: Application): ViewModel() {
private val repository: TileRepository
val repository: TileRepository
init {
val tileDb = TileDB.getInstance(application)