OCMapView 1.0
Simple and easy to use clustering mapView.
/Users/Boti/Documents/coding/iPhone Development/OCMapView+Sample/OCMapView/OCAlgorithms.m
Go to the documentation of this file.
00001 //
00002 //  OCAlgorythms.m
00003 //  openClusterMapView
00004 //
00005 //  Created by Botond Kis on 15.07.11.
00006 //
00007 
00008 #import "OCAlgorithms.h"
00009 #import "OCAnnotation.h"
00010 #import "OCDistance.h"
00011 #import "OCGrouping.h"
00012 #import <math.h>
00013 
00014 @implementation OCAlgorithms
00015 
00016 #pragma mark - bubbleClustering
00017 
00018 // Bubble clustering with iteration
00019 + (NSArray*) bubbleClusteringWithAnnotations:(NSArray *) annotationsToCluster andClusterRadius:(CLLocationDistance)radius grouped:(BOOL) grouped{
00020     
00021     // memory
00022     [annotationsToCluster retain];
00023     
00024     // return array
00025     NSMutableArray *clusteredAnnotations = [[NSMutableArray alloc] init];
00026     
00027         // Clustering
00028         for (id <MKAnnotation> annotation in annotationsToCluster) {
00029                 // flag for cluster
00030                 BOOL isContaining = NO;
00031                 
00032                 // If it's the first one, add it as new cluster annotation
00033                 if([clusteredAnnotations count] == 0){
00034             OCAnnotation *newCluster = [[OCAnnotation alloc] initWithAnnotation:annotation];
00035             [clusteredAnnotations addObject:newCluster];
00036             
00037             // check group
00038             if (grouped && [annotation respondsToSelector:@selector(groupTag)]) {
00039                 newCluster.groupTag = ((id <OCGrouping>)annotation).groupTag;
00040             }
00041             
00042             [newCluster release];
00043                 }
00044                 else {
00045             for (OCAnnotation *clusterAnnotation in clusteredAnnotations) {
00046                 // If the annotation is in range of the Cluster add it to it
00047                 if(isLocationNearToOtherLocation([annotation coordinate], [clusterAnnotation coordinate], radius)){
00048                     
00049                     // check group
00050                     if (grouped && [annotation respondsToSelector:@selector(groupTag)]) {
00051                         if (![clusterAnnotation.groupTag isEqualToString:((id <OCGrouping>)annotation).groupTag])
00052                             continue;
00053                     }
00054                     
00055                                         isContaining = YES;
00056                                         [clusterAnnotation addAnnotation:annotation];
00057                                         break;
00058                                 }
00059             }
00060             
00061             // If the annotation is not in a Cluster make it to a new one
00062                         if (!isContaining){
00063                                 OCAnnotation *newCluster = [[OCAnnotation alloc] initWithAnnotation:annotation];
00064                                 [clusteredAnnotations addObject:newCluster];
00065                 
00066                 // check group
00067                 if (grouped && [annotation respondsToSelector:@selector(groupTag)]) {
00068                     newCluster.groupTag = ((id <OCGrouping>)annotation).groupTag;
00069                 }
00070                 
00071                 [newCluster release];
00072                         }
00073                 }
00074         }
00075     
00076     NSMutableArray *returnArray = [[NSMutableArray alloc] init];
00077     
00078     // whipe all empty or single annotations
00079     for (OCAnnotation *anAnnotation in clusteredAnnotations) {
00080         if ([anAnnotation.annotationsInCluster count] <= 1) {
00081             [returnArray addObject:[anAnnotation.annotationsInCluster lastObject]];
00082         }
00083         else{
00084             [returnArray addObject:anAnnotation];
00085         }
00086     }
00087     
00088     // memory
00089     [annotationsToCluster release];
00090     [clusteredAnnotations release];
00091     
00092     return [returnArray autorelease];
00093 }
00094 
00095 
00096 // Grid clustering with predefined size
00097 + (NSArray*) gridClusteringWithAnnotations:(NSArray *) annotationsToCluster andClusterRect:(MKCoordinateSpan)tileRect grouped:(BOOL) grouped{
00098     
00099     // memory
00100     [annotationsToCluster retain];
00101     
00102     // return array
00103     NSMutableDictionary *clusteredAnnotations = [[NSMutableDictionary alloc] init];
00104     
00105     // iterate through all annotations
00106         for (id <MKAnnotation> annotation in annotationsToCluster) {
00107         
00108         // calculate grid coordinates of the annotation
00109         int row = ([annotation coordinate].longitude+180.0)/tileRect.longitudeDelta;
00110         int column = ([annotation coordinate].latitude+90.0)/tileRect.latitudeDelta;
00111         
00112         NSString *key = [NSString stringWithFormat:@"%d%d",row,column];
00113         
00114         
00115         // get the cluster for the calculated coordinates
00116         OCAnnotation *clusterAnnotation = [[clusteredAnnotations objectForKey:key] retain];
00117         
00118         // if there is none, create one
00119         if (clusterAnnotation == nil) {
00120             clusterAnnotation = [[OCAnnotation alloc] init];
00121             
00122             CLLocationDegrees lon = row * tileRect.longitudeDelta + tileRect.longitudeDelta/2.0 - 180.0;
00123             CLLocationDegrees lat = (column * tileRect.latitudeDelta) + tileRect.latitudeDelta/2.0 - 90.0;
00124             clusterAnnotation.coordinate = CLLocationCoordinate2DMake(lat, lon);
00125             
00126             // check group
00127             if (grouped && [annotation respondsToSelector:@selector(groupTag)]) {
00128                 clusterAnnotation.groupTag = ((id <OCGrouping>)annotation).groupTag;
00129             }
00130             
00131             [clusteredAnnotations setValue:clusterAnnotation forKey:key];
00132         }
00133         
00134         // check group
00135         if (grouped && [annotation respondsToSelector:@selector(groupTag)]) {
00136             if (![clusterAnnotation.groupTag isEqualToString:((id <OCGrouping>)annotation).groupTag])
00137                 continue;
00138         }
00139         
00140         // add annotation to the cluster
00141         [clusterAnnotation addAnnotation:annotation];
00142         [clusterAnnotation release];
00143         }
00144     
00145     // return array
00146     NSMutableArray *returnArray = [[NSMutableArray alloc] init];
00147     
00148     // whipe all empty or single annotations
00149     for (OCAnnotation *anAnnotation in [clusteredAnnotations allValues]) {
00150         if ([anAnnotation.annotationsInCluster count] <= 1) {
00151             [returnArray addObject:[anAnnotation.annotationsInCluster lastObject]];
00152         }
00153         else{
00154             [returnArray addObject:anAnnotation];
00155         }
00156     }
00157     
00158     // memory
00159     [annotationsToCluster release];
00160     [clusteredAnnotations release];
00161     
00162     return [returnArray autorelease];
00163 }
00164 
00165 @end
 All Data Structures Files Functions Variables Enumerations Enumerator Properties