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
Related
I want to show my current location on the left-hand side of the map.
CLLocationCoordinate2D theCoordinate;
theCoordinate.latitude = 26.926;
theCoordinate.longitude = 75.8235;
MKCoordinateRegion region;
region.center = theCoordinate;
MKCoordinateSpan span;
span.latitudeDelta = 0.005;
span.longitudeDelta = 0.005;
region.span=span;
[mapView setRegion:region animated:TRUE];
The above code shows my location in the center of the map because of this line:
region.center = theCoordinate;
Is there a way to change this on any specific position other than the center?
Thank you.
Nitesh
This is not specific to Objective-C. You need to calculate what the center would be, if the desired location is on the left of the map. ie, given a map of width X in pixels, and scale T, what is the long/lat of the point X/2 pixels east of my position. Once you have that, you can assign
region.center = theNewCoordinate;
You could add a kind of offset ?
CLLocationCoordinate2D coordinatesForCenter = [theCoordinate copy];
// Add an offset :
coordinatesForCenter.latitude+=5; // 5 for exemple (it's not significant)
coordinatesForCenter.longitude+=5;
// Center on your new coordinates :
region.center = coordinatesForCenter;
Hope it helps.
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`
I am working with a MKMapView thats visible area (zoom level) is set with a slider.
I set the visible area with a MKCoordinateRegion and setRegion:animated:.
The problem is that I don't seem to be able to get extremely precise control over the visible area. It's as if the latitude\longitude deltas snap to the default ~21 zoom levels provided by Google.
What I really want is similar to the behavior of the Map.app when pinching to zoom. It scales the view until the threshold for a new zoom level is reached, and then it renders the new map level.
Is there a simple way to access\emulate this behavior? How does it work?
Code I'm using:
MKCoordinateRegion region;
MKCoordinateSpan span;
CLLocationCoordinate2D center = {45.475969,-73.64095};
region.center = center;
span.latitudeDelta = 0.01;
span.longitudeDelta = 0.01;
region.span = span;
[mapView setRegion:region animated:TRUE];
If I use a delta of 0.01 or 0.013, I get the exact same map.
The simple answer is that MapKit does not allow you to programatically set a zoom level other than the default 21 levels supplied by google. The region span you set will always "snap" to the closest one.
Are you using setRegion:animated: ?
http://developer.apple.com/library/ios/#documentation/MapKit/Reference/MKMapView_Class/MKMapView/MKMapView.html#//apple_ref/occ/instm/MKMapView/setRegion:animated:
You can set mapview's visibleMapRect to achieve continuous zooming.
Following code shows how to zoom in 1 level (it's a subclass of a MKMapView so self is an instance of MKMapView).
MKMapRect visibleRect = self.visibleMapRect;
MKMapSize size = visibleRect.size;
CGFloat aspectRatio = size.width / size.height;
CGPoint center = CGPointMake(visibleRect.origin.x + size.width/2, visibleRect.origin.y + size.height/2);
CGFloat zoomedHeight = size.height / 2; // By divide by 2, will zoom in exact 1 level
CGFloat zoomedWidth = zoomedHeight * aspectRatio;
visibleRect = MKMapRectMake(center.x - zoomedWidth/2, center.y - zoomedHeight/2, zoomedWidth, zoomedHeight);
self.visibleMapRect = visibleRect;
I'm looking for a method to convert meters to a mapview region.
CLLocation's horizontalAccuracy is a double, representing the accuracy in meters. regionThatFits: takes an MKCoordinateRegion which has a span with longitudeDelta and latitudeDelta. How can I convert meters to a longitude/latitude span?
Found an answer. It seems that 1 degree of latitude is equal to around 111 kilometers, or 111120 meters
- (MKCoordinateRegion)regionForAccuracyOfLocation:(CLLocation *)location
{
CLLocationDegrees spanInDegrees = (CLLocationDegrees) (location.horizontalAccuracy / 222240);
MKCoordinateSpan span = MKCoordinateSpanMake(spanInDegrees, spanInDegrees) ;
CLLocationCoordinate2D coordinate = location.coordinate;
MKCoordinateRegion region = MKCoordinateRegionMake(coordinate, span);
return region;
}
I need to know the distance (in kilometers) from center map to the other side of the screen, (and if the zoom change the distance will change).
I need to implement this feature in this function
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{
}
Any ideas how i can do this?
Thanks
MkMapView has properties named centerCoordinate(CLLocationCoordinate2D) and region (MKCoordinateRegion). Region is a struct that:
typedef struct {
CLLocationDegrees latitudeDelta;
CLLocationDegrees longitudeDelta;
}MKCoordinateSpan
You should be able to create another point, based on centerCoordinate, let's say, by adding latitudeDelta to you latitude property or centerCoordinate, and calculate distance using the method of CLLocation:
- (CLLocationDistance)distanceFromLocation:(const CLLocation *)location
Something like this
MkMapView * mapView; // init somewhere
MKCoordinateRegion region = mapView.region;
CLLocationCoordinate2D centerCoordinate = mapView.centerCoordinate;
CLLocation * newLocation = [[[CLLocation alloc] initWithLatitude:centerCoordinate.latitude+region.span.latitudeDelta longitude:centerCoordinate.longitude] autorelease];
CLLocation * centerLocation = [[[CLLocation alloc] initWithLatitude:centerCoordinate.latitude:longitude:centerCoordinate.longitude] autorelease];
CLLocationDistance distance = [centerLocation distanceFromLocation:newLocation]; // in meters
And just calculate each time a delegate fires a certain method (decide which you need: MKMapViewDelegate)
Because rectangles aren't circles you can't get a radius.
But you can still get the furthest distance from the center of a region.
Reusing the same idea as above but embeded in a swift extension.
extension MKCoordinateRegion {
func distanceMax() -> CLLocationDistance {
let furthest = CLLocation(latitude: center.latitude + (span.latitudeDelta/2),
longitude: center.longitude + (span.longitudeDelta/2))
let centerLoc = CLLocation(latitude: center.latitude, longitude: center.longitude)
return centerLoc.distanceFromLocation(furthest)
}
}
Usage
let radius = mapView.region.distanceMax()