Android Maps Point Clustering

Android Maps Point Clustering

Last night i got into PointClustering on Android MapView. Saw that there was nothing out for the community so i would like to share.

Groups the geopoints if the projection of them in the mapView is too close. Also renders only the visible poins.

UPDATE

Code reworked from scrach.

Now available at GitHub

  1. Code Reworked from scratch
  2. Used GVM clustering algorithm (pretty fast but doesn't position clustered point as good as mine)
  3. Soon to add previous clustering algorithm too

Sample Image

Android Google maps markerClickListener for clusterItems

Okay, after some more trail and error, I think I've got it sorted out for the most part. All I had to do was to attach a custom DefaultClusterRenderer to my clusterManager. In the mapfragment I could use onClusterItemClick for handling the marker clicks. The one problem I still have is that the circles are not all properly rendered when zooming in and out.

private void markGeofencesOnMap() {
new GeofenceAreasRequest().getAllAreas(new GeofenceAreasCallback() {
@Override
public void onAreasLoaded(List<Point> points) {
for (final Point point : points) {
mClusterManager.addItem(point);
}
}
});
}

private void googleMapSettings() {
mClusterManager = new ClusterManager<Point>(getActivity(), googleMap );
// attach custom renderer behaviour
mClusterManager.setRenderer(new OwnPointRendered(getActivity().getApplicationContext(), googleMap, mClusterManager));
mClusterManager.setOnClusterItemClickListener(this);
googleMap.setOnMarkerClickListener(mClusterManager);
googleMap.setOnCameraIdleListener(mClusterManager);
}

@Override
public boolean onClusterItemClick(ClusterItem clusterItem) {
// cast ClusterItem to my Point class to handle marker clicks
Point retailer = (Point) clusterItem;
String retailerId = retailer.getRetailer();
return true;
}

OwnPointRendered.class

public class OwnPointRendered extends DefaultClusterRenderer<Point> {
private final GoogleMap map;
private List<Circle> circleList = new ArrayList<>();

public OwnPointRendered(Context context, GoogleMap map,
ClusterManager<Point> clusterManager) {
super(context, map, clusterManager);
this.map = map;
}

@Override
protected void onBeforeClusterItemRendered(Point item, MarkerOptions markerOptions) {
markerOptions.flat(true);
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(195));
drawRadius(item);
super.onBeforeClusterItemRendered(item, markerOptions);
}

@Override
protected void onClusterRendered(Cluster<Point> cluster, Marker marker) {
super.onClusterRendered(cluster, marker);
for (Circle circle : circleList) {
circle.remove();
}
circleList.clear();
}

private void drawRadius(Point point) {
CircleOptions circleOptions = new CircleOptions()
.center(point.getPosition())
.strokeColor(Color.argb(50, 70, 70, 70))
.fillColor(Color.argb(100, 150, 150, 150))
.radius(point.getRadius());
Circle circle = map.addCircle(circleOptions);
circleList.add(circle);
}

google map marker clustering ad custom Infowindow Adapter how to set tag for clusterItem (marker)

I think this tutorial on cluster manager might help you as it has create a custom popup on a marker click which I think is what you are after.
Work with ClusterManager

How to implement Marker Clustering for Google Maps in Xamarin

You want to use the Xamarin.Android Binding project that includes the android-maps-utils.aar file.

Note: I have forked an older Github repo that included a binding project and example and updated it to the latest version of android-maps-utils.aar (v0.4.3 as of this post).

Just clone that repo and copy the entire GoogleMapsUtility project into your Xamarin.Android solution and add that to your solution (via Add Existing Project).

Then you can create a Google Map like you would normally, i.e.:

GoogleMapOptions mapOptions = new GoogleMapOptions()
.InvokeMapType(GoogleMap.MapTypeNormal)
.InvokeZoomControlsEnabled(true)
.InvokeMapToolbarEnabled(true)
.InvokeZoomGesturesEnabled(true)
.InvokeRotateGesturesEnabled(true)
.InvokeCompassEnabled(true);

Then you can add your Map markers to the ClusterManager and let it manage the clustering:

_clusterManager = new ClusterManager(this, _map);
_clusterManager.SetOnClusterClickListener(this);
_clusterManager.SetOnClusterItemClickListener(this);
_map.SetOnCameraChangeListener(_clusterManager);
_map.SetOnMarkerClickListener(_clusterManager);

I modified the original example to create 20 markers in a log. spiral pattern to test the cluster at various zoom levels:

private void AddClusterItems()
{
double lat = 47.59978;
double lng = -122.3346;

var items = new List<ClusterItem>();

// Create a log. spiral of markers to test clustering
for (int i = 0; i < 20; ++i)
{
var t = i * Math.PI * 0.33f;
var r = 0.005 * Math.Exp(0.1 * t);
var x = r * Math.Cos(t);
var y = r * Math.Sin(t);
var item = new ClusterItem(lat + x, lng + y);
items.Add(item);
}
_clusterManager.AddItems(items);
}

Sample Image



Related Topics



Leave a reply



Submit