Кластеризация карты - маркеры максимального масштаба все еще сгруппированы

Я использую утилиты карт Android для кластеризации маркеров на картах Google API v2. Это работало нормально, но когда я добавил более 2000 маркеров, при максимальном увеличении они все еще сгруппированы (у маркеров все еще есть числа):

2000+ маркеровмаксимальное увеличение

Вот мой метод заполнения карты маркерами:

public void getRiverData(String state, String type) {
    URL = getResources().getString(R.string.base_url) + state + "/" + type
            + getResources().getString(R.string.end_url);
    SimpleXmlRequest<XMLData> simpleRequest = new SimpleXmlRequest<XMLData>(
            URL, XMLData.class, new Response.Listener<XMLData>() {

                @Override
                public void onResponse(XMLData response) {

                    // Initialize the manager with the context and the map.
                    // (Activity extends context, so we can pass 'this' in
                    // the constructor.)
                    mClusterManager = new ClusterManager<MarkerItem>(
                            getActivity(), map);

                    mClusterManager.setRenderer(new ClusterRenderer(
                            getActivity(), map, mClusterManager));

                    // response Object
                    waterItemsList = response.getNews();

                    for (News item : waterItemsList) {
                        if (item.getRiver_name() != null
                                && item.getRiver_name() != "") {

                            water_level_value = item.getWater_level_value();

                            if (water_level_value != null
                                    && !water_level_value.equals(0)
                                    && !water_level_value.equals("")) {

                                MarkerItem offsetItem = new MarkerItem(item);
                                mClusterManager.addItem(offsetItem);

                            }

                            map.setOnMarkerClickListener(mClusterManager);

                            map.setInfoWindowAdapter(new InfoWindowAdapter() {

                                @Override
                                public View getInfoWindow(Marker marker) {

                                    return null;
                                }

                                @Override
                                public View getInfoContents(Marker marker) {

                                    try {
                                        View v = getActivity()
                                                .getLayoutInflater()
                                                .inflate(
                                                        R.layout.marker_info,
                                                        null);
                                        TextView title = (TextView) v
                                                .findViewById(R.id.tvMarkerTitle);
                                        TextView info = (TextView) v
                                                .findViewById(R.id.tvMarkerInfo);

                                        title.setText(marker.getTitle()
                                                .toString());
                                        info.setText(marker.getSnippet()
                                                .toString());
                                        return v;
                                    } catch (Exception e) {
                                        // kliknięcie w cluster
                                        return null;

                                    }

                                }
                            });

                        }

                    }

                    map.setOnCameraChangeListener(mClusterManager);

                    map.setOnInfoWindowClickListener(mClusterManager);

                    mClusterManager.cluster();

                }

            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    // error Object
                    error.printStackTrace();
                }
            });

    AppController.getInstance().addToRequestQueue(simpleRequest);
}

Может кто-нибудь мне помочь? Почему это не работает?


person dudeck    schedule 11.06.2014    source источник
comment
я думаю, что это происходит из-за (7) маркера с той же позицией.   -  person Haresh Chhelana    schedule 11.06.2014
comment
Возможно. Есть ли способ проверить, существует ли маркер с той же позицией?   -  person dudeck    schedule 11.06.2014
comment
Просто сделайте это специально: дайте вашей карте 7 маркеров с одинаковым положением, чтобы проверить, как она себя ведет. И дайте ему 7 маркеров с немного разными положениями (+/- 0,0001 широта/долгота), чтобы увидеть, работает ли он.   -  person Vincent Mimoun-Prat    schedule 11.06.2014
comment
@dudeck та же позиция означает те же координаты, так что вы можете легко проверить себя.   -  person Marcin Orlowski    schedule 11.06.2014
comment
это не решение ri8, но мы должны найти какое-то другое решение для этого!!!   -  person Haresh Chhelana    schedule 11.06.2014
comment
@Marcin Orlowski Да, я знаю, что это значит, но мне нужно проверить, добавил ли я маркер в эту позицию. И я не знаю, какое лучшее решение, чтобы проверить это. Я могу сделать для каждого цикла и еще один список «Новости», чтобы проверить, были ли добавлены в список долгота или долгота маркера, но я не знаю, является ли это эффективным способом.   -  person dudeck    schedule 11.06.2014
comment
@MarvinLabs Я сделал, как вы сказали, и знаю, что это работает. Так что спасибо всем вам за то, что вы нашли причину, а теперь, пожалуйста, ответьте, как лучше всего фильтровать эти маркеры для одного маркера на одной позиции (шнуров).   -  person dudeck    schedule 11.06.2014
comment
Хорошо, я добавляю вот так: } } if (!markerExists) { addItemsList.add(item); и это работает :)   -  person dudeck    schedule 11.06.2014


Ответы (3)


Чтобы отфильтровать маркеры с одинаковой позицией, вы можете просто использовать хэш-маску, ключ которой вычисляется из координат маркера.

Что-то вроде:

Map<String, Marker> uniqueMarkers = new HashMap<String, Marker>();
for (Markers m : allMarkers) {
  // Compute a key to filter duplicates
  // You may need to account for small floating point precision errors by 
  // rounding those coordinates
  String key = m.getLatitude() + "|" + m.getLongitude();

  if (uniqueMarkers.get(key)!=null ) {
    // Skip if we have a marker with the same coordinates
    continue;
  }

  // Add marker and do something with it  
  uniqueMarkers.add(key, m);

  // ...
}
person Vincent Mimoun-Prat    schedule 11.06.2014

Вы можете расширить класс DefaultClusterRenderer и установить минимальные маркеры для кластера.

public class InfoMarkerRenderer extends DefaultClusterRenderer<MyCustomMarker> {

public InfoMarkerRenderer(Context context, GoogleMap map, ClusterManager<MyCustomMarker> clusterManager) {
    super(context, map, clusterManager);
    //constructor
}

@Override
protected void onBeforeClusterItemRendered(final MyCustomMarker infomarker, MarkerOptions markerOptions) {
      // you can change marker options
}

@Override
protected boolean shouldRenderAsCluster(Cluster cluster) {
    return cluster.getSize() > 5; // if markers <=5 then not clustering
}
}
person buxik    schedule 29.07.2014
comment
Этот подход прекрасно работает. Вы можете использовать более сложные тесты, чтобы определить, нужно ли кластеризовать или нет. - person rfay; 07.11.2014

Путем следов и ошибок я обнаружил, что если маркеры находятся в пределах ~ 10 футов (эквивалентно 0,0000350º разницы в широте или долготе), маркеры не исчезают даже при максимальном уровне масштабирования.

Один из способов решить эту проблему — реализовать собственный рендерер и позволить приложению решать, когда выполнять кластеризацию. Например, приведенный ниже код будет кластеризоваться только при наличии более 1 маркера и не при максимальном масштабе. Другими словами, он удалит все маркеры при максимальном увеличении.

mClusterManager.setRenderer(new DefaultClusterRenderer<MyItem>(mContext, googleMap, mClusterManager) {
    @Override
    protected boolean shouldRenderAsCluster(Cluster cluster) {
        if(cluster.getSize() > 1 && mCurrentZoom < mMaxZoom) {
            return true;
        } else {
            return false;
        }
    }
});
person Vijay    schedule 22.12.2016