【问题标题】:Does the Google Maps Android API Utility Cluster Manager have a minimum number of markers before it will create a cluster?Google Maps Android API Utility Cluster Manager 在创建集群之前是否有最少数量的标记?
【发布时间】:2014-04-29 11:18:58
【问题描述】:

我正在使用 Google Maps Android API 实用程序库在我的应用程序中启用集群。当五个或更多标记位于同一位置时,将创建一个集群:

四个或更少类似的位于同一位置的标记不会创建集群:

这是设计使然还是我做错了什么,因为我的地图有 2、3 或 4 个明显重叠但不会形成集群的标记?

演示问题的代码:

地图布局:

<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:map="http://schemas.android.com/apk/res-auto"
      android:id="@+id/map"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:name="com.google.android.gms.maps.SupportMapFragment"/>

活动:

    package com.example.android.clusteringminima;

    import android.os.Bundle;
    import android.support.v4.app.FragmentActivity;

    import com.google.android.gms.maps.CameraUpdateFactory;
    import com.google.android.gms.maps.GoogleMap;
    import com.google.android.gms.maps.SupportMapFragment;
    import com.google.android.gms.maps.model.LatLng;
    import com.google.maps.android.clustering.ClusterItem;
    import com.google.maps.android.clustering.ClusterManager;

    public class ClusteringMinimaTest extends FragmentActivity {

    private GoogleMap mMap;
    private ClusterManager<Place> mClusterManager;

    public class Place implements ClusterItem {
        private final LatLng mPosition;

        public Place(double lat, double lng) {
            mPosition = new LatLng(lat, lng);
        }

        @Override
        public LatLng getPosition() {
            return mPosition;
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.map);
        setUpMapIfNeeded();
    }

    @Override
    protected void onResume() {
        super.onResume();
        setUpMapIfNeeded();
    }

    private void setUpMapIfNeeded() {
        if (mMap != null) {
            return;
        }
        mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
        if (mMap != null) {
            mClusterManager = new ClusterManager<Place>(this, mMap);
            mMap.setOnCameraChangeListener(mClusterManager);

            // Cluster of 4 or 5
            mClusterManager.addItem(new Place(51.471524, -0.454280));
            mClusterManager.addItem(new Place(51.471311, -0.452257));
            mClusterManager.addItem(new Place(51.471510, -0.453514));
            mClusterManager.addItem(new Place(51.471710, -0.453714));
            // Remove this item to create a group of four
            mClusterManager.addItem(new Place(51.471810, -0.453714));

            // Cluster of 9 (depending on zoom level)
            mClusterManager.addItem(new Place(51.517399, -0.177480));
            mClusterManager.addItem(new Place(51.509899, -0.134180));
            mClusterManager.addItem(new Place(51.495708, -0.144370));
            mClusterManager.addItem(new Place(51.496112, -0.144162));
            mClusterManager.addItem(new Place(51.512458, -0.118644));
            mClusterManager.addItem(new Place(51.518600, -0.081300));
            mClusterManager.addItem(new Place(51.530449, -0.125480));
            mClusterManager.addItem(new Place(51.513008, -0.088430));
            mClusterManager.addItem(new Place(51.505001, -0.086000));

            mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(51.5, -0.35), 9));        
        }
    }
}

【问题讨论】:

  • 嗨,我使用同一个库,地图可以显示,但如果我实例化 mCLusterManager,应用程序会崩溃,你知道发生了什么吗?谢谢!

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


【解决方案1】:

更新(原始答案发布 3 年后:D)

正如@schaenk 所指出的,DefaultClusterRenderer 现在有 setMinClusterSize(int) 方法可以做同样的事情。

原始答案

负责决定是否对项目进行聚类/不聚类的类是DefaultClusterRenderer。如果您查看DefaultClusterRenderer#shouldRenderAsCluster() 方法 - 您会看到它仅在集群大小> MIN_CLUSTER_SIZE 时才开始集群。在我们的例子中MIN_CLUSTER_SIZE = 4

很遗憾,您无法动态更改此常量,因此您需要扩展DefaultClusterRenderer 类并覆盖shouldRenderAsCluster() 方法以提供您自己的逻辑:

class CustomRenderer<T extends ClusterItem> extends DefaultClusterRenderer<T>
{
    public CustomRenderer(Context context, GoogleMap map, ClusterManager<T> clusterManager) {
        super(context, map, clusterManager);            
    }

    @Override
    protected boolean shouldRenderAsCluster(Cluster<T> cluster) {
        //start clustering if at least 2 items overlap
        return cluster.getSize() > 1;
    }
}

private void setUpMapIfNeeded() {
    if (mMap != null) {
        return;
    }
    mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
    if (mMap != null) {
        mClusterManager = new ClusterManager<Place>(this, mMap);
        mClusterManager.setRenderer(new CustomRenderer<Place>(this, mMap, mClusterManager));
        ........
    }
}

【讨论】:

  • 谢谢,帮了我很大的忙 :) 这是一个奇怪的默认设置,这样做是为了使完全相同的位置上的 2-3 个标记不会聚集...奇怪的选择。
  • @Pavel Dudka mClusterManager = new ClusterManager&lt;Place&gt;(this, mMap); 如果我注释掉mClusterManger =new ...,地图会显示出来,你能帮忙吗?我的问题链接stackoverflow.com/questions/26165285/…
  • @PavelDudka 有没有办法覆盖集群地图的默认标记?因为我想将数据库中的图像设置为标记
  • @20Cents 绝对。如果您扩展 DefaultClusterRenderer,您可以覆盖 onBeforeClusterItemRendered(对于单个项目)和 onBeforeClusterRendered(对于集群)。每个函数都接收MarkerOptions 作为参数。您可以通过MarkerOptions#icon() 将自定义图标设置为这些选项
  • DefaultClusterRenderer 提供了一个方法setMinClusterSize()。在mClusterManager = new ClusterManager&lt;Place&gt;(this, mMap); 之后,只需致电mClusterManager.setMinClusterSize(2)。这将完成相同的工作,而无需在类中添加函数。
猜你喜欢
  • 2016-09-09
  • 1970-01-01
  • 2013-03-07
  • 1970-01-01
  • 1970-01-01
  • 2022-10-21
  • 2014-02-18
  • 2021-03-21
  • 1970-01-01
相关资源
最近更新 更多