2

So I've got a bunch of annotations spread out on my map... everything is just dandy. Now I need to be able to set the map's position and zoom so they all fit perfectly. How can I do this?

E-Madd
  • 4,414
  • 5
  • 45
  • 77

2 Answers2

4

From Apple forums...

- (void)recenterMap {

         NSArray *coordinates = [self.mapView valueForKeyPath:@"annotations.coordinate"];



         CLLocationCoordinate2D maxCoord = {-90.0f, -180.0f};

         CLLocationCoordinate2D minCoord = {90.0f, 180.0f};



         for(NSValue *value in coordinates) {

              CLLocationCoordinate2D coord = {0.0f, 0.0f};

              [value getValue:&coord];

              if(coord.longitude > maxCoord.longitude) {

                   maxCoord.longitude = coord.longitude;

              }

              if(coord.latitude > maxCoord.latitude) {

                   maxCoord.latitude = coord.latitude;

              }

              if(coord.longitude < minCoord.longitude) {

                   minCoord.longitude = coord.longitude;

              }

              if(coord.latitude < minCoord.latitude) {

                   minCoord.latitude = coord.latitude;

              }

         }

         MKCoordinateRegion region = {{0.0f, 0.0f}, {0.0f, 0.0f}};

         region.center.longitude = (minCoord.longitude + maxCoord.longitude) / 2.0;

         region.center.latitude = (minCoord.latitude + maxCoord.latitude) / 2.0;

         region.span.longitudeDelta = maxCoord.longitude - minCoord.longitude;

         region.span.latitudeDelta = maxCoord.latitude - minCoord.latitude;

         [self.mapView setRegion:region animated:YES];  

    }
E-Madd
  • 4,414
  • 5
  • 45
  • 77
4
@interface MKMapView (zoomToFit)

- (void)zoomToFitOverlays; //Animation defaults to YES
- (void)zoomToFitOverlay:(id<MKOverlay>)anOverlay;
- (void)zoomToFitOverlays:(NSArray *)someOverlays;

- (void)zoomToFitOverlaysAnimated:(BOOL)animated;
- (void)zoomToFitOverlay:(id<MKOverlay>)anOverlay animated:(BOOL)animated;
- (void)zoomToFitOverlays:(NSArray *)someOverlays animated:(BOOL)animated;

- (void)zoomToFitOverlays:(NSArray *)someOverlays animated:(BOOL)animated insetProportion:(CGFloat)insetProportion; //inset 0->1, defaults in other methods to .1 (10%)

@end

@implementation MKMapView (zoomToFit)


#pragma mark -
#pragma mark Zoom to Fit

- (void)zoomToFitOverlays {
    [self zoomToFitOverlaysAnimated:YES];
}

- (void)zoomToFitOverlay:(id<MKOverlay>)anOverlay {
    [self zoomToFitOverlay:[NSArray arrayWithObject:anOverlay] animated:YES];
}

- (void)zoomToFitOverlays:(NSArray *)someOverlays {
    [self zoomToFitOverlays:someOverlays animated:YES];
}

- (void)zoomToFitOverlaysAnimated:(BOOL)animated {
    [self zoomToFitOverlays:self.overlays animated:animated];
}

- (void)zoomToFitOverlay:(id<MKOverlay>)anOverlay animated:(BOOL)animated {
    [self zoomToFitOverlays:[NSArray arrayWithObject:anOverlay] animated:YES];  
}

- (void)zoomToFitOverlays:(NSArray *)someOverlays animated:(BOOL)animated {
    [self zoomToFitOverlays:someOverlays animated:animated insetProportion:.1];
}

- (void)zoomToFitOverlays:(NSArray *)someOverlays animated:(BOOL)animated insetProportion:(CGFloat)insetProportion {
    //Check
    if ( !someOverlays || !someOverlays.count ) {
        return;
    }

    //Union
    MKMapRect mapRect = MKMapRectNull;
    if ( someOverlays.count == 1 ) {
        mapRect = ((id<MKOverlay>)someOverlays.lastObject).boundingMapRect;
    } else {
        for ( id<MKOverlay> anOverlay in someOverlays ) {
            mapRect = MKMapRectUnion(mapRect, anOverlay.boundingMapRect);
        }
    }

    //Inset
    CGFloat inset = (CGFloat)(mapRect.size.width*insetProportion);
    mapRect = [self mapRectThatFits:MKMapRectInset(mapRect, inset, inset)];

    //Set
    MKCoordinateRegion region = MKCoordinateRegionForMapRect(mapRect);
    [self setRegion:region animated:animated];
}

@end
SG1
  • 2,871
  • 1
  • 29
  • 41