缩放MKMapView以适合注释引脚?

fuz*_*oat 190 iphone cocoa-touch objective-c mkmapview ios

我正在使用MKMapView并在地图上添加了许多注释引脚,大约5-10公里的区域.当我运行应用程序时,我的地图开始缩小以显示整个世界,缩放地图以使引脚适​​合视图的最佳方法是什么?

编辑: 我最初的想法是使用MKCoordinateRegionMake并从我的注释中计算坐标中心,longitudeDelta和latitudeDelta.我很确定这会起作用,但我只是想检查一下我没有遗漏任何明显的东西.

代码添加,BTW:FGLocation是一个符合的类MKAnnotation,locationFake是NSMutableArray这些对象中的一个.欢迎评论....

- (MKCoordinateRegion)regionFromLocations {
    CLLocationCoordinate2D upper = [[locationFake objectAtIndex:0] coordinate];
    CLLocationCoordinate2D lower = [[locationFake objectAtIndex:0] coordinate];

    // FIND LIMITS
    for(FGLocation *eachLocation in locationFake) {
        if([eachLocation coordinate].latitude > upper.latitude) upper.latitude = [eachLocation coordinate].latitude;
        if([eachLocation coordinate].latitude < lower.latitude) lower.latitude = [eachLocation coordinate].latitude;
        if([eachLocation coordinate].longitude > upper.longitude) upper.longitude = [eachLocation coordinate].longitude;
        if([eachLocation coordinate].longitude < lower.longitude) lower.longitude = [eachLocation coordinate].longitude;
    }

    // FIND REGION
    MKCoordinateSpan locationSpan;
    locationSpan.latitudeDelta = upper.latitude - lower.latitude;
    locationSpan.longitudeDelta = upper.longitude - lower.longitude;
    CLLocationCoordinate2D locationCenter;
    locationCenter.latitude = (upper.latitude + lower.latitude) / 2;
    locationCenter.longitude = (upper.longitude + lower.longitude) / 2;

    MKCoordinateRegion region = MKCoordinateRegionMake(locationCenter, locationSpan);
    return region;
}
Run Code Online (Sandbox Code Playgroud)

jow*_*wie 334

这是我在这里找到的对我有用的:

(编辑:我已经使用@ Micah的建议更新了解决方案,将pointRect增加0.1,以确保rect不会最终变得极小!)

MKMapRect zoomRect = MKMapRectNull;
for (id <MKAnnotation> annotation in mapView.annotations)
{
    MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
    MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.1, 0.1);
    zoomRect = MKMapRectUnion(zoomRect, pointRect);
}
[mapView setVisibleMapRect:zoomRect animated:YES];
Run Code Online (Sandbox Code Playgroud)

 

您还可以通过将第一行替换为以下内容来更新此包含userLocation引脚:

MKMapPoint annotationPoint = MKMapPointForCoordinate(mapView.userLocation.coordinate);
MKMapRect zoomRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.1, 0.1);
Run Code Online (Sandbox Code Playgroud)

  • 很好的解决方案!这是添加一些填充的额外小触摸:double inset = -zoomRect.size.width*0.1; [self.mapView setVisibleMapRect:MKMapRectInset(zoomRect,inset,inset)animated:YES]; (36认同)
  • 确实不错.您不需要检查isNull.MKMapRectUnion为您完成此任务.从文档:"如果任一矩形为null,则此方法返回另一个矩形." (4认同)
  • 用于填充的@CraigB解决方案非常出色,但是当路径垂直时它不能正常工作,例如从南向北移动,以修复此使用双插入= MIN(-zoomRect.size.width*0.1,-zoomRect.size.身高*0.1); (2认同)

小智 120

Apple为IOS 7添加了一种新方法,以简化生活.

[mapView showAnnotations:yourAnnotationArray animated:YES];
Run Code Online (Sandbox Code Playgroud)

您可以轻松地从存储在地图视图中的数组中提取:

yourAnnotationArray = mapView.annotations;
Run Code Online (Sandbox Code Playgroud)

并快速调整相机!

mapView.camera.altitude *= 1.4;
Run Code Online (Sandbox Code Playgroud)

除非用户安装了iOS 7+或OS X 10.9+,否则这将无效.在这里查看自定义动画


Mat*_*ick 116

你做得对.

找出你的最大和最小纬度和经度,应用一些简单的算术,并使用MKCoordinateRegionMake.

对于iOS 7及更高版本,请使用showAnnotations:animated:,来自MKMapView.h:

// Position the map such that the provided array of annotations are all visible to the fullest extent possible. 
- (void)showAnnotations:(NSArray *)annotations animated:(BOOL)animated NS_AVAILABLE(10_9, 7_0);
Run Code Online (Sandbox Code Playgroud)

  • **对于iOS 7及更高版本(参考MKMapView.h):**`//定位地图,使所提供的注释数组尽可能全部可见." - (void)showAnnotations:(NSArray*)注释动画:(BOOL)动画NS_AVAILABLE(10_9,7_0);` (158认同)
  • 重要的是要注意`showAnnotations`也会将注释添加到地图中,即使该位置的注释已经存在也是如此. (5认同)

Raf*_*ira 42

我使用这个代码,对我来说很好用:

-(void)zoomToFitMapAnnotations:(MKMapView*)aMapView
{
    if([aMapView.annotations count] == 0)
        return;

    CLLocationCoordinate2D topLeftCoord;
    topLeftCoord.latitude = -90;
    topLeftCoord.longitude = 180;

    CLLocationCoordinate2D bottomRightCoord;
    bottomRightCoord.latitude = 90;
    bottomRightCoord.longitude = -180;

    for(MapViewAnnotation *annotation in mapView.annotations)
    {
        topLeftCoord.longitude = fmin(topLeftCoord.longitude, annotation.coordinate.longitude);
        topLeftCoord.latitude = fmax(topLeftCoord.latitude, annotation.coordinate.latitude);

        bottomRightCoord.longitude = fmax(bottomRightCoord.longitude, annotation.coordinate.longitude);
        bottomRightCoord.latitude = fmin(bottomRightCoord.latitude, annotation.coordinate.latitude);
    }

    MKCoordinateRegion region;
    region.center.latitude = topLeftCoord.latitude - (topLeftCoord.latitude - bottomRightCoord.latitude) * 0.5;
    region.center.longitude = topLeftCoord.longitude + (bottomRightCoord.longitude - topLeftCoord.longitude) * 0.5;
    region.span.latitudeDelta = fabs(topLeftCoord.latitude - bottomRightCoord.latitude) * 1.1; // Add a little extra space on the sides
    region.span.longitudeDelta = fabs(bottomRightCoord.longitude - topLeftCoord.longitude) * 1.1; // Add a little extra space on the sides

    region = [aMapView regionThatFits:region];
    [mapView setRegion:region animated:YES];
}
Run Code Online (Sandbox Code Playgroud)


Sre*_*M S 21

在Swift中使用

mapView.showAnnotations(annotationArray, animated: true)
Run Code Online (Sandbox Code Playgroud)

在目标c

[mapView showAnnotations:annotationArray animated:YES];
Run Code Online (Sandbox Code Playgroud)

  • 如果已经在 mapView 上设置了注释,您可以直接使用以下命令引用它们:`mapView.showAnnotations(mapView.annotations,animated: true)` (3认同)

小智 13

@ jowie的解决方案效果很好.一个问题是,如果一个地图只有一个注释,你最终会得到一个完全缩小的地图.我向rect make size添加了0.1,以确保setVisibleMapRect有缩放的东西.

MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.1, 0.1);
Run Code Online (Sandbox Code Playgroud)


osc*_*lon 13

Swift 3这是在地图中拟合所有注释的正确方法.

func zoomMapaFitAnnotations() {

        var zoomRect = MKMapRectNull
        for annotation in mapview.annotations {

            let annotationPoint = MKMapPointForCoordinate(annotation.coordinate)

            let pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0, 0)

            if (MKMapRectIsNull(zoomRect)) {
                zoomRect = pointRect
            } else {
                zoomRect = MKMapRectUnion(zoomRect, pointRect)
            }
        }
        self.mapview.setVisibleMapRect(zoomRect, edgePadding: UIEdgeInsetsMake(50, 50, 50, 50), animated: true)

    }
Run Code Online (Sandbox Code Playgroud)


小智 12

我已经转换了Rafael Moreira的答案.归功于他.对于那些寻找Swift版本的人来说,这里是代码:

 func zoomToFitMapAnnotations(aMapView: MKMapView) {
    guard aMapView.annotations.count > 0 else {
        return
    }
    var topLeftCoord: CLLocationCoordinate2D = CLLocationCoordinate2D()
    topLeftCoord.latitude = -90
    topLeftCoord.longitude = 180
    var bottomRightCoord: CLLocationCoordinate2D = CLLocationCoordinate2D()
    bottomRightCoord.latitude = 90
    bottomRightCoord.longitude = -180
    for annotation: MKAnnotation in myMap.annotations as! [MKAnnotation]{
        topLeftCoord.longitude = fmin(topLeftCoord.longitude, annotation.coordinate.longitude)
        topLeftCoord.latitude = fmax(topLeftCoord.latitude, annotation.coordinate.latitude)
        bottomRightCoord.longitude = fmax(bottomRightCoord.longitude, annotation.coordinate.longitude)
        bottomRightCoord.latitude = fmin(bottomRightCoord.latitude, annotation.coordinate.latitude)
    }

    var region: MKCoordinateRegion = MKCoordinateRegion()
    region.center.latitude = topLeftCoord.latitude - (topLeftCoord.latitude - bottomRightCoord.latitude) * 0.5
    region.center.longitude = topLeftCoord.longitude + (bottomRightCoord.longitude - topLeftCoord.longitude) * 0.5
    region.span.latitudeDelta = fabs(topLeftCoord.latitude - bottomRightCoord.latitude) * 1.4
    region.span.longitudeDelta = fabs(bottomRightCoord.longitude - topLeftCoord.longitude) * 1.4
    region = aMapView.regionThatFits(region)
    myMap.setRegion(region, animated: true)
}
Run Code Online (Sandbox Code Playgroud)


Hel*_*kku 12

如果您正在寻找iOS 8及更高版本,最简单的方法是var layoutMargins: UIEdgeInsets { get set }在调用之前设置地图视图func showAnnotations(annotations: [MKAnnotation], animated: Bool)

例如(Swift 2.1):

@IBOutlet weak var map: MKMapView! {
    didSet {
        map.delegate = self
        map.mapType = .Standard
        map.pitchEnabled = false
        map.rotateEnabled = false
        map.scrollEnabled = true
        map.zoomEnabled = true
    }
}

// call 'updateView()' when viewWillAppear or whenever you set the map annotations
func updateView() {
    map.layoutMargins = UIEdgeInsets(top: 25, left: 25, bottom: 25, right: 25)
    map.showAnnotations(map.annotations, animated: true)
}
Run Code Online (Sandbox Code Playgroud)


Ank*_*ava 11

我创建了一个扩展,使用swift中的一些代码来显示所有注释.如果即使在最大缩放级别也无法显示,则不会显示所有注释.

import MapKit

extension MKMapView {
    func fitAllAnnotations() {
        var zoomRect = MKMapRectNull;
        for annotation in annotations {
            let annotationPoint = MKMapPointForCoordinate(annotation.coordinate)
            let pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.1, 0.1);
            zoomRect = MKMapRectUnion(zoomRect, pointRect);
        }
        setVisibleMapRect(zoomRect, edgePadding: UIEdgeInsets(top: 50, left: 50, bottom: 50, right: 50), animated: true)
    }
}
Run Code Online (Sandbox Code Playgroud)


Sam*_*io2 8

在for循环中添加了此If循环,以从此方法中排除用户位置引脚(在我的情况下,可能是其他人)

if (![annotation isKindOfClass:[MKUserLocation class]] ) {

//Code Here...

}
Run Code Online (Sandbox Code Playgroud)


小智 8

对于iOS 7及更高版本(参考MKMapView.h):

// Position the map such that the provided array of annotations are all visible to the fullest extent possible.          

- (void)showAnnotations:(NSArray *)annotations animated:(BOOL)animated NS_AVAILABLE(10_9, 7_0);
Run Code Online (Sandbox Code Playgroud)

来自Abhishek Bedi的话

你打电话:

 [yourMapView showAnnotations:@[yourAnnotation] animated:YES];
Run Code Online (Sandbox Code Playgroud)


ali*_*tur 5

    var zoomRect: MKMapRect = MKMapRect.null
    for annotation in mapView.annotations {
        let annotationPoint = MKMapPoint(annotation.coordinate)
        let pointRect = MKMapRect(x: annotationPoint.x, y: annotationPoint.y, width: 0.1, height: 0.1)
        zoomRect = zoomRect.union(pointRect)
    }
    mapView.setVisibleMapRect(zoomRect, animated: true)
Run Code Online (Sandbox Code Playgroud)

//编辑迅速5


小智 5

在斯威夫特

    var zoomRect = MKMapRectNull;

    for i in 0..<self.map.annotations.count {

        let annotation: MKAnnotation = self.map.annotations[i]

        let annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
        let pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.1, 0.1);
        zoomRect = MKMapRectUnion(zoomRect, pointRect);
    }

    self.map.setVisibleMapRect(zoomRect, animated: true)
Run Code Online (Sandbox Code Playgroud)