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];
}
This was very helpful thanks! 👍