Google Maps Utility: How To Get All Markers From Clustermanager?
Solution 1:
I will give you a nice workaround. First, I will give some background. Then, I will tell you the very simple method for modifying your code.
BACKGROUND: Let's first look at the implementation of ClusterManager.addItem from the library code:
publicvoidaddItem(T myItem) {
this.mAlgorithmLock.writeLock().lock();
try {
this.mAlgorithm.addItem(myItem);
} finally {
this.mAlgorithmLock.writeLock().unlock();
}
}
As you can see, when you call clusterManager.addItem, the ClusterManager then calls this.mAlgorithm.addItem. mAlgorithm is where your item is stored. Let's now look at the default constructor of ClusterManager:
publicClusterManager(Context context, GoogleMap map, MarkerManager markerManager){
...
this.mAlgorithm = newPreCachingAlgorithmDecorator(newNonHierarchicalDistanceBasedAlgorithm());
...
}
mAlgorithm is instantiated as a PreCachingAlgorithmDecorator containing a NonHierarchicalDistanceBasedAlgorithm. Unfortunately, since mAlgorithm is declared private, we don't have access to the items which are being added to the algorithm. However, there is happily an easy workaround! We simply instantiate mAlgorithm using ClusterManager.setAlgorithm. This allows us access to the algorithm class.
WORKAROUND: Here is your code with the workaround inserted.
Put this declaration with your class variables:
privateAlgorithm<Post> clusterManagerAlgorithm;
In the place where you instantiate your ClusterManager, put this immediately afterwards:
// Instantiate the cluster manager algorithm as is done in the ClusterManager clusterManagerAlgorithm = newNonHierarchicalDistanceBasedAlgorithm(); // Set this local algorithm in clusterManager clusterManager.setAlgorithm(clusterManagerAlgorithm);
You can leave your code for inserting items into the cluster exactly the same.
When you want to get access to the items inserted, you simply use the algorithm as opposed to the ClusterManager:
Collection<ClusterItemImpl> items = clusterManagerAlgorithm.getItems();
This returns the items instead of the Marker objects, but I believe it is what you need.
Solution 2:
override one of these:
onBeforeClusterItemRendered
onBeforeClusterRendered
onClusterRendered
onClusterItemRendered
Just like
@OverrideprotectedvoidonClusterRendered(Cluster<MyItem> cluster, Marker marker) {
super.onClusterRendered(cluster, marker);
}
cluster.getItems() will returns the markers in a Cluster
Solution 3:
@Ethan solution works. Another hack is to use Reflection
API in order to access the mAlgorithm
(As mention by Ethan mAlgorithm is where your item is stored) field of ClusterManager
class.
try {
Fieldfield= mClusterManager.getClass().getDeclaredField("mAlgorithm");
field.setAccessible(true);
ObjectmAlgorithm= field.get(mClusterManager);
List<MapItems> markers = newArrayList<>(((Algorithm<MapItems>)mAlgorithm).getItems());
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
Note :- In future if there any changes in field name(i.e. private Algorithm<T> mAlgorithm
), change need to be done in business logic.
Solution 4:
I had the same problem to get all the markers or at least to get the number of markers. I think I found the solution to get the markers.
I tried like you
markers = clusterManager.getMarkerCollection().getMarkers();
Try instead
markers = clusterManager.getClusterMarkerCollection().getMarkers();
This line returned me markers but I am not sure if it is the result that you/we want. I need to check this.
NOTE I would write my answer as a comment but I don't have enough point..
Solution 5:
Ethan's answer is nice but you still can't get marker(s) with it. You need to create custom ClusterRenderer and use it to get Marker or ClusterItem.
overridefunonMapReady(map: GoogleMap) {
clusterManager = ClusterManager(this, map)
clusterRenderer = CustomClusterRenderer(this@ATMActivity, map, this)
clusterManager.renderer = clusterRenderer
}
innerclassCustomClusterRenderer(
context: Context,
map: GoogleMap,
clusterManager: ClusterManager<CustomClusterItem>
) : DefaultClusterRenderer<CustomClusterItem>(context, map, clusterManager)
And then you can get marker or cluster item from clusterRenderer
clusterRenderer.getMarker(clusterItem) // returns Marker object for selected cluster item
clusterRenderer.getClusterItem(marker) // returns ClusterItem object for selected marker
It doesn't provide you whole collection of markers, but if you really still need it you should use loop to create it.
Post a Comment for "Google Maps Utility: How To Get All Markers From Clustermanager?"