Positioning MKMapView to show multiple annotations at once
The link posted by Jim is now dead, but i was able to find the code (which I had bookmarked somewhere). Hope this helps.
- (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];
}
I have done something similiar to this to zoom out (or in) to an area that included a point annotation and the current location. You could expand this by looping through your annotations.
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
-(IBAction)zoomOut:(id)sender {
CLLocationCoordinate2D southWest = _newLocation.coordinate;
CLLocationCoordinate2D northEast = southWest;
southWest.latitude = MIN(southWest.latitude, _annotation.coordinate.latitude);
southWest.longitude = MIN(southWest.longitude, _annotation.coordinate.longitude);
northEast.latitude = MAX(northEast.latitude, _annotation.coordinate.latitude);
northEast.longitude = MAX(northEast.longitude, _annotation.coordinate.longitude);
CLLocation *locSouthWest = [[CLLocation alloc] initWithLatitude:southWest.latitude longitude:southWest.longitude];
CLLocation *locNorthEast = [[CLLocation alloc] initWithLatitude:northEast.latitude longitude:northEast.longitude];
// This is a diag distance (if you wanted tighter you could do NE-NW or NE-SE)
CLLocationDistance meters = [locSouthWest getDistanceFrom:locNorthEast];
MKCoordinateRegion region;
region.center.latitude = (southWest.latitude + northEast.latitude) / 2.0;
region.center.longitude = (southWest.longitude + northEast.longitude) / 2.0;
region.span.latitudeDelta = meters / 111319.5;
region.span.longitudeDelta = 0.0;
_savedRegion = [_mapView regionThatFits:region];
[_mapView setRegion:_savedRegion animated:YES];
[locSouthWest release];
[locNorthEast release];
}
As of iOS7 you can use showAnnotations:animated:
[mapView showAnnotations:annotations animated:YES];
Why so complicated?
MKCoordinateRegion coordinateRegionForCoordinates(CLLocationCoordinate2D *coords, NSUInteger coordCount) {
MKMapRect r = MKMapRectNull;
for (NSUInteger i=0; i < coordCount; ++i) {
MKMapPoint p = MKMapPointForCoordinate(coords[i]);
r = MKMapRectUnion(r, MKMapRectMake(p.x, p.y, 0, 0));
}
return MKCoordinateRegionForMapRect(r);
}