diff --git a/README.md b/README.md
index 6bfb3245..d31dcb5c 100644
--- a/README.md
+++ b/README.md
@@ -199,6 +199,38 @@ and don't use `Marker` composables (unless you don't care about `onClick`
events). Clustering is the only use-case tested with `MapEffect`, there may be
gotchas depending on what features you use in the utility library.
+## Widgets
+
+This library also provides optional composable widgets in the `maps-compose-widgets` library that you can use alongside the `GoogleMap` composable.
+
+### ScaleBar
+
+This widget shows the current scale of the map in feet and meters when zoomed into the map, changing to miles and kilometers, respectively, when zooming out. A `DisappearingScaleBar` is also included, which appears when the zoom level of the map changes, and then disappears after a configurable timeout period.
+
+The [ScaleBarActivity](app/src/main/java/com/google/maps/android/compose/ScaleBarActivity.kt) demonstrates both of these, with the `DisappearingScaleBar` in the upper left corner and the normal base `ScaleBar` in the upper right:
+
+![maps-compose-scale-bar-cropped](https://user-images.githubusercontent.com/928045/175665891-a0635004-2201-4392-83b3-0c6553b96926.gif)
+
+Both versions of this widget leverage the `CameraPositionState` in `maps-compose` and therefore are very simple to configure with their defaults:
+
+```kotlin
+ScaleBar(
+ modifier = Modifier
+ .padding(top = 5.dp, end = 15.dp)
+ .align(Alignment.TopEnd),
+ cameraPositionState = cameraPositionState
+)
+
+DisappearingScaleBar(
+ modifier = Modifier
+ .padding(top = 5.dp, end = 15.dp)
+ .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.
+
## Sample App
This repository includes a [sample app](app).
@@ -218,7 +250,10 @@ dependencies {
implementation 'com.google.android.gms:play-services-maps:18.0.2'
// Also include Compose version `1.2.0-alpha03` or higher - for example:
- implementation "androidx.compose.foundation:foundation:2.4.0-alpha03"
+ implementation 'androidx.compose.foundation:foundation:2.4.0-alpha03'
+
+ // Optionally, you can include the widgets library if you want to use ScaleBar, etc.
+ implementation 'com.google.maps.android:maps-compose-widgets:1.0.0'
}
```
diff --git a/app/build.gradle b/app/build.gradle
index 68f34789..c979f201 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -59,6 +59,8 @@ dependencies {
// declaration if you want to test the sample app with a Maven Central release of the library.
//implementation "com.google.maps.android:maps-compose:2.2.1"
implementation project(':maps-compose')
+ //implementation "com.google.maps.android:maps-compose-widgets:1.0.0"
+ implementation project(':maps-compose-widgets')
implementation 'com.google.android.gms:play-services-maps:18.0.2'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 69904cab..7532eb52 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -52,6 +52,9 @@
+
diff --git a/app/src/main/java/com/google/maps/android/compose/MainActivity.kt b/app/src/main/java/com/google/maps/android/compose/MainActivity.kt
index ad7a75b0..4ca344be 100644
--- a/app/src/main/java/com/google/maps/android/compose/MainActivity.kt
+++ b/app/src/main/java/com/google/maps/android/compose/MainActivity.kt
@@ -81,6 +81,13 @@ class MainActivity : ComponentActivity() {
}) {
Text(getString(R.string.location_tracking_activity))
}
+ Spacer(modifier = Modifier.padding(5.dp))
+ Button(
+ onClick = {
+ context.startActivity(Intent(context, ScaleBarActivity::class.java))
+ }) {
+ Text(getString(R.string.scale_bar_activity))
+ }
}
}
}
diff --git a/app/src/main/java/com/google/maps/android/compose/ScaleBarActivity.kt b/app/src/main/java/com/google/maps/android/compose/ScaleBarActivity.kt
new file mode 100644
index 00000000..ca3e7266
--- /dev/null
+++ b/app/src/main/java/com/google/maps/android/compose/ScaleBarActivity.kt
@@ -0,0 +1,99 @@
+// Copyright 2022 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
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.animation.EnterTransition
+import androidx.compose.animation.fadeOut
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.wrapContentSize
+import androidx.compose.material.CircularProgressIndicator
+import androidx.compose.material.MaterialTheme
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import com.google.android.gms.maps.model.CameraPosition
+import com.google.android.gms.maps.model.LatLng
+import com.google.maps.android.compose.widgets.DisappearingScaleBar
+import com.google.maps.android.compose.widgets.ScaleBar
+
+private const val TAG = "ScaleBarActivity"
+
+private const val zoom = 8f
+private val singapore = LatLng(1.35, 103.87)
+private val defaultCameraPosition = CameraPosition.fromLatLngZoom(singapore, zoom)
+
+class ScaleBarActivity : ComponentActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ setContent {
+ var isMapLoaded by remember { mutableStateOf(false) }
+
+ // To control and observe the map camera
+ val cameraPositionState = rememberCameraPositionState {
+ position = defaultCameraPosition
+ }
+
+ Box(Modifier.fillMaxSize()) {
+ GoogleMap(
+ modifier = Modifier.matchParentSize(),
+ cameraPositionState = cameraPositionState,
+ onMapLoaded = {
+ isMapLoaded = true
+ }
+ )
+ DisappearingScaleBar(
+ modifier = Modifier
+ .padding(top = 5.dp, end = 15.dp)
+ .align(Alignment.TopStart),
+ cameraPositionState = cameraPositionState
+ )
+ ScaleBar(
+ modifier = Modifier
+ .padding(top = 5.dp, end = 15.dp)
+ .align(Alignment.TopEnd),
+ cameraPositionState = cameraPositionState
+ )
+ if (!isMapLoaded) {
+ AnimatedVisibility(
+ modifier = Modifier
+ .matchParentSize(),
+ visible = !isMapLoaded,
+ enter = EnterTransition.None,
+ exit = fadeOut()
+ ) {
+ CircularProgressIndicator(
+ modifier = Modifier
+ .background(MaterialTheme.colors.background)
+ .wrapContentSize()
+ )
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 49f6e6e9..51a91f28 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -21,4 +21,5 @@
Map In Column
Map Clustering
Location Tracking
+ Scale Bar
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index cb30c3ae..0566fd47 100644
--- a/build.gradle
+++ b/build.gradle
@@ -21,7 +21,7 @@ plugins {
}
ext.projectArtifactId = { project ->
- if (project.name == 'maps-compose') {
+ if (project.name == 'maps-compose' || project.name == 'maps-compose-widgets') {
return project.name
} else {
return null
diff --git a/maps-compose-widgets/.gitignore b/maps-compose-widgets/.gitignore
new file mode 100644
index 00000000..42afabfd
--- /dev/null
+++ b/maps-compose-widgets/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/maps-compose-widgets/build.gradle b/maps-compose-widgets/build.gradle
new file mode 100644
index 00000000..a3dc1b8f
--- /dev/null
+++ b/maps-compose-widgets/build.gradle
@@ -0,0 +1,51 @@
+plugins {
+ id 'kotlin-android'
+ id 'kotlin-parcelize'
+}
+
+android {
+ compileSdk 31
+
+ defaultConfig {
+ minSdk 21
+ targetSdk 31
+ versionCode 1
+ versionName "1.0"
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+
+ composeOptions {
+ kotlinCompilerExtensionVersion "$compose_version"
+ }
+
+ buildFeatures {
+ buildConfig false
+ compose true
+ }
+
+ kotlinOptions {
+ jvmTarget = '1.8'
+ freeCompilerArgs += '-Xexplicit-api=strict'
+ freeCompilerArgs += '-Xopt-in=kotlin.RequiresOptIn'
+ }
+}
+
+dependencies {
+ implementation "androidx.compose.foundation:foundation:$compose_version"
+ implementation project(':maps-compose')
+ implementation 'androidx.compose.material:material:1.1.1'
+ implementation 'androidx.core:core-ktx:1.7.0'
+ implementation 'com.google.android.gms:play-services-maps:18.0.2'
+ implementation 'com.google.maps.android:maps-ktx:3.4.0'
+ implementation 'com.google.maps.android:maps-utils-ktx:3.3.0'
+
+ testImplementation 'junit:junit:4.13.2'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.3'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
+ implementation "androidx.core:core-ktx:1.7.0"
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+}
\ No newline at end of file
diff --git a/maps-compose-widgets/consumer-rules.pro b/maps-compose-widgets/consumer-rules.pro
new file mode 100644
index 00000000..e69de29b
diff --git a/maps-compose-widgets/proguard-rules.pro b/maps-compose-widgets/proguard-rules.pro
new file mode 100644
index 00000000..481bb434
--- /dev/null
+++ b/maps-compose-widgets/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/maps-compose-widgets/src/androidTest/java/com/google/maps/android/compose/widgets/ExampleInstrumentedTest.kt b/maps-compose-widgets/src/androidTest/java/com/google/maps/android/compose/widgets/ExampleInstrumentedTest.kt
new file mode 100644
index 00000000..509b3912
--- /dev/null
+++ b/maps-compose-widgets/src/androidTest/java/com/google/maps/android/compose/widgets/ExampleInstrumentedTest.kt
@@ -0,0 +1,36 @@
+// Copyright 2021 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.widgets
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.platform.app.InstrumentationRegistry
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+@RunWith(AndroidJUnit4::class)
+internal class ExampleInstrumentedTest {
+ @Test
+ fun useAppContext() {
+ // Context of the app under test.
+ val appContext = InstrumentationRegistry.getInstrumentation().targetContext
+ assertEquals("com.google.maps.android.compose.widgets.test", appContext.packageName)
+ }
+}
\ No newline at end of file
diff --git a/maps-compose-widgets/src/main/AndroidManifest.xml b/maps-compose-widgets/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..7931c287
--- /dev/null
+++ b/maps-compose-widgets/src/main/AndroidManifest.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/maps-compose-widgets/src/main/java/com/google/maps/android/compose/widgets/ScaleBar.kt b/maps-compose-widgets/src/main/java/com/google/maps/android/compose/widgets/ScaleBar.kt
new file mode 100644
index 00000000..d988268d
--- /dev/null
+++ b/maps-compose-widgets/src/main/java/com/google/maps/android/compose/widgets/ScaleBar.kt
@@ -0,0 +1,286 @@
+// Copyright 2022 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.widgets
+
+import android.graphics.Point
+import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.animation.EnterTransition
+import androidx.compose.animation.ExitTransition
+import androidx.compose.animation.core.MutableTransitionState
+import androidx.compose.animation.fadeIn
+import androidx.compose.animation.fadeOut
+import androidx.compose.foundation.Canvas
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.size
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment.Companion.End
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.Shadow
+import androidx.compose.ui.graphics.StrokeCap
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.google.android.gms.maps.model.LatLng
+import com.google.maps.android.compose.CameraPositionState
+import com.google.maps.android.ktx.utils.sphericalDistance
+import kotlinx.coroutines.delay
+
+public val DarkGray: Color = Color(0xFF3a3c3b)
+private val defaultWidth: Dp = 65.dp
+private val defaultHeight: Dp = 50.dp
+
+/**
+ * A scale bar composable that shows the current scale of the map in feet and meters when zoomed in
+ * to the map, changing to miles and kilometers, respectively, when zooming out.
+ *
+ * Implement your own observer on camera move events using [CameraPositionState] and pass it in
+ * as [cameraPositionState].
+ */
+@Composable
+public fun ScaleBar(
+ modifier: Modifier = Modifier,
+ width: Dp = defaultWidth,
+ height: Dp = defaultHeight,
+ cameraPositionState: CameraPositionState,
+ textColor: Color = DarkGray,
+ lineColor: Color = DarkGray,
+ shadowColor: Color = Color.White,
+) {
+ Box(
+ modifier = modifier
+ .size(width = width, height = height)
+ ) {
+ var horizontalLineWidthMeters by remember {
+ mutableStateOf(0)
+ }
+
+ Canvas(
+ modifier = Modifier.fillMaxSize(),
+ onDraw = {
+ // Get width of canvas in meters
+ val upperLeftLatLng =
+ cameraPositionState.projection?.fromScreenLocation(Point(0, 0))
+ ?: LatLng(0.0, 0.0)
+ val upperRightLatLng =
+ cameraPositionState.projection?.fromScreenLocation(Point(0, size.width.toInt()))
+ ?: LatLng(0.0, 0.0)
+ val canvasWidthMeters = upperLeftLatLng.sphericalDistance(upperRightLatLng)
+ val eightNinthsCanvasMeters = (canvasWidthMeters * 8 / 9).toInt()
+
+ horizontalLineWidthMeters = eightNinthsCanvasMeters
+
+ val oneNinthWidth = size.width / 9
+ val midHeight = size.height / 2
+ val oneThirdHeight = size.height / 3
+ val twoThirdsHeight = size.height * 2 / 3
+ val strokeWidth = 4f
+ val shadowStrokeWidth = strokeWidth + 3
+
+ // Middle horizontal line shadow (drawn under main lines)
+ drawLine(
+ color = shadowColor,
+ start = Offset(oneNinthWidth, midHeight),
+ end = Offset(size.width, midHeight),
+ strokeWidth = shadowStrokeWidth,
+ cap = StrokeCap.Round
+ )
+ // Top vertical line shadow (drawn under main lines)
+ drawLine(
+ color = shadowColor,
+ start = Offset(oneNinthWidth, oneThirdHeight),
+ end = Offset(oneNinthWidth, midHeight),
+ strokeWidth = shadowStrokeWidth,
+ cap = StrokeCap.Round
+ )
+ // Bottom vertical line shadow (drawn under main lines)
+ drawLine(
+ color = shadowColor,
+ start = Offset(oneNinthWidth, midHeight),
+ end = Offset(oneNinthWidth, twoThirdsHeight),
+ strokeWidth = shadowStrokeWidth,
+ cap = StrokeCap.Round
+ )
+
+ // Middle horizontal line
+ drawLine(
+ color = lineColor,
+ start = Offset(oneNinthWidth, midHeight),
+ end = Offset(size.width, midHeight),
+ strokeWidth = strokeWidth,
+ cap = StrokeCap.Round
+ )
+ // Top vertical line
+ drawLine(
+ color = lineColor,
+ start = Offset(oneNinthWidth, oneThirdHeight),
+ end = Offset(oneNinthWidth, midHeight),
+ strokeWidth = strokeWidth,
+ cap = StrokeCap.Round
+ )
+ // Bottom vertical line
+ drawLine(
+ color = lineColor,
+ start = Offset(oneNinthWidth, midHeight),
+ end = Offset(oneNinthWidth, twoThirdsHeight),
+ strokeWidth = strokeWidth,
+ cap = StrokeCap.Round
+ )
+ }
+ )
+ Column(
+ modifier = Modifier.fillMaxSize(),
+ verticalArrangement = Arrangement.SpaceAround
+ ) {
+ var metricUnits = "m"
+ var metricDistance = horizontalLineWidthMeters
+ if (horizontalLineWidthMeters > METERS_IN_KILOMETER) {
+ // Switch from meters to kilometers as unit
+ metricUnits = "km"
+ metricDistance /= METERS_IN_KILOMETER.toInt()
+ }
+
+ var imperialUnits = "ft"
+ var imperialDistance = horizontalLineWidthMeters.toDouble().toFeet()
+ if (imperialDistance > FEET_IN_MILE) {
+ // Switch from ft to miles as unit
+ imperialUnits = "mi"
+ imperialDistance = imperialDistance.toMiles()
+ }
+
+ ScaleText(
+ modifier = Modifier.align(End),
+ textColor = textColor,
+ shadowColor = shadowColor,
+ text = "${imperialDistance.toInt()} $imperialUnits"
+ )
+ ScaleText(
+ modifier = Modifier.align(End),
+ textColor = textColor,
+ shadowColor = shadowColor,
+ text = "$metricDistance $metricUnits"
+ )
+ }
+ }
+}
+
+/**
+ * An animated scale bar that appears when the zoom level of the map changes, and then disappears
+ * after [visibilityDurationMillis]. This composable wraps [ScaleBar] with visibility animations.
+ *
+ * Implement your own observer on camera move events using [CameraPositionState] and pass it in
+ * as [cameraPositionState].
+ */
+@Composable
+public fun DisappearingScaleBar(
+ modifier: Modifier = Modifier,
+ width: Dp = defaultWidth,
+ height: Dp = defaultHeight,
+ cameraPositionState: CameraPositionState,
+ textColor: Color = DarkGray,
+ lineColor: Color = DarkGray,
+ shadowColor: Color = Color.White,
+ visibilityDurationMillis: Int = 3_000,
+ enterTransition: EnterTransition = fadeIn(),
+ exitTransition: ExitTransition = fadeOut(),
+) {
+ val visible = remember {
+ MutableTransitionState(true)
+ }
+
+ LaunchedEffect(key1 = cameraPositionState.position.zoom) {
+ if (visible.isIdle && !visible.currentState) {
+ // Show ScaleBar
+ visible.targetState = true
+ } else if (visible.isIdle && visible.currentState) {
+ // Hide ScaleBar after timeout period
+ delay(visibilityDurationMillis.toLong())
+ visible.targetState = false
+ }
+ }
+
+ AnimatedVisibility(
+ visibleState = visible,
+ enter = enterTransition,
+ exit = exitTransition
+ ) {
+ ScaleBar(
+ modifier = modifier,
+ width = width,
+ height = height,
+ cameraPositionState = cameraPositionState,
+ textColor = textColor,
+ lineColor = lineColor,
+ shadowColor = shadowColor
+ )
+ }
+}
+
+@Composable
+private fun ScaleText(
+ modifier: Modifier = Modifier,
+ text: String,
+ textColor: Color = DarkGray,
+ shadowColor: Color = Color.White,
+) {
+ Text(
+ text = text,
+ fontSize = 12.sp,
+ color = textColor,
+ textAlign = TextAlign.End,
+ modifier = modifier,
+ style = MaterialTheme.typography.h4.copy(
+ shadow = Shadow(
+ color = shadowColor,
+ offset = Offset(2f, 2f),
+ blurRadius = 1f
+ )
+ )
+ )
+}
+
+/**
+ * Converts [this] value in meters to the corresponding value in feet
+ * @return [this] meters value converted to feet
+ */
+internal fun Double.toFeet(): Double {
+ return this * CENTIMETERS_IN_METER / CENTIMETERS_IN_INCH / INCHES_IN_FOOT
+}
+
+/**
+ * Converts [this] value in feet to the corresponding value in miles
+ * @return [this] feet value converted to miles
+ */
+internal fun Double.toMiles(): Double {
+ return this / FEET_IN_MILE
+}
+
+private const val CENTIMETERS_IN_METER: Double = 100.0
+private const val METERS_IN_KILOMETER: Double = 1000.0
+private const val CENTIMETERS_IN_INCH: Double = 2.54
+private const val INCHES_IN_FOOT: Double = 12.0
+private const val FEET_IN_MILE: Double = 5280.0
\ No newline at end of file
diff --git a/maps-compose/build.gradle b/maps-compose/build.gradle
index a29ec320..c1d45183 100644
--- a/maps-compose/build.gradle
+++ b/maps-compose/build.gradle
@@ -38,7 +38,7 @@ dependencies {
implementation "androidx.compose.foundation:foundation:$compose_version"
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'com.google.android.gms:play-services-maps:18.0.2'
- implementation 'com.google.maps.android:maps-ktx:3.3.0'
+ implementation 'com.google.maps.android:maps-ktx:3.4.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
diff --git a/settings.gradle b/settings.gradle
index 797e7c77..5f7603c4 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -9,3 +9,4 @@ dependencyResolutionManagement {
rootProject.name = "android-maps-compose"
include ':app'
include ':maps-compose'
+include ':maps-compose-widgets'