Could someone please help me?
I'm trying to create a zoom in and zoom out button, I've tried every possible way but it never works. In Debug, the values of scaleState are updated but the map always remains the same no matter if I click on the Zoom In or Zoom Out button.
Thank you very much for your time and for your help!
@Composable
fun MapPage() {
val context = LocalContext.current
val coroutineScope = rememberCoroutineScope()
ArcGISEnvironment.applicationContext = context.applicationContext
val scaleState = remember { mutableStateOf(1000) }
val locationDisplay = rememberLocationDisplay().apply {
setAutoPanMode(LocationDisplayAutoPanMode.Recenter)
}
val requestPermission = remember { mutableStateOf(false) }
if (checkPermissions(context)) {
LaunchedEffect(Unit) {
locationDisplay.dataSource.start()
}
} else {
requestPermission.value = true
}
if (requestPermission.value) {
RequestPermissions(
context = context,
onPermissionsGranted = {
coroutineScope.launch {
locationDisplay.dataSource.start()
requestPermission.value = false
}
}
)
}
val map = remember {
createMap(scaleState.value)
}
Scaffold(
topBar = {
// Add a top bar (optional)
},
content = {
Box(modifier = Modifier.fillMaxSize()) {
MapView(
modifier = Modifier
.fillMaxSize()
.padding(it),
arcGISMap = map,
locationDisplay = locationDisplay,
)
Box(
modifier = Modifier
.align(Alignment.BottomEnd)
.padding(10.dp)
.padding(bottom = 200.dp)
) {
Column {
IconButton(onClick = {
coroutineScope.launch {
locationDisplay.setAutoPanMode(LocationDisplayAutoPanMode.Recenter)
locationDisplay.dataSource.start()
}
}) {
Icon(
Icons.Rounded.LocationOn,
contentDescription = "Center on current location"
)
}
IconButton(onClick = {
coroutineScope.launch {
scaleState.value *= 2
}
}) {
Icon(
Icons.Rounded.KeyboardArrowUp,
contentDescription = "Zoom In"
)
}
IconButton(onClick = {
coroutineScope.launch {
if (scaleState.value / 2 > 0) {
scaleState.value /= 2
}
}
}) {
Icon(
Icons.Rounded.KeyboardArrowDown,
contentDescription = "Zoom Out"
)
}
}
}
}
}
)
}
fun createMap(scale: Int): ArcGISMap {
val busStopUrl =
"https://labgeo3.recife.ifpe.edu.br/server/rest/services/Sigabem_2021_2022/bdlabgeo_gisadmin_Paradas_Onibus_2023/FeatureServer/0"
// Create feature table and feature layer
val serviceFeatureTable = ServiceFeatureTable(busStopUrl)
val featureLayer = FeatureLayer.createWithFeatureTable(serviceFeatureTable)
// Create map and add feature layer
return ArcGISMap(BasemapStyle.ArcGISTopographic).apply {
initialViewpoint = Viewpoint(
latitude = -8.0475622,
longitude = -34.8769643,
scale = scale.toDouble()
)
operationalLayers.add(featureLayer)
}
}
fun checkPermissions(context: Context): Boolean {
// Check permissions to see if both permissions are granted.
// Coarse location permission.
val permissionCheckCoarseLocation = ContextCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_COARSE_LOCATION
) == PackageManager.PERMISSION_GRANTED
// Fine location permission.
val permissionCheckFineLocation = ContextCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
return permissionCheckCoarseLocation && permissionCheckFineLocation
}
@Composable
fun RequestPermissions(context: Context, onPermissionsGranted: () -> Unit) {
// Create an activity result launcher using permissions contract and handle the result.
val activityResultLauncher = rememberLauncherForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
) { permissions ->
// Check if both fine & coarse location permissions are true.
if (permissions.all { it.value }) {
onPermissionsGranted()
} else {
showError(context, "Location permissions were denied")
}
}
LaunchedEffect(Unit) {
activityResultLauncher.launch(
// Request both fine and coarse location permissions.
arrayOf(
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION
)
)
}
}
fun showError(context: Context, message: String) {
// Show an error message
Toast.makeText(context, message, Toast.LENGTH_LONG).show()
}
Hello @allamymp ,
It seems that you are not applying the new value on the MapView after you change it. This should be done through the MapViewProxy
You will first have to define a MapViewProxy instance, then in your zoom buttons you'll have to set the new scale value, as such:
IconButton(onClick = {
...
coroutineScope.launch {
...
mapViewProxy.setViewpointScale((scaleState.value))
}
...