I will point the camera to the coordinates according to the existing API. but only the marker can go to the coordinates but not the camera.
Please help
I include my code snippet
// Membuat objek LatLng dari nilai latitude dan longitude
val coordinatesStr = gempaInfo?.infogempa?.gempa?.coordinates
val (latitudeStr, longitudeStr) = coordinatesStr?.split(",") ?: listOf("0.0", "0.0")
val latitude = latitudeStr.trim().toDoubleOrNull() ?: 0.0
val longitude = longitudeStr.trim().toDoubleOrNull() ?: 0.0
val koordinat = LatLng(latitude, longitude)
val cameraPositionState = rememberCameraPositionState {
position = CameraPosition.fromLatLngZoom(koordinat, 10f)
}
// Menampilkan peta Google dengan marker di koordinat
GoogleMap(
modifier = Modifier.fillMaxSize(),
cameraPositionState = cameraPositionState
) {
Marker(
state = MarkerState(position = koordinat),
title = "Lokasi Gempa",
snippet = "Marker di lokasi gempa"
)
}
I want when the map is loaded it will automatically point to the coordinates according to what has been created by the API
Does val coordinatesStr = gempaInfo?.infogempa?.gempa?.coordinates
ever change? If gempaInfo
is static, your code should work. If it changes, you will have to observe gempInfo
and update the cameraPositionState.
For example
val scope = rememberCoroutineScope()
LaunchedEffect(gempaInfo) {
val koordinat = gempaInfo?.infogempa?.gempa?.coordinates
?.split(",")
?.map { it.trim().toDoubleOrNull() ?: 0.0 }
?.let { coords -> LatLng(coords[0], coords[1]) } ?: LatLng(0.0. 0.0)
scope.launch {
cameraPositionState.animate(
update = CameraUpdateFactory.newLatLngBounds(boundingBox, 64),
durationMs = 1000
)
}
}
Here is a longer example that makes use of Kotlin flows to jump around. Notice that the data is cleaned up before getting to the GoogleMap. (In general, apps should only send cleaned up data to the UI.)
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
val locationStrings = listOf(
null,
"39.9559152,-105.2938497",
"39.429725,-105.080054",
"39.9559152",
"null,no op",
" 38.839155 , -105.0345258 ",
)
val locFlow = MutableStateFlow(LatLng(0.0, 0.0))
val context = LocalContext.current
LaunchedEffect(Unit) {
while (true) {
locationStrings.asFlow()
.onEach {
delay(5.seconds)
Log.w("LocationFollower", "Location: $it")
}
.mapNotNull { locationString ->
locationString?.split(",")
?.mapNotNull { it.trim().toDoubleOrNull() }
?.takeIf { it.size == 2 }
?.let { (lat, lng) ->
LatLng(lat, lng)
} ?: run {
Log.w("LocationFollower", "Invalid location: $locationString")
Toast.makeText(
context,
"Invalid location: $locationString",
Toast.LENGTH_SHORT
).show()
null
}
}.collect {
locFlow.value = it
}
}
}
LocationFollowerTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
val location by locFlow.collectAsState(initial = LatLng(0.0, 0.0))
MyMap(modifier = Modifier.padding(innerPadding), location = location)
}
}
}
}
}
@Composable
fun MyMap(modifier: Modifier, location: LatLng) {
val cameraPositionState = rememberCameraPositionState {
position = CameraPosition.fromLatLngZoom(location, 15f)
}
val scope = rememberCoroutineScope()
val markerState = rememberMarkerState(position = location)
LaunchedEffect(location) {
scope.launch {
cameraPositionState.animate(
CameraUpdateFactory.newCameraPosition(
CameraPosition.fromLatLngZoom(location, 15f)
),
2.seconds.inWholeMilliseconds.toInt()
)
}
markerState.position = location
}
GoogleMap(
modifier = modifier,
cameraPositionState = cameraPositionState
) {
Marker(
state = markerState,
title = "Marker",
)
}
}