In iOS 6, I'm trying to implement the ability to change the region of an MkMapView without changing the rotation.
Basically, I need to be able to move the map to display a region (and therefore set the zoom) but also I don't want to rotate the map when I call [mapView setRegion:]
.
[mapView setCenterCoordinate:]
works well, but doesn't allow me to change the zoom level.
In iOS 7, I use [mapView setCamera:]
, where I have a camera with the center coordinate and the zoom level specified... I basically need this functionality in iOS 6.
Any ideas? Thanks!
I had this exact same problem and ended up abandoning the [mapView setRegion:]
method entirely, in favor of [mapView setCamera:]
using the original region and heading as the basis for how to orient the camera.
MKCoordinateRegion currentRegion = MKCoordinateRegionMake(center, span);
double altitude = [self determineAltitudeForMapRect:MKMapRectForCoordinateRegion(currentRegion) withHeading:_heading andWithViewport:[[UIScreen mainScreen] bounds].size];
MKMapCamera *currentCamera = [MKMapCamera new];
[currentCamera setHeading:_heading];
[currentCamera setCenterCoordinate:center];
[currentCamera setAltitude:altitude];
[_mapView setCamera:currentCamera];
The trick with this option was how to determine [currentCamera setAltitude:]
value, which would normally have been set automatically with [mapView setRegion:]
My solution was an adaptation this answer https://stackoverflow.com/a/21034410/1130983 where it uses some simple trig to determine the altitude, assuming the map camara has about a 30 degree viewing angle. However, instead of passing in a polygon, I'm passing in the MKMapRect directly:
- (double)determineAltitudeForMapRect:(MKMapRect)boundingRect withHeading:(double)heading andWithViewport:(CGSize)viewport
{
// Get a bounding rectangle that encompasses the polygon and represents its
// true aspect ratio based on the understanding of its heading.
MKCoordinateRegion boundingRectRegion = MKCoordinateRegionForMapRect(boundingRect);
// Calculate a new bounding rectangle that is corrected for the aspect ratio
// of the viewport/camera -- this will be needed to ensure the resulting
// altitude actually fits the polygon in view for the observer.
CLLocationCoordinate2D upperLeftCoord = CLLocationCoordinate2DMake(boundingRectRegion.center.latitude + boundingRectRegion.span.latitudeDelta / 2, boundingRectRegion.center.longitude - boundingRectRegion.span.longitudeDelta / 2);
CLLocationCoordinate2D upperRightCoord = CLLocationCoordinate2DMake(boundingRectRegion.center.latitude + boundingRectRegion.span.latitudeDelta / 2, boundingRectRegion.center.longitude + boundingRectRegion.span.longitudeDelta / 2);
CLLocationCoordinate2D lowerLeftCoord = CLLocationCoordinate2DMake(boundingRectRegion.center.latitude - boundingRectRegion.span.latitudeDelta / 2, boundingRectRegion.center.longitude - boundingRectRegion.span.longitudeDelta / 2);
CLLocationDistance hDist = MKMetersBetweenMapPoints(MKMapPointForCoordinate(upperLeftCoord), MKMapPointForCoordinate(upperRightCoord));
CLLocationDistance vDist = MKMetersBetweenMapPoints(MKMapPointForCoordinate(upperLeftCoord), MKMapPointForCoordinate(lowerLeftCoord));
double adjacent;
if (boundingRect.size.height > boundingRect.size.width)
{
adjacent = vDist / 2;
}
else
{
adjacent = hDist / 2;
}
double result = adjacent / tan(DEGREES_TO_RADIANS(15));
return result;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With