91 lines
2.7 KiB
Kotlin
Raw Normal View History

2024-06-06 16:54:17 +03:00
package space.kscience.controls.demo.map
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
import io.ktor.client.HttpClient
import io.ktor.client.engine.cio.CIO
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import space.kscience.controls.manager.DeviceManager
import space.kscience.controls.spec.propertyFlow
import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.request
import space.kscience.maps.compose.MapView
import space.kscience.maps.compose.OpenStreetMapTileProvider
import space.kscience.maps.features.ViewConfig
import space.kscience.maps.features.circle
import space.kscience.maps.features.color
import space.kscience.maps.features.rectangle
import java.nio.file.Path
@Composable
fun rememberDeviceManager(): DeviceManager = remember {
val context = Context {
plugin(DeviceManager)
}
context.request(DeviceManager)
}
@Composable
fun App() {
val scope = rememberCoroutineScope()
val deviceManager = rememberDeviceManager()
val collectiveModel = remember {
generateModel(deviceManager.context)
}
val devices: Map<RemoteDeviceId, RemoteDevice> = remember {
collectiveModel.deviceStates.associate {
val device = RemoteDeviceConstructor(deviceManager.context, it.configuration, it.position, it.velocity)
device.moveInCircles()
it.id to device
}
}
val mapTileProvider = remember {
OpenStreetMapTileProvider(
client = HttpClient(CIO),
cacheDirectory = Path.of("mapCache")
)
}
MapView(
mapTileProvider = mapTileProvider,
config = ViewConfig()
) {
collectiveModel.deviceStates.forEach { device ->
circle(device.position.value, id = device.id + ".position").color(Color.Red)
device.position.valueFlow.onEach {
circle(device.position.value, id = device.id + ".position").color(Color.Red)
}.launchIn(scope)
}
devices.forEach { (id, device) ->
device.propertyFlow(RemoteDevice.position).onEach { position ->
rectangle(position, id = id).color(Color.Blue)
}.launchIn(scope)
}
}
}
fun main() = application {
Window(onCloseRequest = ::exitApplication, title = "Maps-kt demo", icon = painterResource("SPC-logo.png")) {
MaterialTheme {
App()
}
}
}