MKCoordinateSpan в метрах? - PullRequest
       32

MKCoordinateSpan в метрах?

26 голосов
/ 12 сентября 2011

Мне нужно создать MKCoordinateSpan , что составляет около 500 метров.

Как рассчитать значения для передачи в конструктор MKCoordinateSpan ?

Ответы на любом языке программирования (Obj-C, .Net) хороши.

Ответы [ 3 ]

94 голосов
/ 12 сентября 2011

Другой альтернативой является использование функции MKCoordinateRegionMakeWithDistance MapKit:

MKCoordinateRegion rgn = MKCoordinateRegionMakeWithDistance(
    CLLocationCoordinate2DMake(someLatitude, someLongitude), 500, 500);

MKCoordinateSpan будет в rgn.span.

39 голосов
/ 12 сентября 2011

Если вам не нужна большая точность, вы можете сделать это намного проще с приближением. Первая проблема состоит в том, чтобы найти долю градуса широты, представляющую 500 метров. Легко, поскольку градус широты постоянен в любом месте, примерно 111 км. Так что 500 метров - это 0,0045 градуса широты.

Тогда становится сложнее, потому что длина градуса долготы меняется в зависимости от того, где вы находитесь. Может быть аппроксимирован

enter image description here

где альфа - экваториальный радиус Земли, 6 378 137 км, b / a - 0,99664719 (постоянная величина, используемая для модели сфероида WGC84, используемой всеми устройствами GPS) и enter image description here, где phi - степень широты.

Представьте себе, что на секунду вам повезло оказаться в Мельбурне с долготой 37,783 градуса южной широты. Север или юг здесь не имеет значения. получается бета-версия 37.6899, а остальная часть решается, чтобы дать продольную степень длиной 88 км. Таким образом, 500 метров - это 0,0057 градуса.

Результат для Мельбурна - MKCoordinateSpan melbourne500MeterSpan = MKCoordinateSpanMake(.0045, .0057);

Вы можете проверить свои ответы и свой код с помощью этого онлайн-калькулятора

В вики-статье по долготе есть намного больше подробностей об этом (и это источник изображений здесь)

Код:

#define EARTH_EQUATORIAL_RADIUS (6378137.0)
#define WGS84_CONSTANT (0.99664719)

#define degreesToRadians(x) (M_PI * (x) / 180.0)

// accepts decimal degrees. Convert from HMS first if that's what you have
double spanOfMetersAtDegreeLongitude(double degrees, double meters) {

    double tanDegrees = tanf(degreesToRadians(degrees));
    double beta =  tanDegrees * WGS84_CONSTANT;
    double lengthOfDegree = cos(atan(beta)) * EARTH_EQUATORIAL_RADIUS * M_PI / 180.0;
    double measuresInDegreeLength = lengthOfDegree / meters;
    return 1.0 / measuresInDegreeLength;
}
0 голосов
/ 13 сентября 2011

В MonoTouch, затем с помощью этого решения вы можете использовать этот вспомогательный метод:

    public static void ZoomToCoordinateAndCenter (MKMapView mapView, CLLocationCoordinate2D coordinate, double meters, bool showUserLocationToo, bool animate)
    {
        if (!coordinate.IsValid ())
            return;

        mapView.SetCenterCoordinate (coordinate, animate);
        mapView.SetRegion (MKCoordinateRegion.FromDistance (coordinate, meters, meters), animate);      
    }
...