MapKit's built in function MKCoordinateRegionMakeWithDistance
takes distances in meters and turns them into a MKCoordinateRegion
:
func MKCoordinateRegionMakeWithDistance(
_ centerCoordinate: CLLocationCoordinate2D,
_ latitudinalMeters: CLLocationDistance,
_ longitudinalMeters: CLLocationDistance)
-> MKCoordinateRegion
is there a reverse function that takes a MKCoordinateRegion
and gives me latitudinalMeters and longitudinalMeters?
MKCoordinateRegion
gives a center (latitude and longitude) and span (delta latitude and longitude). Given these values, you can determine the location of the edges of the region in latitude and longitude. Once you do that, you can use the haversine formula to obtain latitudinal and longitudinal distances, and you already know the center. In fact, CLLocation
has a function distanceFromLocation:(const CLLocation *)location
which you should use to avoid a direct implementation of the formula.
Based on Adam H.s idea, this is my implementation in Swift 4
with unit tests:
extension MKCoordinateRegion {
/// middle of the south edge
var south: CLLocation {
return CLLocation(latitude: center.latitude - span.latitudeDelta / 2, longitude: center.longitude)
}
/// middle of the north edge
var north: CLLocation {
return CLLocation(latitude: center.latitude + span.latitudeDelta / 2, longitude: center.longitude)
}
/// middle of the east edge
var east: CLLocation {
return CLLocation(latitude: center.latitude, longitude: center.longitude + span.longitudeDelta / 2)
}
/// middle of the west edge
var west: CLLocation {
return CLLocation(latitude: center.latitude, longitude: center.longitude - span.longitudeDelta / 2)
}
/// distance between south and north in meters. Reverse function for MKCoordinateRegionMakeWithDistance
var latitudinalMeters: CLLocationDistance {
return south.distance(from: north)
}
/// distance between east and west in meters. Reverse function for MKCoordinateRegionMakeWithDistance
var longitudinalMeters: CLLocationDistance {
return east.distance(from: west)
}
}
Unit test:
func testMKCoordinateRegionMakeWithDistance() {
// arbitrary parameters
let center = CLLocationCoordinate2DMake(49, 9)
let latitudinalMeters: CLLocationDistance = 1000
let longitudinalMeters: CLLocationDistance = 2000
let region = MKCoordinateRegionMakeWithDistance(center, latitudinalMeters, longitudinalMeters)
XCTAssertEqual(latitudinalMeters, round(region.latitudinalMeters*100)/100)
XCTAssertEqual(longitudinalMeters, round(region.longitudinalMeters*100)/100)
}
test design:
- use different numbers for lat and long to find errors where variables are mixed up
- rounding checks for about 5 significant decimal places
来源:https://stackoverflow.com/questions/51788045/reverse-function-of-mkcoordinateregionmakewithdistance