How to detect that MKMapView is zoomed out/in?

后端 未结 1 1130
余生分开走
余生分开走 2021-02-04 15:32

I am writing the following code,

- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {
    mapRegion = mapView.region; //MKCoordinateRe         


        
相关标签:
1条回答
  • 2021-02-04 16:01

    Create MKMapView+ZoomLevel.h as

    #import <MapKit/MapKit.h>
    
    @interface MKMapView (ZoomLevel)
    
    - (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
                      zoomLevel:(double)zoomLevel
                       animated:(BOOL)animated;
    
    @end 
    

    Create MKMapView+ZoomLevel.m as

    #import "MKMapView+ZoomLevel.h"
    
    #define MERCATOR_OFFSET 268435456
    #define MERCATOR_RADIUS 85445659.44705395
    
    @implementation MKMapView (ZoomLevel)
    
    #pragma mark -
    #pragma mark Map conversion methods
    
    - (double)longitudeToPixelSpaceX:(double)longitude
    {
        return round(MERCATOR_OFFSET + MERCATOR_RADIUS * longitude * M_PI / 180.0);
    }
    
    - (double)latitudeToPixelSpaceY:(double)latitude
    {
        return round(MERCATOR_OFFSET - MERCATOR_RADIUS * logf((1 + sinf(latitude * M_PI / 180.0)) / (1 - sinf(latitude * M_PI / 180.0))) / 2.0);
    }
    
    - (double)pixelSpaceXToLongitude:(double)pixelX
    {
        return ((round(pixelX) - MERCATOR_OFFSET) / MERCATOR_RADIUS) * 180.0 / M_PI;
    }
    
    - (double)pixelSpaceYToLatitude:(double)pixelY
    {
        return (M_PI / 2.0 - 2.0 * atan(exp((round(pixelY) - MERCATOR_OFFSET) / MERCATOR_RADIUS))) * 180.0 / M_PI;
    }
    
    #pragma mark -
    #pragma mark Helper methods
    
    - (MKCoordinateSpan)coordinateSpanWithMapView:(MKMapView *)mapView
                                 centerCoordinate:(CLLocationCoordinate2D)centerCoordinate
                                     andZoomLevel:(double)zoomLevel
    {
        NSLog(@"in custom zoomlevel-->%f",zoomLevel);
        // convert center coordiate to pixel space
        double centerPixelX = [self longitudeToPixelSpaceX:centerCoordinate.longitude];
        double centerPixelY = [self latitudeToPixelSpaceY:centerCoordinate.latitude];
    
        // determine the scale value from the zoom level
        double zoomExponent = 20.0 - zoomLevel;
        double zoomScale = pow(2, zoomExponent);
    
        // scale the map’s size in pixel space
        CGSize mapSizeInPixels = mapView.bounds.size;
        double scaledMapWidth = mapSizeInPixels.width * zoomScale;
        double scaledMapHeight = mapSizeInPixels.height * zoomScale;
    
        // figure out the position of the top-left pixel
        double topLeftPixelX = centerPixelX - (scaledMapWidth / 2);
        double topLeftPixelY = centerPixelY - (scaledMapHeight / 2);
    
        // find delta between left and right longitudes
        CLLocationDegrees minLng = [self pixelSpaceXToLongitude:topLeftPixelX];
        CLLocationDegrees maxLng = [self pixelSpaceXToLongitude:topLeftPixelX + scaledMapWidth];
        CLLocationDegrees longitudeDelta = maxLng - minLng;
    
        // find delta between top and bottom latitudes
        CLLocationDegrees minLat = [self pixelSpaceYToLatitude:topLeftPixelY];
        CLLocationDegrees maxLat = [self pixelSpaceYToLatitude:topLeftPixelY + scaledMapHeight];
        CLLocationDegrees latitudeDelta = -1 * (maxLat - minLat);
    
        // create and return the lat/lng span
        MKCoordinateSpan span = MKCoordinateSpanMake(latitudeDelta, longitudeDelta);
        return span;
    }
    
    #pragma mark -
    #pragma mark Public methods
    
    - (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
                      zoomLevel:(double)zoomLevel
                       animated:(BOOL)animated
    {
        // clamp large numbers to 28
        zoomLevel = MIN(zoomLevel, 28);
    
        // use the zoom level to compute the region
        MKCoordinateSpan span = [self coordinateSpanWithMapView:self centerCoordinate:centerCoordinate andZoomLevel:zoomLevel];
        MKCoordinateRegion region = MKCoordinateRegionMake(centerCoordinate, span);
    
        // set the region like normal
        [self setRegion:region animated:animated];
    }
    
    @end 
    

    #import "MKMapView+ZoomLevel.h" statement in your view controller where MKMapView is taken.

    - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
    {   
        double zoomLevel = [self getZoomLevel]; 
        [lblCurrentLevel setText:[NSString stringWithFormat:@"%.2f",zoomLevel]];
    
        NSLog(@"zoomlevel-->%f long-->%f lat-->%f",zoomLevel,mapView.region.span.longitudeDelta,mapView.region.span.latitudeDelta);
    }
    
    - (double) getZoomLevel
    {
        return 21.00 - log2(objMapView.region.span.longitudeDelta * MERCATOR_RADIUS * M_PI / (180.0 * objMapView.bounds.size.width));
    }
    

    In above methods you can get zoom levels as desired, the only thing you have to do is maintain initial zoom and compare latest zoom in/out with that and assign again to that variable.

    In case of any query let me know we will work out on that :D

    Edit

    This source code is from Troy's Blog. Apologize for not mentioning before.

    0 讨论(0)
提交回复
热议问题