Skip to main content

Data clustering

A newer version of the Maps SDK is available
This page uses v9.7.1 of the Mapbox Maps SDK. A newer version of the SDK is available. Learn about the latest version, v11.3.0, in the Maps SDK documentation.

Often, a map can show too much data at a single time. Markers overlap with each other. The map looks and feels cluttered. Users can't get a quick understanding of what the data is supposed to say.

Showing clustered data is entirely possible by using the data-driven styling capabilities of the Mapbox Maps SDK for Android.

Adjusting the amount of data shown on the map to the map's camera zoom level, is a way to provide users with a cleaner UI experience and less overwhelming location data experience.

CircleLayer

Using CircleLayers is one way of two recommended ways to show data clustering. Different circle colors can represent the various data ranges. For example, blue circles might be clusters with 100+ data points, red circles with 50+, and green circles with 10+. Once the map is zoomed in enough, only individual data points would be visible.

example
CircleLayer clustering

Use GeoJSON data and layers to show data with circle clusters.

chevron-right

SymbolLayer

The SymbolLayer is more complicated but like the CircleLayer implementation above. Depending on the shape/size of the SymbolLayer icons that you use, you might have to use thePropertyFactory's iconTranslate method to make sure that the data count SymbolLayer number text is lined up directly on top of the SymbolLayer cluster icons. Different icons could represent the various data ranges. For example, one image could be clusters with 100+ data points, a second image with 50+, and third image with 10+. Once the map is zoomed in enough, only individual data points would be visible

example
SymbolLayer clustering

Use GeoJSON data and layers to show data with various images as the cluster icons.

chevron-right

To do this:

  1. Use a GeoJSON data source and add it to the Mapbox map as a GeoJsonSource.

mapboxMap.getStyle {
try {
it.addSource(GeoJsonSource("GEOJSON_SOURCE_ID",
URI("URL_POINTING_TO_GEOJSON_FILE"),
GeoJsonOptions()
.withCluster(true)
.withClusterMaxZoom(MAX_ZOOM)
.withClusterRadius(DESIRED_CLUSTER_RADIUS)))
} catch (exception: URISyntaxException) {
Log.e(FragmentActivity.TAG, "Check the URL " + exception.message)
}
}
  1. Create a SymbolLayer with icons that represent the individual data points for when points are not clustered. These icons will only be visible when the map's camera is close enough to the map. Remember, the higher the map zoom value, the more zoomed in the camera is. A zoom level of 12 is closer to the map than a zoom value of 4.
  2. Create as many additional SymbolLayers or CircleLayers as you want for the various data ranges. You might have red circles represent data clusters that have 10-30 data points and then blue circles that have 50 or more data points. Data-driven styling and Expression filtering will determine which cluster layers are displayed at which zoom level.
  3. Create a SymbolLayer for the hidden data amount text. That is, the number that appears and tells a user how many more data points are "hidden" behind the cluster icon/circle and can be viewed if the map is zoomed in on. Don't forget to use runtime styling to adjust the text size, text color, and other text properties:
mapboxMap.getStyle {
val countLayer = SymbolLayer("SYMBOL_LAYER_COUNT_LAYER_ID", "GEOJSON_SOURCE_ID")
countLayer.setProperties(
textField(Expression.toString(get("point_count"))),
textSize(TEXT_SIZE),
textColor(TEXT_COLOR),
textIgnorePlacement(true),
textAllowOverlap(true))

it.addLayer(countLayer)
}