首页 > 技术文章 > 高德地图缩放

mgbert 2014-12-02 10:21 原文

 1 #import <MAMapKit/MAMapKit.h>
 2 
 3 @interface MAMapView (ZoomLevel)
 4 - (NSUInteger)getZoomLevel;
 5 
 6 - (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
 7                   zoomLevel:(NSUInteger)zoomLevel
 8                    animated:(BOOL)animated;
 9 
10 - (void)zoomToFitMapAnnotations;
11 @end
  1 //
  2 //  MAMapView+ZoomLevel.m
  3 //  Yjf
  4 //
  5 //  Created by iMac on 14/12/2.
  6 //  Copyright (c) 2014年 POTech. All rights reserved.
  7 //
  8 
  9 #import "MAMapView+ZoomLevel.h"
 10 
 11 #define MERCATOR_OFFSET 268435456
 12 #define MERCATOR_RADIUS 85445659.44705395
 13 
 14 @implementation MAMapView (ZoomLevel)
 15 
 16 #pragma mark - Map conversion methods
 17 
 18 - (double)longitudeToPixelSpaceX:(double)longitude
 19 {
 20     return round(MERCATOR_OFFSET + MERCATOR_RADIUS * longitude * M_PI / 180.0);
 21 }
 22 
 23 - (double)latitudeToPixelSpaceY:(double)latitude
 24 {
 25     return round(MERCATOR_OFFSET - MERCATOR_RADIUS * logf((1 + sinf(latitude * M_PI / 180.0)) / (1 - sinf(latitude * M_PI / 180.0))) / 2.0);
 26 }
 27 
 28 - (double)pixelSpaceXToLongitude:(double)pixelX
 29 {
 30     return ((round(pixelX) - MERCATOR_OFFSET) / MERCATOR_RADIUS) * 180.0 / M_PI;
 31 }
 32 
 33 - (double)pixelSpaceYToLatitude:(double)pixelY
 34 {
 35     return (M_PI / 2.0 - 2.0 * atan(exp((round(pixelY) - MERCATOR_OFFSET) / MERCATOR_RADIUS))) * 180.0 / M_PI;
 36 }
 37 
 38 #pragma mark - Helper methods
 39 
 40 - (MACoordinateSpan)coordinateSpanWithMapView:(MAMapView *)mapView
 41                              centerCoordinate:(CLLocationCoordinate2D)centerCoordinate
 42                                  andZoomLevel:(NSUInteger)zoomLevel
 43 {
 44     // convert center coordiate to pixel space
 45     double centerPixelX = [self longitudeToPixelSpaceX:centerCoordinate.longitude];
 46     double centerPixelY = [self latitudeToPixelSpaceY:centerCoordinate.latitude];
 47     
 48     // determine the scale value from the zoom level
 49     NSInteger zoomExponent = 20 - zoomLevel;
 50     double zoomScale = pow(2, zoomExponent);
 51     
 52     // scale the map’s size in pixel space
 53     CGSize mapSizeInPixels = mapView.bounds.size;
 54     double scaledMapWidth = mapSizeInPixels.width * zoomScale;
 55     double scaledMapHeight = mapSizeInPixels.height * zoomScale;
 56     
 57     // figure out the position of the top-left pixel
 58     double topLeftPixelX = centerPixelX - (scaledMapWidth / 2);
 59     double topLeftPixelY = centerPixelY - (scaledMapHeight / 2);
 60     
 61     // find delta between left and right longitudes
 62     CLLocationDegrees minLng = [self pixelSpaceXToLongitude:topLeftPixelX];
 63     CLLocationDegrees maxLng = [self pixelSpaceXToLongitude:topLeftPixelX + scaledMapWidth];
 64     CLLocationDegrees longitudeDelta = maxLng - minLng;
 65     
 66     // find delta between top and bottom latitudes
 67     CLLocationDegrees minLat = [self pixelSpaceYToLatitude:topLeftPixelY];
 68     CLLocationDegrees maxLat = [self pixelSpaceYToLatitude:topLeftPixelY + scaledMapHeight];
 69     CLLocationDegrees latitudeDelta = -1 * (maxLat - minLat);
 70     
 71     // create and return the lat/lng span
 72     MACoordinateSpan span = MACoordinateSpanMake(latitudeDelta, longitudeDelta);
 73     return span;
 74 }
 75 
 76 #pragma mark - Public methods
 77 
 78 - (NSUInteger)getZoomLevel
 79 {
 80     return 21-round(log2(self.region.span.longitudeDelta * MERCATOR_RADIUS * M_PI / (180.0 * self.bounds.size.width)));
 81 }
 82 
 83 - (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
 84                   zoomLevel:(NSUInteger)zoomLevel
 85                    animated:(BOOL)animated
 86 {
 87     // clamp large numbers to 28
 88     zoomLevel = MIN(zoomLevel, 28);
 89     
 90     // use the zoom level to compute the region
 91     MACoordinateSpan span = [self coordinateSpanWithMapView:self centerCoordinate:centerCoordinate andZoomLevel:zoomLevel];
 92     MACoordinateRegion region = MACoordinateRegionMake(centerCoordinate, span);
 93     
 94     // set the region like normal
 95     [self setRegion:region animated:animated];
 96 }
 97 
 98 - (void)zoomToFitMapAnnotations
 99 {
100     if ([self.annotations count] == 0) return;
101     
102     CLLocationCoordinate2D topLeftCoord;
103     topLeftCoord.latitude = -90;
104     topLeftCoord.longitude = 180;
105     
106     CLLocationCoordinate2D bottomRightCoord;
107     bottomRightCoord.latitude = 90;
108     bottomRightCoord.longitude = -180;
109     
110     for(id<MAAnnotation> annotation in self.annotations) {
111         if ([annotation isKindOfClass:[MAUserLocation class]]) {
112             continue;
113         }
114         topLeftCoord.longitude = fmin(topLeftCoord.longitude, annotation.coordinate.longitude);
115         topLeftCoord.latitude = fmax(topLeftCoord.latitude, annotation.coordinate.latitude);
116         bottomRightCoord.longitude = fmax(bottomRightCoord.longitude, annotation.coordinate.longitude);
117         bottomRightCoord.latitude = fmin(bottomRightCoord.latitude, annotation.coordinate.latitude);
118     }
119     
120     MACoordinateRegion region;
121     region.center.latitude = topLeftCoord.latitude - (topLeftCoord.latitude - bottomRightCoord.latitude) * 0.5;
122     region.center.longitude = topLeftCoord.longitude + (bottomRightCoord.longitude - topLeftCoord.longitude) * 0.5;
123     region.span.latitudeDelta = fabs(topLeftCoord.latitude - bottomRightCoord.latitude) * 1.2;
124     region.span.longitudeDelta = fabs(bottomRightCoord.longitude - topLeftCoord.longitude) * 1.2;
125     
126     region = [self regionThatFits:region];
127     [self setRegion:region animated:YES];
128 }
129 
130 @end

 

推荐阅读