I push my tiles into my database
This commit is contained in:
parent
8bec8e4b16
commit
c0644b4c70
5 changed files with 81 additions and 32 deletions
13
.idea/deviceManager.xml
generated
Normal file
13
.idea/deviceManager.xml
generated
Normal 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>
|
||||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
||||
var filePath: String? = null
|
||||
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()
|
||||
|
||||
KtHeightMapTheme {
|
||||
Column(Modifier.fillMaxSize()
|
||||
.safeDrawingPadding()) {
|
||||
Button(onClick = {
|
||||
launcher.launch(null)
|
||||
}) { Text(text = "Select database") }
|
||||
Button(onClick = { coroutineScope.launch { processZip(filePath) } }) {
|
||||
Text(text = "Load database")
|
||||
}
|
||||
}
|
||||
val owner = LocalViewModelStoreOwner.current
|
||||
owner?.let {
|
||||
val viewModel: TileViewModel = viewModel(
|
||||
it,
|
||||
"TileViewModel2",
|
||||
TileViewModelFactory(LocalContext.current.applicationContext as Application)
|
||||
)
|
||||
SettingsMain(viewModel, launcher)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processZip(filePath: String?) = coroutineScope {
|
||||
@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(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?): 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)
|
||||
}
|
||||
|
|
@ -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() }
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue