Android Maps ClusteredMarkers - don't show unclustered?

1.8k views Asked by At

I'm using the Google Maps Android Marker Clustering Utility from here and I am adding a bunch of items (about 700) from a list I receive from my server. I've ironed out my initial bugs and I can see the clusters, then zoom in on them and see them decluster into individual markers. However, there's a couple of items which are distant from all the others, so that even at maximum zoom out, they never would be clustered. For some reason, these items do not get shown on my map - not when I zoom in, not when I zoom out.

I've checked the coordinates, they are real, and before I started using clustering I could see these items no problem, so I assume I have done something wrong in my clustering code.

Here is some code:

private void setUpClusterer() {
    // Initialize the manager with the context and the map
    mClusterManager = new ClusterManager<>(getActivity(), map);
    vendorRenderer = new VendorRenderer();
    mClusterManager.setRenderer(vendorRenderer);
    mClusterManager.setOnClusterClickListener(this);
    mClusterManager.setOnClusterItemClickListener(this);
    //point the maps listeners at the listeners implemented by the cluster manager
    map.setOnCameraChangeListener(mClusterManager);
    map.setOnMarkerClickListener(mClusterManager);

    //add items to the cluster manager
    addClusterItems(-1);
    mClusterManager.cluster();
}

private void addClusterItems(int positionToMark) {
    if (null == list) {
        return;
    }
    LatLng position;
    int maxMarkers = Math.min(list.size(), getResources().getInteger(R.integer.number_of_results_on_map));

    mClusterManager.clearItems();

    for (int i = 0; i < maxMarkers; i++) {

        vendorItem = list.get(i);

        if (vendorItem.getAddress().contains("Remote 1")) {
            Log.e("Kibi", "Adding Remote 1, pos = " + i);
            Log.e("Kibi", "Coordinates  =" + vendorItem.getPointCoordinates().toString());
        }
        if (vendorItem.getAddress().contains("Clustered 1")) {
            Log.e("Kibi", "Adding Clustered 1, pos = " + i);
            Log.e("Kibi", "Coordinates  =" + vendorItem.getPointCoordinates().toString());
        }
        if (vendorItem.getAddress().contains("Remote 2")) {
            Log.e("Kibi", "Adding Remote 2, pos = " + i);
            Log.e("Kibi", "Coordinates  =" + vendorItem.getPointCoordinates().toString());
        }
        VendorMapItem item = new VendorMapItem(vendorItem.getPointCoordinates(),
                "Some other text");
        if (i == positionToMark) {
            selectedItem = item;
        }

        mClusterManager.addItem(item);
    }
    if (-1 == positionToMark) {
        selectedItem = null;
    }
}

This shows the items getting added - The Logs I have added help me see that my 2 remote items are added with good coordinates, and look similar (though distant from) my selected clustered item (which is seen)

Here is the renderer code:

/* This draws the markers for us */
private class VendorRenderer extends DefaultClusterRenderer<VendorMapItem> {
    Context context = getActivity().getApplicationContext();
    public final IconGenerator mIconGenerator = new IconGenerator(context);
    public final IconGenerator mSelectedIconGenerator = new IconGenerator(context);
    private final View mItemView;
    private final View mSelectedItemView;

    public VendorRenderer() {
        super(getActivity().getApplicationContext(), map, mClusterManager);

        // Create selected custom Marker
        RelativeLayout selectedContainer = (RelativeLayout) view.findViewById(R.id.marker_map_selected_container);
        mSelectedItemView = ((LayoutInflater) getActivity().getSystemService
                (Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.map_marker_selected_layout, selectedContainer, false);
        mSelectedIconGenerator.setContentView(mSelectedItemView);
        mSelectedIconGenerator.setBackground(null);

        // Create custom Marker
        LinearLayout container = (LinearLayout) view.findViewById(R.id.text_marker_map_container);
        mItemView = ((LayoutInflater) getActivity().getSystemService
                (Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.map_marker_layout, container, true);

        mIconGenerator.setContentView(mItemView);
        mIconGenerator.setBackground(null);
    }

    @Override
    protected void onBeforeClusterItemRendered(VendorMapItem vendor, MarkerOptions markerOptions) {
        // Draw a single vendor.
        Bitmap icon;
        if (null == selectedItem || !vendor.getPosition().equals(selectedItem.getPosition()))
        {
            icon = mIconGenerator.makeIcon();
        } else {
            icon = mSelectedIconGenerator.makeIcon();
        }
        markerOptions.title(vendor.getTitle());
        markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));
    }

    @Override
    protected void onBeforeClusterRendered(Cluster<VendorMapItem> cluster, MarkerOptions markerOptions) {
        // Draw multiple vendors clustered...
        Bitmap icon = mIconGenerator.makeIcon();
        markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));
    }

    @Override
    protected boolean shouldRenderAsCluster(Cluster cluster) {
        // Always render clusters.
        return cluster.getSize() > 1;
    }
}

In general clustered items are shown, and also declustered ones, whether selected or not. I have another view showing all the locations data in a list and my remote locations show up just fins there.

Any ideas what I am doing wrong?

2

There are 2 answers

0
Kibi On BEST ANSWER

Stupidity.

Basically I was calling map.clear() too many times. I guess there is no need to call clear if all that is drawn on the map are the pins which are controlled by the clusterer. Once the clear() calls were removed, my pins show up again.

2
Pratik Lad On

public class ClusterIconProvider implements IconDataProvider {

private static final int[] res = {R.drawable.m1,R.drawable.m2,R.drawable.m3,R.drawable.m4,R.drawable.m5};
private static final int[] forCounts = { 10, 100, 1000, 10000, Integer.MAX_VALUE };
private Bitmap[] baseBitmaps;
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Rect bounds = new Rect();
private MarkerOptions markerOptions = new MarkerOptions().anchor(0.5f, 0.5f);


public ClusterIconProvider(Resources resources){
    baseBitmaps = new Bitmap[res.length];
    for (int i = 0; i < res.length; i++) {
        baseBitmaps[i] = BitmapFactory.decodeResource(resources, res[i]);
    }
    paint.setColor(Color.WHITE);
    paint.setTextAlign(Align.CENTER);
    paint.setTextSize(resources.getDimension(R.dimen.Cluster));
}
@Override
public MarkerOptions getIconData(int markersCount) {
    // TODO Auto-generated method stub
    Bitmap base;
    int i = 0;
    do {
        base = baseBitmaps[i];
    } while (markersCount >= forCounts[i++]);
    Bitmap bitmap = base.copy(Config.ARGB_8888, true);      
    String text = String.valueOf(markersCount);
    paint.getTextBounds(text, 0, text.length(), bounds);
    float x = bitmap.getWidth() / 2.0f;
    float y = (bitmap.getHeight() - bounds.height()) / 2.0f - bounds.top;
    Canvas canvas = new Canvas(bitmap);
    canvas.drawText(text, x, y, paint);
    BitmapDescriptor icon = BitmapDescriptorFactory.fromBitmap(bitmap);
    return markerOptions.icon(icon);
}

}