lunes, 10 de febrero de 2014

Obtener fecha y hora GPS de un Mensaje TAIP utilizando C#.

Como se comentó en el post anterior, una forma muy sencilla de obtener la fecha y hora GPS locales de un mensaje TAIP es con un método como sigue, el cual recibe como argumentos los 3 campos de tiempo que el mensaje TAIP tiene, además de que se debe importar el paquete System.Globalization:

private String GetDate(string seconds, string day, string week){
    //Se crea una instancia del objeto      DateTime Inicializado el 6 de Enero de 1980 a las 00:00:00 hrs UTC.
   DateTime dT = new DateTime(1980, 1, 6, new GregorianCalendar());
   //A la instancia de la fecha anterior se le suman las semanas, el día y los segundos dados por el mensaje TAIP.
   dT = new CultureInfo("es-MX").Calendar.AddWeeks(dT,Convert.ToInt32(week)).AddDays(Convert.ToDouble(day)).AddSeconds(Convert.ToDouble(seconds));
   //Se convierte esta fecha a UTC-6 y se regresa como string en formato YYYY-MM-DD HH:mm:ss.
   return dT.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss", new CultureInfo("es-MX")); 
}

Parseo de una sentencia TAIP.

Otro de los formatos en los cuales algunos dispositivos GPS transmiten sus localizaciones es en el formato TAIP (Trimble ASCII Interface Protocol).

Los mensajes TAIP tienen en general la siguiente estructura:

>REVAABBBBCDDDDDEEEEEEEEFFFFFFFFFGGGHHHJK<

Donde:

>: Inicio del Mensaje.
REV: Tipo de Mensaje.
AA: Tipo de Evento.
BBBB: Número de Semana (Desde el 6 de Enero de 1980 a las 00:00:00 hrs. UTC).
C: Día de la Semana (0 domingo).
DDDDD: Número de Segundos transcurridos en el día(UTC).
EEEEEEEE: Latitud (Grados decimales WGS-84).
FFFFFFFFF: Longitud (Grados decimales WGS-84)
GGG: Velocidad (MPH).
HHH: Rumbo (Grados sexagesimales).
J: Fuente de la última posición (0: 2D, 1: 3D, 9: No Fix).
K: Antigüedad del Mensaje (0: No disponible, 1: Mayor a 10 segundos, 2: Menor a 10 segundos).
<: Fin del Mensaje.

Un ejemplo de un mensaje TAIP es el siguiente:

>REV011779180540+1931046-0991095500000012<

Siguiendo la descripción anterior para este mensaje tenemos lo siguiente:

>: Inicio del Mensaje.
REV: Mensaje de Posición.
01:  Evento 01.
1779: Semana 1,779 desde el 6 de Enero de 1980 a las 00:00:00 hrs. UTC.
1    : Lunes.
80540 : 80,540 segundos.
+1931046: Se divide entre 100,000 para obtener la latitud (19.31046).
-09910955: Se divide entre 100,000 para obtener la longitud (-99.10955).
000: 0 MPH.
000: Norte.
1: 3D.
2: Mensaje con menos de 10 segundos de antigüedad.
<: Fin del Mensaje.

Para obtener Hora GPS se propone seguir el siguiente procedimiento (se tomará el mensaje de ejemplo):

1) Dividir entre 60 el número de segundos para obtener los minutos:
80,540 seg = 1,342.3333 min
2) Separar la parte entera y la parte decimal:
 Parte Entera = 1,342 min.
 Parte Decimal = 0.33333333 min.
3) Multiplicar por 60 la parte decimal para obtener este dato en segundos:
   0.33333333 min * 60 = 20 seg.
   Con esto tenemos que: 80,540 seg = 1,342 min 20 seg.
4) Dividimos el número de minutos entre 60:
   1,342 min = 22.366666666 hrs.
5) Separar la parte entera y la parte decimal:
   Parte Entera = 22 hrs.
   Parte Decimal = 0.36666666 hrs.
6) Multiplicar por 60 la parte decimal para obtener este dato en minutos:
   0.36666666 hrs. * 60 = 22 min.
   Con esto tenemos que: 80,540 seg = 1,342 min 20 seg = 22 hrs 22 min 20 seg, por lo que la hora UTC es 22:22:20 hrs. En el caso de México, la zona horaria es UTC -6, por lo que para obtener la hora local se deben restar 6 horas a esta hora, quedando como 16:22:20 hrs.

Computacionalmente el proceso de obtener la fecha resulta complicado, por lo que en el post siguiente daré una alternativa de cómo obtener las fechas y horas GPS de un Mensaje TAIP con C# de una forma rápida y sencilla.

miércoles, 15 de enero de 2014

Convertir tablas de InnoDB a MyISAM de una Forma rápida.

En ocasiones resulta de suma utilidad el convertir el engine de una tabla, ya sea por performance o por algún otro objetivo que se tenga en mente. Esta tarea no resulta sencilla cuando tenemos un gran número de tablas con engine InnoDB, puesto que existen dependencias con llaves de otras tablas, por lo que el proceso se vuelve largo y tedioso, pues se deben eliminar las llaves foráneas antes y posteriormente cambiar a MyISAM.

Una forma sencilla de hacer este cambio a gran escala es escribir una sentencia SQL que a su vez construya todas las consultas que nos permitirán hacer estos cambios.

La siguiente consulta nos da como resultado las consultas que se deberán ejecutar para eliminar todas las llaves foráneas de una Base de Datos específica, en este caso se deberán seleccionar sólo aquellas consultas que eliminen las llaves que se desean eliminar:

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,'  drop foreign key ', CONSTRAINT_NAME,';') FROM information_schema.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE='FOREIGN KEY' AND table_schema = 'NOMBRE_BD';

Después de eliminar las llaves foráneas, es posible hacer el cambio de engine de InnoDB a MyISAM, si se trata de muchas tablas podemos ejecutar una consulta que nos de como resultado las consultas necesarias para transformar cada tabla InnoDB a MyISAM y seleccionar las que sean útiles para ejecutarlas, para el caso esta es la consulta:

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,'  engine=MyISAM;') FROM information_schema.tables WHERE engine = 'InnoDB'  and table_schema = 'NOMBRE_BD';