iOS MKMapView缩放以显示所有标记

Mat*_*cer 22 iphone mkmapview

我正在使用MKMapView并在地图上绘制了几个点.我已经使用了MKCoordinateRegionMKCoordinateSpan围绕其中一个点启用缩放等 - 但这不是我想要的......

我正在尝试使用类似于Javascript zoom to bounds功能的东西.所以我的所有要点都应该对用户可见.(英国各地将有大约10个点)我想向他们展示所有这些,或者如果他们大多数都在伦敦地区,请放大到那里.

有没有办法以编程方式解决这个问题?

Sea*_*ell 68

当然.您希望在注释中找到最大和最小的纬度和经度值(您可以通过迭代map.annotations来完成),然后设置地图以显示所有这些值.

// 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];
Run Code Online (Sandbox Code Playgroud)


Ger*_*haw 18

如果您只定位iOS 7或更高版本,现在可以使用:

- (void)showAnnotations:(NSArray *)annotations 
               animated:(BOOL)animated
Run Code Online (Sandbox Code Playgroud)


Wil*_*ter 14

这是一项改进,它考虑了您覆盖在地图上的注释视图的高度(例如,当其坐标偏移位于底部时,注释的顶部不会被截断).或者进一步概括,允许您指定以像素为单位的填充而不是百分比.它需要两阶段传递,您可以找到注释的边界,然后进一步增加边界以考虑您的地图填充.

- (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];
}
Run Code Online (Sandbox Code Playgroud)


Mat*_*att 7

这是一个老问题,我知道你可能不需要任何帮助.但是我现在只是为那些正在寻找方法的人提供它,MKMapView因为iOS 7中有一种可以使用的新方法.它既干净又容易.

宣言

迅速

func showAnnotations(_ annotations: [AnyObject]!,
            animated animated: Bool)
Run Code Online (Sandbox Code Playgroud)

Objective-C的

- (void)showAnnotations:(NSArray *)annotations
               animated:(BOOL)animated
Run Code Online (Sandbox Code Playgroud)

参数

注释要在地图中显示的注释.如果要将地图区域更改设置为动画,则为"是";如果希望地图在没有动画的情况下立即显示新区域,则为"否".

讨论

调用此方法会更新region属性中的值以及可能的其他属性以反映新的地图区域.