     
     let max = 8
     
-    init(boundingBox box: MKMapRect) {
+    init(boundingBox box: Bounds) {
         boundingBox = box
     }
     

    
    private(set) var annotations = [MKAnnotation]()
    
    private(set) let boundingBox: MKMapRect
    
    var siblings: Siblings?
    

    
}

extension MKMapRect {
    var minX: Double { return MKMapRectGetMinX(self) }
    var minY: Double { return MKMapRectGetMinY(self) }
    var midX: Double { return MKMapRectGetMidX(self) }
    var midY: Double { return MKMapRectGetMidY(self) }
    var maxX: Double { return MKMapRectGetMaxX(self) }
    var maxY: Double { return MKMapRectGetMaxY(self) }
}

struct Bounds {
    
    let topLeft, bottomRight: CLLocationCoordinate2D
    
    var mapRect: MKMapRect {
        return [topLeft, bottomRight].map { MKMapPointForCoordinate($0) }.map { MKMapRect(origin: $0, size: MKMapSize()) }.reduce(MKMapRectNull, MKMapRectUnion)
//        return MKMapRect(origin: MKMapPointForCoordinate(topLeft), size: MKMapSize(width: bottomRight.latitude - topLeft.latitude, height: bottomRight.longitude - topLeft.longitude))
    }
    
    var midLatitude: CLLocationDegrees {
        return (topLeft.latitude + bottomRight.latitude) / 2
    }
    
    var midLongitude: CLLocationDegrees {
        return (topLeft.longitude + bottomRight.longitude) / 2
    }
    
    static func make(_ mapRect: MKMapRect) -> Bounds {
        let topLeft = MKCoordinateForMapPoint(MKMapPointMake(MKMapRectGetMinX(mapRect), MKMapRectGetMinY(mapRect)))
        let bottomRight = MKCoordinateForMapPoint(MKMapPointMake(MKMapRectGetMaxX(mapRect), MKMapRectGetMaxY(mapRect)))
        return Bounds(topLeft: topLeft, bottomRight: bottomRight)
    }
    
    func intersects(_ bounds: Bounds) -> Bool {
        return MKMapRectIntersectsRect(mapRect, bounds.mapRect)
    }
    
    func contains(_ coordinate: CLLocationCoordinate2D) -> Bool {
        return MKMapRectContainsPoint(mapRect, MKMapPointForCoordinate(coordinate))
    }
    
}
