I saw simple code for calculating a grid of tile bounds needed for a given MKMapRect
but I can't find it now. IIRC it was a function built-in to MapKit
.
Given a MKMapRect
like mapview.visibleMapRect
and zoom level, how can I calculate an array of tile paths that will be used for the given rect?
import MapKit
class ViewController: UIViewController {
@IBOutlet weak var mapview: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
mapview.delegate = self
let location = CLLocationCoordinate2D(latitude: 44.0, longitude: -120.0)
let span = MKCoordinateSpanMake(1.0, 1.0)
let region = MKCoordinateRegion(center: location, span: span)
mapview.setRegion(region, animated: true)
let rect = mapview.visibleMapRect
let requiredTiles = ?
}
}
I've been working with MapKit and MKTileOverlays for years, and I don't recall ever seeing a built-in way to calculate tiles in an area. But there are some libraries out there that can help with it. For example, gis-tools, and the MapTile
struct.
You can initialize a MapTile
with a coordinate and zoom level, so you can calculate the northwest and southeast corners of your MKMapRect
, convert them to coordinates and then to MapTiles
, and then use a simple nested for
loop to go through the tile keys.
That would look something like this:
let nwCoord = Coordinate3D(mapRect.origin.coordinate)
let seCoord = Coordinate3D(MKMapPoint(x: mapRect.maxX, y: mapRect.maxY).coordinate)
let nwTile = MapTile(coordinate: nwCoord, atZoom: zoom)
let seTile = MapTile(coordinate: seCoord, atZoom: zoom)
var result = Set<MapTile>()
for x in nwTile.x...seTile.x {
for y in nwTile.y...seTile.y {
result.insert(MapTile(x: x, y: y, z: zoom))
}
}
Maybe not the exact elegant solution you were looking for, but hopefully it's helpful.