将MKMapView缩放以适应折线点

35

我有一个数组allCollections,它保存了用户通过我的iOS应用程序记录的CLLocations的程序化创建数组。 allCollections中的每个子数组都保存了一次旅行中的所有位置点。

我使用allCollections中数组中的CLLocations绘制MKPolylines以在MKMapView上表示这些旅行。我的问题是:在将折线添加到地图上后,如何编程实现缩放和居中地图以显示所有内容?

8个回答

71
-(void)zoomToPolyLine: (MKMapView*)map polyline: (MKPolyline*)polyline animated: (BOOL)animated
{
    [map setVisibleMapRect:[polyline boundingMapRect] edgePadding:UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0) animated:animated];
}

1
@BradKoch 这个解决方案使用 boundingMapRect 来定义一个包含折线覆盖层的矩形。然后,它使用 setVisibleMapRect 将地图缩放区域设置为该矩形,并考虑到可调整的填充值 edgePadding。我发现这个解决方案最有帮助,因为它可以用很少的代码高效地解决问题,并且还允许通过插图更改地图视图区域。 - sheepgobeep
2
这对我有效。但显然,这将缩放因子设置为填充屏幕,而不是适合屏幕。你能想到解决办法吗? - Julian F. Weinert
对于具有插入的解决方案,加一。 - fulvio
好的解决方案+1。唯一需要注意的是填充需要根据视觉需求进行调整,这样它就能支持所有其他叠加层。 - iLearner

15

在Swift中:

if let first = mapView.overlays.first {
    let rect = mapView.overlays.reduce(first.boundingMapRect, combine: {MKMapRectUnion($0, $1.boundingMapRect)})
    mapView.setVisibleMapRect(rect, edgePadding: UIEdgeInsets(top: 50.0, left: 50.0, bottom: 50.0, right: 50.0), animated: true)
}

这将缩放/平移以适应所有覆盖层,留有一定的缓冲区


15
-(void)zoomToPolyLine: (MKMapView*)map polyLine: (MKPolyline*)polyLine 
animated (BOOL)animated
{
MKPolygon* polygon = 
    [MKPolygon polygonWithPoints:polyLine.points count:polyLine.pointCount];

[map setRegion:MKCoordinateRegionForMapRect([polygon boundingMapRect]) 
     animated:animated];
}

2
不需要创建MKPolygon,因为MKPolyline已经实现了boundingMapRect。 - foOg
你是如何将围栏指定给CLLocation的?? 在地理围栏中,你如何分配CLRegion而不是圆形区域? - Majid Bashir

10
您可以遍历所有的CLLocations,记录max/min坐标,并使用它来设置视图矩形,就像这个问题中所做的那样:iOS MKMapView zoom to show all markers
或者您可以遍历每个覆盖层并获取它们的boundingMapRect,然后使用MKMapRectUnionhttp://developer.apple.com/library/ios/documentation/MapKit/Reference/MapKitFunctionsReference/Reference/reference.html#//apple_ref/c/func/MKMapRectUnion)将它们组合成一个覆盖所有区域的MKMapRect,并使用它来设置视图。
[mapView setVisibleMapRect:zoomRect animated:YES]

这个问题展示了一个简单的循环,将maprects合并到联合中,就像我建议的一样:MKMapRect zooms too much


我欠你一瓶啤酒 :) - Devarshi
MKMapRectUnion链接已损坏,这是新页面https://developer.apple.com/documentation/mapkit/1452123-mkmaprectunion - Marco Boschi

9

这是Swift 4 / fundtimer答案的略微修改版。

 func setVisibleMapArea(polyline: MKPolyline, edgeInsets: UIEdgeInsets, animated: Bool = false) {
    mapView.setVisibleMapRect(polyline.boundingMapRect, edgePadding: edgeInsets, animated: animated)
}

使用路线的折线并保留默认设置为不动画,同时在周围添加小边缘插图10:

setVisibleMapArea(polyline: route.polyline, edgeInsets: UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0))

一个简单的解决方案 - 很好! - user1162328

9

Swift 3 版本的 garafajon 优秀代码

    if let first = self.mapView.overlays.first {
        let rect = self.mapView.overlays.reduce(first.boundingMapRect, {MKMapRectUnion($0, $1.boundingMapRect)})
        self.mapView.setVisibleMapRect(rect, edgePadding: UIEdgeInsets(top: 50.0, left: 50.0, bottom: 50.0, right: 50.0), animated: true)
    }

Swift 5版本:以上代码的第二行稍作更改: let rect = self.mapView.overlays.reduce(first.boundingMapRect, {$0.union($1.boundingMapRect)}) - cseh_17

1
我有另一个解决这个问题的方案。
private func mapRegion() -> MKCoordinateRegion? {


    let latitudes = self.coordinates.map { location -> Double in

        return location.latitude
    }

    let longitudes = self.coordinates.map { location -> Double in

        return location.longitude
    }

    let maxLat = latitudes.max()!
    let minLat = latitudes.min()!
    let maxLong = longitudes.max()!
    let minLong = longitudes.min()!

    let center = CLLocationCoordinate2D(latitude: (minLat + maxLat) / 2,
                                        longitude: (minLong + maxLong) / 2)
    let span = MKCoordinateSpan(latitudeDelta: (maxLat - minLat) * 1.3,
                                longitudeDelta: (maxLong - minLong) * 1.3)
    return MKCoordinateRegion(center: center, span: span)
}

坐标是一个CLLocationCoordinate2D数组

希望对某些人有所帮助


0

@Fundtimer说得没错,唯一需要注意的是填充(Padding)需要根据实际需求进行调整,这样就可以支持所有其他叠加层。以下是适用于所有叠加层的通用解决方案。

-(void)zoomIntoExistingMapObjectForAnnot:(CustomMapAnnotation *)annot
{
   id overlay = annot.shape;//I have overlay property in custom annotation class.
   [_mapView setVisibleMapRect:[overlay boundingMapRect] edgePadding:UIEdgeInsetsMake(150.0, 150.0, 150.0, 150.0) animated:YES];
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接