Hola a todos.
Esta es una función para convertir un número de posición geográfica en grados, minutos y segundos.
Como algunos pocos recordarán,una posición geográfica esta definida por latitud (Norte / Sur) y longitud (Este / Oeste) teniendo como referencia para la longitud el meridiano de Greenwich (Meridiano 0) y para la latitud la linea del Ecuador (Paralelo 0). Por lo que siempre hablaremos de posición "Grados Norte", o "Grados Este".
Ahora es cuando entra en juego las matemáticas y la trigonometría (he de admitir que me encantan :D ). El hemisferio norte o sur solo tendría 90° Norte o Sur. Por ejemplo, El polo norte está a 90° 0' 0'' N de latitud. La longitud podríamos considerar el 0° 0' 0'' (estamos en el polo norte, por lo que es un solo punto, no hay longitud).
En cambio, si nos movemos alrededor de la tierra por la linea de Ecuador, la latitud será 0° 0' 0'' (ni al norte, ni al sur) pero de Este a Oeste nos moveremos en un rango de 180°. Desde el Meridiano de Greenwich al Meridiano de cambio de fecha (el 180). Por ejemplo, la ciudad de Calacalí, en Ecuador, E 70° 30' 47'' - N 0° 0' 0'' (por algo es llamada la ciudad en la mitad del mundo).
Después de esta breve clase de geografía, vamos a poner en práctica estos conocimientos con las nuevas tecnologías.
En algunas aplicaciones de geoposicionamiento (Latitude de Google, Loopt de Apple, etc..), estas posiciones son dadas en un numero con (mas o menos) 8 decimales. Signo + o -, esto significa que esta al Este u Oeste (si es Longitud) o Norte o Sur (si es Latitud).
Ejemplo:
Puerta del Sol de Madrid.
Latitud: 40.4166846
Longitud: -3.7025638
Lo que tenemos que hacer es convertir esta numeración en Grados Minutos y Segundos.
1) Los grados serán la parte entera
2) Los minutos serán la diferencia de la parte decimal multiplicado por 60
3) Los segundos será lo que queda multiplicado por 60
Ahora lo vemos en código:
double absValue = Math.Abs(Math.Round(position * 1000000));
int sign = Math.Sign(position);
Int Degress = (int)Math.Floor(absValue / 1000000);
Int Minutes = (int)Math.Floor(((absValue / 1000000) - Math.Floor(absValue / 1000000)) * 60);
Decimal Seconds = (Decimal)Math.Floor(((((absValue / 1000000) - Math.Floor(absValue / 1000000)) * 60) - Math.Floor(((absValue / 1000000) - Math.Floor(absValue / 1000000)) * 60)) * 100000) * 60 / 100000;
Esta es una función para convertir un número de posición geográfica en grados, minutos y segundos.
Como algunos pocos recordarán,una posición geográfica esta definida por latitud (Norte / Sur) y longitud (Este / Oeste) teniendo como referencia para la longitud el meridiano de Greenwich (Meridiano 0) y para la latitud la linea del Ecuador (Paralelo 0). Por lo que siempre hablaremos de posición "Grados Norte", o "Grados Este".
Ahora es cuando entra en juego las matemáticas y la trigonometría (he de admitir que me encantan :D ). El hemisferio norte o sur solo tendría 90° Norte o Sur. Por ejemplo, El polo norte está a 90° 0' 0'' N de latitud. La longitud podríamos considerar el 0° 0' 0'' (estamos en el polo norte, por lo que es un solo punto, no hay longitud).
En cambio, si nos movemos alrededor de la tierra por la linea de Ecuador, la latitud será 0° 0' 0'' (ni al norte, ni al sur) pero de Este a Oeste nos moveremos en un rango de 180°. Desde el Meridiano de Greenwich al Meridiano de cambio de fecha (el 180). Por ejemplo, la ciudad de Calacalí, en Ecuador, E 70° 30' 47'' - N 0° 0' 0'' (por algo es llamada la ciudad en la mitad del mundo).
Después de esta breve clase de geografía, vamos a poner en práctica estos conocimientos con las nuevas tecnologías.
En algunas aplicaciones de geoposicionamiento (Latitude de Google, Loopt de Apple, etc..), estas posiciones son dadas en un numero con (mas o menos) 8 decimales. Signo + o -, esto significa que esta al Este u Oeste (si es Longitud) o Norte o Sur (si es Latitud).
Ejemplo:
Puerta del Sol de Madrid.
Latitud: 40.4166846
Longitud: -3.7025638
Lo que tenemos que hacer es convertir esta numeración en Grados Minutos y Segundos.
1) Los grados serán la parte entera
2) Los minutos serán la diferencia de la parte decimal multiplicado por 60
3) Los segundos será lo que queda multiplicado por 60
Ahora lo vemos en código:
double absValue = Math.Abs(Math.Round(position * 1000000));
int sign = Math.Sign(position);
Int Degress = (int)Math.Floor(absValue / 1000000);
Int Minutes = (int)Math.Floor(((absValue / 1000000) - Math.Floor(absValue / 1000000)) * 60);
Decimal Seconds = (Decimal)Math.Floor(((((absValue / 1000000) - Math.Floor(absValue / 1000000)) * 60) - Math.Floor(((absValue / 1000000) - Math.Floor(absValue / 1000000)) * 60)) * 100000) * 60 / 100000;
Pero vamos a ser un poco mas sofisticados. Como es una función para calcular posiciones geográficas, vamos a usar una estructura para contener esta información:
public
struct Coordenates
{
public int Degress;
public int Minutes;
public decimal Seconds;
public String Geo; // N,S,E,W
}
El valor Geo tendrá el valor de Norte, Sur, Este y (W)Oeste. Por lo que tenemos que tener algún parámetro para saber si es Latitud o Longitud. Empezamos a definir nuestra función:
public static Coordenates Convert2DegressMinutesSeconds(double position, bool isLong)
Vamos a sobrecargar esta función para que por defecto, lo que vamos a convertir es una Latitud.
public static Coordenates
Convert2DegressMinutesSeconds(double position)
{
// By
default, it is a Latitude (North / South)
return Convert2DegressMinutesSeconds(position, false);
}
y como había dicho antes, si es positivo, y es latitud, estamos hablando de Norte.
Esta sería la función final.
Como siempre, la función la puedes encontrar en el siguiente enlace.
KurroSoftware.Common.zip
Signo
|
Posición
|
isLong
|
Positivo
|
Norte
|
False
|
Negativo
|
Sur
|
False
|
Positivo
|
Este
|
True
|
Negativo
|
Oeste
|
True
|
Esta sería la función final.
public static Coordenates
Convert2DegressMinutesSeconds(double position, bool isLong)
{
Coordenates
ret = new Coordenates();
//
Negative: North
//
Positive: South
// if
isLong = true
//
Negative: East
//
Positive: West
double
absValue = Math.Abs(Math.Round(position
* 1000000));
int
sign = Math.Sign(position);
ret.Degress = (int)Math.Floor(absValue
/ 1000000);
ret.Minutes = (int)Math.Floor(((absValue
/ 1000000) - Math.Floor(absValue / 1000000))
* 60);
ret.Seconds = (Decimal)Math.Floor(((((absValue
/ 1000000) - Math.Floor(absValue / 1000000))
* 60) - Math.Floor(((absValue / 1000000) - Math.Floor(absValue / 1000000)) * 60)) * 100000) *
60 / 100000;
if
(isLong)
if
(sign > 0)
ret.Geo = "W";
else
ret.Geo = "E";
else
if
(sign > 0)
ret.Geo = "N";
else
ret.Geo = "S";
return ret;
}
¿A que es bonita?
Como siempre, la función la puedes encontrar en el siguiente enlace.
KurroSoftware.Common.zip
Muy buen códigos es de gran utilidad
ResponderEliminarAsí o más difícil...?
ResponderEliminarPara qué poner al compilador a realizar la misma operación tantas veces... Math.Floor(absValue / 1000000)...?
No es mejor usar una notación compacta para mejorar la visibilidad del código...?
coordinates.Geo = isLongitude
? sign > 0 ? "W" : "E"
: sign > 0 ? "N" : "S"
;
Que esto...?
if (isLong)
if (sign > 0)
ret.Geo = "W";
else
ret.Geo = "E";
else
if (sign > 0)
ret.Geo = "N";
else
ret.Geo = "S";
Terminé redactando todo el código desde cero... ¬¬