Skip to content

Commit

Permalink
chore: demonstrate using StreetViewUtils to avoid crashes when adding…
Browse files Browse the repository at this point in the history
… a Street View composable (#435)

* chore: add StreetViewUtil sample

* doc: add documentation

---------

Co-authored-by: Angela Yu <[email protected]>
  • Loading branch information
kikoso and wangela authored Oct 25, 2023
1 parent 99646dd commit f7a2e18
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 37 deletions.
43 changes: 34 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ You no longer need to specify the Maps SDK for Android or its Utility Library as
```groovy
dependencies {
implementation 'com.google.maps.android:maps-compose:3.1.1'
// Optionally, you can include the Compose utils library for Clustering, etc.
// Optionally, you can include the Compose utils library for Clustering,
// Street View metadata checks, etc.
implementation 'com.google.maps.android:maps-compose-utils:3.1.1'
// Optionally, you can include the widgets library for ScaleBar, etc.
Expand Down Expand Up @@ -230,7 +231,16 @@ MarkerInfoWindow(
### Street View

You can add a Street View given a location using the `StreetView` composable.
To use it, provide a `StreetViewPanoramaOptions` object as follows:

1. Test whether a Street View location is valid with the the
`fetchStreetViewData` utility from the [`maps-compose-utils` library](#maps-compose-utility-library).

```kotlin
streetViewResult =
fetchStreetViewData(singapore, BuildConfig.MAPS_API_KEY)
```

2. Once the location is confirmed valid, add a Street View composable by providing a `StreetViewPanoramaOptions` object.

```kotlin
val singapore = LatLng(1.3588227, 103.8742114)
Expand Down Expand Up @@ -264,9 +274,9 @@ GoogleMap(

</details>

## Utility Library
## Maps Compose Utility Library

This library also provides optional utilities in the `maps-compose-utils` library.
This library provides optional utilities in the `maps-compose-utils` library from the [Maps SDK for Android Utility Library](https://github.com/googlemaps/android-maps-utils).

### Clustering

Expand All @@ -289,7 +299,22 @@ Clustering(
)
```

## Widgets
### Street View metadata utility

The `fetchStreetViewData` method provides functionality to check whether a location is supported in StreetView. You can avoid errors when adding a Street View panorama to an Android app by calling this metadata utility and only adding a Street View panorama if the response is OK.

> [!IMPORTANT]
> Be sure to [enable Street View Static API](https://goo.gle/enable-sv-static-api) on the project associated with your API key.
You can see example usage
in the [`StreetViewActivity`](https://github.com/googlemaps/android-maps-compose/blob/main/app/src/main/java/com/google/maps/android/compose/StreetViewActivity.kt) of the demo app:

```kotlin
streetViewResult =
fetchStreetViewData(singapore, BuildConfig.MAPS_API_KEY)
```

## Maps Compose Widgets

This library also provides optional composable widgets in the `maps-compose-widgets` library that you can use alongside the `GoogleMap` composable.

Expand All @@ -304,8 +329,8 @@ The [ScaleBarActivity](app/src/main/java/com/google/maps/android/compose/ScaleBa
Both versions of this widget leverage the `CameraPositionState` in `maps-compose` and therefore are very simple to configure with their defaults:

```kotlin
Box(Modifier.fillMaxSize()) {
Box(Modifier.fillMaxSize()) {

GoogleMap(
modifier = Modifier.fillMaxSize(),
cameraPositionState = cameraPositionState
Expand All @@ -328,7 +353,7 @@ Box(Modifier.fillMaxSize()) {
.align(Alignment.TopStart),
cameraPositionState = cameraPositionState
)
}
}
```

The colors of the text, line, and shadow are also all configurable (e.g., based on `isSystemInDarkTheme()` on a dark map). Similarly, the `DisappearingScaleBar` animations can be configured.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,31 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.google.android.gms.maps.StreetViewPanoramaOptions
import com.google.android.gms.maps.model.LatLng
import com.google.maps.android.Status
import com.google.maps.android.compose.streetview.StreetView
import com.google.maps.android.compose.streetview.rememberStreetViewCameraPositionState
import com.google.maps.android.ktx.MapsExperimentalFeature
import kotlinx.coroutines.launch
import com.google.maps.android.StreetViewUtils.Companion.fetchStreetViewData

class StreetViewActivity : ComponentActivity() {

private val TAG = StreetViewActivity::class.java.simpleName

// This is an invalid location. If you use it instead of Singapore, the StreetViewUtils
// will return NOT_FOUND.
val invalidLocation = LatLng(32.429634, -96.828891)

@OptIn(MapsExperimentalFeature::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setContent {
var isPanningEnabled by remember { mutableStateOf(false) }
var isZoomEnabled by remember { mutableStateOf(false) }
var streetViewResult by remember { mutableStateOf(Status.NOT_FOUND) }

val camera = rememberStreetViewCameraPositionState()
LaunchedEffect(camera) {
launch {
Expand All @@ -69,41 +79,52 @@ class StreetViewActivity : ComponentActivity() {
Log.d(TAG, "Location at: $it")
}
}
launch {
// Be sure to enable the Street View Static API on the project associated with
// this API key using the instructions at https://goo.gle/enable-sv-static-api
streetViewResult =
fetchStreetViewData(singapore, BuildConfig.MAPS_API_KEY)
}
}
Box(Modifier.fillMaxSize(), Alignment.BottomStart) {
StreetView(
Modifier.matchParentSize(),
cameraPositionState = camera,
streetViewPanoramaOptionsFactory = {
StreetViewPanoramaOptions().position(singapore)
},
isPanningGesturesEnabled = isPanningEnabled,
isZoomGesturesEnabled = isZoomEnabled,
onClick = {
Log.d(TAG, "Street view clicked")
},
onLongClick = {
Log.d(TAG, "Street view long clicked")
}
)
Column(
Modifier
.fillMaxWidth()
.background(Color.White)
.padding(8.dp)
) {
StreetViewSwitch(title = "Panning", checked = isPanningEnabled) {
isPanningEnabled = it
}
StreetViewSwitch(title = "Zooming", checked = isZoomEnabled) {
isZoomEnabled = it
if (streetViewResult == Status.OK) {
StreetView(
Modifier.matchParentSize(),
cameraPositionState = camera,
streetViewPanoramaOptionsFactory = {
StreetViewPanoramaOptions().position(singapore)
},
isPanningGesturesEnabled = isPanningEnabled,
isZoomGesturesEnabled = isZoomEnabled,
onClick = {
Log.d(TAG, "Street view clicked")
},
onLongClick = {
Log.d(TAG, "Street view long clicked")
}
)
Column(
Modifier
.fillMaxWidth()
.background(Color.White)
.padding(8.dp)
) {
StreetViewSwitch(title = "Panning", checked = isPanningEnabled) {
isPanningEnabled = it
}
StreetViewSwitch(title = "Zooming", checked = isZoomEnabled) {
isZoomEnabled = it
}
}
} else {
Text("Location not available.")
}
}
}
}
}


@Composable
fun StreetViewSwitch(title: String, checked: Boolean, onCheckedChange: (Boolean) -> Unit) {
Row(Modifier.padding(4.dp)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.maps.android.compose.streetview

import android.content.ComponentCallbacks
Expand All @@ -23,14 +37,17 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import com.google.android.gms.maps.StreetViewPanoramaOptions
import com.google.android.gms.maps.StreetViewPanoramaView
import com.google.android.gms.maps.model.StreetViewPanoramaCamera
import com.google.android.gms.maps.model.StreetViewPanoramaOrientation
import com.google.maps.android.compose.disposingComposition
import com.google.maps.android.ktx.MapsExperimentalFeature
import com.google.maps.android.ktx.awaitStreetViewPanorama

/**
* A composable for displaying a Street View for a given location.
* A composable for displaying a Street View for a given location. A location might not be available for a given
* set of coordinates. We recommend you to check our sample on [StreetViewActivity] using our utility function
* in [StreetViewUtils] to manage non-existing locations.
*
*
*
* @param modifier Modifier to be applied to the StreetView
* @param cameraPositionState the [StreetViewCameraPositionState] to be used to control or observe
Expand Down

0 comments on commit f7a2e18

Please sign in to comment.