It seems like many have touched on this issue of overlapping MKAnnotation Views, and gracefully spreading them out at the end of a zoom, and at viewdidload. So I think I am just going to bite the bullet and dev out a solution, but before I do I wanted to ask advice on the algo to implement. Previous posts about this topic that had no viable solution offered:
ios sdk MKMapView overlapping pins? Laying out overlapping rectangles
and many more...
So the function I am thinking of is this: (Note all the CGRects are the same size)
-(NSArray *)spreadOutTheseViews:(NSArray *)arrayofCGRects{
////////////////////////////////////
//find out who overlaps with who..
////////////////////////////////////
NSMutableArray *arrayOfArraysOfRects = [[NSMutableArray alloc] init];
// 1. make an array to let you know which Rects have already been added to one of the sets
int n = (int)[arrayofCGRects count];
NSMutableArray *addedAlready = [[NSMutableArray alloc] init];
for (id obj in arrayofCGRects ) {
[addedAlready addObject:@0];
}
// 2. go through and add them if they overlap
for (int i=0; i<[arrayofCGRects count]; i++) {
if ([[addedAlready objectAtIndex:i] isEqualToValue:@(0)]) {
CGRect rect1 = [[arrayOfArraysOfRects objectAtIndex:i] CGRectValue];
[arrayOfArraysOfRects addObject:[[NSMutableArray alloc] initWithObjects:@(i), nil]];
[addedAlready insertObject:@(1) atIndex:i];
for (int j=0; j<[arrayofCGRects count]; j++){
if (i!=j && [[addedAlready objectAtIndex:j] isEqualToValue:@(0)] ) {
CGRect rect2 = [[arrayOfArraysOfRects objectAtIndex:j] CGRectValue];
if (CGRectIntersectsRect(rect1,rect2)){
// check if they are overlapping, if so, add it to
[[arrayOfArraysOfRects lastObject] addObject:@(j)];
[addedAlready insertObject:@(1) atIndex:j];
}
}
}
}
}
NSMutableArray *arrayofCGPoints = [[NSMutableArray alloc] init];
//3. now that we have "clusters" of overlapping rects.. push them away from each other..
for(NSArray *indexArray in arrayOfArraysOfRects){
if ([indexArray count]==1){
// just simply add the CGPoint
CGRect rect = [[arrayofCGRects objectAtIndex:(NSInteger)[indexArray firstObject]] CGRectValue];
[arrayofCGPoints addObject:[NSValue valueWithCGPoint:rect.origin] ];
}else{
// heart of the algo..
// Idea 1: get the average of the CGPoints to find the center of all of them, then find a ring with a specific radius that we can put them all on. Note this is a packing problem that I really dont have a better solution for..
}
}
return arrayofCGPoints;
}
Any help here would be greatly appreciated..