I am using the Google Maps Android API Utility Library to enable clustering in my app. When five or more markers are co-located a cluster is created:
Four or fewer similarly co-located markers won't create a cluster:
Is this by design or am I doing something wrong, because my maps have 2, 3 or 4 markers that clearly overlap, but won't form a cluster?
The code to demonstrate the problem:
Map layout:
<?xml version="1.0" encoding="utf-8"?> <fragment xmlns:android="http://schemas.android.com/apk/res/android" xmlns:map="http://schemas.android.com/apk/res-auto" android:id="@+id/map" android:layout_width="match_parent" android:layout_height="match_parent" android:name="com.google.android.gms.maps.SupportMapFragment"/>
Activity:
package com.example.android.clusteringminima; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.LatLng; import com.google.maps.android.clustering.ClusterItem; import com.google.maps.android.clustering.ClusterManager; public class ClusteringMinimaTest extends FragmentActivity { private GoogleMap mMap; private ClusterManager<Place> mClusterManager; public class Place implements ClusterItem { private final LatLng mPosition; public Place(double lat, double lng) { mPosition = new LatLng(lat, lng); } @Override public LatLng getPosition() { return mPosition; } } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.map); setUpMapIfNeeded(); } @Override protected void onResume() { super.onResume(); setUpMapIfNeeded(); } private void setUpMapIfNeeded() { if (mMap != null) { return; } mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap(); if (mMap != null) { mClusterManager = new ClusterManager<Place>(this, mMap); mMap.setOnCameraChangeListener(mClusterManager); // Cluster of 4 or 5 mClusterManager.addItem(new Place(51.471524, -0.454280)); mClusterManager.addItem(new Place(51.471311, -0.452257)); mClusterManager.addItem(new Place(51.471510, -0.453514)); mClusterManager.addItem(new Place(51.471710, -0.453714)); // Remove this item to create a group of four mClusterManager.addItem(new Place(51.471810, -0.453714)); // Cluster of 9 (depending on zoom level) mClusterManager.addItem(new Place(51.517399, -0.177480)); mClusterManager.addItem(new Place(51.509899, -0.134180)); mClusterManager.addItem(new Place(51.495708, -0.144370)); mClusterManager.addItem(new Place(51.496112, -0.144162)); mClusterManager.addItem(new Place(51.512458, -0.118644)); mClusterManager.addItem(new Place(51.518600, -0.081300)); mClusterManager.addItem(new Place(51.530449, -0.125480)); mClusterManager.addItem(new Place(51.513008, -0.088430)); mClusterManager.addItem(new Place(51.505001, -0.086000)); mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(51.5, -0.35), 9)); } } }
Add a place A map can have up to 10,000 lines, shapes, or places.
You can use marker clusters so that Google map automatically clusters the markers into groups based on the location of the marker. When you click on a particular marker, it will zoom in and show sub-clusters for markers in a selected location.
Marker clusters is the concept of sampling the data values into larger blocks in order to ease readability and increase performance. It is a simple solution to display a large number of markers on a map, or a chart. The number on a cluster shows how many markers it contains.
UPDATE (3 years after original answer was posted :D)
As pointed out by @schaenk, DefaultClusterRenderer
now has setMinClusterSize(int)
method which does the same thing.
ORIGINAL ANSWER
The class responsible for making a decision about clustering/not clustering an item is DefaultClusterRenderer
. If you look at DefaultClusterRenderer#shouldRenderAsCluster()
method - you will see that it starts clustering only when size of cluster is > MIN_CLUSTER_SIZE
. In our case MIN_CLUSTER_SIZE = 4
.
Unfortunately you cannot change this constant dynamically, so you need to extend DefaultClusterRenderer
class and override shouldRenderAsCluster()
method to provide your own logic:
class CustomRenderer<T extends ClusterItem> extends DefaultClusterRenderer<T> { public CustomRenderer(Context context, GoogleMap map, ClusterManager<T> clusterManager) { super(context, map, clusterManager); } @Override protected boolean shouldRenderAsCluster(Cluster<T> cluster) { //start clustering if at least 2 items overlap return cluster.getSize() > 1; } } private void setUpMapIfNeeded() { if (mMap != null) { return; } mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap(); if (mMap != null) { mClusterManager = new ClusterManager<Place>(this, mMap); mClusterManager.setRenderer(new CustomRenderer<Place>(this, mMap, mClusterManager)); ........ } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With