Anybody knows how to remake something similar to what Batchgeo does when clusters/groups markers with dynamic pie charts?
Example: batchgeo map with pie clustering
Thanks,
Regards
Anybody knows how to remake something similar to what Batchgeo does when clusters/groups markers with dynamic pie charts?
Example: batchgeo map with pie clustering
Thanks,
Regards
I don't have a full how to for you, but do have some pointers which might help you and appear to be used by BatchGeo.
I would study the cluster example on Google maps: https://developers.google.com/maps/articles/toomanymarkers
Which covers clustering pretty well... then you would need to look at changing the marker image to a call to Google Charts: https://developers.google.com/chart/image/docs/gallery/pie_charts
Note: this is deprecated and will drop support 2015... but is used by BatchGeo I believe.
There is also an example here that might help get you on your way with the custom cluster marker images, which I can't post (as limited to 2 links) (such as the Hearts, People etc... set in CLUSTER STYLE). If you Google 'google map v3 cluster example' you should find it in the top results.
If you put all that together then I think you should get there.
Regards,
James
I needed a solution to the same problem so I solved it by extending the Google Maps Marker Cluster Library to use Pie charts instead of cluster markers. You can download the solution from my GitHub repository: https://github.com/hassanlatif/chart-marker-clusterer
Quite late, but I needed to replicate BatchGeo map using Google map. So here I present my CustomRendererClass which I used to draw PieChart as Cluster Icon with Size of Cluster as well. Pass dataset as per your custom requirements.
public class TbmClusterRenderer extends DefaultClusterRenderer<VenueItemData> {
private IconGenerator mClusterIconGenerator;
private Context context;
public TbmClusterRenderer(Context context, GoogleMap map,
ClusterManager<VenueItemData> clusterManager) {
super(context, map, clusterManager);
this.context = context;
mClusterIconGenerator = new IconGenerator(context);
}
@Override
protected void onBeforeClusterItemRendered(VenueItemData item,
MarkerOptions markerOptions) {
try {
int markerColor = item.getMarkerColor();
Bitmap icon;
icon = BitmapFactory.decodeResource(context.getResources(),
R.drawable.map_marker).copy(Bitmap.Config.ARGB_8888, true);
Paint paint = new Paint();
ColorFilter filter = new PorterDuffColorFilter(markerColor,
PorterDuff.Mode.SRC_IN);
paint.setColorFilter(filter);
Canvas canvas = new Canvas(icon);
canvas.drawBitmap(icon, 0, 0, paint);
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));
} catch (Exception ex) {
ex.printStackTrace();
Crashlytics.logException(ex);
}
}
@Override
protected void onClusterItemRendered(VenueItemData clusterItem, Marker marker) {
super.onClusterItemRendered(clusterItem, marker);
}
@Override
protected void onBeforeClusterRendered(Cluster<VenueItemData> cluster, MarkerOptions markerOptions) {
ArrayList<VenueItemData> a = (ArrayList<VenueItemData>) cluster.getItems();
Canvas canvas;
@SuppressLint("UseSparseArrays")
HashMap<Integer, Integer> markerColors = new HashMap<>();
// ConcurrentHashMap<Integer, Integer> markerColors = new ConcurrentHashMap<>();
for (VenueItemData data : a) {
if (data.getMarkerColor() != 0) {
if (!markerColors.containsValue(data.getMarkerColor())) {
markerColors.put(data.getMarkerColor(), 0);
}
}
}
Set set = markerColors.entrySet();
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
Object aSet = iterator.next();
Map.Entry<Integer, Integer> entry = (Map.Entry<Integer, Integer>) aSet;
for (VenueItemData data : a) {
if (data.getMarkerColor() == entry.getKey()) {
entry.setValue(entry.getValue() + 1);
}
}
}
Log.e("graph values", new Gson().toJson(markerColors));
Bitmap myBitmap = Bitmap.createBitmap(70, 70, Bitmap.Config.ARGB_8888);
canvas = new Canvas(myBitmap);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(1f);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
RectF rectf = new RectF(2, 2, myBitmap.getWidth() - 2, myBitmap.getHeight() - 2);
set = markerColors.entrySet();
float startAngle = 0.0f;
for (Object aSet : set) {
Map.Entry<Integer, Integer> entry = (Map.Entry<Integer, Integer>) aSet;
float angle = (360.0f / (float) cluster.getSize()) * (float) entry.getValue();
paint.setColor(entry.getKey());
canvas.drawArc(rectf, startAngle, angle, true, paint);
startAngle += angle;
}
BitmapDrawable clusterIcon = new BitmapDrawable(context.getResources(), myBitmap);
if (set.isEmpty()) {
mClusterIconGenerator.setBackground(context.getResources().getDrawable(R.drawable.circle1));
} else {
mClusterIconGenerator.setBackground(clusterIcon);
}
mClusterIconGenerator.setTextAppearance(R.style.ClusterTextAppearance);
Bitmap icon = mClusterIconGenerator.makeIcon(String.valueOf(cluster.getSize()));
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));
mClusterIconGenerator.setContentPadding(20, 20, 20, 20);
}
}
Here I attach Screenshot for reference: