Select platform: [Android](https://developers.google.com/maps/documentation/android-sdk/utility/marker-clustering.md.txt "View this page for the Android platform docs.") [iOS](https://developers.google.com/maps/documentation/ios-sdk/utility/marker-clustering.md.txt "View this page for the iOS platform docs.") [JavaScript](https://developers.google.com/maps/documentation/javascript/marker-clustering.md.txt "View this page for the JavaScript platform docs.")

By clustering your markers, you can put a large number of markers on a map
without making the map hard to read.

## Introduction

This video discusses the use of marker clustering when
your data requires a large number of data points on the map.
[Video](https://www.youtube.com/watch?v=FFm9NmSfjw0)

The marker clustering utility helps you manage multiple markers at different
zoom levels. To be precise, the 'markers' are actually 'items' at this point,
and only become 'Markers' when they're rendered. But for the sake of clarity,
this document will name them 'markers' throughout.

When a user views the map at a high zoom level, the individual
markers show on the map. When the user zooms out, the markers gather
together into clusters, to make viewing the map easier. The marker clustering
utility is part of the [Maps SDK for Android Utility Library](https://developers.google.com/maps/documentation/android-sdk/utility.md.txt). If you haven't yet set up the library,
follow the [setup guide](https://developers.google.com/maps/documentation/android-sdk/utility/setup.md.txt)
before reading the rest of this page.
![A map with clustered markers](https://developers.google.com/static/maps/documentation/android-sdk/images/utility-markercluster.png) Clustered markers

To use the marker clustering utility, you will need to add markers as
`ClusterItem` objects to the `ClusterManager`. The
`ClusterManager` passes the markers to the `Algorithm`,
which transforms them into a set of clusters. The `ClusterRenderer`
takes care of the rendering, by adding and removing clusters and individual
markers. The `ClusterRenderer` and `Algorithm` are
pluggable and can be customized.

The utility library ships with a demo app providing sample implementations
of the marker clustering utility. For help with running the demo app, see the
[setup guide](https://developers.google.com/maps/documentation/android-sdk/utility/setup.md.txt). The demo
app includes the following marker clustering samples:

- `ClusteringDemoActivity`: A simple activity demonstrating marker clustering.
- `BigClusteringDemoActivity`: Clustering with 2 000 markers.
- `CustomMarkerClusteringDemoActivity`: Creating a custom design for clustered markers.

## Add a simple marker clusterer

Follow the steps below to create a simple cluster of ten markers. The result
will look like this, although the number of markers shown/clustered will
change depending on the zoom level:
![A map with ten clustered markers](https://developers.google.com/static/maps/documentation/android-sdk/images/utility-markercluster-simple.png) Ten clustered markers

Here is a summary of the steps required:

1. Implement [`ClusterItem`](https://github.com/googlemaps/android-maps-utils/blob/master/library/src/main/java/com/google/maps/android/clustering/ClusterItem.java) to represent a marker on the map. The cluster item returns the position of the marker as a LatLng object, and an optional title or snippet.
2. Add a new [`ClusterManager`](https://github.com/googlemaps/android-maps-utils/blob/master/library/src/main/java/com/google/maps/android/clustering/ClusterManager.java) to group the cluster items (markers) based on zoom level.
3. Set the map's `OnCameraIdleListener()` to the `ClusterManager`, since `ClusterManager` implements the listener.
4. If you want to add specific functionality in response to a marker click event, set the map's `OnMarkerClickListener()` to the `ClusterManager`, since `ClusterManager` implements the listener.
5. Feed the markers into the `ClusterManager`.

Looking at the steps in more detail: To create our simple cluster of ten
markers, first create a `MyItem` class that implements
`ClusterItem`.

### Kotlin

```kotlin
class MyItem(lat: Double, lng: Double, override val title: String, override val snippet: String) : ClusterItem {

    override val position: LatLng = LatLng(lat, lng)

    override val zIndex: Float = 0f

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (other !is MyItem) return false
        return position == other.position && title == other.title
    }

    override fun hashCode(): Int {
        var result = position.hashCode()
        result = 31 * result + title.hashCode()
        return result
    }
}

      
```

### Java

```java
public static class MyItem implements ClusterItem {
    private final LatLng position;
    private final String title;
    private final String snippet;

    public MyItem(double lat, double lng, String title, String snippet) {
        position = new LatLng(lat, lng);
        this.title = title;
        this.snippet = snippet;
    }

    @Override
    public LatLng getPosition() {
        return position;
    }

    @Override
    public String getTitle() {
        return title;
    }

    @Override
    public String getSnippet() {
        return snippet;
    }

    @Nullable
    @Override
    public Float getZIndex() {
        return 0f;
    }
}


      
```

In your map activity, add the `ClusterManager` and feed it the
cluster items. Note the
[type
argument](http://docs.oracle.com/javase/tutorial/java/generics/types.html) `<MyItem>`, which declares the
`ClusterManager` to be of type `MyItem`.

### Kotlin

```kotlin
// Position the map.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(51.503186, -0.126446), 10f))

// Initialize the manager with the context and the map.
// (Activity extends context, so we can pass 'this' in the constructor.)
val manager = ClusterManager<MyItem>(context, map)
clusterManager = manager

// Point the map's listeners at the listeners implemented by the cluster
// manager.
map.setOnCameraIdleListener(manager)
map.setOnMarkerClickListener(manager)

// Add cluster items (markers) to the cluster manager.
addItems()
manager.cluster()

      
```

### Java

```java
// Position the map.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(51.503186, -0.126446), 10));

// Initialize the manager with the context and the map.
// (Activity extends context, so we can pass 'this' in the constructor.)
clusterManager = new ClusterManager<MyItem>(context, map);

// Point the map's listeners at the listeners implemented by the cluster
// manager.
map.setOnCameraIdleListener(clusterManager);
map.setOnMarkerClickListener(clusterManager);

// Add cluster items (markers) to the cluster manager.
addItems();
clusterManager.cluster();

      
```

You can also choose to disable the clustering animations when zooming in and out.
If animation is turned off, the markers snap into position instead of
migrating in and out of the clusters.

To disable animations, use `setAnimation()` in `ClusterManager`
as shown below:

### Kotlin

```kotlin
it.setAnimation(false)

      
```

### Java

```java
clusterManager.setAnimation(false);

      
```

## Add an info window for an individual clustered marker

To add an info window for specific clustered markers, add title and snippet strings into
the constructor of your implementation of `ClusterItem`.

The following example adds a marker with an info window
in the `addItems()` method, by setting a title and snippet:

### Kotlin

```kotlin
// Set the lat/long coordinates for the marker.
val lat = 51.5009
val lng = -0.122

// Set the title and snippet strings.
val title = "This is the title"
val snippet = "and this is the snippet."

// Create a cluster item for the marker and set the title and snippet using the constructor.
val infoWindowItem = MyItem(lat, lng, title, snippet)

// Add the cluster item (marker) to the cluster manager.
it.addItem(infoWindowItem)
it.cluster()

      
```

### Java

```java
// Set the lat/long coordinates for the marker.
double lat = 51.5009;
double lng = -0.122;

// Set the title and snippet strings.
String title = "This is the title";
String snippet = "and this is the snippet.";

// Create a cluster item for the marker and set the title and snippet using the constructor.
MyItem infoWindowItem = new MyItem(lat, lng, title, snippet);

// Add the cluster item (marker) to the cluster manager.
clusterManager.addItem(infoWindowItem);
clusterManager.cluster();

      
```

## Customize the marker clusters

The `ClusterManager` constructor creates a
`DefaultClusterRenderer` and a
`NonHierarchicalDistanceBasedAlgorithm`. You can change the
`ClusterRenderer` and the `Algorithm`
using the `setAlgorithm(Algorithm<T> algorithm)` and
`setRenderer(ClusterRenderer<T> view)` methods of
`ClusterManager`.

You can implement `ClusterRenderer` to customize the rendering of
the clusters. `DefaultClusterRenderer` provides a good base to
start from. By subclassing `DefaultClusterRenderer`, you can
override the defaults.

For an in-depth example of customization, take a look at
`CustomMarkerClusteringDemoActivity` in the demo app that ships
with the utility library.
![A map with custom clustered markers](https://developers.google.com/static/maps/documentation/android-sdk/images/utility-markercluster-custom.png) Custom clustered markers

The `CustomMarkerClusteringDemoActivity` defines its own cluster
item, a `Person`, and renders it by extending the
`DefaultClusterRenderer` as `PersonRenderer`.

The demo also shows how to implement the
`ClusterManager.OnClusterClickListener<Person>` interface to
display more information about the person when the cluster is clicked. You can
also implement
`ClusterManager.OnClusterItemClickListener<Person>` in a
similar way.

For help with running the demo app, see the
[setup guide](https://developers.google.com/maps/documentation/android-sdk/utility/setup.md.txt).