简体   繁体   English

使用 ClusterManager 时如何更新地图上的标记

[英]How update markers on Map when using ClusterManager

I am trying to update my map with newer data from server but I can't figure out how to remove old items ( markers and cluster - Using ClusterManager ) from map ( - seems to me that I can only add in ClusterManager.我正在尝试使用来自服务器的较新数据更新我的地图,但我无法弄清楚如何从地图中删除旧项目(标记和集群 - 使用 ClusterManager )( - 在我看来,我只能添加到 ClusterManager 中。

I have BroadcastReceiver which get intent when there are new data.我有 BroadcastReceiver,当有新数据时它会得到意图。 I was trying something like this: ( but it gives me UnsupportedOperationException on line with "...getMarkers().clear();"我正在尝试这样的事情:(但它给了我UnsupportedOperationException“...getMarkers().clear();”

private BroadcastReceiver myRefrestMapBroadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "onReceive");
        mClusterManager.clearItems();
        mClusterManager.getMarkerCollection().getMarkers().clear();
        mClusterManager.getClusterMarkerCollection().getMarkers().clear();
        mClusterManager.addItems(LocationGetter.getReports());
    }
};

I added data to map only with this function.添加了数据以仅使用此功能进行映射。

java.util.Collection<Marker> userCollection = mClusterManager.getMarkerCollection().getMarkers();
            ArrayList<Marker> userList = new ArrayList<Marker>(userCollection);
            // now is userList empty
            for(Marker marker: userList){
                marker.remove();
            }

            java.util.Collection<Marker> userCollection2 = mClusterManager.getClusterMarkerCollection().getMarkers();
            ArrayList<Marker> userList2 = new ArrayList<Marker>(userCollection2);
            // now is userList2 empty
            for(Marker marker: userList2){
                marker.remove();
            }

            mClusterManager.addItems(LocationGetter.getReports());

According to ClusterManager documentation , we can use mClusterManager.cluster();根据ClusterManager 文档,我们可以使用mClusterManager.cluster();

This method Force a re-cluster.此方法强制重新群集。 You may want to call this after adding new item(s).您可能想在添加新项目后调用它。

I was concentrating the whole time on ClusterManager, so I forgot about GoogleMap , and specifically the method clear() .我一直专注于 ClusterManager,所以我忘记了GoogleMap ,特别是clear()方法。 I was able to solve the problem with this code:我能够用这段代码解决这个问题:

mGoogleMap.clear();
mClusterManager.clearItems();  // calling just in case (may not be needed)
mClusterManager.addItems(LocationGetter.getReports());

There isn't any API to notify that a cluster item has been updated.没有任何 API 来通知集群项目已更新。 But you can use clusterManager.removeItem() + clusterManager.addItem() to force an update to an item.但是您可以使用clusterManager.removeItem() + clusterManager.addItem()强制更新项目。

But you must be careful, as you normally want to update an item because it has changed some properties that affect rendering you need to use a custom ClusterRenderer that supports this and overrides onClusterItemRendered() and/or onClusterRendered() .但是你必须小心,因为你通常想要更新一个项目,因为它改变了一些影响渲染的属性,你需要使用一个自定义的ClusterRenderer支持这个并覆盖onClusterItemRendered()和/或onClusterRendered() Using the onBefore variants wont work because they are only called once on marker creation.使用 onBefore 变体不起作用,因为它们仅在标记创建时调用一次。

You can look at this GitHub issue GitHub issue你可以看这个GitHub issue GitHub issue

Since my app needs to update the clusters multiple times after the map is created, I found this workflow as the best solution to remove and add new clusters:由于我的应用程序需要在创建地图后多次更新集群,我发现此工作流程是删除和添加新集群的最佳解决方案:

mGoogleMap.clear();
mClusterManager.clear(); 
//Do work to add items to cluster
mClusterManager.addItems(yourItemsList);
//Finally 
mClusterManager.cluster(); 

That should force the clusters to rerender after modifying the contents.这应该会强制集群在修改内容后重新渲染。

What worked for me was not clear() the map, because I have some other markers not attached to the cluster manager.对我有用的不是clear()地图,因为我还有一些其他标记没有附加到集群管理器。

What worked for me is:对我有用的是:

this.clustermanger.clearItems()
this.clustermanager.clusterMakerCollection.clear()
//and I had to force a "cluster" again, force the clustermanager to take down all markers
this.clustermanager.cluster()

You should be able to do:你应该能够做到:

val didUpdate = clusterManager?.updateItem(MyClusterItem(data))
clusterManager?.cluster()

The key here to ensure that the clusterManager does actually update the item is to override equals and hashcode in your class that extends ClusterItem, like:这里确保 clusterManager 确实更新项目的关键是覆盖扩展 ClusterItem 的类中的 equals 和 hashcode,例如:

fun getId(): String {
    return data.id
}
override fun equals(other: Any?): Boolean {
    return other is MyClusterItem && other.getId() == getId()
}
override fun hashCode(): Int {
    return getId().hashCode()
}

I was wondering how I could have had this problem - I've never ran into issues like this before with map nodes.我想知道我怎么会遇到这个问题 - 我以前从未遇到过地图节点这样的问题。

However, this was in my sample app's set-up-or-update-map logic:但是,这是在我的示例应用程序的设置或更新地图逻辑中:

        mClusterManager = new ClusterManager<>(getContext(), googleMap);
        mClusterManager.setAnimation(false);
        mClusterManager.clearItems();

I was adding nodes from a db then also some nodes from a request, there was a noticeable impact until I added a null check for the constructor我从数据库中添加节点,然后从请求中添加一些节点,有一个明显的影响,直到我为构造函数添加了空检查

ie, this is how I should have had it:即,这就是我应该拥有的方式:

    if (mClusterManager == null)
            mClusterManager = new ClusterManager<>(getContext(), googleMap);
        mClusterManager.setAnimation(false);
        mClusterManager.clearItems();

I must have copied and pasted this and wasted half an hour on that .. watch out!我一定是复制粘贴了这个,浪费了半个小时……小心!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM