Andre
Andre

Reputation: 7638

iOS: Max zoom out for MapKit

How can I calculate the max zoom out in MapKit to show the entire globe?

Example:

let region: MKCoordinateRegion = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: -37.8136, longitude: 144.9631), span: MKCoordinateSpan(latitudeDelta: 170, longitudeDelta: 170))

If instead of 170 I put 200 the App crash telling me:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid Region <center:-37.81360000, +144.96310000 span:+200.00000000, +200.00000000>'

Upvotes: 0

Views: 793

Answers (2)

Neklas
Neklas

Reputation: 542

When initializing MKCoordinateRegion with coordinate and span and use MKMapView.setRegion(_ region: MKCoordinateRegion, animated: Bool)

Changing just the center coordinate of the region can still cause the span values to change implicitly. The span values might change because the distances represented by a span change at different latitudes and longitudes and the map view may need to adjust the span to account for the new location

Ref: MKMapView.setRegion(_ region: MKCoordinateRegion, animated: Bool)

Here is my workaround with MKMapCamera.

Code in MapScreen.swift


import UIKit
import MapKit
import CoreLocation

class MapScreen: UIViewController {

    @IBOutlet weak var mapView: MKMapView!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        self.mapView.mapType = .hybridFlyover // Change to satellite mode
        // Or you can use .satelliteFlyover
    
        // We delay update by 1 second to get final size of mapView on UI.
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
            self.focusOnPointAndShowGlobe()
        }
    }
    
    func focusOnPointAndShowGlobe() {
        let mapHeight = mapView.bounds.height // the constraint of visible Map area will base on HEIGHT of mapview

        // These are standard/base value from adjustment
        let standardMapHeight: CGFloat = 450
        let standardCameraDistance: CGFloat = 24 * 1000 * 1000 // 24,000 km
        
        let targetDistance = (mapHeight / standardMapHeight) * standardCameraDistance
        let center = CLLocationCoordinate2D(latitude: -37.8136, longitude: 144.9631)
        let camera = MKMapCamera(lookingAtCenter: center, fromDistance: targetDistance, pitch: 0, heading: 0)
        self.mapView.setCamera(camera, animated: true)
    }
}

MapView layout in Xib (I'm using fullscreen layout)

enter image description here

This is result on Portrait mode, focusOnPointAndShowGlobe() will focus on center location then move away from the Earth to disply entire globe, when you open this screen or call focusOnPointAndShowGlobe() again.

enter image description here

Upvotes: 1

mani
mani

Reputation: 3096

The Earth has 2 hemispheres, divided into 90 degrees each. So latitude range is from -90 to 90 i.e. latitudeDelta cannot be more than 180 degrees.

Longitude range is from -180 to 180, so longitudeDelta max is 360 degrees.

To show a globe, set MapView.mapType = .hybridFlyover or MapView.mapType = .satelliteFlyover.

Upvotes: 1

Related Questions