Clustering point data

When visualizing many data points on the map, data points may overlap over each other. The overlap may cause the map may become unreadable and difficult to use. Clustering point data is the process of combining point data that are near each other and representing them on the map as a single clustered data point. As the user zooms into the map, the clusters break apart into their individual data points. When you work with large number of data points, use the clustering processes to improve your user experience.

Enabling clustering on a data source

Enable clustering in the DataSource class by setting the cluster option to true. Set ClusterRadius to selects nearby points and combines them into a cluster. The value of ClusterRadius is in pixels. Use clusterMaxZoom to Specify a zoom level at which to disable the clustering logic. Here is an example of how to enable clustering in a data source.

//Create a data source and enable clustering.
var datasource = new atlas.source.DataSource(null, {
	//Tell the data source to cluster point data.
	cluster: true,

	//The radius in pixels to cluster points together.
	clusterRadius: 45,

	//The maximum zoom level in which clustering occurs.
	//If you zoom in more than this, all points are rendered as symbols.
	clusterMaxZoom: 15


If two data points are close together on the ground, it's possible the cluster will never break apart, no matter how close the user zooms in. To address this, you can set the clusterMaxZoom option to disable the clustering logic and simply display everything.

Here are additional methods that the DataSource class provides for clustering:

Method Return type Description
getClusterChildren(clusterId: number) Promise<Array<Feature<Geometry, any> | Shape>> Retrieves the children of the given cluster on the next zoom level. These children may be a combination of shapes and subclusters. The subclusters will be features with properties matching ClusteredProperties.
getClusterExpansionZoom(clusterId: number) Promise<number> Calculates a zoom level at which the cluster will start expanding or break apart.
getClusterLeaves(clusterId: number, limit: number, offset: number) Promise<Array<Feature<Geometry, any> | Shape>> Retrieves all points in a cluster. Set the limit to return a subset of the points, and use the offset to page through the points.

Display clusters using a bubble layer

A bubble layer is a great way to render clustered points. Use expressions to scale the radius and change the color based on the number of points in the cluster. If you display clusters using a bubble layer, then you should use a separate layer to render unclustered data points.

To display the size of the cluster on top of the bubble, use a symbol layer with text, and don't use an icon.

Display clusters using a symbol layer

When visualizing data points, the symbol layer automatically hides symbols that overlap each other to ensure a cleaner user interface. This default behavior might be undesirable if you want to show the data points density on the map. However, these settings can be changed. To display all symbols, set the allowOverlap option of the Symbol layers iconOptions property to true.

Use clustering to show the data points density while keeping a clean user interface. The sample below shows you how to add custom symbols and represent clusters and individual data points using the symbol layer.

Clustering and the heat maps layer

Heat maps are a great way to display the density of data on the map. This visualization method can handle a large number of data points on its own. If the data points are clustered and the cluster size is used as the weight of the heat map, then the heat map can handle even more data. To achieve this option, set the weight option of the heat map layer to ['get', 'point_count']. When the cluster radius is small, the heat map will look nearly identical to a heat map using the unclustered data points, but it will perform much better. However, the smaller the cluster radius, the more accurate the heat map will be, but with fewer performance benefits.

Mouse events on clustered data points

When mouse events occur on a layer that contains clustered data points, the clustered data point return to the event as a GeoJSON point feature object. This point feature will have the following properties:

Property name Type Description
cluster boolean Indicates if feature represents a cluster.
cluster_id string A unique ID for the cluster that can be used with the DataSource getClusterExpansionZoom, getClusterChildren, and getClusterLeaves methods.
point_count number The number of points the cluster contains.
point_count_abbreviated string A string that abbreviates the point_count value if it's long. (for example, 4,000 becomes 4K)

This example takes a bubble layer that renders cluster points and adds a click event. When the click event triggers, the code calculates and zooms the map to the next zoom level, at which the cluster breaks apart. This functionality is implemented using the getClusterExpansionZoom method of the DataSource class and the cluster_id property of the clicked clustered data point.

Display cluster area

The point data that a cluster represents is spread over an area. In this sample when the mouse is hovered over a cluster, two main behaviors occur. First, the individual data points contained in the cluster will be used to calculate a convex hull. Then, the convex hull will be displayed on the map to show an area. A convex hull is a polygon that wraps a set of points like an elastic band and can be calculated using the atlas.math.getConvexHull method. All points contained in a cluster can be retrieved from the data source using the getClusterLeaves method.

Aggregating data in clusters

Often clusters are represented using a symbol with the number of points that are within the cluster. But, sometimes it's desirable to customize the style of clusters with additional metrics. With cluster aggregates, custom properties can be created and populated using an aggregate expression calculation. Cluster aggregates can be defined in clusterProperties option of the DataSource.

The following sample uses an aggregate expression. The code calculates a count based on the entity type property of each data point in a cluster. When a user clicks on a cluster, a popup shows with additional information about the cluster.

Next steps

Learn more about the classes and methods used in this article:

See code examples to add functionality to your app: