使用 Googles android-maps-utils 禁用最大缩放级别的聚类

Eri*_*all 4 java android google-maps google-maps-android-api-2 android-maps-utils

我正在使用android-maps-utils 中的聚类在 Android 中的 Google 地图上对标记进行聚类。我想在地图处于最大缩放级别时禁用聚类(即,如果地图处于最大缩放级别,则始终呈现单个 ClusterItems,否则群集正常)。

通过在扩展 DefaultClusterRenderer 的自定义类中对 shouldRenderAsCluster() 中的缩放级别进行测试,我几乎可以让它工作。但是,我的解决方案比实际缩放级别落后一步。例如,如果地图的最大缩放级别为 21,并且用户从级别 20 放大到级别 21,则 shouldRenderAsCluster 中的检查将获得当前缩放级别 20。如果用户然后缩小到级别 20,检查将获得第 21 级。 ClusterItems 像我想要的那样被渲染为单个项目,但是一个缩放操作为时已晚。

我从 DefaultClusterRenderer 中设置的变量 mZoom 中获得了“当前缩放”(显然不是真正的当前缩放)。

这是代码:

public class UserClusterRenderer extends PosMapDefaultClusterRenderer<UserClusterItem> {

    // ...

    @Override
    protected boolean shouldRenderAsCluster(Cluster cluster) {
        return mZoom < mMap.getMaxZoomLevel() && cluster.getSize() > 1;
    }
}
Run Code Online (Sandbox Code Playgroud)

变量 mZoom 和 mMap 在 DefaultClusterRenderer 中设置。因为他们在那里有私有访问权限,所以我制作了一个名为 PosMapDefaultClusterRenderer 的 DefaultClusterRenderer 副本。唯一的区别是 mZoom 和 mMap 被声明为受保护的,因此它们可以在 UserClusterRenderer 中访问。

为什么 mZoom 会落后一个缩放操作?有没有办法获得正在渲染集群的真实缩放级别?

缩放是通过使用来自cameraPosition 的cameraUpdate 调用animateCamera 来完成的。

这也是我在 StackOverflow 上的第一个问题,所以欢迎任何关于标签、格式等的输入。

编辑:Vai 回答后的工作代码:

public class UserClusterRenderer extends DefaultClusterRenderer<UserClusterItem> {

    GoogleMap mMapCopy; // Store a ref to the map here from constructor

    // ...

    @Override
    protected boolean shouldRenderAsCluster(Cluster cluster) {
        float currentZoom = mMapCopy.getCameraPosition().zoom;
        float currentMaxZoom = mMapCopy.getMaxZoomLevel();
        return currentZoom < currentMaxZoom && cluster.getSize() > 1;
    }
}
Run Code Online (Sandbox Code Playgroud)

Bre*_*eno 7

@Marc DI 遇到了与线程异常相同的问题,上面提出的解决方案对我不起作用。

为了解决这个问题,我将初始缩放级别和所需的最大缩放级别作为参数传递到自定义渲染器中以进行聚类,然后使自定义渲染器类实现 GoogleMap.onCameraMoveListener 以便它可以获取对缩放级别,并将地图上的 onCameraMoveListener 设置为我的自定义渲染器类实例。

以下对我来说非常有效:

public class MaxZoomClusterRenderer extends DefaultClusterRenderer<JobClusterItem> implements ClusterManager.OnClusterItemClickListener<JobClusterItem>, GoogleMap.OnCameraMoveListener {

    private final GoogleMap mMap;
    private float currentZoomLevel, maxZoomLevel;

    public MaxZoomClusterRenderer(Context context, GoogleMap map, ClusterManager<JobClusterItem> clusterManager, float currentZoomLevel, float maxZoomLevel) {
        super(context, map, clusterManager);

        this.mMap = map;
        this.currentZoomLevel = currentZoomLevel;
        this.maxZoomLevel = maxZoomLevel;
    }

    @Override
    public void onCameraMove() {
        currentZoomLevel = mMap.getCameraPosition().zoom;
    }

    @Override
    protected boolean shouldRenderAsCluster(Cluster<JobClusterItem> cluster) {
        // determine if superclass would cluster first, based on cluster size
        return super.shouldRenderAsCluster(cluster) && currentZoomLevel < maxZoomLevel;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在配置地图时在片段/活动中:

mClusterManager = new ClusterManager<>(getContext(), _map);

// Set custom renderer to allow us to control appearance and behaviour of the clustering
MaxZoomClusterRenderer customRenderer = new MaxZoomClusterRenderer(getContext(), _map, mClusterManager, _map.getCameraPosition().zoom, 18.0f);
mClusterManager.setRenderer(customRenderer);
_map.setOnCameraMoveListener(customRenderer);
_map.setOnCameraIdleListener(mClusterManager);
_map.setOnMarkerClickListener(mClusterManager);
Run Code Online (Sandbox Code Playgroud)

JobClusterItem 只是我实现ClusterItem 的自定义集群项类。

关键是没有尝试在 shouldRenderAsCluster 方法中引用地图实例。


nat*_*rio 0

您不需要复制粘贴整个类来获取mZoom. 您可以使用以下命令获取当前缩放(我希望不会滞后):

mMap.getCameraPosition().zoom
Run Code Online (Sandbox Code Playgroud)

你的做法shouldRenderAsCluster()看起来是正确的。如果这不起作用,请告诉我,我们会检查一下。欢迎来到SO。

  • protected boolean shouldRenderAsCluster(Cluster&lt;T&gt; cluster) { return map.getCameraPosition().zoom &lt; 11; } } 抛出 java.lang.IllegalStateException:不在主线程上 (4认同)