Toom to selected Feature

This commit is contained in:
2025-12-18 11:10:48 +01:00
parent 1c5d43bb02
commit a5f8746fc4
4 changed files with 87 additions and 10 deletions

View File

@@ -36,6 +36,11 @@ fun MainScreen(modifier: Modifier = Modifier, application: Application) {
var selectedIndex by remember { mutableStateOf(0) } var selectedIndex by remember { mutableStateOf(0) }
val mapViewModel = remember { MapViewModel(application) }
val listViewModel = remember { ListViewModel(application) }
var selectedObjectId by remember { mutableStateOf<Int?>(null) }
Scaffold(modifier = Modifier.fillMaxSize(), Scaffold(modifier = Modifier.fillMaxSize(),
bottomBar = { bottomBar = {
NavigationBar { NavigationBar {
@@ -52,18 +57,36 @@ fun MainScreen(modifier: Modifier = Modifier, application: Application) {
} }
}) { }) {
innerPadding -> innerPadding ->
ContentScreen(modifier = Modifier.padding(innerPadding), selectedIndex, application) ContentScreen(modifier = Modifier.padding(innerPadding),
selectedIndex,
mapViewModel,
listViewModel,
selectedObjectId,
onFeatureSelected = { objectId ->
selectedObjectId = objectId
selectedIndex = 0
},
onObjectIdUsed = {
selectedObjectId = null
})
} }
} }
@Composable @Composable
fun ContentScreen(modifier: Modifier = Modifier, selectedIndex: Int, application: Application) { fun ContentScreen(
val mapViewModel = remember { MapViewModel(application) } modifier: Modifier = Modifier,
val listViewModel = remember { ListViewModel(application) } selectedIndex: Int,
mapViewModel: MapViewModel,
listViewModel: ListViewModel,
selectedObjectId: Int?,
onFeatureSelected: (Int) -> Unit,
onObjectIdUsed: () -> Unit
) {
when(selectedIndex) { when(selectedIndex) {
0 -> MapPage(modifier = modifier, mapViewModel = mapViewModel) 0 -> MapPage(modifier = modifier, mapViewModel = mapViewModel,selectedObjectId=selectedObjectId, onObjectIdUsed = onObjectIdUsed)
1 -> CreatePage(modifier = modifier, mapViewModel = mapViewModel) 1 -> CreatePage(modifier = modifier, mapViewModel = mapViewModel)
2 -> ListPage(modifier = modifier, listViewModel = listViewModel) 2 -> ListPage(modifier = modifier, listViewModel = listViewModel, onFeatureClick = onFeatureSelected)
3 -> SettingsPage() 3 -> SettingsPage()
} }
} }

View File

@@ -10,6 +10,7 @@ import androidx.lifecycle.viewModelScope
import com.arcgismaps.LoadStatus import com.arcgismaps.LoadStatus
import com.arcgismaps.data.ArcGISFeature import com.arcgismaps.data.ArcGISFeature
import com.arcgismaps.data.CodedValueDomain import com.arcgismaps.data.CodedValueDomain
import com.arcgismaps.data.QueryParameters
import com.arcgismaps.data.ServiceFeatureTable import com.arcgismaps.data.ServiceFeatureTable
import com.arcgismaps.geometry.GeometryEngine import com.arcgismaps.geometry.GeometryEngine
import com.arcgismaps.geometry.Point import com.arcgismaps.geometry.Point
@@ -336,6 +337,28 @@ class MapViewModel(application: Application): AndroidViewModel(application) {
} }
} }
} }
fun zoomToFeature(objectId: Int){
viewModelScope.launch {
val queryParameters = QueryParameters().apply {
whereClause = "OBJECTID = ${objectId}"
}
serviceFeatureTable.queryFeatures(queryParameters).onSuccess {
featureResult ->
val feature = featureResult.firstOrNull() as? ArcGISFeature
feature?.let{ feature->
feature.geometry?.let{ geometry ->
mapViewProxy.setViewpointGeometry(geometry,50.0)
}
featureLayer.clearSelection()
featureLayer.selectFeature(feature)
selectedFeature = feature
}
}.onFailure { error ->
snackBarMessage = "Feature nicht gefunden!"
}
}
}
} }
enum class FeatureOperationType(val operationName: String, val instruction: String) { enum class FeatureOperationType(val operationName: String, val instruction: String) {

View File

@@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Divider
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@@ -19,7 +20,7 @@ import de.jadehs.strassenschadenpro2.Feature
import de.jadehs.strassenschadenpro2.ListViewModel import de.jadehs.strassenschadenpro2.ListViewModel
@Composable @Composable
fun ListPage(modifier: Modifier = Modifier, listViewModel: ListViewModel) { fun ListPage(modifier: Modifier = Modifier, listViewModel: ListViewModel, onFeatureClick: (Int) -> Unit) {
val features = listViewModel.features.collectAsState() val features = listViewModel.features.collectAsState()
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
listViewModel.fetch() listViewModel.fetch()
@@ -30,7 +31,9 @@ fun ListPage(modifier: Modifier = Modifier, listViewModel: ListViewModel) {
items(features.value){ feature -> items(features.value){ feature ->
FeatureItem(feature = feature, FeatureItem(feature = feature,
onClick = { onClick = {
feature.properties?.OBJECTID?.let { objectId ->
onFeatureClick(objectId)
}
} }
) )
} }
@@ -52,5 +55,23 @@ fun FeatureItem(feature: Feature, onClick: () -> Unit){
text = "Beschreibung: ${feature.properties?.Beschreibung ?: "-"}", text = "Beschreibung: ${feature.properties?.Beschreibung ?: "-"}",
style = MaterialTheme.typography.bodyMedium style = MaterialTheme.typography.bodyMedium
) )
val coords = feature.geometry?.coordinates
val coordsText = if (coords != null && coords.size == 2) "${coords[0]}, ${coords[1]}" else "-"
Text(
text = "Koordinaten: ${coordsText}",
style = MaterialTheme.typography.bodySmall
)
Divider(modifier = Modifier.padding(top= 12.dp))
} }
} }

View File

@@ -40,7 +40,10 @@ import de.jadehs.strassenschadenpro2.components.DropDownMenuBox
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@Composable @Composable
fun MapPage(modifier: Modifier = Modifier, mapViewModel: MapViewModel) { fun MapPage(modifier: Modifier = Modifier,
mapViewModel: MapViewModel,
selectedObjectId: Int? = null,
onObjectIdUsed: () -> Unit = {}) {
val context = LocalContext.current val context = LocalContext.current
val coroutineScope = rememberCoroutineScope() val coroutineScope = rememberCoroutineScope()
@@ -55,6 +58,13 @@ fun MapPage(modifier: Modifier = Modifier, mapViewModel: MapViewModel) {
setAutoPanMode(LocationDisplayAutoPanMode.Off) setAutoPanMode(LocationDisplayAutoPanMode.Off)
} }
LaunchedEffect(selectedObjectId) {
selectedObjectId?.let{
mapViewModel.zoomToFeature(selectedObjectId)
onObjectIdUsed()
}
}
if (checkPermissions(context)) { if (checkPermissions(context)) {
// Permissions are already granted. // Permissions are already granted.
LaunchedEffect(Unit) { LaunchedEffect(Unit) {