How do can I add 2 miles to viewRegion.span.latitudeDelta? - iphone

How do can I add 2 miles to viewRegion.span.latitudeDelta ? How do can I calculate kTwoMiles?
MKCoordinateRegion viewRegion;
viewRegion.center = coordinateCentre;
viewRegion.span.latitudeDelta = latitudeMax - latitudeMin + kTwoMiles;
viewRegion.span.longitudeDelta = longitudeMax - longitudeMin + kTwoMiles;
MKCoordinateRegion adjustedRegion = [mapView regionThatFits:viewRegion];
[mapView setRegion:adjustedRegion animated:YES];

Basically this is relatively complicated because every degree has a different delta.
At Earth's equator you will have 111 km per degree and at the poles 0 km. (http://en.wikipedia.org/wiki/Longitude#Degree_length)

I decided to add 2 miles only in the latitudeDelta. Probably regionThatFits will resize longitudeDelta.
double kTwoMiles = (double)2/69;
MKCoordinateRegion viewRegion;
viewRegion.center = coordinateCentre;
viewRegion.span.latitudeDelta = latitudeMax - latitudeMin + kTwoMiles;
viewRegion.span.longitudeDelta = longitudeMax - longitudeMin;
MKCoordinateRegion adjustedRegion = [mapView regionThatFits:viewRegion];
[mapView setRegion:adjustedRegion animated:YES];`enter code here`

Related

How to set the map to a particular location on map load

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.

how to make mapview zoom to 5 mile radius of current location

I know its a very common issue but I am not getting the exact answer for this thing.
How to make MKMapView defaults to a zoom of a 5 mile radius of current location.
Thanks in advance.
Use the MKCoordinateRegionMakeWithDistance function from MapKit.
Use a conversion function to convert miles to meters since MapKit uses meters.
float MilesToMeters(float miles) {
// 1 mile is 1609.344 meters
// source: http://www.google.com/search?q=1+mile+in+meters
return 1609.344f * miles;
}
Then in your code set the map region as (thanks to #DylanBettermann for pointing out that to get a radius of 5 miles, the distance needs to be doubled)
mapView.region = MKCoordinateRegionMakeWithDistance(
centerCoordinate,
MilesToMeters(10.0f),
MilesToMeters(10.0f)
);
swift 4 version :
mapView.region = MKCoordinateRegion(
center: centerCoordinate,
latitudinalMeters: MilesToMeters(10.0f),
longitudinalMeters: MilesToMeters(10.0f)
)
Use the following code when ever you want to zoom to 5 miles radius:
double miles = 5.0;
double scalingFactor = ABS( (cos(2 * M_PI * newLocation.coordinate.latitude / 360.0) ));
MKCoordinateSpan span;
span.latitudeDelta = miles/69.0;
span.longitudeDelta = miles/(scalingFactor * 69.0);
MKCoordinateRegion region;
region.span = span;
region.center = newLocation.coordinate;
[mapView setRegion:region animated:YES];
[self.theMapView setRegion:MKCoordinateRegionMake(
[theConsumer.latLong.clLocation coordinate],
MKCoordinateSpanMake( MAP_SPAN, MAP_SPAN ))
animated:YES];
The parameters to MKCoordinateSpanMake are in degrees, and 1 degree is approx 69 miles at the equator. Thus MAP_SPAN would be 5.0/69.0

How can I center a UIMapView around an array of MKAnnotation?

How can I center a UIMapView around an array of MKAnnotation?
First find the minimum and maximum latitude and longitude from your array of annotations. Then you can set the region:
MKCoordinateRegion extents;
extents.center.latitude = (maxLat + minLat)/2.0;
extents.center.longitude = (maxLong + minLong)/2.0;
extents.span.latitudeDelta = (maxLat - minLat);
extents.span.longitudeDelta = (maxLong - minLong);
MKCoordinateRegion fittedRegion = [mapView regionThatFits:extents];
[mapView setRegion:fittedRegion animated:YES];

iOS MKMapView zoom to show all markers

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];
}

MKMapView broken in 3.2.3 / OS4 - Can't set region

In the last version of Xcode, set region worked fine, now in 3.2.3 it doesn't snap to your specified region?
After View did load...
[mapView setMapType:MKMapTypeHybrid];
[mapView setZoomEnabled:YES];
[mapView setScrollEnabled:YES];
MKCoordinateRegion region = { {0.0, 0.0 }, { 0.0, 0.0 } };
region.center.latitude = 41.902245099708516;
region.center.longitude = 12.457906007766724;
region.span.longitudeDelta = 0.04f;
region.span.latitudeDelta = 0.04f;
[mapView setRegion:region animated:YES];
[mapView setDelegate:self];
This is the code that worked fine, now it doesn't snap to the location denoted above, it just shows the world map.
Any help greatly appreciated.
I've done it lots in 3.2.3 and iOS4. I promise it works.
I like MKCoordinateRegionMakeWithDistance().
CLLocationCoordinate2d coord = { 41.902245099708516, 12.457906007766724 };
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(coord, 1000, 1000);
[mapView setRegion:[mapView regionThatFits:region] animated:YES];
That "1000, 1000" in the second and third arg are the latitudinal and longitudinal meters of the range component of the region. Passing the region through the mapview's -regionThatFits: method is just good practice.