MKMapView中心和放大

时间:2017-01-13 16:43:00

标签: ios swift mkmapview mapkit

我在项目中使用MKMapView,并希望将地图置于坐标中心并放大。就像谷歌地图一样:

GMSCameraPosition.camera(withLatitude: -33.8683,
                                  longitude: 151.2086,
                                  zoom: 6)

是否有任何Mapkit方法?

9 个答案:

答案 0 :(得分:8)

您可以创建一个MKCoordinateRegion对象并将其设置为MKMapView对象上的区域。

MKCoordinateRegion mapRegion;   
CLLocationCoordinate2D coordinate;
coordinate.latitude = 0;
coordinate.longitude = 0;    
mapRegion.center = coordinate;
mapRegion.span.latitudeDelta = 0.2;
mapRegion.span.longitudeDelta = 0.2;

[mapView setRegion:mapRegion animated: YES];

答案 1 :(得分:5)

以下是我使用 Create procedure procName ( @test int, @clientid int ) As Begin insert into [dbo].[Sku] (skuid,clientid,skudesc,[Type]) values (@test,@clientid,@test, (select Clientid from [dbo].[Client] where clientname like 'Admin')) End 将地图置于预定义CLLocation上的方法。

MKCoordinateRegion

答案 2 :(得分:4)

代码基于:http://troybrant.net/blog/2010/01/set-the-zoom-level-of-an-mkmapview/

    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 * M_PI / 180.0)
    }

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

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

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

    private func coordinateSpan(withMapView mapView: MKMapView, centerCoordinate: CLLocationCoordinate2D, zoomLevel: UInt) ->MKCoordinateSpan {
        let centerPixelX = longitudeToPixelSpaceX(centerCoordinate.longitude)
        let centerPixelY = latitudeToPixelSpaceY(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(topLeftPixelX)
        let maxLng = pixelSpaceXToLongitude(topLeftPixelX + scaledMapWidth)
        let longitudeDelta = maxLng - minLng;

        let minLat = pixelSpaceYToLatitude(topLeftPixelY)
        let maxLat = pixelSpaceYToLatitude(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)

    }
}

答案 3 :(得分:2)

在Swift 4.x中

Apinho 回答

 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)

    }
}

答案 4 :(得分:1)

Swift 3.0

在MapKit函数didUpdateLocations中:

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
            guard let location = locations.last as CLLocation? else { return }

            let userCenter = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
            // Does not have to be userCenter, could replace latitude: and longitude: with any value you would like to center in on

            let region = MKCoordinateRegion(center: userCenter, span: MKCoordinateSpan(latitudeDelta: 180, longitudeDelta: 180))

            mkView.setRegion(region, animated: true)

    }

注意:如果您不希望每次更新位置时都继续设置中心,请执行以下操作:

        let userCenter = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
        // Does not have to be userCenter, could replace latitude: and longitude: with any value you would like to center in on

        let region = MKCoordinateRegion(center: userCenter, span: MKCoordinateSpan(latitudeDelta: 180, longitudeDelta: 180))

        mkView.setRegion(region, animated: true)

答案 5 :(得分:1)

将以下代码放入Solidity的{​​{1}}子类中 呼叫来自CustomMapView

MKMapView

答案 6 :(得分:0)

这是在Swift 4.2上测试过的有效代码

 override func viewDidLoad() {
    super.viewDidLoad()
    let initialLocation = CLLocation(latitude: 28.5761897, longitude: 77.172080)
    self.centerMapOnLocation(location: initialLocation)
}


 func centerMapOnLocation(location: CLLocation) {
    let region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude), span: MKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta: 0.05))
    DispatchQueue.main.async {
        self.mapView.setRegion(region, animated: true)
        let annotation = MKPointAnnotation()
        annotation.coordinate = location.coordinate
        self.mapView.addAnnotation(annotation)
    }
}

这将加载动画。希望能为您提供帮助。

答案 7 :(得分:0)

基于apinho答案。 此选项遵循Swift 5语法,并允许将其用作MKCoordinateRegion的初始化程序,因此可以在MKMapView之外的其他对象中使用,例如在MKMapSnapshotter中。

extension MKCoordinateRegion {

    init(center: CLLocationCoordinate2D, zoom: UInt, bounds: CGRect) {
        let zoom = min(zoom, 20)
        let span = MKCoordinateSpan(center: center, zoom: zoom, bounds: bounds)
        self.init(center: center, span: span)
    }
}

extension MKCoordinateSpan {

    static var mercatorOffset: Double {
        return 268435456.0
    }

    static var mercatorRadius: Double {
        return 85445659.44705395
    }

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

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

    private static func pixelSpaceXToLongitude(pixelX: Double) -> Double {
        return ((round(pixelX) - mercatorOffset) / mercatorRadius) * 180.0 / Double.pi
    }

    private static func pixelSpaceYToLatitude(pixelY: Double) -> Double {
        return (Double.pi / 2.0 - 2.0 * atan(exp((round(pixelY) - mercatorOffset) / mercatorRadius))) * 180.0 / Double.pi
    }

    init(center: CLLocationCoordinate2D, zoom: UInt, bounds: CGRect) {

        let centerPixelX = MKCoordinateSpan.longitudeToPixelSpaceX(longitude: center.longitude)
        let centerPixelY = MKCoordinateSpan.latitudeToPixelSpaceY(latitude: center.latitude)

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

        let mapSizeInPixels = 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 = MKCoordinateSpan.pixelSpaceXToLongitude(pixelX: topLeftPixelX)
        let maxLng = MKCoordinateSpan.pixelSpaceXToLongitude(pixelX: topLeftPixelX + scaledMapWidth)
        let longitudeDelta = maxLng - minLng

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

        self.init(latitudeDelta: latitudeDelta, longitudeDelta: longitudeDelta)
    }
}

答案 8 :(得分:-1)

这可以在iOS 5的Swift 5中使用,并且很容易理解:

只需将以下方法添加到您的课程中即可:

func zoomAndCenter(on centerCoordinate: CLLocationCoordinate2D, zoom: Double) {
    var span: MKCoordinateSpan = mapView.region.span
    span.latitudeDelta *= zoom
    span.longitudeDelta *= zoom
    let region: MKCoordinateRegion = MKCoordinateRegion(center: centerCoordinate, span: span)
    mapView.setRegion(region, animated: true)
}