Issue on removing item from clustermanager

2019-01-23 16:46发布

In my Android application, I have to delete and re-add a cluster item in my GoogleMap, that represents my current location. But when I run this code:

clusterMng.remove(myitem);

I get this Exception:

java.lang.UnsupportedOperationException: NonHierarchicalDistanceBasedAlgorithm.remove    
not implemented.

Can someone explain to me what this means? Do I have to rewrite some methods of ClusterManager.java in the external library? Or can I simply change my algorithm?

5条回答
Bombasti
2楼-- · 2019-01-23 16:56

By default ClusterManager uses NonHierarchicalDistanceBasedAlgorithm, that doesn't implement removing elements.

Try to use GridBasedAlgorithm instead (it supports elements remove):

clusterMng.setAlgorithm(new GridBasedAlgorithm<MyClusterItem>());

Or, for better performance, wrap it with PreCachingAlgorithmDecorator, as ClusterManager does by default:

clusterMng.setAlgorithm(new PreCachingAlgorithmDecorator<MyClusterItem>(new GridBasedAlgorithm<MyClusterItem>()));
查看更多
做个烂人
3楼-- · 2019-01-23 17:02

Here is how I did it:

@Override
public void removeItem(T item) {
    final QuadItem<T> quadItem = new QuadItem<T>(item);
    synchronized (mQuadTree) {
        mItems.remove(quadItem);
        mQuadTree.remove(quadItem);
    }
}

I also implemented equals() and hashCode() in QuadItem as it is recommended in the TODO of the NonHierarchicalDistanceBasedAlgorithm source code:

@Override
public boolean equals(Object o) {
    if (this == o) {
        return true;
    }
    if (!(o instanceof QuadItem)) {
        return false;
    }

    QuadItem quadItem = (QuadItem) o;

    return mClusterItem.equals(quadItem.mClusterItem);

}

@Override
public int hashCode() {
    return mClusterItem.hashCode();
}

Finally, I implemented equals() and hashCode() in my ClusterItem's descendant class.

查看更多
冷血范
4楼-- · 2019-01-23 17:04

I have found removeItem(T item) in the source code of ClusterManager.java Tested, it works Link to source code https://github.com/googlemaps/android-maps-utils/blob/master/library/src/com/google/maps/android/clustering/ClusterManager.java

查看更多
可以哭但决不认输i
5楼-- · 2019-01-23 17:08

As @SergePopulov said, NonHierarchicalDistanceBasedAlgorithm does not implement removing elements. For those who dont want to use GridBasedAlgoritm but still needs to remove single elements from NonHierarchicalDistanceBasedAlgorithm there is another solution.

Using this link (Source) you can find source code for the NonHierarchicalDistanceBasedAlgorithm provided by developers in github.

What I did is just save the old Cluster items, clear the clusterManager and add the old items again but do not add the one that is passed through the method.

Firstly create a separate class and paste NonHierarchicalDstanceBasedAlgorithm class code.

public class CustomNonHierarchicalDistanceBasedAlgorithm<MarkerItem extends ClusterItem> implements Algorithm<MarkerItem>
{
    //copy code here
}

After that find method removeItem and replace it with this code:

@Override
public void removeItem(MarkerItem item)
{
    final Collection<QuadItem<MarkerItem>> items = new ArrayList<QuadItem<MarkerItem>>();
    final PointQuadTree<QuadItem<MarkerItem>> quadTree = new PointQuadTree<QuadItem<MarkerItem>>(0, 1, 0, 1);

    for (QuadItem<MarkerItem> temp : mItems)
    {
        if (item.getPosition() != temp.getPosition())
        {
            synchronized (quadTree)
            {
                items.add(temp);
                quadTree.add(temp);
            }
        }
    }

    clearItems();

    for (QuadItem<MarkerItem> temp : items)
    {
        synchronized (mQuadTree)
        {
            mItems.add(temp);
            mQuadTree.add(temp);
        }
    }
}

After that go where your ClusterManager is created and paste code below containing your class name:

clusterManager.setAlgorithm(new CustomNonHierarchicalDistanceBasedAlgorithm<MarkerItem>());

Where your MarkerItem is your class which implemented ClusterItem. And it should now work.

Don't forget to recluster your ClusterManager after you remove the item by running:

clusterManager.cluster();
查看更多
唯我独甜
6楼-- · 2019-01-23 17:15

After updating android-maps-utils to 0.5

clusterManager.remove(item); will never throw an UnsupportedOperationException("NonHierarchicalDistanceBasedAlgorithm.remove not implemented")

Refer this thread

查看更多
登录 后发表回答