I am creating an Android app using Open Street View Maps. I am using the below library for the same.
implementation 'org.osmdroid:osmdroid-android:6.0.2'
I am also using cluster mechanism to group markers in a cluster. For that I am using the below bonus pack library.
implementation 'com.github.MKergall:osmbonuspack:6.5.2'
So far everything works great. I have my own cluster icon as well as marker icon. Below is the code for the same
private void populateMarkers(final List<Datum> datumList) {
if (datumList != null) {
CustomMarkerClusterer poiMarkers = new CustomMarkerClusterer(this);
map.getOverlays().add(poiMarkers);
for (int i = 0; i < datumList.size(); i++) {
Marker marker = new Marker(map);
marker.setPosition(new GeoPoint(Double.parseDouble(datumList.get(i).getLat()), Double.parseDouble(datumList.get(i).getLng())));
Drawable currentDraw = ResourcesCompat.getDrawable(getResources(), R.drawable.location_marker, null);
marker.setIcon(currentDraw);
final int finalI = i;
marker.setOnMarkerClickListener((marker1, mapView) -> {
if (marker1.isInfoWindowShown()) {
InfoWindow.closeAllInfoWindowsOn(mapView);
} else {
mapView.getController().animateTo(new GeoPoint(marker1.getPosition().getLatitude(), marker1.getPosition().getLongitude()));
getMarkerDetails(marker1, datumList.get(finalI).getId());
}
return false;
});
poiMarkers.add(marker);
poiMarkers.setRadius(300);
poiMarkers.getTextPaint().setColor(Color.BLACK);
map.invalidate();
}
}
progressDialog.dismiss();
}
Now problem is that when I zoom in to see the marker in the cluster, an unknown type of marker is appearing on the map. By unknown I mean that I haven't written any code for that type of marker nor I have that marker icon image in my project.
I currently have no idea from where that marker icon appears. See the screenshot
See the green color hand icon in the screenshot. I am asking about that icon. This thing is neither clickable nor it shows any infowindow on click, while I have a infowindow opening on marker click.
CustomMarkerClusterer class code
public class CustomMarkerClusterer extends MarkerClusterer {
private int mMaxClusteringZoomLevel = 17;
private int mRadiusInPixels = 100;
private double mRadiusInMeters;
private Paint mTextPaint;
private ArrayList<Marker> mClonedMarkers;
private Context context;
private long firstClick;
private long lastClick;
private int count;
/**
* cluster icon anchor
*/
public float mAnchorU = Marker.ANCHOR_CENTER, mAnchorV = Marker.ANCHOR_CENTER;
/**
* anchor point to draw the number of markers inside the cluster icon
*/
public float mTextAnchorU = Marker.ANCHOR_CENTER, mTextAnchorV = Marker.ANCHOR_CENTER;
public CustomMarkerClusterer(Context ctx) {
super();
mTextPaint = new Paint();
mTextPaint.setColor(Color.BLACK);
mTextPaint.setTextSize(15 * ctx.getResources().getDisplayMetrics().density);
mTextPaint.setFakeBoldText(true);
mTextPaint.setTextAlign(Paint.Align.CENTER);
mTextPaint.setAntiAlias(true);
this.context = ctx;
Drawable clusterIconD = ctx.getResources().getDrawable(R.drawable.cluster2);
Bitmap clusterIcon = ((BitmapDrawable) clusterIconD).getBitmap();
setIcon(clusterIcon);
}
/**
* If you want to change the default text paint (color, size, font)
*/
public Paint getTextPaint() {
return mTextPaint;
}
/**
* Set the radius of clustering in pixels. Default is 100px.
*/
public void setRadius(int radius) {
mRadiusInPixels = radius;
}
/**
* Set max zoom level with clustering. When zoom is higher or equal to this level, clustering is disabled.
* You can put a high value to disable this feature.
*/
public void setMaxClusteringZoomLevel(int zoom) {
mMaxClusteringZoomLevel = zoom;
}
/**
* Radius-Based clustering algorithm
*/
@Override
public ArrayList<StaticCluster> clusterer(MapView mapView) {
ArrayList<StaticCluster> clusters = new ArrayList<StaticCluster>();
convertRadiusToMeters(mapView);
mClonedMarkers = new ArrayList<Marker>(mItems); //shallow copy
while (!mClonedMarkers.isEmpty()) {
Marker m = mClonedMarkers.get(0);
m.setIcon(context.getResources().getDrawable(R.drawable.location_marker));
StaticCluster cluster = createCluster(m, mapView);
clusters.add(cluster);
}
return clusters;
}
private StaticCluster createCluster(Marker m, MapView mapView) {
GeoPoint clusterPosition = m.getPosition();
StaticCluster cluster = new StaticCluster(clusterPosition);
cluster.add(m);
mClonedMarkers.remove(m);
if (mapView.getZoomLevel() > mMaxClusteringZoomLevel) {
//above max level => block clustering:
return cluster;
}
Iterator<Marker> it = mClonedMarkers.iterator();
while (it.hasNext()) {
Marker neighbour = it.next();
double distance = clusterPosition.distanceToAsDouble(neighbour.getPosition());
if (distance <= mRadiusInMeters) {
cluster.add(neighbour);
it.remove();
}
}
return cluster;
}
@Override
public Marker buildClusterMarker(StaticCluster cluster, MapView mapView) {
Marker m = new Marker(mapView);
m.setPosition(cluster.getPosition());
m.setInfoWindow(null);
m.setAnchor(mAnchorU, mAnchorV);
Bitmap mutableBitmap=null;
if (cluster.getSize() < 10) {
Bitmap icon = Bitmap.createBitmap(((BitmapDrawable) context.getResources().getDrawable(R.drawable.cluster1)).getBitmap());
mutableBitmap = icon.copy(Bitmap.Config.ARGB_8888, true);
Canvas iconCanvas = new Canvas(mutableBitmap);
// iconCanvas.drawBitmap(mClusterIcon, 0, 0, null);
String text = "" + cluster.getSize();
int textHeight = (int) (mTextPaint.descent() + mTextPaint.ascent());
iconCanvas.drawText(text,
mTextAnchorU * icon.getWidth(),
mTextAnchorV * icon.getHeight() - textHeight / 2,
mTextPaint);
m.setIcon(new BitmapDrawable(mapView.getContext().getResources(), mutableBitmap));
} else if (cluster.getSize() > 10 && cluster.getSize() < 100) {
Bitmap icon = Bitmap.createBitmap(((BitmapDrawable) context.getResources().getDrawable(R.drawable.cluster3)).getBitmap());
mutableBitmap = icon.copy(Bitmap.Config.ARGB_8888, true);
Canvas iconCanvas = new Canvas(mutableBitmap);
//iconCanvas.drawBitmap(mClusterIcon, 0, 0, null);
String text = "" + cluster.getSize();
int textHeight = (int) (mTextPaint.descent() + mTextPaint.ascent());
iconCanvas.drawText(text,
mTextAnchorU * icon.getWidth(),
mTextAnchorV * icon.getHeight() - textHeight / 2,
mTextPaint);
m.setIcon(new BitmapDrawable(mapView.getContext().getResources(), mutableBitmap));
} else if (cluster.getSize() > 100) {
Bitmap icon = Bitmap.createBitmap(((BitmapDrawable) context.getResources().getDrawable(R.drawable.cluster2)).getBitmap());
mutableBitmap = icon.copy(Bitmap.Config.ARGB_8888, true);
Canvas iconCanvas = new Canvas(mutableBitmap);
//iconCanvas.drawBitmap(mClusterIcon, 0, 0, null);
String text = "" + cluster.getSize();
int textHeight = (int) (mTextPaint.descent() + mTextPaint.ascent());
iconCanvas.drawText(text,
mTextAnchorU * icon.getWidth(),
mTextAnchorV * icon.getHeight() - textHeight / 2,
mTextPaint);
m.setIcon(new BitmapDrawable(mapView.getContext().getResources(), mutableBitmap));
}
m.setOnMarkerClickListener(new Marker.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker, MapView mapView) {
mapView.getController().setZoom(mapView.getZoomLevelDouble()+2);
return true;
}
});
// m.setIcon(new BitmapDrawable(mapView.getContext().getResources(), mutableBitmap));
return m;
}
@Override
public void renderer(ArrayList<StaticCluster> clusters, Canvas canvas, MapView mapView) {
for (StaticCluster cluster : clusters) {
if (cluster.getSize() == 1) {
//cluster has only 1 marker => use it as it is:
cluster.setMarker(cluster.getItem(0));
} else {
//only draw 1 Marker at Cluster center, displaying number of Markers contained
Marker m = buildClusterMarker(cluster, mapView);
cluster.setMarker(m);
}
}
}
private void convertRadiusToMeters(MapView mapView) {
Rect mScreenRect = mapView.getIntrinsicScreenRect(null);
int screenWidth = mScreenRect.right - mScreenRect.left;
int screenHeight = mScreenRect.bottom - mScreenRect.top;
BoundingBox bb = mapView.getBoundingBox();
double diagonalInMeters = bb.getDiagonalLengthInMeters();
double diagonalInPixels = Math.sqrt(screenWidth * screenWidth + screenHeight * screenHeight);
double metersInPixel = diagonalInMeters / diagonalInPixels;
mRadiusInMeters = mRadiusInPixels * metersInPixel;
}
}
Your buildClusterMarker is buggy: Look at what happens when the cluster size is = 10 or = 100 : No "if" in both cases. So m.setIcon is not called, and you still have the default osmdroid Marker icon: this funny "green color hand icon".
BTW, why did you copy the whole RadiusMarkerClusterer code, when you can just inherit from it and implement (properly) your own buildClusterMarker ??? Perfect example of what should never been done.