Skip to content

Commit 2564d06

Browse files
authored
Merge pull request #31 from joreilly/map_clustering
Maps Compose clustering
2 parents 0a552b6 + c67db27 commit 2564d06

File tree

3 files changed

+46
-10
lines changed

3 files changed

+46
-10
lines changed

android-app/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,14 @@ dependencies {
149149
implementation(accompanistPlaceholder)
150150
implementation(accompanistSwipeRefresh)
151151
implementation(mapsCompose)
152+
implementation(mapsComposeUtils)
152153

153154
implementation(material3)
154155
implementation(material3WindowSizeClass)
155156
}
156157
implementation("io.github.pushpalroy:jetlime:1.0.3")
157158
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.6.4")
159+
implementation("com.google.maps.android:android-maps-utils:2.3.0")
158160

159161
with(Deps.PlayServices) {
160162
implementation(maps)

android-app/src/main/java/dev/johnoreilly/galwaybus/ui/screens/NearbyBusStopsScreen.kt

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ import android.annotation.SuppressLint
66
import android.content.Context
77
import android.graphics.Bitmap
88
import androidx.annotation.ColorRes
9+
import androidx.compose.foundation.BorderStroke
910
import androidx.compose.foundation.clickable
1011
import androidx.compose.foundation.layout.*
1112
import androidx.compose.foundation.lazy.LazyColumn
1213
import androidx.compose.foundation.lazy.items
14+
import androidx.compose.foundation.shape.CircleShape
1315
import androidx.compose.material.ExperimentalMaterialApi
1416
import androidx.compose.material.ModalBottomSheetLayout
1517
import androidx.compose.material.ModalBottomSheetValue
@@ -27,6 +29,7 @@ import androidx.compose.ui.res.stringResource
2729
import androidx.compose.ui.text.font.FontWeight
2830
import androidx.compose.ui.text.style.TextAlign
2931
import androidx.compose.ui.unit.dp
32+
import androidx.compose.ui.unit.sp
3033
import androidx.core.content.ContextCompat
3134
import androidx.core.graphics.drawable.DrawableCompat
3235
import androidx.navigation.NavHostController
@@ -36,6 +39,8 @@ import com.google.firebase.analytics.ktx.analytics
3639
import com.google.firebase.analytics.ktx.logEvent
3740
import com.google.firebase.ktx.Firebase
3841
import com.google.maps.android.compose.*
42+
import com.google.maps.android.compose.clustering.Clustering
43+
import com.google.maps.android.clustering.ClusterItem
3944
import com.surrus.galwaybus.common.model.BusStop
4045
import com.surrus.galwaybus.common.model.GalwayBusDeparture
4146
import com.surrus.galwaybus.common.model.Location
@@ -50,7 +55,7 @@ import kotlinx.coroutines.launch
5055

5156

5257
@OptIn(ExperimentalMaterialApi::class, ExperimentalMaterialApi::class)
53-
@SuppressLint("MissingPermission")
58+
@SuppressLint("MissingPermission", "CoroutineCreationDuringComposition")
5459
@Composable
5560
fun NearestBusStopsScreen(viewModel: GalwayBusViewModel, navController: NavHostController) {
5661
val coroutineScope = rememberCoroutineScope()
@@ -216,6 +221,16 @@ fun BusStopView(stop: BusStop, stopSelected : (stop : BusStop) -> Unit, isFavori
216221
}
217222

218223

224+
data class BusStopPositionClusterItem(
225+
val itemPosition: LatLng,
226+
val itemTitle: String,
227+
val itemSnippet: String,
228+
) : ClusterItem {
229+
override fun getPosition(): LatLng = itemPosition
230+
override fun getTitle(): String = itemTitle
231+
override fun getSnippet(): String = itemSnippet
232+
}
233+
219234
@Composable
220235
private fun GoogleMapView(modifier: Modifier, viewModel: GalwayBusViewModel, stops: List<BusStop>) {
221236
val context = LocalContext.current
@@ -249,15 +264,33 @@ private fun GoogleMapView(modifier: Modifier, viewModel: GalwayBusViewModel, sto
249264
properties = mapProperties,
250265
uiSettings = uiSettings
251266
) {
252-
stops.forEach { stop ->
253-
val latitude = stop.latitude
254-
val longitude = stop.longitude
255-
if (latitude != null && longitude != null) {
256-
val busStopLocation = LatLng(latitude, longitude)
257-
val icon = bitmapDescriptorFromVector(context, R.drawable.ic_stop, R.color.mapMarkerGreen)
258-
Marker(state = MarkerState(position = busStopLocation), title = stop.shortName, icon = icon)
267+
268+
Clustering(
269+
items = stops.map { stop ->
270+
val latitude = stop.latitude
271+
val longitude = stop.longitude
272+
val busStopLocation = LatLng(latitude!!, longitude!!)
273+
BusStopPositionClusterItem(busStopLocation, stop.shortName, "Snippet")
274+
},
275+
clusterContent = { cluster ->
276+
Surface(
277+
Modifier.size(40.dp),
278+
shape = CircleShape,
279+
color = Color.Blue,
280+
contentColor = Color.White,
281+
border = BorderStroke(1.dp, Color.White)
282+
) {
283+
Box(contentAlignment = Alignment.Center) {
284+
Text(
285+
"%,d".format(cluster.size),
286+
fontSize = 16.sp,
287+
fontWeight = FontWeight.Black,
288+
textAlign = TextAlign.Center
289+
)
290+
}
291+
}
259292
}
260-
}
293+
)
261294
}
262295
}
263296

buildSrc/src/main/java/Dependencies.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ object Versions {
1717
const val composeCompiler = "1.4.0"
1818
const val navCompose = "2.5.2"
1919
const val accompanist = "0.29.0-alpha"
20-
const val mapsCompose = "2.8.1"
20+
const val mapsCompose = "2.11.0"
2121
const val composeMaterial3 = "1.0.0"
2222

2323
const val kermit = "1.0.0"
@@ -67,6 +67,7 @@ object Deps {
6767
const val accompanistPlaceholder = "com.google.accompanist:accompanist-placeholder:${Versions.accompanist}"
6868
const val accompanistSwipeRefresh = "com.google.accompanist:accompanist-swiperefresh:${Versions.accompanist}"
6969
const val mapsCompose = "com.google.maps.android:maps-compose:${Versions.mapsCompose}"
70+
const val mapsComposeUtils = "com.google.maps.android:maps-compose-utils:${Versions.mapsCompose}"
7071

7172
const val material3 = "androidx.compose.material3:material3:${Versions.composeMaterial3}"
7273
const val material3WindowSizeClass = "androidx.compose.material3:material3-window-size-class:${Versions.composeMaterial3}"

0 commit comments

Comments
 (0)