如何使用Swift限制MKMapView最大缩放级别

时间:2018-12-26 14:59:29

标签: ios swift

我试图限制我的快速应用程序中的最大缩放级别,否则在缩放过程中我的应用程序因内存过载而崩溃。我正在遵循Is there way to limit MKMapView maximum zoom level?中提出的建议 建议之一是用Objective-C中的以下代码实现regionDidChangeAnimated。以下是代码

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
    // Constrain zoom level to 8.
    if( [mapView zoomLevel] < 8 )
    {
        [mapView setCenterCoordinate:mapView.centerCoordinate 
            zoomLevel:8 
            animated:NO];
    }
}

我正在尝试将其转换为Swift并面临问题。如何转换成迅捷

2 个答案:

答案 0 :(得分:0)

我认为您可以改用mapView.camera.altitude

因此它将是:

func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
    if mapView.camera.altitude < 8 {
        mapView.camera.altitude = 8
    }
}

还请记住,您将必须添加MKMapViewDelegate作为超类(class ViewController : UIViewController, MKMapViewDelegate

祝你好运!

最好的问候。

答案 1 :(得分:0)

我对您要查找的内容有一个快速的了解,我不记得从哪里获得的信息,但我不应该因此而认为它。

extension MKMapView {
var MERCATOR_OFFSET : Double {
    return 268435456.0
}

var MERCATOR_RADIUS : Double  {
    return 85445659.44705395
}

private func longitudeToPixelSpaceX(longitude: Double) -> Double {
    return round(MERCATOR_OFFSET + MERCATOR_RADIUS * longitude * Double.pi / 180.0)
}

private func latitudeToPixelSpaceY(latitude: Double) -> Double {
    return round(MERCATOR_OFFSET - MERCATOR_RADIUS * log((1 + sin(latitude * Double.pi / 180.0)) / (1 - sin(latitude * Double.pi / 180.0))) / 2.0)
}

private  func pixelSpaceXToLongitude(pixelX: Double) -> Double {
    return ((round(pixelX) - MERCATOR_OFFSET) / MERCATOR_RADIUS) * 180.0 / Double.pi;
}

private func pixelSpaceYToLatitude(pixelY: Double) -> Double {
    return (Double.pi / 2.0 - 2.0 * atan(exp((round(pixelY) - MERCATOR_OFFSET) / MERCATOR_RADIUS))) * 180.0 / Double.pi;
}

private func coordinateSpan(withMapView mapView: MKMapView, centerCoordinate: CLLocationCoordinate2D, zoomLevel: UInt) ->MKCoordinateSpan {
    let centerPixelX = longitudeToPixelSpaceX(longitude: centerCoordinate.longitude)
    let centerPixelY = latitudeToPixelSpaceY(latitude: centerCoordinate.latitude)

    let zoomExponent = Double(20 - zoomLevel)
    let zoomScale = pow(2.0, zoomExponent)

    let mapSizeInPixels = mapView.bounds.size
    let scaledMapWidth =  Double(mapSizeInPixels.width) * zoomScale
    let scaledMapHeight = Double(mapSizeInPixels.height) * zoomScale

    let topLeftPixelX = centerPixelX - (scaledMapWidth / 2);
    let topLeftPixelY = centerPixelY - (scaledMapHeight / 2);

    //find delta between left and right longitudes
    let minLng = pixelSpaceXToLongitude(pixelX: topLeftPixelX)
    let maxLng = pixelSpaceXToLongitude(pixelX: topLeftPixelX + scaledMapWidth)
    let longitudeDelta = maxLng - minLng;

    let minLat = pixelSpaceYToLatitude(pixelY: topLeftPixelY)
    let maxLat = pixelSpaceYToLatitude(pixelY: topLeftPixelY + scaledMapHeight)
    let latitudeDelta = -1 * (maxLat - minLat);

    let span = MKCoordinateSpanMake(latitudeDelta, longitudeDelta)
    return span
}

func zoom(toCenterCoordinate centerCoordinate:CLLocationCoordinate2D ,zoomLevel: UInt) {
    let zoomLevel = min(zoomLevel, 20)
    let span = self.coordinateSpan(withMapView: self, centerCoordinate: centerCoordinate, zoomLevel: zoomLevel)
    let region = MKCoordinateRegionMake(centerCoordinate, span)
    self.setRegion(region, animated: true)

  }
}

用法示例:

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = manager.location?.coordinate {
   mapView.zoom(toCenterCoordinate: CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude), zoomLevel: 16)
  }
}