Marker Clustering
You can use marker clustering to reduce the visual overload caused by too many markers being displayed on the map at once. With this feature markers that are close together are automatically replaced by numbered cluster markers to indicate that multiple map markers are represented. For better user experience, the replacement algorithm depends on the device pixel density. Therefore you can observe different behavior on different devices.

Showing Cluster Markers
You can enable cluster markers on a map by using a ClusterLayer
and adding map markers to it. All markers that are on a layer are automatically clustered based on a grid-based clustering algorithm that depends on the map zoom level.
The following steps demonstrate how to use the ClusterLayer
class:
- Create map markers as normal:
MapMarker mm = new MapMarker(); mm.setIcon(myImage); mm.setCoordinate(new GeoCoordinate(52.53,13.23));
- Create a
ClusterLayer
object.ClusterLayer cl = new ClusterLayer();
- Add markers to the cluster layer instead of the map directly. You can also add a
Collection
ofMapMarker
instead of just adding a single marker.cl.addMarker(mm);
- Add the cluster layer to the map.
mMap.addClusterLayer(cl);
Note: The order of these two steps is not important. You can also add the cluster layer to the map first and add markers to it afterwards. - To remove a marker or collection or markers from the cluster layer again call:
cl.removeMarker(mm);
You can also retrieve all markers on a cluster layer with the ClusterLayer.getMarkers()
method. This is useful if you would like to remove all markers by using the removeMarkers(Collection<MapMarker>)
method.
Theming
You can customize clusters by assigning a ClusterTheme
object to the ClusterLayer
. Every theme consists of several styles, and a cluster style defines the look of marker cluster objects at a particular density. Cluster density is the amount of markers represented by a cluster.

There are three available cluster styles you can use with a ClusterTheme
:
- Default cluster style - the predefined markers behavior. This is the default style used if you do not set a theme. It is also used for ranges not covered by your own theme.
-
BasicClusterStyle
- similar to the default style but you can change the fill color, text color, and stroke color for the markers. -
ImageClusterStyle
- use your own bitmap image as a marker.
To set a style use the setStyleForDensityRange(int, int, ClusterStyle)
or setStyleForDensityRange(ClusterDensityRange, ClusterStyle)
methods in ClusterTheme
. For example, if you want red for all clusters between density 10
to 19
, and green for 20
to 49
, and the default blue for all other cases, you can use BasicClusterStyle
as follows:
- Create a style with a red circle and a style with a green one:
BasicClusterStyle redStyle = new BasicClusterStyle(); redStyle.setFillColor(Color.RED); BasicClusterStyle greenStyle = new BasicClusterStyle(); greenStyle.setFillColor(Color.GREEN);
- Create a new theme and add those styles to the theme with defining the density ranges they should be used for:
Instead of setting the integer values directly you can also make use of theClusterTheme theme = new ClusterTheme(); theme.setStyleForDensityRange(10, 19, redStyle); theme.setStyleForDensityRange(20, 49, greenStyle);
ClusterDensityRange
class.Note: Do not overlap density ranges. Overlapping ranges causesInvalidArgumentException
. - Finally, add this theme to the cluster layer you use:
cl.setTheme(theme);
To use your own image as a cluster icon, set an Image
to an ImageClusterStyle
instance before setting the style to the cluster theme. For example:
Image img = new Image();
try {
img.setImageResource(R.drawable.banner);
} catch (IOException e) {
e.printStackTrace();
}
ImageClusterStyle imageCluster = new ImageClusterStyle(img);
ClusterTheme theme = new ClusterTheme();
theme.setStyleForDensityRange(2, 9, imageCluster);
cl.setTheme(theme);
Although you can only set one theme per layer, you can mix styles for different densities in a single theme. For example, you can set a BasicClusterStyle
from density of 10
to 19
and an ImageClusterStyle
from 20
to 30
. The default theme applies for all other densities not covered by the custom themes.
Cluster Marker Events
Cluster markers are similar to normal markers on the map. You can also use map object gesture listeners in a similar manner as normal map markers. For example:
- Add a gesture listener to the map via:
mMapFragment.getMapGesture().addOnGestureListener(mMyGestureHandler);
- Next, listen for
to get the map click event.public boolean onMapObjectsSelected(List<ViewObject> viewObjects)
- Iterate over the
ViewObjects
and check for typePROXY_OBJECT
and sub-typeCLUSTER_MARKER
. Alternatively, you can also use theinstanceof
keyword.@Override public boolean onMapObjectsSelected(List<ViewObject> viewObjects) { for (ViewObject obj : viewObjects){ if (obj.getBaseType() == ViewObject.Type.PROXY_OBJECT){ if (proxyObj.getType() == MapProxyObject.Type.CLUSTER_MARKER) { ClusterViewObject cv = (ClusterViewObject) proxyObj; Log.i(TAG, "Cluster clicked: markers#"+cv.getMarkers().size()); return true; } } return false; }
Working with Clusters
HERE SDK also provides a few other ways for you to interact with marker clusters. You can get all markers inside one specific cluster by using the ClusterViewObject
, which is a proxy object representing a cluster. For example:
Collection<MapMarker> ClusterViewObject.getMarkers()
You can also retrieve the bounding box around all markers that are in a cluster marker by calling the following:
BoundingBox ClusterViewObject.getBoundingBox();