2011-09-11 8 views
24

Necesito crear un MKCoordinateSpan que está a unos 500 metros.MKCoordinateSpan en metros?

¿Cómo calculo los valores para pasar al constructor MKCoordinateSpan?

Las respuestas en cualquier lenguaje de programación (Obj-C, .Net) están bien.

Respuesta

88

Otra alternativa es utilizar MapKit de MKCoordinateRegionMakeWithDistance Función:

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

El MKCoordinateSpan estará en rgn.span.

+5

+1, esa es la manera fácil - ¡No sabía de eso! –

+2

Esto es realmente bueno – Eugene

39

A menos que necesite una gran precisión, puede hacerlo mucho más fácil con la aproximación. El primer problema es encontrar la fracción de un grado de latitud que representa 500 metros. Fácil ya que un grado de latitud es una constante en cualquier ubicación, aproximadamente 111 km. Entonces, 500 metros es 0.0000 grados de latitud.

Luego se hace más difícil porque la longitud de un grado de longitud varía dependiendo de dónde se encuentre. Se puede aproximar con

enter image description here

donde alfa es el radio ecuatorial de la Tierra, 6.378.137 kilometros, b/a es 0,99664719 (una constante en uso para el modelo esferoide WGC84 en uso por todos los dispositivos GPS) y enter image description here donde phi es el grado de latitud

Imagine por un segundo que tiene la suerte de estar en Melbourne con una longitud de 37.783 grados S. Norte o Sur no importa aquí. beta funciona como 37.6899 y el resto resuelve dar un grado longitudinal de 88 km. Entonces 500 metros es .0057 de un grado.

Resultado de Melbourne - MKCoordinateSpan melbourne500MeterSpan = MKCoordinateSpanMake(.0045, .0057);

Puede comprobar sus respuestas y su código with this online calculator

El wiki article de longitud tiene muchos más detalles sobre esto (y que la fuente de las imágenes aquí)

Código:

#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; 
} 
+3

wow. ahora esa es una respuesta. Lástima que solo puedo darle un pulgar hacia arriba ... –

+1

No use esta respuesta. Tan gratificante como obtener los puntos, MKCoordinateRegionMakeWithDistance es la manera correcta. –

-2

En MonoTouch, a continuación, utilizando esta solución se puede utilizar este método de ayuda:

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);  
    } 
+9

-1 por forzarme a Google MonoTouch. – sean

+0

¡No hay problema con una solución monotouch! –

Cuestiones relacionadas