У менеджеров кластеров API Android Android API минимальное количество маркеров до создания кластера?
Я использую утилиту Google API Android API для включения кластеризации в своем приложении. Когда пять или более маркеров расположены совместно, создается кластер: ![enter image description here]()
Четыре или менее одинаково размещенные маркеры не будут создавать кластер:
![enter image description here]()
Это по дизайну или я делаю что-то неправильно, потому что мои карты имеют 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));
}
}
}
Ответы
Ответ 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));
........
}
}