我正在尝试根据群集大小在地图上使用不同颜色的群集。
为此,我子类化 MarkerClusterer ,并根据我的要求更改了代码。
下面是代码
public class CustomMarkerClusterer extends MarkerClusterer {
protected int mMaxClusteringZoomLevel = 17;
protected int mRadiusInPixels = 100;
protected double mRadiusInMeters;
protected Paint mTextPaint;
private ArrayList<Marker> mClonedMarkers;
private Context context;
/**
* 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);
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.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;
}}
buildClusterMarker()是我尝试根据群集的大小将其他图像分配给群集的方法。
当我调试代码时,它可以正常工作,但它只能设置在类的构造函数中定义的单色群集。如果我在那里更改图像,则它会更改,但适用于所有群集。
答案 0 :(得分:2)
buildClusterMakerMethod()
中有三个类似的分支(如果有代码),这是第一个分支:
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); //<=== HERE
...
让我们逐行浏览代码。
1)从可绘制R.drawable.cluster1
创建了一个位图,并将其存储在icon
变量中。
2)图标的副本存储在mutableBitmap
变量中。
3)mutableBitmap
用于创建画布。这意味着,在画布上执行的所有操作都将被绘制到该位图中。
4)原始图标(存储在mClusterIcon
域中)在所需位图上绘制在画布上,从而用构造函数中设置的图标/位图覆盖。
这发生在所有3个分支上。
您可以删除所有出现的行(iconCanvas.drawBitmap(mClusterIcon, 0, 0, null);
来解决问题。