swiftmapkitmkcoordinateregion

How to fix this 'Invalid Region <center:-180.00000000, -180.00000000 span:nan, nan>' error in swift


I would like to get the region so I can fit the annotations inside of it. But I got uncaught exception 'NSInvalidArgumentException', reason: 'Invalid Region '. So how cloud I resolve this problem please ?

var topLeftCoordinate = CLLocationCoordinate2D(latitude: -90, longitude: 180)
var bottomRightCoordinate = CLLocationCoordinate2D(latitude: 90, longitude: -180)

for annotation in mapView.annotations where !annotation.isKind(of: DriverAnnotation.self){
            topLeftCoordinate.longitude = fmin(topLeftCoordinate.longitude, annotation.coordinate.longitude)
            topLeftCoordinate.latitude = fmax(topLeftCoordinate.latitude, annotation.coordinate.latitude)
            bottomRightCoordinate.longitude = fmin(bottomRightCoordinate.longitude, annotation.coordinate.longitude)
            bottomRightCoordinate.latitude = fmax(bottomRightCoordinate.latitude, annotation.coordinate.latitude)
        }

var region = MKCoordinateRegion(center: CLLocationCoordinate2DMake(topLeftCoordinate.latitude - (topLeftCoordinate.latitude - bottomRightCoordinate.latitude) * 0.5, topLeftCoordinate.longitude + (bottomRightCoordinate.longitude - topLeftCoordinate.longitude) * 0.5), span: MKCoordinateSpan(latitudeDelta: fabs(topLeftCoordinate.latitude - bottomRightCoordinate.latitude) * 2.0, longitudeDelta: fabs(bottomRightCoordinate.longitude - topLeftCoordinate.longitude) * 2.0))

region = mapView.regionThatFits(region) mapView.setRegion(region, animated: true)


Solution

  • This is the wrong way to calculate the rectangle which fits the bounds of all annotations.

    Use this, it maps the annotations to their coordinates and then to MKMapRect instances. The reduce/union function calculates the size of the rect

    let coordinates = mapView.annotations.lazy.filter{!($0 is DriverAnnotation)}.map{ $0.coordinate }
    let rects = coordinates.map { MKMapRect(origin: MKMapPoint($0), size: MKMapSize()) }
    let mapRect = rects.reduce(MKMapRect.null) { $0.union($1) }
    mapView.setVisibleMapRect(mapRect, animated: true)
    

    Or, much simpler (thanks to Sulthan)

    let annotations = mapView.annotations.filter{!($0 is DriverAnnotation)}
    mapView.showAnnotations(annotations, animated: true)