MKCoordinateSpan в метрах?
Мне нужно создать MKCoordinateSpan, который составляет около 500 метров.
Как рассчитать значения для передачи в конструктор MKCoordinateSpan?
Ответы на любом языке программирования (Obj-C, .Net) хороши.
3 ответа
Другой альтернативой является использование MapKit's MKCoordinateRegionMakeWithDistance
функция:
MKCoordinateRegion rgn = MKCoordinateRegionMakeWithDistance(
CLLocationCoordinate2DMake(someLatitude, someLongitude), 500, 500);
MKCoordinateSpan
будет в rgn.span
,
Если вам не нужна большая точность, вы можете сделать это намного проще с приближением. Первая проблема состоит в том, чтобы найти долю градуса широты, представляющую 500 метров. Легко, поскольку градус широты постоянен в любом месте, примерно 111 км. Так что 500 метров - это 0,0045 градуса широты.
Тогда это становится сложнее, потому что длина градуса долготы меняется в зависимости от того, где вы находитесь. Это может быть аппроксимировано с
где альфа - экваториальный радиус Земли, 6 378 137 км, b/a - 0,99664719 (постоянная величина, используемая для модели сфероида WGC84, используемой всеми устройствами GPS) и где фи - градус широты.
Представьте себе, что на секунду вам повезло оказаться в Мельбурне с долготой 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;
}
В 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);
}