-
-
Save vatsal1992/17e1313fa58e73da9e4657a18b5dea92 to your computer and use it in GitHub Desktop.
MKMapView extension to center map to coordinates with defined zoom level using Swift3 language
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// MKMapViewExtension.swift | |
// AutocompleteTextfieldSwift | |
// | |
// Created by Mylene Bayan on 2/22/15. | |
// Copyright (c) 2015 MaiLin. All rights reserved. | |
// | |
let MERCATOR_OFFSET = 268435456.0 | |
let MERCATOR_RADIUS = 85445659.44705395 | |
let DEGREES = 180.0 | |
extension MKMapView{ | |
//MARK: Map Conversion Methods | |
private func longitudeToPixelSpaceX(longitude:Double)->Double{ | |
return round(MERCATOR_OFFSET + MERCATOR_RADIUS * longitude * M_PI / DEGREES) | |
} | |
private func latitudeToPixelSpaceY(latitude:Double)->Double{ | |
return round(MERCATOR_OFFSET - MERCATOR_RADIUS * log((1 + sin(latitude * M_PI / DEGREES)) / (1 - sin(latitude * M_PI / DEGREES))) / 2.0) | |
} | |
private func pixelSpaceXToLongitude(pixelX:Double)->Double{ | |
return ((round(pixelX) - MERCATOR_OFFSET) / MERCATOR_RADIUS) * DEGREES / M_PI | |
} | |
private func pixelSpaceYToLatitude(pixelY:Double)->Double{ | |
return (M_PI / 2.0 - 2.0 * atan(exp((round(pixelY) - MERCATOR_OFFSET) / MERCATOR_RADIUS))) * DEGREES / M_PI | |
} | |
private func coordinateSpanWithCenterCoordinate(_ centerCoordinate:CLLocationCoordinate2D, zoomLevel:Double)->MKCoordinateSpan{ | |
// convert center coordiate to pixel space | |
let centerPixelX = longitudeToPixelSpaceX(longitude: centerCoordinate.longitude) | |
let centerPixelY = latitudeToPixelSpaceY(latitude: centerCoordinate.latitude) | |
// determine the scale value from the zoom level | |
let zoomExponent:Double = 20.0 - zoomLevel | |
let zoomScale:Double = pow(2.0, zoomExponent) | |
// scale the map’s size in pixel space | |
let mapSizeInPixels = self.bounds.size | |
let scaledMapWidth = Double(mapSizeInPixels.width) * zoomScale | |
let scaledMapHeight = Double(mapSizeInPixels.height) * zoomScale | |
// figure out the position of the top-left pixel | |
let topLeftPixelX = centerPixelX - (scaledMapWidth / 2.0) | |
let topLeftPixelY = centerPixelY - (scaledMapHeight / 2.0) | |
// find delta between left and right longitudes | |
let minLng = pixelSpaceXToLongitude(pixelX: topLeftPixelX) | |
let maxLng = pixelSpaceXToLongitude(pixelX: topLeftPixelX + scaledMapWidth) | |
let longitudeDelta = maxLng - minLng | |
let minLat = pixelSpaceYToLatitude(pixelY: topLeftPixelY) | |
let maxLat = pixelSpaceYToLatitude(pixelY: topLeftPixelY + scaledMapHeight) | |
let latitudeDelta = -1.0 * (maxLat - minLat) | |
return MKCoordinateSpan(latitudeDelta: latitudeDelta, longitudeDelta: longitudeDelta) | |
} | |
func setCenterCoordinate(_ centerCoordinate:CLLocationCoordinate2D, zoomLevel:Double, animated:Bool){ | |
// clamp large numbers to 28 | |
let zoomLevel = min(zoomLevel,28) | |
//zoomLevel = min(zoomLevel, 28) | |
// use the zoom level to compute the region | |
let span = self.coordinateSpanWithCenterCoordinate(centerCoordinate, zoomLevel: zoomLevel) | |
let region = MKCoordinateRegionMake(centerCoordinate, span) | |
if region.center.longitude == -180.00000000{ | |
fatalError("Invalid Region") | |
} | |
else{ | |
self.setRegion(region, animated: animated) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment