Skip to content

Commit 4ada6c9

Browse files
authored
docs: adding sample with Clustering Algorithms (#1567)
* docs: adding sample with Clustering Algorithms * docs: header * docs: comments from PR
1 parent f891ddf commit 4ada6c9

File tree

5 files changed

+199
-1
lines changed

5 files changed

+199
-1
lines changed

demo/src/main/AndroidManifest.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@
124124
<activity
125125
android:name=".StreetViewDemoActivity"
126126
android:exported="true" />
127+
<activity
128+
android:name=".ClusterAlgorithmsDemoActivity"
129+
android:exported="true" />
127130

128131
</application>
129132

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/*
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.maps.android.utils.demo
18+
19+
import android.view.View
20+
import android.widget.AdapterView
21+
import android.widget.ArrayAdapter
22+
import android.widget.Spinner
23+
import com.google.android.gms.maps.CameraUpdateFactory
24+
import com.google.android.gms.maps.MapView
25+
import com.google.android.gms.maps.model.LatLng
26+
import com.google.maps.android.clustering.ClusterManager
27+
import com.google.maps.android.clustering.algo.AbstractAlgorithm
28+
import com.google.maps.android.clustering.algo.CentroidNonHierarchicalDistanceBasedAlgorithm
29+
import com.google.maps.android.clustering.algo.ContinuousZoomEuclideanCentroidAlgorithm
30+
import com.google.maps.android.clustering.algo.GridBasedAlgorithm
31+
import com.google.maps.android.clustering.algo.NonHierarchicalDistanceBasedAlgorithm
32+
import com.google.maps.android.clustering.algo.NonHierarchicalViewBasedAlgorithm
33+
import com.google.maps.android.utils.demo.model.MyItem
34+
import kotlin.random.Random
35+
36+
/**
37+
* A demo activity that showcases the various clustering algorithms
38+
* available in the library.
39+
*/
40+
class ClusterAlgorithmsDemoActivity : BaseDemoActivity() {
41+
42+
private var clusterManager: ClusterManager<MyItem>? = null
43+
private lateinit var mapView: MapView
44+
45+
override fun getLayoutId(): Int {
46+
return R.layout.activity_cluster_algorithms_demo
47+
}
48+
49+
override fun startDemo(isRestore: Boolean) {
50+
51+
if (!isRestore) {
52+
map.moveCamera(
53+
CameraUpdateFactory.newLatLngZoom(
54+
LatLng(51.503186, -0.126446), 10f
55+
)
56+
)
57+
}
58+
59+
setupSpinner()
60+
61+
setupClusterer(0)
62+
}
63+
64+
private fun setupSpinner() {
65+
val spinner: Spinner = findViewById(R.id.algorithm_spinner)
66+
val adapter = ArrayAdapter.createFromResource(
67+
this, R.array.clustering_algorithms, android.R.layout.simple_spinner_item
68+
)
69+
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
70+
spinner.adapter = adapter
71+
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
72+
override fun onItemSelected(
73+
parent: AdapterView<*>?, view: View?, position: Int, id: Long
74+
) {
75+
setupClusterer(position)
76+
}
77+
78+
override fun onNothingSelected(parent: AdapterView<*>?) {
79+
// Do nothing
80+
}
81+
}
82+
}
83+
84+
/**
85+
* Sets up the ClusterManager with the chosen algorithm and populates it with items.
86+
*/
87+
private fun setupClusterer(algorithmPosition: Int) {
88+
// 1. Clear the map and previous cluster manager
89+
map.clear()
90+
91+
// 2. Initialize a new ClusterManager, using getMap() from BaseDemoActivity
92+
clusterManager = ClusterManager(this, map)
93+
94+
// 3. Set the desired algorithm based on the spinner position
95+
clusterManager?.algorithm = when (algorithmPosition) {
96+
1 -> GridBasedAlgorithm()
97+
2 -> NonHierarchicalDistanceBasedAlgorithm()
98+
3 -> CentroidNonHierarchicalDistanceBasedAlgorithm()
99+
4 -> NonHierarchicalViewBasedAlgorithm(mapView.width, mapView.height)
100+
5 -> ContinuousZoomEuclideanCentroidAlgorithm()
101+
else -> error("Unsupported algorithm position: $algorithmPosition")
102+
}
103+
104+
// 4. Point the map's listeners to the ClusterManager
105+
map.setOnCameraIdleListener(clusterManager)
106+
map.setOnMarkerClickListener(clusterManager)
107+
108+
// 5. Generate and add cluster items to the manager
109+
val items = generateItems()
110+
clusterManager?.addItems(items)
111+
112+
// 6. Trigger the initial clustering
113+
clusterManager?.cluster()
114+
}
115+
116+
private fun generateItems(): List<MyItem> {
117+
val items = mutableListOf<MyItem>()
118+
// Add 100 random items in the map region
119+
for (i in 0 until 100) {
120+
val lat = 51.5145 + (Random.nextDouble() - 0.5) / 2.0
121+
val lng = -0.1245 + (Random.nextDouble() - 0.5) / 2.0
122+
items.add(MyItem(lat, lng, "Marker #$i", "Snippet for marker #$i"))
123+
}
124+
return items
125+
}
126+
}

demo/src/main/java/com/google/maps/android/utils/demo/MainActivity.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,9 @@ protected void onCreate(Bundle savedInstanceState) {
3636

3737
mListView = findViewById(R.id.list);
3838

39-
addDemo("Clustering", ClusteringDemoActivity.class);
4039
addDemo("Advanced Markers Clustering Example", CustomAdvancedMarkerClusteringDemoActivity.class);
40+
addDemo("Cluster Algorithms", ClusterAlgorithmsDemoActivity.class);
41+
addDemo("Clustering", ClusteringDemoActivity.class);
4142
addDemo("Clustering: Custom Look", CustomMarkerClusteringDemoActivity.class);
4243
addDemo("Clustering: Diff", ClusteringDiffDemoActivity.class);
4344
addDemo("Clustering: 2K markers", BigClusteringDemoActivity.class);
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
Copyright 2025 Google LLC
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
-->
17+
18+
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
19+
android:layout_width="match_parent"
20+
android:layout_height="match_parent">
21+
22+
<!-- Map Fragment -->
23+
<androidx.fragment.app.FragmentContainerView xmlns:android="http://schemas.android.com/apk/res/android"
24+
xmlns:map="http://schemas.android.com/apk/res-auto"
25+
android:id="@+id/map"
26+
android:name="com.google.android.gms.maps.SupportMapFragment"
27+
android:layout_width="match_parent"
28+
android:layout_height="match_parent"
29+
map:mapId="mapId" />
30+
31+
32+
<Spinner
33+
android:id="@+id/algorithm_spinner"
34+
android:layout_width="wrap_content"
35+
android:layout_height="wrap_content"
36+
android:layout_gravity="top|center_horizontal"
37+
android:layout_marginTop="16dp"
38+
android:background="@android:drawable/btn_dropdown"
39+
android:padding="8dp" />
40+
41+
</FrameLayout>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
Copyright 2025 Google LLC
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
-->
17+
18+
<resources>
19+
<string-array name="clustering_algorithms">
20+
<item>Default</item>
21+
<item>Grid-based</item>
22+
<item>Distance-based</item>
23+
<item>Distance-based (Centroid)</item>
24+
<item>View-based</item>
25+
<item>Continuous Zoom (Centroid)</item>
26+
</string-array>
27+
</resources>

0 commit comments

Comments
 (0)