Я сделал нечто очень похожее для приложения, с которым я играл. Мое предназначено для размещения цветной сетки над картой, чтобы в квадратной миле было 15 столбцов и рядов вокруг домашнего местоположения, поэтому вам нужно будет скорректировать расчеты для ваших расстояний, но тот же общий подход должен работать. На данный момент приложение является всего лишь прототипом и не было оптимизировано (для начала можно изменить код из viewDidLoad!), Но код должен быть достаточно хорошим, чтобы начать работу.
var homeLocation: CLLocationCoordinate2D!
let metresPerMile = 1609.344
var degPerHorizEdge: Double!
var degPerVertEdge: Double!
override func viewDidLoad() {
homeLocation = CLLocationCoordinate2D(latitude: 53.7011, longitude: -2.1071)
let hd = CLLocation(latitude: homeLocation.latitude, longitude: homeLocation.longitude).distance(from: CLLocation(latitude: homeLocation.latitude + 1, longitude: homeLocation.longitude))
let vd = CLLocation(latitude: homeLocation.latitude, longitude: homeLocation.longitude).distance(from: CLLocation(latitude: homeLocation.latitude, longitude: homeLocation.longitude + 1))
let degPerHMile = 1 / (hd / metresPerMile)
let degPerVMile = 1 / (vd / metresPerMile)
degPerHorizEdge = degPerHMile / 15
degPerVertEdge = degPerVMile / 15
super.viewDidLoad()
let gridController = GridController(for: gameID!)
gridController.delegate = self
let mapSize = CLLocationDistance(1.2 * metresPerMile)
let region = MKCoordinateRegion(center: homeLocation, latitudinalMeters: mapSize, longitudinalMeters: mapSize)
mapView.delegate = self
mapView.showsUserLocation = true
mapView.showsBuildings = true
mapView.mapType = .standard
mapView.setRegion(region, animated: true)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if let overlays = prepareOverlays() {
mapView.addOverlays(overlays)
}
}
func prepareOverlays() -> [MKPolygon]? {
let topLeft = CLLocationCoordinate2D(latitude: homeLocation.latitude - 7.5 * degPerHorizEdge, longitude: homeLocation.longitude - degPerVertEdge * 7.5)
var overlays = [MKPolygon]()
var locations = [CLLocationCoordinate2D]()
for y in 0...14 {
for x in 0...14 {
locations.append(CLLocationCoordinate2D(latitude: topLeft.latitude + Double(x) * degPerHorizEdge, longitude: topLeft.longitude + Double(y) * degPerVertEdge))
}
}
for coord in locations.enumerated() {
let location = coord.element
var corners = [location, //has to be a var due to using pointer in next line
CLLocationCoordinate2D(latitude: location.latitude + degPerHorizEdge, longitude: location.longitude),
CLLocationCoordinate2D(latitude: location.latitude + degPerHorizEdge, longitude: location.longitude + degPerVertEdge),
CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude + degPerVertEdge)]
let overlay = MKPolygon(coordinates: &corners, count: 4)
overlay.title = "\(coord.offset)"
overlays.append(overlay)
}
return overlays.count > 0 ? overlays : ni
}
//MARK:- MKMapViewDelegate
extension MapViewController: MKMapViewDelegate {
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
// overlay is a WSW zone
if let polygon = overlay as? MKPolygon {
let renderer = MKPolygonRenderer(polygon: polygon)
renderer.strokeColor = UIColor.gray.withAlphaComponent(0.4)
renderer.fillColor = UIColor.orange.withAlphaComponent(0.5)
renderer.lineWidth = 2
return renderer
}
// overlay is a line segment from the run (only remaining overlay type)
else {
let renderer = MKPolylineRenderer(polyline: overlay as! MKPolyline)
renderer.strokeColor = UIColor.blue.withAlphaComponent(0.8)
renderer.lineWidth = 3
return renderer
}
}
}