MapKit Clustering for iOS


REVClusterMap API is a simple implementation of clustering for the iOS platform.
An extra layer of functionalities that enables clustering built on top of the MapKit Framework.
With a small set of customizable settings the simple cluster algorithm provides an easy way to cluster your annotations.

The source code is free to use in non-commercial and commercial projects without our written consent.
Additions or bug-fixes are more than welcome. Shout-outs are always encouraged.
Enjoy!

Download

 

15 Responses to MapKit Clustering for iOS

  1. MNBE says:

    Hi,

    I’ve made a few changes to your code, maybe You can integrate them. I must say this plugin is very usefull for our project! Thx for this!

    Some changes:

    REVClusterMapView.m:
    -(void)awakeFromNib {
        annotationsCopy = nil;
     
        self.minimumClusterLevel = 100000;
        self.blocks = 4;
     
        super.delegate = self;
     
        zoomLevel = self.visibleMapRect.size.width * self.visibleMapRect.size.height;
    }

    -> now the class can be used from interfacebuilder.

    Also the REVClusterMap did not support userlocations, I fixed this by adding the following in the manager:

    + (BOOL) clusterAlreadyExistsForMapView:(MKMapView *)mapView andBlockCluster:(REVClusterBlock *)cluster
    {
        for ( REVClusterPin *pin in mapView.annotations )
        {
            if (![pin isKindOfClass:[MKUserLocation class]]) {
                if( [[pin nodes] count] > 0 )
                {
                    MKMapPoint point1 =  MKMapPointForCoordinate([pin coordinate]);
                    MKMapPoint point2 =  MKMapPointForCoordinate([[cluster getClusteredAnnotation] coordinate]);
     
                    if( MKMapPointEqualToPoint(point1,point2) )
                    {
                        return YES;
                    }
                }
            }   
        }
        return NO;
    }

    And to make it work in the example class (RevMapViewController.h)

    - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id )annotation
    {
        if ([annotation isKindOfClass:[MKUserLocation class]])
            return nil;
        REVClusterPin *pin = (REVClusterPin *)annotation;
     
        MKAnnotationView *annView;
     
        if( [pin nodeCount] > 0 ){
            annView = (REVClusterAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:@"cluster"];
     
            if( !annView )
                annView = (REVClusterAnnotationView*)[[[REVClusterAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"cluster"] autorelease];
     
            annView.image = [UIImage imageNamed:@"cluster.png"];
            [(REVClusterAnnotationView*)annView setClusterText:[NSString stringWithFormat:@"%i",[pin nodeCount]]];
            annView.canShowCallout = YES;
        } else {
            annView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"pin"];
     
            if( !annView )
                annView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"pin"] autorelease];
     
            annView.image = [UIImage imageNamed:@"pinpoint.png"];
            annView.canShowCallout = YES;   
        }
        return annView;
    }
    • admin says:

      Thanks for the additions, the example view controller that is in the project is just for example purposes, and in this particular example it doesn’t use a NIB.
      The userLocation bug was spotted earlier and a fix for that is already checked in into the github repo.

      • MNBE says:

        Yes, but I think people look at the example to integrate, maybe useful to integrate.

        It is a great control, thanks for that!

        M.

  2. Stefano says:

    The REVClusterAnnotationView seems recognize touch events as not calling the didSelectAnnotationView delegate method.
    I’ve tried to add annView.enabled = YES in viewForAnnotation method but nothing changed. I’ve tried to remove the label from the REVClusterAnnotationView without success. I don’t found other way to solve my problem.
    Have you a suggest?

  3. Rob says:

    This is absolutely awesome.

    Thanks very much just what I needed!

  4. Rany Ishak says:

    Hey ,
    First: Thanks soo much for this great effort.
    Second: i saw when using that , that removing annotations is not included and i had some problems doing that , and i got to fix them so here is the code, if you would like to add it to REVClusterMapView.

    - (void) removeAnnotations:(NSArray *)annotations
    {

    [annotationsCopy removeObjectsInArray:annotations];
    [super removeAnnotations:annotations];
    [super removeAnnotations:self.annotations];
    self.showsUserLocation = self.showsUserLocation;
    NSArray *add = [REVClusterManager clusterAnnotationsForMapView:self forAnnotations:annotationsCopy blocks:self.blocks minClusterLevel:self.minimumClusterLevel];
    [super addAnnotations:add];
    }

  5. marmaduk says:

    Hi, MNBE I want to ask what is “gt” in your code. when I use it says “gt undeclaired”.

  6. marmaduk says:

    Im using this API and it works like charm but I want cluster to handle with single touch, not with double touch. plz can anyone help me how to do that plz plz plz….

  7. This project is great! Thank you! It really helps me with some project I’m working on.

  8. Pingback: Quora

  9. Mike says:

    Anyone interested in integrating this into the MapKit plugin for Phonegap?
    https://github.com/phonegap/phonegap-plugins/tree/master/iPhone/MapKitPlug

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">