【问题标题】:Issue on removing item from clustermanager从集群管理器中删除项目的问题
【发布时间】:2014-02-26 17:31:10
【问题描述】:

在我的 Android 应用程序中,我必须在我的 GoogleMap 中删除并重新添加一个集群项目,它代表我当前的位置。但是当我运行这段代码时:

clusterMng.remove(myitem);

我得到这个异常:

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

谁能给我解释一下这是什么意思? 是否必须在外部库中重写 ClusterManager.java 的一些方法?或者我可以简单地改变我的算法吗?

【问题讨论】:

    标签: android google-maps google-maps-android-api-2 marker


    【解决方案1】:

    默认情况下 ClusterManager 使用 NonHierarchicalDistanceBasedAlgorithm,它不实现删除元素。

    尝试使用 GridBasedAlgorithm 代替(它支持元素删除):

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

    或者,为了获得更好的性能,用 PreCachingAlgorithmDecorator 包装它,就像 ClusterManager 默认做的那样:

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

    【讨论】:

    • 这是一个很好的解决方案,但是用PreCachingAlgorithmDecorator 包装算法是不必要的,因为它会在setAlgorithm() 方法中自动执行此操作。
    【解决方案2】:

    正如@SergePopulov 所说,NonHierarchicalDistanceBasedAlgorithm 没有实现删除元素。对于那些不想使用 GridBasedAlgoritm 但仍需要从 NonHierarchicalDistanceBasedAlgorithm 中删除单个元素的人,还有另一种解决方案。

    使用此链接 (Source),您可以在 github 中找到开发人员提供的 NonHierarchicalDistanceBasedAlgorithm 的源代码。

    我所做的只是保存旧的 Cluster 项,清除 clusterManager 并再次添加旧项,但不添加通过该方法传递的项。

    首先创建一个单独的类并粘贴 NonHierarchicalDstanceBasedAlgorithm 类代码。

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

    之后找到方法 removeItem 并将其替换为以下代码:

    @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);
            }
        }
    }
    

    之后,转到创建 ClusterManager 的位置,并在下面粘贴包含您的类名的代码:

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

    您的 MarkerItem 是实现 ClusterItem 的类。它现在应该可以工作了。

    在删除项目后不要忘记重新集群集群管理器:

    clusterManager.cluster();
    

    【讨论】:

    • 我收到无法将 MarkerItems 解析为类型错误消息
    【解决方案3】:

    我是这样做的:

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

    我还在QuadItem 中实现了equals()hashCode(),正如NonHierarchicalDistanceBasedAlgorithm 源代码的TODO 中所推荐的那样:

    @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();
    }
    

    最后,我在ClusterItem 的后代类中实现了equals()hashCode()

    【讨论】:

    • 确认,此解决方案有效!性能方面看起来不错。可以处理超过 1k 个标记
    • @Viachaslau Tysianchuk ,您是如何设法修改 NonHierarchicalDistanceBasedAlgorithm.QuadItem 以实现这些方法的?您必须将库用作模块吗?
    • @desgraci 我已将 android-maps-utils 的完整源代码复制到我的项目中,因为我需要进行其他一些更改。对于这种情况,仅复制 NonHierarchicalDistanceBasedAlgorithm 就足够了。
    • 这对我不起作用。我下载了 NonHierarchical 类并更改了 removeItem 方法,并实现了 equals 和 hashcode 方法。然后,在我的“CustomItem 扩展 ClusterItem”类中,我只是覆盖了等于和哈希码。有什么建议?谢谢!
    • @xsorifc28 如果不查看您的代码,就无法提出太多建议。也许检查你的 hashCode() 实现是否遵循docs.oracle.com/javase/7/docs/api/java/lang/… 的规则。 hashCode() 的错误实现可能会在使用 hashmaps 和 hashsets 时导致错误。
    【解决方案4】:

    android-maps-utils更新为0.5

    clusterManager.remove(item); 永远不会抛出 UnsupportedOperationException("NonHierarchicalDistanceBasedAlgorithm.remove not implemented")

    Refer this thread

    【讨论】:

      【解决方案5】:

      我在 ClusterManager.java 的源代码中找到了removeItem(T item) 经测试,有效 链接源代码https://github.com/googlemaps/android-maps-utils/blob/master/library/src/com/google/maps/android/clustering/ClusterManager.java

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-14
        • 1970-01-01
        • 2013-02-24
        • 2022-01-27
        • 2023-03-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多