lunes, 11 de noviembre de 2013

Convertir latlong GPRMC a grados decimales (WGS84).

Continuando con el post anterior resulta muy útil saber la forma de convertir las coordenadas GPRMC a un formato conocido como el que utilizan mapas como Here de Nokia o Google Maps. Retomando la trama GPRMC del post anterior ($GPRMC,055956.00,A,2029.49050,N,10316.32055,W,000.00,000.0,111113,08.0,E,D*27), tenemos la siguiente información para latitud: 2029.49050,N y para longitud tenemos: 10316.32055,W.

El proceso para obtener la latitud en grados decimales es el siguiente:

1.- Se divide la latitud entre 100, quedando como resultado 20.294905.
2.- Se obtiene la parte entera del resultado del punto anterior, en este caso sería 20.
3.- A la latitud original (2029.49050) se le resta la parte entera que se obtuvo en el punto anterior multiplicada por 100, dando como resultado 29.4905.
4.- El resultado del punto anterior se divide entre 60, quedando 0.4915083333333333.
5.- Se suman los resultados obtenidos del punto 2 (20) y del punto 4 (0.4915083333333333), resultando 20.49150833333333.
6.- Si el hemisferio es sur (S), el resultado del punto anterior se debe multiplicar por -1 para obtener la latitud, si el hemisferio es norte (N), la latitud es el valor obtenido en el punto 5.

El proceso para obtener la longitud en grados decimales es el siguiente:

1.- Se divide la longitud entre 100, quedando como resultado 103.1632055.
2.- Se obtiene la parte entera del resultado del punto anterior, en este caso sería 103.
3.- A la longitud original (10316.32055) se le resta la parte entera que se obtuvo en el punto anterior multiplicada por 100, dando como resultado 16.32055.
4.- El resultado del punto anterior se divide entre 60, quedando 0.2720091666666667.
5.- Se suman los resultados obtenidos del punto 2 (103) y del punto 4 (0.2720091666666667), resultando 103.2720091666667.
6.- Si el hemisferio es oeste (W), el resultado del punto anterior se debe multiplicar por -1 para obtener la longitud (-103.2720091666667), si el hemisferio es este(E), la longitud es el valor obtenido en el punto 5.

De acuerdo a lo anterior tenemos que latlong en grados decimales WGS84 es 20.49150833333333,-103.2720091666667.

Parseo de una trama GPRMC.

Muchos dispositivos GPS transmiten tramas en el formato GPRMC, que es un formato creado por NMEA (National Marine electronics Association). La trama GPRMC contiene información acerca de la ubicación del dispositivo GPS y ciertas variables calculadas por los satélites GPS. Aunque puede variar un poco, la siguiente es una muestra de una trama GPRMC:

$GPRMC,055956.00,A,2029.49050,N,10316.32055,W,000.00,000.0,111113,08.0,E,D*27

Como se aprecia, la trama GPRMC separa la información por medio de comas, por lo que cada dato que se encuentra entre comas representa una variable calculada por los satélites GPS. A continuación desglosaré la trama anterior y diré el significado de cada parte de la trama:

$GPRMC       - Esta variable indica el formato de la trama, en este caso es GPRMC.
055956.00      - Hora UTC en la que se obtuvo la posición del GPS (hhmmss).
A                    - Estatus de la trama A significa que es una trama válida, 9 que es una trama de caché y V significa que es una trama inválida.
2029.49050    - Latitud.
N                    - Hemisferio (N: Norte, S: Sur).
10316.32055  - Longitud.
W                   - Hemisferio (E: Este, W: Oeste).
000.00            - Velocidad en nudos.
000.0              - Rumbo en grados (0° a 360°).
111113           - Fecha UTC en la que se obtuvo la posición del GPS (DDMMAA).
08.0,E             - Variación magnética.
D*27               - Checksum.

viernes, 8 de febrero de 2013

Como obtener el resultado de una consulta en MySQL como Cadena.


Hace un par de semanas me enfrenté con un pequeño problema que resolví de buena manera. Dicho problema fue el siguiente: Necesitaba obtener un reporte de todos los usuarios de un sistema, además de ello necesitaba obtener las fechas de inicio de sesión de cada usuario de los últimos 30 días. En pocas palabras, requería algo como lo siguiente:

-----------------------------------------------------------------
| Nombre de Usuario    | Fechas de Inicio de sesión                    |
-----------------------------------------------------------------
| correo1@mail.com     | 2012-15-24,2012-15-25,2012-15-26 |
| correo2@mail.com     | 2012-15-20,2012-15-25,2012-15-27 |
| correo3@mail.com     | 2012-15-24,2012-15-25,2012-15-26 |
| correo4@mail.com     | 2012-15-24,2012-15-25                     |
-----------------------------------------------------------------

Esto es un problema sencillo de resolver, bastaría con ejecutar 2 consultas y algo de programación. Pero es más rápido y eficiente ejecutar una sola consulta. Esto se podría hacer gracias a la función de MySQL GROUP_CONCAT, la cual permite obtener los resultados de una consulta como una cadena.

Para el caso de este problema supongamos que se tienen 2 tablas, una llamada Usuario con idUsuario(Pk) y nombreUsuario y la otra llamada AccessLog con idUsuario(Fk) y FechaInicio (Se que esta tabla debería llevar una llave primaria , pero para el ejemplo la omití). La tabla AccessLog almacena las fechas de inicio de sesión de los usuarios de los últimos 30 días.

La consulta para obtener la talba de arriba sería la siguiente:

SELECT Usuario.nombreUsuario AS Usuario,
               GROUP_CONCAT(AccessLog.FechaInicio) AS Fechas
FROM   Usuario, AccessLog
WHERE  Usuario.idUsuario = AccessLog.idUsuario

Con esta consulta nos ahorramos hacer una consulta que traiga a todos los usuarios y otra que además por cada usuario traiga las fechas de inicio de sesión, aunado a los ciclos necesarios para construir la tabla de arriba.

viernes, 2 de noviembre de 2012

Correr Netcat en segundo plano y redirigir la salida a un archivo

Hace unos días me enfrenté con un problema que me dió verdaderos dolores de cabeza. Resulta que necesitaba escribir un socket TCP para conectarme a un servidor que envía información a todos los clientes que se conectan a el. Este cliente TCP debía estar siempre conectado y recibiendo información del Servidor. Yo por su parte debía redirigir la salida de dicho socket a un archivo para que después otro programa leyera dicho archivo y lo procesara. Para hacer el trabajo más ligero, decidí probar con telnet, pero se me presentaron algunos inconvenientes, así que decidí utilizar netcat.

Sentí una gran alegría al ver que netcat trabajaba muy bien. El problema era que tenía que mantener mí sesión SSH abierta para que mí socket siguiera funcionando, cosa que supuse era sencilla con el uso de nohup. Pero que sorpresa me llevé al ver que nohup no lograba poner a mí socket en segundo plano. Me la pase googleando y probando alternativas todo el día hasta que después de toda una jornada laboral de trabajo encontré la solución que es bastante sencilla:

Lo único que se debe hacer para correr netcat en segundo plano es añadir la opción -d, que le indica a netcat que no lea de la salida estándar (el teclado). Mí comando para correr netcat en segundo plano quedó como sigue:

nohup nc -d <IP Servidor> <Puerto Remoto> & >> archivo.log

Es importante señalar que esta solución funciona en un Ubuntu 11.10, no lo he probado en otras distribuciones de Linux ni en otras versiones de Ubuntu, pero me imagino que no debe haber mucha variación. Espero este texto sea de utilidad, ya que existe poca información acerca de como resolver este problema y la información que existe se encunetra en inglés.

sábado, 4 de agosto de 2012

Importancia del uso de índices en una Base de Datos MYSQL

Un día me encontraba tratando de resolver un problema de lentitud de un programa. El programa ejecutaba consultas a una tabla y después sobre la misma tabla actualizaba un campo para indicar los registros que ya habían sido procesados.

Al comenzar a debuggear el programa revisé el performance del servidor donde este programa se ejecutaba, revisé casi línea por línea el programa y me dí cuenta para mí sorpresa que el problema se encontraba en la consulta que actualizaba los registros ya procesados. Cada sentencia UPDATE tomaba aproximadamente 20 segundos en ejecutarse, demasiado tiempo para procesar información de una tabla que recibe al rededor de 700 registros por minuto.

Buscando información en foros, manuales y blogs y después de probar varias posibles soluciones, me dí cuenta que el problema se resolvía indexando el campo por el cual se actualizan los registros. La tabla en cuestión es InnoDB y el campo por el cual se realiza el UPDATE es de tipo entero, sin embargo este campo no estaba indexado y al indexarlo me dí cuenta que el UPDATE tomaba menos de 1 segundo en ejecutarse. De esta forma se resolvió mí problema.

Con esta información me dí cuenta que en tablas grandes que son InnoDB, los UPDATES sobre campos de tipo entero (INT) son muy rápidos.

Bienvenida

Este blog está realizado con la finalidad de contribuir con la comunidad de Internet y proveer de tips y consejos de mí experiencia laboral. Espero sea de utilida.