Skip to content

Instantly share code, notes, and snippets.

@ThinhPhan
Last active August 21, 2024 15:00
Show Gist options
  • Save ThinhPhan/e983985c677534603fb2 to your computer and use it in GitHub Desktop.
Save ThinhPhan/e983985c677534603fb2 to your computer and use it in GitHub Desktop.
Zoom out to fit all annotations on MapView

I search a lot of questions and answers in SO. This is what i figure out. The result I want is map can zoom out to fit all/some annotations INCLUDE user's location.

The basic steps are:

  • Calculate the min lat/long
  • Calculate the max lat/long
  • Create CLLocation objects for these two points
  • Calculate distance between points
  • Create region using center point between points and distance converted to degrees
  • Pass region into MapView to adjust
  • Use adjusted region to set MapView region

Approach 1: Use system functions - It's only fit annotations NOT INCLUDE user's location For iOS 7 and above (Referring MKMapView.h):

// Position the map such that the provided array of annotations are all visible to the fullest extent possible. 
- (void)showAnnotations:(NSArray *)annotations animated:(BOOL)animated NS_AVAILABLE(10_9, 7_0);

Approach 2: This is the most answer on SO

- (void)zoomToFitMapAnnotations:(MKMapView *)mapView {
    if ([mapView.annotations count] == 0) return;
    
    CLLocationCoordinate2D topLeftCoord;
    topLeftCoord.latitude = -90;
    topLeftCoord.longitude = 180;
    
    CLLocationCoordinate2D bottomRightCoord;
    bottomRightCoord.latitude = 90;
    bottomRightCoord.longitude = -180;
    
    for(id<MKAnnotation> annotation in mapView.annotations) {
        topLeftCoord.longitude = fmin(topLeftCoord.longitude, annotation.coordinate.longitude);
        topLeftCoord.latitude = fmax(topLeftCoord.latitude, annotation.coordinate.latitude);
        bottomRightCoord.longitude = fmax(bottomRightCoord.longitude, annotation.coordinate.longitude);
        bottomRightCoord.latitude = fmin(bottomRightCoord.latitude, annotation.coordinate.latitude);
    }
    
    MKCoordinateRegion region;
    region.center.latitude = topLeftCoord.latitude - (topLeftCoord.latitude - bottomRightCoord.latitude) * 0.5;
    region.center.longitude = topLeftCoord.longitude + (bottomRightCoord.longitude - topLeftCoord.longitude) * 0.5;
    
    // Add a little extra space on the sides
    region.span.latitudeDelta = fabs(topLeftCoord.latitude - bottomRightCoord.latitude) * 1.1;
    region.span.longitudeDelta = fabs(bottomRightCoord.longitude - topLeftCoord.longitude) * 1.1;
    
    region = [mapView regionThatFits:region];
    [mapView setRegion:region animated:YES];
}

Approach 3: And can modify it like this:

- (void)fitMapViewToAnnotationList {
    MKMapRect zoomRect = MKMapRectNull;
    for (id <MKAnnotation> annotation in _mapView.annotations) {
        MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
        MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.1, 0.1);
        if (MKMapRectIsNull(zoomRect)) {
            zoomRect = pointRect;
        } else {
            zoomRect = MKMapRectUnion(zoomRect, pointRect);
        }
    }
    [_mapView setVisibleMapRect:zoomRect edgePadding:UIEdgeInsetsMake(10, 10, 10, 10) animated:YES];
}
@mbuff24
Copy link

mbuff24 commented Feb 23, 2017

This was very helpful thanks! 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment