Last active
December 11, 2023 21:06
-
-
Save nirbhayph/91bc8dae56bf078ff2b007b4a55edc96 to your computer and use it in GitHub Desktop.
Google Maps and Jetpack Compose
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Composable | |
fun CircleMap() { | |
// Define the coordinates for circle centers and their associated information | |
val circleData = listOf( | |
CircleInfo("Park A", LatLng(37.7749, -122.4194), "This is Park A"), | |
CircleInfo("Park B", LatLng(36.7783, -119.4179), "This is Park B"), | |
CircleInfo("Park C", LatLng(34.0522, -118.2437), "This is Park C") | |
) | |
// Create a mutable state to track the selected circle | |
var selectedCircle by remember { mutableStateOf<CircleInfo?>(null) } | |
val cameraPositionState = rememberCameraPositionState { | |
position = CameraPosition.fromLatLngZoom(LatLng(36.7783, -119.4179), 11f) | |
} | |
GoogleMap( | |
modifier = Modifier.fillMaxSize(), | |
cameraPositionState = cameraPositionState | |
) { | |
// Draw clickable circles for each location | |
circleData.forEach { circleInfo -> | |
Circle( | |
center = circleInfo.center, | |
clickable = true, | |
fillColor = Color.Blue.copy(alpha = 0.3f), | |
radius = 5000.0, // Specify the radius in meters | |
strokeColor = Color.Black, | |
strokeWidth = 2f, | |
tag = circleInfo, | |
onClick = { circle -> | |
// Handle circle click event | |
selectedCircle = circle.tag as? CircleInfo | |
} | |
) | |
} | |
} | |
// Display information about the selected circle | |
selectedCircle?.let { circle -> | |
Box( | |
contentAlignment = Alignment.TopCenter, | |
modifier = Modifier.offset(y = 24.dp) | |
) { | |
Column( | |
modifier = Modifier | |
.wrapContentHeight() | |
.width(350.dp) | |
.clip(RoundedCornerShape(10)) | |
.background(Color.DarkGray) | |
.padding(20.dp) | |
) { | |
Text(text = circle.name, style = TextStyle(fontSize = 20.sp)) | |
Spacer(modifier = Modifier.height(8.dp)) | |
Text(text = circle.description, style = TextStyle(fontSize = 16.sp)) | |
} | |
} | |
} | |
} | |
data class CircleInfo(val name: String, val center: LatLng, val description: String) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Composable | |
fun MapScreenWithCustomMarker() { | |
val philipineSea = LatLng(20.302039, 134.2082661) | |
val cameraPositionState = rememberCameraPositionState { | |
position = CameraPosition.fromLatLngZoom(philipineSea, 2f) | |
} | |
GoogleMap( | |
modifier = Modifier.fillMaxSize(), | |
cameraPositionState = cameraPositionState | |
) { | |
Marker( | |
state = MarkerState(position = LatLng(-34.0, 151.0)), | |
title = "Marker in Sydney" | |
) | |
Marker( | |
state = MarkerState(position = LatLng(35.66, 139.6)), | |
title = "Marker in Tokyo" | |
) | |
MarkerComposable( | |
state = MarkerState(position = LatLng(11.6600892, 117.3276336)), | |
) { | |
Icon( | |
imageVector = Icons.Filled.Star, | |
contentDescription = "Philippines", | |
tint = Color.Blue, | |
modifier = Modifier.size(64.dp) | |
) | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Composable | |
fun MapScreenWithMarkerInfoWindow() { | |
val philipineSea = LatLng(20.302039, 134.2082661) | |
val cameraPositionState = rememberCameraPositionState { | |
position = CameraPosition.fromLatLngZoom(philipineSea, 2f) | |
} | |
val markerState = MarkerState(LatLng(14.5892056, 120.9646546)) | |
GoogleMap( | |
modifier = Modifier.fillMaxSize(), | |
cameraPositionState = cameraPositionState | |
) { | |
MarkerInfoWindow( | |
state = markerState, | |
icon = bitmapDescriptorFromVector(LocalContext.current, R.drawable.baseline_location_city_24) | |
) { | |
Column( | |
horizontalAlignment = Alignment.CenterHorizontally, | |
verticalArrangement = Arrangement.Center, | |
modifier = Modifier | |
.border( | |
BorderStroke(1.dp, Color.Black), | |
RoundedCornerShape(10) | |
) | |
.clip(RoundedCornerShape(10)) | |
.background(Color.Red) | |
.padding(20.dp) | |
) { | |
Icon( | |
Icons.Filled.Info, | |
contentDescription = null, | |
modifier = Modifier.size(36.dp) | |
) | |
Text("Manila", fontWeight = FontWeight.Bold) | |
Text("Capital of the Philippines", fontWeight = FontWeight.Medium) | |
} | |
} | |
} | |
} | |
// from stack overflow - https://stackoverflow.com/a/45564994 | |
private fun bitmapDescriptorFromVector(context: Context, vectorResId: Int): BitmapDescriptor? { | |
return ContextCompat.getDrawable(context, vectorResId)?.run { | |
setBounds(0, 0, intrinsicWidth, intrinsicHeight) | |
val bitmap = Bitmap.createBitmap(intrinsicWidth, intrinsicHeight, Bitmap.Config.ARGB_8888) | |
draw(Canvas(bitmap)) | |
BitmapDescriptorFactory.fromBitmap(bitmap) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Composable | |
fun MapWithSwitchableProperties() { | |
val mumbai = LatLng(19.0760, 72.8777) | |
val cameraPositionState = rememberCameraPositionState { | |
position = CameraPosition.fromLatLngZoom(mumbai, 11f) | |
} | |
var uiSettings by remember { mutableStateOf(MapUiSettings(zoomControlsEnabled = true)) } | |
var properties by remember { | |
mutableStateOf(MapProperties(mapType = MapType.TERRAIN)) | |
} | |
Box(Modifier.fillMaxSize()) { | |
GoogleMap( | |
modifier = Modifier.matchParentSize(), | |
cameraPositionState = cameraPositionState, | |
properties = properties, | |
uiSettings = uiSettings | |
) | |
Switch( | |
modifier = Modifier | |
.align(Alignment.BottomCenter) | |
.padding(vertical = 16.dp), | |
checked = uiSettings.zoomControlsEnabled, | |
onCheckedChange = { | |
uiSettings = uiSettings.copy(zoomControlsEnabled = it) | |
properties = if (it) { | |
properties.copy(mapType = MapType.TERRAIN) | |
} else { | |
properties.copy(mapType = MapType.SATELLITE) | |
} | |
} | |
) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Composable | |
fun MapScreenWithMarker() { | |
// change color of the marker | |
// implement onClick with popup composable | |
val philipineSea = LatLng(20.302039, 134.2082661) | |
val cameraPositionState = rememberCameraPositionState { | |
position = CameraPosition.fromLatLngZoom(philipineSea, 2f) | |
} | |
GoogleMap( | |
modifier = Modifier.fillMaxSize(), | |
cameraPositionState = cameraPositionState | |
) { | |
Marker( | |
state = MarkerState(position = LatLng(-34.0, 151.0)), | |
title = "Marker in Sydney" | |
) | |
Marker( | |
state = MarkerState(position = LatLng(35.66, 139.6)), | |
title = "Marker in Tokyo" | |
) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Composable | |
fun MapScreenWithPhotoMarkers() { | |
val center = LatLng(38.7319874, -109.7504477) | |
val cameraPositionState = rememberCameraPositionState { | |
position = CameraPosition.fromLatLngZoom(center, 10f) | |
} | |
val arches = MarkerState(position = LatLng(38.7319874, -109.7504477)) | |
val canyonLands = MarkerState(position = LatLng(38.5348271, -109.816405)) | |
val archesIconState = remember { mutableStateOf<BitmapDescriptor?>(null) } | |
val canyonIconState = remember { mutableStateOf<BitmapDescriptor?>(null) } | |
val context = LocalContext.current | |
LaunchedEffect(key1 = Unit, block = { | |
archesIconState.value = loadBitmapDescriptorFromUrl( | |
context, | |
"https://source.unsplash.com/random/128x128/?arches%20national%20park" | |
) | |
canyonIconState.value = loadBitmapDescriptorFromUrl( | |
context, | |
"https://source.unsplash.com/random/128x128/?canyon%20national%20park" | |
) | |
}) | |
GoogleMap( | |
modifier = Modifier.fillMaxSize(), | |
cameraPositionState = cameraPositionState | |
) { | |
archesIconState.value?.let { | |
Marker(state = arches, icon = it) | |
} | |
canyonIconState.value?.let { | |
Marker(state = canyonLands, icon = it) | |
} | |
} | |
} | |
suspend fun loadBitmapDescriptorFromUrl(context: Context, imageUrl: String): BitmapDescriptor { | |
return withContext(Dispatchers.IO) { | |
Glide.with(context) | |
.asBitmap() | |
.load(imageUrl) | |
.circleCrop() | |
.submit() | |
.get() | |
} | |
.let { bitmap -> | |
val resizedBitmap = Bitmap.createScaledBitmap(bitmap, 130, 130, false) | |
BitmapDescriptorFactory.fromBitmap(resizedBitmap) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Composable | |
fun MapWithPolygon() { | |
val polygonPoints = listOf( | |
LatLng(37.7749, -122.4194), | |
LatLng(37.8049, -122.4400), | |
LatLng(37.7949, -122.4100) | |
) | |
// Create a mutable state to track whether the polygon is selected | |
var isPolygonSelected by remember { mutableStateOf(false) } | |
GoogleMap( | |
modifier = Modifier.fillMaxSize(), | |
cameraPositionState = rememberCameraPositionState { | |
position = CameraPosition.fromLatLngZoom(LatLng(37.7749, -122.4194), 13f) | |
} | |
) { | |
Polygon( | |
points = polygonPoints, | |
clickable = true, | |
fillColor = if (isPolygonSelected) Color.Red else Color.Green, | |
strokeColor = Color.Blue, | |
strokeWidth = 5f, | |
tag = "San Francisco", | |
onClick = { polygon -> | |
// Handle polygon click event | |
isPolygonSelected = true | |
} | |
) | |
} | |
// Add a button to reset the selection | |
Box(contentAlignment = Alignment.BottomCenter) { | |
Button( | |
onClick = { | |
isPolygonSelected = false | |
}, | |
modifier = Modifier | |
.padding(16.dp) | |
) { | |
Text("Reset Selection") | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Composable | |
fun RouteMap() { | |
// Define the coordinates for a route as a list of LatLng points | |
val routeCoordinates = listOf( | |
LatLng(37.7749, -122.4194), // Starting point (e.g., San Francisco) | |
LatLng(36.7783, -119.4179), // Waypoint 1 | |
LatLng(34.0522, -118.2437), // Waypoint 2 (e.g., Los Angeles) | |
LatLng(32.7157, -117.1611) // Ending point (e.g., San Diego) | |
) | |
// Create a mutable state to track the selected route | |
var selectedRoute by remember { mutableStateOf<Route?>(null) } | |
val cameraPositionState = rememberCameraPositionState { | |
position = CameraPosition.fromLatLngZoom(LatLng(36.7783, -119.4179), 6f) | |
} | |
GoogleMap( | |
modifier = Modifier.fillMaxSize(), | |
cameraPositionState = cameraPositionState | |
) { | |
// Draw the route polyline | |
Polyline( | |
points = routeCoordinates, | |
clickable = true, | |
color = Color.Blue, | |
width = 5f, | |
tag = CaliforniaRoute, | |
onClick = { polyline -> | |
// Handle polyline click event | |
selectedRoute = polyline.tag as? Route | |
} | |
) | |
} | |
// Display information about the selected route | |
selectedRoute?.let { route -> | |
Box( | |
contentAlignment = Alignment.TopCenter, | |
modifier = Modifier.offset(y = 24.dp) | |
) { | |
Column( | |
modifier = Modifier | |
.wrapContentHeight() | |
.width(350.dp) | |
.clip(RoundedCornerShape(10)) | |
.background(Color.DarkGray) | |
.padding(20.dp) | |
) { | |
Text(text = route.name, style = TextStyle(fontSize = 20.sp)) | |
Spacer(modifier = Modifier.height(8.dp)) | |
Text(text = route.description, style = TextStyle(fontSize = 16.sp)) | |
} | |
} | |
} | |
} | |
data class Route(val name: String, val description: String) | |
val CaliforniaRoute = Route( | |
name = "California Road Trip", | |
description = "Explore the beautiful coast of California on this scenic road trip from San Francisco to San Diego." | |
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Composable | |
fun MapScreen() { | |
val mumbai = LatLng(19.0760, 72.8777) | |
val cameraPositionState = rememberCameraPositionState { | |
position = CameraPosition.fromLatLngZoom(mumbai, 11f) | |
} | |
GoogleMap( | |
modifier = Modifier.fillMaxSize(), | |
cameraPositionState = cameraPositionState | |
) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Composable | |
fun StreetViewExplorer() { | |
// Define the location for the Street View Panorama | |
val constitutionAve = LatLng(38.8921, -77.0067) // Example: DC | |
StreetView( | |
streetViewPanoramaOptionsFactory = { | |
StreetViewPanoramaOptions().position(constitutionAve) | |
}, | |
isPanningGesturesEnabled = true, | |
isStreetNamesEnabled = true, | |
isUserNavigationEnabled = true, | |
isZoomGesturesEnabled = true | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment