I am doing an app based on mapview. I am getting the location(place) and converting it to co-ordinates. Using this, I am zooming into the exact location of the place specified.
But the problem I am facing is that,
If I am specifying just the street name or the city name or the state name or the country name the zoom level is always the same. (The zoomlevel is always the same as that of the street.)
If I am just specifying just the country name, the zoom level should be of the country level and not zooming right into any random street of the country.
Here is the code I have used in zooming.
-(void)zoomToFitMapAnnotations:(MKMapView*)mapViews
{
if([mapViews.annotations count] == 0)
return;
CLLocationCoordinate2D topLeftCoordinate;
topLeftCoordinate.latitude = -90;
topLeftCoordinate.longitude = 180;
CLLocationCoordinate2D bottomRightCoord;
bottomRightCoord.latitude = 90;
bottomRightCoord.longitude = -180;
for(SJAddressAnnotation* annotation in mapViews.annotations)
{
topLeftCoordinate.longitude = fmin(topLeftCoordinate.longitude, annotation.coordinate.longitude);
topLeftCoordinate.latitude = fmax(topLeftCoordinate.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 = topLeftCoordinate.latitude - (topLeftCoordinate.latitude - bottomRightCoord.latitude) * 0.5;
region.center.longitude = topLeftCoordinate.longitude + (bottomRightCoord.longitude - topLeftCoordinate.longitude) * 0.5;
region.span.latitudeDelta = fabs(topLeftCoordinate.latitude - bottomRightCoord.latitude) * 1.1; // Add a little extra space on the sides
region.span.longitudeDelta = fabs(bottomRightCoord.longitude - topLeftCoordinate.longitude) * 1.1; // Add a little extra space on the sides
region = [mapView regionThatFits:region];
[mapView setRegion:region animated:YES];
}
I have tried changing the span level unsuccessfully. Needs help in this case.
As I said earlier there is problem with one annotation. If you are retrieving the places from Google search then with each place they give approximate level of zoom(depending upon whether it is country/city). you can try by typing http://maps.google.com/maps/geo?q=asia&output=json in your browser. you can try different entries by replacing asia with china or newyork etc. Look at the Accuracy attribute of response in browser. It will be 0 for continents, 1 for countries etc.
If you have created annotations by yourself then you can attach a parameter to it which will relate to zoomlevel.
#interface AddressAnnotation : NSObject<MKAnnotation> {
double zoomLevel;
}
#property(readwrite,nonatomic) double zoomLevel ;
#end
#implementation AddressAnnotation
#synthesize zoomLevel;
-(void)setZoomLevel (double) parameter
{
self.zoomLevel = parameter;
}
#end
and finally assuming annot is your annotation then
[annot setZoomLevel: .1]; //instead of .1 you can set different values
when you are displaying this annotation set region center as annotation coordinate and set span as annotation.zoomLevel.
MKCoordinateRegion region;
region.center.latitude = annotation.coordinate.latitude;
region.center.longitude = annotation.coordinate.longitude;
region.span.latitudeDelta = annotation.zoomLevel;
region.span.longitudeDelta = annotation.zoomLevel;
Related
I need to zoom the map annotations below the over laid view.
Im using this method to zoom to the 2 annotations.
I can't seem to find a way to fit the 2 annotations below the over laid view, because:
Setting map edgePadding will hide the bottom pin
Setting the map center will hide the bottom pin
Setting the latitudeDelta would work I guess but if pins are horizontally parallel it would not be necessary + it would get messy with different cases.
So i'm wondering if there's an elegant solution for this problem that I might have missed?
This overlay also hides the annotation callout, I guess this could be fixed if I have a solution for the first problem.
Maybe you should try this code to handle perfect fit for Annotations :
- (void)zoomMapViewToFitAnnotations:(MKMapView *)mapView animated:(BOOL)animated
{
NSArray *annotations = mapView.annotations;
int count = [mapView.annotations count];
if ( count == 0) { return; } //return if no annotations
//convert NSArray of id <MKAnnotation> into an MKCoordinateRegion that can be used to set the map size
//can't use NSArray with MKMapPoint because MKMapPoint is not an id
MKMapPoint points[count]; //C array of MKMapPoint struct
for( int i=0; i<count; i++ ) //load points C array by converting coordinates to points
{
CLLocationCoordinate2D coordinate = [(id <MKAnnotation>)[annotations objectAtIndex:i] coordinate];
points[i] = MKMapPointForCoordinate(coordinate);
}
//create MKMapRect from array of MKMapPoint
MKMapRect mapRect = [[MKPolygon polygonWithPoints:points count:count] boundingMapRect];
//convert MKCoordinateRegion from MKMapRect
MKCoordinateRegion region = MKCoordinateRegionForMapRect(mapRect);
//add padding so pins aren't scrunched on the edges
region.span.latitudeDelta *= ANNOTATION_REGION_PAD_FACTOR;
region.span.longitudeDelta *= ANNOTATION_REGION_PAD_FACTOR;
//but padding can't be bigger than the world
if( region.span.latitudeDelta > MAX_DEGREES_ARC ) { region.span.latitudeDelta = MAX_DEGREES_ARC; }
if( region.span.longitudeDelta > MAX_DEGREES_ARC ){ region.span.longitudeDelta = MAX_DEGREES_ARC; }
//and don't zoom in stupid-close on small samples
if( region.span.latitudeDelta < MINIMUM_ZOOM_ARC ) { region.span.latitudeDelta = MINIMUM_ZOOM_ARC; }
if( region.span.longitudeDelta < MINIMUM_ZOOM_ARC ) { region.span.longitudeDelta = MINIMUM_ZOOM_ARC; }
//and if there is a sample of 1 we want the max zoom-in instead of max zoom-out
if( count == 1 )
{
region.span.latitudeDelta = MINIMUM_ZOOM_ARC;
region.span.longitudeDelta = MINIMUM_ZOOM_ARC;
}
[mapView setRegion:region animated:animated];
}
So, you have to define the Padding, Maximum degree arc and Minimum zoom arc. For Ex. should belike this :
#define MINIMUM_ZOOM_ARC 0.05 //approximately 1 miles (1 degree of arc ~= 69 miles)
#define ANNOTATION_REGION_PAD_FACTOR 1.25
#define MAX_DEGREES_ARC 360
Hopefully, You will like it, Cheers
Set userintercation disabled for the overlay if you want touch points on the overlay.
For setting the zoom level I made a few adjustments after plotting the points. You can calculate the average of the lat longs and then adjust the lat longs as per size of the overlay. Here's what I did:
float latAvg,longAvg;
latAvg = (location1.latitude + location.latitude)/2;
longAvg = (location1.longitude + location.longitude)/2;
MKCoordinateSpan span;// = MKCoordinateSpanMake(0.006, 0.006);
span.latitudeDelta = fabs(location1.latitude - location.latitude);
span.longitudeDelta = fabs(location1.longitude - location.longitude);
//Then adjust the lat longs delta according to your need.
span.latitudeDelta = span.latitudeDelta + 0.0010;
span.longitudeDelta = span.longitudeDelta + 0.0010;
CLLocationCoordinate2D locationLatlng;
locationLatlng.latitude = latAvg;
locationLatlng.longitude = longAvg;
MKCoordinateRegion viewRegion = MKCoordinateRegionMake(locationLatlng, span);
[map setRegion:viewRegion animated:YES];
[map regionThatFits:viewRegion];
I have been using the following code to zoom the mapview, so that all the annotations will be displayed in the view at the same time at optimum zoom level. But in IOS 6, there seems to be some problem with the zoom level. Testing a few cases, I found that
1. If the contacts are in US, when the map is loaded it is zooming else where.
2. The zoom level seems to be correct in the UK area(as far as I have tested).
3. When I include contacts from both UK and US, the UK contacts gets rightly zoomed, but the US contacts are out of the view. But a slight swipe will ensure that all contacts fit into the view and are zoomed properly.
-(void)zoomToFitMapAnnotations:(MKMapView*)mapViews insideArray:(NSArray*)anAnnotationArray
{
if([mapViews.annotations count] == 0) return;
CLLocationCoordinate2D topLeftCoord;
topLeftCoord.latitude = -90;
topLeftCoord.longitude = 180;
CLLocationCoordinate2D bottomRightCoord;
bottomRightCoord.latitude = 90;
bottomRightCoord.longitude = -180;
for(MKPointAnnotation* annotation in anAnnotationArray)
{
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;
region.span.latitudeDelta = fabs(topLeftCoord.latitude - bottomRightCoord.latitude) * 1.1; // Add a little extra space on the sides
region.span.longitudeDelta = fabs(bottomRightCoord.longitude - topLeftCoord.longitude) * 1.1; // Add a little extra space on the sides
region = [mapViews regionThatFits:region];
[mapView setRegion:region animated:YES];
}
After loading the mapview with annotations, in random cases I get the following log
<GEOTileSource: 0x108f6470>: Error downloading tiles Server Error: Error Domain=GEOErrorDomain Code=-204 "The operation couldn’t be completed. (GEOErrorDomain error -204.)" UserInfo=0x18a5b9c0 {UnderlyingErrors=(
"Error Domain=GEOErrorDomain Code=-204 \"The operation couldn\U2019t be completed. (GEOErrorDomain error -204.)\""
)}
What could be the reason for this and how can I correct it? Couldn't find anything helpful after googling.
I am not able to identify any particular pattern for this zooming inconsistency. The above code is working fine in previous IOS versions.
I almost offered a bounty on your question but then I noticed, that with the new maps in iOS6 you just cannot zoom out to see the whole world (try it yourself in the maps app). There is a maximum zoom level which you can figure out by commenting out your for loop and logging this:
NSLog(#"region.span.latitudeDelta = %f", region.span.latitudeDelta);
NSLog(#"longitudeDelta = %f", region.span.longitudeDelta);
[map setRegion:region animated:NO];
NSLog(#"region.span.latitudeDelta = %f", map.region.span.latitudeDelta);
NSLog(#"longitudeDelta = %f", map.region.span.longitudeDelta);
The output looks like this:
region.span.latitudeDelta = 179.283409
longitudeDelta = 360.000000
region.span.latitudeDelta = 76.269114
longitudeDelta = 98.437499
I'm trying to zoom in on a map that focuses on all the pins that were associated that map. I have that information saved off in my map property.
I am starting with this, but it's not working yet:
double maxLatitude = 0;
double minLatitude = 0;
double maxLongitude = 0;
double minLongitude = 0;
for (MKAnnotation *address in self.map.locations) {
// Latitude
if ([address.latitude doubleValue] > 0) {
maxLatitude = MAX(maxLatitude, [address.latitude doubleValue]);
}
else {
minLatitude = MAX(abs(minLatitude), abs([address.latitude doubleValue]));
}
// Longitude
if ([address.longitude doubleValue] > 0) {
maxLongitude = MAX(maxLongitude, [address.longitude doubleValue]);
}
else {
minLongitude = MAX(abs(minLongitude), abs([address.longitude doubleValue]));
}
}
double centerLatitude = (maxLatitude - abs(minLatitude)) / 2;
centerLatitude *= [self calculateSignWithFirstValue:maxLatitude secondValue:minLatitude];
double centerLongitude = (maxLongitude - abs(minLongitude)) / 2;
centerLongitude *= [self calculateSignWithFirstValue:maxLongitude secondValue:minLongitude];
// Create some MKMapRect with the coordinates?
I don't think I understand the MKMapRect though since when I try to do something like this:
CLLocationCoordinate2D theOrigin = CLLocationCoordinate2DMake(32, -117);
MKMapRect mapRect;
mapRect.origin = MKMapPointForCoordinate(theOrigin);
mapRect.size = MKMapSizeMake(10, 10);
I get put over the ocean instead of San Diego. Not sure what's going on with a MKMapRect.
/**
* Return a region covering all the annotations in the given array.
* #param annotations Array of objects conforming to the <MKAnnotation> protocol.
*/
+(MKCoordinateRegion) regionForAnnotations:(NSArray*) annotations
{
double minLat=90.0f, maxLat=-90.0f;
double minLon=180.0f, maxLon=-180.0f;
for (id<MKAnnotation> mka in annotations) {
if ( mka.coordinate.latitude < minLat ) minLat = mka.coordinate.latitude;
if ( mka.coordinate.latitude > maxLat ) maxLat = mka.coordinate.latitude;
if ( mka.coordinate.longitude < minLon ) minLon = mka.coordinate.longitude;
if ( mka.coordinate.longitude > maxLon ) maxLon = mka.coordinate.longitude;
}
CLLocationCoordinate2D center = CLLocationCoordinate2DMake((minLat+maxLat)/2.0, (minLon+maxLon)/2.0);
MKCoordinateSpan span = MKCoordinateSpanMake(maxLat-minLat, maxLon-minLon);
MKCoordinateRegion region = MKCoordinateRegionMake (center, span);
return region;
}
// usage
MKCoordinateRegion region = [XXXX regionForAnnotations:self.mapView.annotations];
[self.mapView setRegion:region animated:YES];
MKMapView zooms to discrete intervals, meaning if you zoom over a random region, it will choose the nearest zoom interval. This may have to do with the tiles resolution, but AFAIK is undocumented.
Just to explain the second part of your question about creating an MKMapRect over San Diego and ending up in the ocean...
First, the coordinate 32, -117 is only "near" San Diego.
Actually, it is several kilometers south, in the Pacific Ocean a few km off the west coast of Mexico.
Also note that in an MKMapRect, the origin is the top-left corner of the rectangle (not the center) so the resulting rectangle doesn't completely include the region around the coordinate you are specifying.
The other real problem is that the span size is set to MKMapSizeMake(10, 10).
MKMapSize uses MKMapPoint units (not degrees, meters, miles, km, etc).
The distance in meters a map point equals varies by latitude.
At latitude 32, 10 map points corresponds to 1.261110 meters (which you can calculate with the MapKit function MKMetersPerMapPointAtLatitude using 10.0 * MKMetersPerMapPointAtLatitude(32)).
So the map rect being created is positioned off the west coast of Mexico and it is about 1.26 x 1.26 meters in size. Therefore, you see nothing but ocean (until you zoom out a lot).
Though you could use the function mentioned above to convert meters to map points and create an MKMapRect, it would be easier to use the MKCoordinateRegionMakeWithDistance function which takes a regular coordinate (latitude and longitude in degrees), and the desired width and height in meters so all the calculations are handled by the map view.
I've got a good feeling Jano's answer works perfectly as well, but here is another solution for the sake of variety. It's what I typically use to zoom into the given annotations:
-(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(MKPointAnnotation *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;
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];
}
As of iOS 7 there's a much simpler way to do this:
mapView.showAnnotations(mapView.showAnnotations, animated: true)
Hope this helps.
I am using a mapkit I found on Github to plot directions, but the problem is when the mapview loads it shows US at startup and then moves to the location where route is plotted. Is there any way to show Australia instead at the startup?
Thanks
I'm using this to initialize the Map View, and it works perfectly for me :
CLLocationCoordinate2D coord = {.latitude = XX.XXX, .longitude = X.XXX};
MKCoordinateSpan span = {.latitudeDelta = X.XX, .longitudeDelta = X.XX};
MKCoordinateRegion region = {coord, span};
Then, use the setRegion method for your MKMapView
Is it that you're looking for?
I do the following:
CLLocationCoordinate2D maxCoord = {-90.0f, -180.0f};
CLLocationCoordinate2D minCoord = {90.0f, 180.0f};
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.mainMapView setRegion:region animated:YES];
You can adjust the maxCoord and minCoord inputs to the values you'd like for Australia.
I'm working with MKMapView and have plotted several points on the map. I have used the MKCoordinateRegion and MKCoordinateSpan to enable zooming etc around one of the points - but that's not what I want...
I'm trying to use something similar to the Javascript zoom to bounds function. so all my points should be visible to the user. (There will be around 10 points around the UK) I'd like to show them all, or if most of them were in the London area, zoom to there.
Is there a way to work this out programatically?
Sure. You want to find the biggest and smallest latitude and longitude values among your annotations (which you can do by iterating over map.annotations), then set the map to show all of them.
// pad our map by 10% around the farthest annotations
#define MAP_PADDING 1.1
// we'll make sure that our minimum vertical span is about a kilometer
// there are ~111km to a degree of latitude. regionThatFits will take care of
// longitude, which is more complicated, anyway.
#define MINIMUM_VISIBLE_LATITUDE 0.01
MKCoordinateRegion region;
region.center.latitude = (minLatitude + maxLatitude) / 2;
region.center.longitude = (minLongitude + maxLongitude) / 2;
region.span.latitudeDelta = (maxLatitude - minLatitude) * MAP_PADDING;
region.span.latitudeDelta = (region.span.latitudeDelta < MINIMUM_VISIBLE_LATITUDE)
? MINIMUM_VISIBLE_LATITUDE
: region.span.latitudeDelta;
region.span.longitudeDelta = (maxLongitude - minLongitude) * MAP_PADDING;
MKCoordinateRegion scaledRegion = [map regionThatFits:region];
[map setRegion:scaledRegion animated:YES];
If you are only targeting iOS 7 or greater you can now use:
- (void)showAnnotations:(NSArray *)annotations
animated:(BOOL)animated
Here is an improvement that takes into account the height of the annotation views that you are overlaying onto the map (such that the top of the annotation does not get cut off when its coordinate offset is at the bottom for example). Or to generalise further, allows you to specify padding in pixels as opposed to as a percentage. It requires a two stage pass whereby you find out the bounds for the annotations, then you further increase the bounds to take into account your map padding.
- (void) zoomToAnnotationsBounds:(NSArray *)annotations {
CLLocationDegrees minLatitude = DBL_MAX;
CLLocationDegrees maxLatitude = -DBL_MAX;
CLLocationDegrees minLongitude = DBL_MAX;
CLLocationDegrees maxLongitude = -DBL_MAX;
for (MyAnnotation *annotation in annotations) {
double annotationLat = annotation.coordinate.latitude;
double annotationLong = annotation.coordinate.longitude;
minLatitude = fmin(annotationLat, minLatitude);
maxLatitude = fmax(annotationLat, maxLatitude);
minLongitude = fmin(annotationLong, minLongitude);
maxLongitude = fmax(annotationLong, maxLongitude);
}
// See function below
[self setMapRegionForMinLat:minLatitude minLong:minLongitude maxLat:maxLatitude maxLong:maxLongitude];
// If your markers were 40 in height and 20 in width, this would zoom the map to fit them perfectly. Note that there is a bug in mkmapview's set region which means it will snap the map to the nearest whole zoom level, so you will rarely get a perfect fit. But this will ensure a minimum padding.
UIEdgeInsets mapPadding = UIEdgeInsetsMake(40.0, 10.0, 0.0, 10.0);
CLLocationCoordinate2D relativeFromCoord = [self.mapView convertPoint:CGPointMake(0, 0) toCoordinateFromView:self.mapView];
// Calculate the additional lat/long required at the current zoom level to add the padding
CLLocationCoordinate2D topCoord = [self.mapView convertPoint:CGPointMake(0, mapPadding.top) toCoordinateFromView:self.mapView];
CLLocationCoordinate2D rightCoord = [self.mapView convertPoint:CGPointMake(0, mapPadding.right) toCoordinateFromView:self.mapView];
CLLocationCoordinate2D bottomCoord = [self.mapView convertPoint:CGPointMake(0, mapPadding.bottom) toCoordinateFromView:self.mapView];
CLLocationCoordinate2D leftCoord = [self.mapView convertPoint:CGPointMake(0, mapPadding.left) toCoordinateFromView:self.mapView];
double latitudeSpanToBeAddedToTop = relativeFromCoord.latitude - topCoord.latitude;
double longitudeSpanToBeAddedToRight = relativeFromCoord.latitude - rightCoord.latitude;
double latitudeSpanToBeAddedToBottom = relativeFromCoord.latitude - bottomCoord.latitude;
double longitudeSpanToBeAddedToLeft = relativeFromCoord.latitude - leftCoord.latitude;
maxLatitude = maxLatitude + latitudeSpanToBeAddedToTop;
minLatitude = minLatitude - latitudeSpanToBeAddedToBottom;
maxLongitude = maxLongitude + longitudeSpanToBeAddedToRight;
minLongitude = minLongitude - longitudeSpanToBeAddedToLeft;
[self setMapRegionForMinLat:minLatitude minLong:minLongitude maxLat:maxLatitude maxLong:maxLongitude];
}
-(void) setMapRegionForMinLat:(double)minLatitude minLong:(double)minLongitude maxLat:(double)maxLatitude maxLong:(double)maxLongitude {
MKCoordinateRegion region;
region.center.latitude = (minLatitude + maxLatitude) / 2;
region.center.longitude = (minLongitude + maxLongitude) / 2;
region.span.latitudeDelta = (maxLatitude - minLatitude);
region.span.longitudeDelta = (maxLongitude - minLongitude);
// MKMapView BUG: this snaps to the nearest whole zoom level, which is wrong- it doesn't respect the exact region you asked for. See http://stackoverflow.com/questions/1383296/why-mkmapview-region-is-different-than-requested
[self.mapView setRegion:region animated:YES];
}
It's an old question and I know you might not need any help. But I'm just putting it out there for anyone who is looking for a way to do this now as there's a new method in MKMapView as of iOS 7 that can be used. It is both clean and easy.
Declaration
SWIFT
func showAnnotations(_ annotations: [AnyObject]!,
animated animated: Bool)
OBJECTIVE-C
- (void)showAnnotations:(NSArray *)annotations
animated:(BOOL)animated
Parameters
annotations The annotations that you want to be visible in
the map. animated YES if you want the map region change to be
animated, or NO if you want the map to display the new region
immediately without animations.
Discussion
Calling this method updates
the value in the region property and potentially other properties to
reflect the new map region.
Modified Answer with all Perfect Working Code.
//Zooming the ploted Area
- (void)zoomToAnnotationsBounds:(NSArray *)latLongArray {
__block CLLocationDegrees minLatitude = DBL_MAX;
__block CLLocationDegrees maxLatitude = -DBL_MAX;
__block CLLocationDegrees minLongitude = DBL_MAX;
__block CLLocationDegrees maxLongitude = -DBL_MAX;
[latLongArray enumerateObjectsUsingBlock:^(NSString *latLongObj, NSUInteger latLongIdx, BOOL *stop) {
latLongObj = [latLongArray objectAtIndex:latLongIdx];
NSArray *latLongPoint = [latLongObj componentsSeparatedByString:#","];
double annotationLat = [[latLongPoint objectAtIndex:0] doubleValue];
double annotationLong = [[latLongPoint objectAtIndex:1] doubleValue];
minLatitude = fmin(annotationLat, minLatitude);
maxLatitude = fmax(annotationLat, maxLatitude);
minLongitude = fmin(annotationLong, minLongitude);
maxLongitude = fmax(annotationLong, maxLongitude);
}];
[self setMapRegionForMinLat:minLatitude minLong:minLongitude maxLat:maxLatitude maxLong:maxLongitude];
}
-(void) setMapRegionForMinLat:(double)minLatitude minLong:(double)minLongitude maxLat:(double)maxLatitude maxLong:(double)maxLongitude {
// pad our map by 10% around the farthest annotations
// we'll make sure that our minimum vertical span is about a kilometer
// there are ~111km to a degree of latitude. regionThatFits will take care of
// longitude, which is more complicated, anyway.
MKCoordinateRegion region;
region.center.latitude = (minLatitude + maxLatitude) / 2;
region.center.longitude = (minLongitude + maxLongitude) / 2;
region.span.latitudeDelta = (maxLatitude - minLatitude) * MAP_PADDING;
region.span.latitudeDelta = (region.span.latitudeDelta < MINIMUM_VISIBLE_LATITUDE)
? MINIMUM_VISIBLE_LATITUDE
: region.span.latitudeDelta;
region.span.longitudeDelta = (maxLongitude - minLongitude) * MAP_PADDING;
MKCoordinateRegion scaledRegion = [regionsMapView regionThatFits:region];
[regionsMapView setRegion:scaledRegion animated:YES];
}