Convert span value into meters on a mapview
Asked Answered
H

6

22

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

Harrietteharrigan answered 11/3, 2011 at 8:14 Comment(0)
H
42

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);
}
Harrietteharrigan answered 28/4, 2011 at 4:23 Comment(0)
C
18
- (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).

Calceolaria answered 27/4, 2011 at 3:9 Comment(1)
Thanks, this works so i upvoted you. But i think this solution is kind of unclean (the calculation makes the code harder to read, and you have approximation in the result)Harrietteharrigan
K
4

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)
Katelyn answered 14/4, 2015 at 18:13 Comment(1)
@wade is milesWide from the center of the map or is this from left to right marginPeeling
S
2

Swift 4.2

    func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {

        let mapRect = mapView.visibleMapRect
        let westMapPoint = MKMapPoint(x: mapRect.minX, y: mapRect.midY)
        let eastMapPoint = MKMapPoint(x: mapRect.maxX, y: mapRect.midY)
        let visibleDistance = westMapPoint.distance(to: eastMapPoint)
    }
Sympathy answered 14/2, 2019 at 22:6 Comment(0)
D
1

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;

}
Demonic answered 3/7, 2012 at 1:7 Comment(2)
works well, thanks. Wondering why you divide them by 10, though.Campos
actually, I don't remember why it was 10, and looking at it now I think that might not actually be accurate for all places - it looks like MapRects are in "map points", and it appears that the proper math would include a conversion using something like MKMetersBetweenMapPoints, as the above answer shows. Sorry, I don't know for sure.Demonic
P
0

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)
  }
}
Phasis answered 8/2, 2018 at 14:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.