Reputation: 2269
I want these lines to be visible on a regular map in such a way where each square represents 1x1m.
I looked into MKTileOverlay
but didn't find too much about it. Is it possible to show the gridline on the map as well as change the color?
Upvotes: 1
Views: 519
Reputation: 4200
I've done something very similar for an app I've been playing around with. Mine is for putting a coloured grid over a map so that there are 15 columns and rows in a square mile around a home location, so you'll need to adjust the calculations for your distances but the same general approach should work. The app is only a prototype at the moment, and hasnt been optimised (could refactor code out of viewDidLoad for a start!), but the code should be good enough to get you started.
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
}
}
}
Upvotes: 2