Convert span value into meters on a mapview

2019-01-21 17:14发布

问题:

Whenever the user zoom in or out the map i need to know how many meters are currently represented on the map (width or height).

What i need is the inverse function of MKCoordinateRegionMakeWithDistance to calculate the distance represented by the current map span.

I tried the following code but i get wrong results :

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
    MKMapRect mRect = self.map.visibleMapRect;
    MKMapPoint northMapPoint = MKMapPointMake(MKMapRectGetMidX(mRect), MKMapRectGetMinY(mRect));
    MKMapPoint southMapPoint = MKMapPointMake(MKMapRectGetMidX(mRect), MKMapRectGetMaxY(mRect));

    self.currentDist = MKMetersBetweenMapPoints(northMapPoint, southMapPoint);
}

If i set the map region to 1500 meters i get something like 1800 as a result..

Thanks for your help, Vincent

回答1:

Actually it was a really stupid mistake, if i do the same operation along the X axis then i get the correct value :

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
MKMapRect mRect = self.map.visibleMapRect;
MKMapPoint eastMapPoint = MKMapPointMake(MKMapRectGetMinX(mRect), MKMapRectGetMidY(mRect));
MKMapPoint westMapPoint = MKMapPointMake(MKMapRectGetMaxX(mRect), MKMapRectGetMidY(mRect));

self.currentDist = MKMetersBetweenMapPoints(eastMapPoint, westMapPoint);
}


回答2:

- (void)mapView:(MKMapView *)map regionDidChangeAnimated:(BOOL)animated {
  MKCoordinateSpan span = mapView.region.span;
  NSLog(@" 1 = ~111 km -> %f = ~ %f km ",span.latitudeDelta,span.latitudeDelta*111);
}

According to the docs http://developer.apple.com/library/ios/#documentation/MapKit/Reference/MapKitDataTypesReference/Reference/reference.html,

latitudeDelta

The amount of north-to-south distance (measured in degrees) to display on the map. Unlike longitudinal distances, which vary based on the latitude, one degree of latitude is always approximately 111 kilometers (69 miles).



回答3:

Thanks for the post all. I have an app that required a mile radius to figure out how many location records to fetch so this came in handy. Here is the swift equivalent for anyone who might come across this in the future.

let mRect: MKMapRect = self.mapView.visibleMapRect
        let eastMapPoint = MKMapPointMake(MKMapRectGetMinX(mRect), MKMapRectGetMidY(mRect))
        let westMapPoint = MKMapPointMake(MKMapRectGetMaxX(mRect), MKMapRectGetMidY(mRect))
        let currentDistWideInMeters = MKMetersBetweenMapPoints(eastMapPoint, westMapPoint)
        let milesWide = currentDistWideInMeters / 1609.34  // number of meters in a mile
        println(milesWide)


回答4:

Here's an easier way (to get width and height in meters)...

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {

    MKMapRect rect = mapView.visibleMapRect;

    double mapWidth = MKMapRectGetWidth(rect) / 10;
    double mapHeight = MKMapRectGetHeight(rect) / 10;

}


回答5:

Swift 4

extension MKMapView {
  func regionInMeter() -> CLLocationDistance {
    let eastMapPoint = MKMapPointMake(MKMapRectGetMinX(visibleMapRect), MKMapRectGetMidY(visibleMapRect))
    let westMapPoint = MKMapPointMake(MKMapRectGetMaxX(visibleMapRect), MKMapRectGetMidY(visibleMapRect))

    return MKMetersBetweenMapPoints(eastMapPoint, westMapPoint)
  }
}