dc09-sensors2 #5
3 changed files with 59 additions and 53 deletions
57
app/src/main/java/ru/nm17/narodmon/ui/elements/TileMap.kt
Normal file
57
app/src/main/java/ru/nm17/narodmon/ui/elements/TileMap.kt
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
package ru.nm17.narodmon.ui.elements
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.geometry.Offset
|
||||||
|
import io.ktor.client.HttpClient
|
||||||
|
import io.ktor.client.engine.cio.CIO
|
||||||
|
import io.ktor.client.request.get
|
||||||
|
import io.ktor.client.statement.bodyAsChannel
|
||||||
|
import io.ktor.utils.io.jvm.javaio.toInputStream
|
||||||
|
import ovh.plrapps.mapcompose.api.addLayer
|
||||||
|
import ovh.plrapps.mapcompose.api.scale
|
||||||
|
import ovh.plrapps.mapcompose.api.setScroll
|
||||||
|
import ovh.plrapps.mapcompose.core.TileStreamProvider
|
||||||
|
import ovh.plrapps.mapcompose.ui.MapUI
|
||||||
|
import ovh.plrapps.mapcompose.ui.state.MapState
|
||||||
|
import java.io.InputStream
|
||||||
|
|
||||||
|
const val mapSize = 32768
|
||||||
|
|
||||||
|
val client = HttpClient(CIO)
|
||||||
|
val tileStreamProvider = TileStreamProvider { row, col, zoom ->
|
||||||
|
requestTile(row, col, zoom)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun requestTile(row: Int, col: Int, zoom: Int): InputStream {
|
||||||
|
val response = client.get("https://tile.openstreetmap.org/${zoom}/${col}/${row}.png")
|
||||||
|
return response.bodyAsChannel().toInputStream()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TileMap(modifier: Modifier = Modifier) {
|
||||||
|
val state by remember {
|
||||||
|
mutableStateOf(
|
||||||
|
MapState(
|
||||||
|
levelCount = 8,
|
||||||
|
fullWidth = mapSize,
|
||||||
|
fullHeight = mapSize,
|
||||||
|
workerCount = 16,
|
||||||
|
).apply {
|
||||||
|
addLayer(tileStreamProvider)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
LaunchedEffect(state) {
|
||||||
|
// TODO: Подгружать сохранённую позицию
|
||||||
|
state.setScroll(Offset(28702.6F, 14787.6F))
|
||||||
|
state.scale = 1.4658884F
|
||||||
|
}
|
||||||
|
|
||||||
|
MapUI(modifier = modifier, state = state)
|
||||||
|
}
|
|
@ -9,23 +9,18 @@ import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.FilterChip
|
import androidx.compose.material3.FilterChip
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.geometry.Offset
|
|
||||||
import androidx.compose.ui.platform.LocalConfiguration
|
import androidx.compose.ui.platform.LocalConfiguration
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import ovh.plrapps.mapcompose.api.scale
|
|
||||||
import ovh.plrapps.mapcompose.api.setScroll
|
|
||||||
import ovh.plrapps.mapcompose.ui.MapUI
|
|
||||||
import ru.nm17.narodmon.R
|
import ru.nm17.narodmon.R
|
||||||
import ru.nm17.narodmon.ui.elements.GenericNavScaffold
|
import ru.nm17.narodmon.ui.elements.GenericNavScaffold
|
||||||
import ru.nm17.narodmon.ui.viewmodel.MapViewModel
|
import ru.nm17.narodmon.ui.elements.TileMap
|
||||||
|
|
||||||
enum class SensorsFilter {
|
enum class SensorsFilter {
|
||||||
All, Thermometer, Camera,
|
All, Thermometer, Camera,
|
||||||
|
@ -34,24 +29,17 @@ enum class SensorsFilter {
|
||||||
@ExperimentalMaterial3Api
|
@ExperimentalMaterial3Api
|
||||||
@Composable
|
@Composable
|
||||||
fun SensorsPage(navController: NavController) {
|
fun SensorsPage(navController: NavController) {
|
||||||
val mapVM by remember { mutableStateOf(MapViewModel()) }
|
|
||||||
var filter by remember { mutableStateOf(SensorsFilter.All) }
|
var filter by remember { mutableStateOf(SensorsFilter.All) }
|
||||||
|
|
||||||
val scrConfig = LocalConfiguration.current
|
val scrConfig = LocalConfiguration.current
|
||||||
val mapHeight = scrConfig.screenHeightDp / 3
|
val mapHeight = scrConfig.screenHeightDp / 3
|
||||||
|
|
||||||
LaunchedEffect(mapVM) {
|
|
||||||
// TODO: Подгружать сохранённую позицию
|
|
||||||
mapVM.state.setScroll(Offset(28702.6F, 14787.6F))
|
|
||||||
mapVM.state.scale = 1.4658884F
|
|
||||||
}
|
|
||||||
|
|
||||||
GenericNavScaffold(
|
GenericNavScaffold(
|
||||||
title = { Text(text = stringResource(R.string.sensors_page_title)) }
|
title = { Text(text = stringResource(R.string.sensors_page_title)) }
|
||||||
) {
|
) {
|
||||||
Column(modifier = Modifier.padding(it)) {
|
Column(modifier = Modifier.padding(it)) {
|
||||||
|
|
||||||
MapUI(state = mapVM.state, modifier = Modifier.height(mapHeight.dp))
|
TileMap(modifier = Modifier.height(mapHeight.dp))
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier.padding(horizontal = 8.dp),
|
modifier = Modifier.padding(horizontal = 8.dp),
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
package ru.nm17.narodmon.ui.viewmodel
|
|
||||||
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.lifecycle.ViewModel
|
|
||||||
import io.ktor.client.HttpClient
|
|
||||||
import io.ktor.client.engine.cio.CIO
|
|
||||||
import io.ktor.client.request.get
|
|
||||||
import io.ktor.client.statement.bodyAsChannel
|
|
||||||
import io.ktor.utils.io.jvm.javaio.toInputStream
|
|
||||||
import ovh.plrapps.mapcompose.api.addLayer
|
|
||||||
import ovh.plrapps.mapcompose.core.TileStreamProvider
|
|
||||||
import ovh.plrapps.mapcompose.ui.state.MapState
|
|
||||||
import java.io.InputStream
|
|
||||||
|
|
||||||
class MapViewModel : ViewModel() {
|
|
||||||
private val client = HttpClient(CIO)
|
|
||||||
|
|
||||||
private val tileStreamProvider = TileStreamProvider { row, col, zoom ->
|
|
||||||
requestTile(row, col, zoom)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val mapSize = 32768
|
|
||||||
val state: MapState by mutableStateOf(
|
|
||||||
MapState(
|
|
||||||
levelCount = 8,
|
|
||||||
fullWidth = mapSize,
|
|
||||||
fullHeight = mapSize,
|
|
||||||
workerCount = 16,
|
|
||||||
).apply {
|
|
||||||
addLayer(tileStreamProvider)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
private suspend fun requestTile(row: Int, col: Int, zoom: Int): InputStream {
|
|
||||||
val response = client.get("https://tile.openstreetmap.org/${zoom}/${col}/${row}.png")
|
|
||||||
return response.bodyAsChannel().toInputStream()
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue