Monthly Archives: June 2011

Convertir coordenadas geográficas grados-minutos-segundos a notacional decimal (3)

Introducción.

Después de encontrar dos métodos (A y B) para la conversión de coordenadas entre formatos decimal y grados, minutos y segundos, encontré en el libro HTML5 Geolocation de Anthony T. Holdener III la implementación de dos funciones en Javascript que realizan con precisión este procedimiento y que me parecieron muy intersantes.  Este corto libro es en general muy interesante y recomiendo su lectura.

Conversión de coordenadas: formato decimal a grados-minutos-segundos.

/**
 * Convierte una coordenada en formato decimal a su correspondiente
 * versión en formato grados-minutos-segundos.
 *
 * @param	Float	Valor real de la coordenada.
 * @param	Int	Tipo de la coordenada {Coordenada.LATITUD, Coordenada.LONGITUD}.
 * @return	Array	['grados', 'minutos', 'segundos', 'direccion', 'valor'].
 */
function dec2gms(valor, tipo)
{
	grados    = Math.abs(parseInt(valor));
	minutos   = (Math.abs(valor) - grados) * 60;
	segundos  = minutos;
	minutos   = Math.abs(parseInt(minutos));
	segundos  = Math.round((segundos - minutos) * 60 * 1000000) / 1000000;
	signo     = (valor < 0) ? -1 : 1; 	direccion = (tipo == Coordenada.LATITUD) ?
                    ((signo > 0) ? 'N' : 'S') :
	            ((signo > 0) ? 'E' : 'W');
	if(isNaN(direccion))
		grados = grados * signo;
	return {
		'grados'   : grados,
		'minutos'  : minutos,
		'segundos' : segundos,
		'direccion': direccion,
		'valor'    : grados + "\u00b0 " + minutos + "' "+ segundos +
		             "\"" + ((isNaN(direccion)) ? (' ' + direccion) : '')
	};
}

Por ejemplo.

var x = 48.853;
r1 = dec2gms(x, Coordenada.LATITUD);
alert('Conversion dec2gms = ' + r1.valor);

Conversión de coordenadas: formato grados-minutos-segundos a decimal.

/**
 * Convierte una coordenada en formato grados-minutos-segundos a su
 * correspondiente versión en formato decimal.
 *
 * @param	Float	Grados de la coordenada.
 * @param	Float	Minutos de la coordenada.
 * @param	Float	Segundos de la coordenada.
 * @param	String	Sentido de la coordenada {Coordenada.NORTE,
					Coordenada.SUR, Coordenada.ORIENTE,
					Coordenada.OCCIDENTE}
 * @return	Array	['decimal', 'valor'].
 */
function gms2dec(grados, minutos, segundos, direccion)
{
	if(direccion)
	{
		signo     = (direccion.toLowerCase() == 'w' ||
		             direccion.toLowerCase() == 's') ?
		            -1 : 1;
		direccion = (direccion.toLowerCase() == 'w' ||
		             direccion.toLowerCase() == 's' ||
		             direccion.toLowerCase() == 'n' ||
		             direccion.toLowerCase() == 'e') ?
		            direccion.toLowerCase() : '';
	}
	else
	{
		signo     = (grados < 0) ? -1 : 1;
		direccion = '';
	}
	dec = Math.round((Math.abs(grados) + ((minutos * 60) + segundos) / 3600) * 1000000) / 1000000;
	if(isNaN(direccion) || direccion == '')
		dec = dec * signo;
	return {
		'decimal': dec,
		'valor'  : dec + "\u00b0" + ((isNaN(direccion) || direccion == '') ? (' ' + direccion) : '')
	};
}

Por ejemplo.

var xg = 48;
var xm = 51;
var xs = 10.8;
r2 = gms2dec(xg, xm, xs, Coordenada.NORTE);
alert('Conversion gms2dec = ' + r2.valor);

Código fuente y demostración.

Obtenga el código fuente del artículo junto con la ejecución de la demostración en la siguiente ubicación.

http://demo.jorgeivanmeza.com/JavaScript/CoordConverter/0.3/

Como acceder a la geolocalización desde Javascript

Introducción.

La geolocalización es la posibilidad de conocer cual es la ubicación física de un dispositivo.  Esta ubicación es geográfica, es decir, se define especialmente mediante sus correspondientes valores de latitud y longitud.

Los dispositivos pueden obtener esta información desde diferentes fuentes, las cuales estarán relacionadas a su vez con precisión de estos datos.  Los orígenes mas comúnes para la información de geolocalización de un dispositivo son los siguientes.

  1. Utilizando un GPS (Global Positioning System).
  2. Mediante su identificación en celdas GSM/CDMA.
  3. Mediante su dirección IP.
  4. Mediante la dirección MAC de WiFi y Bluetooth.
  5. Especificado por el usuario manualmente.

Estos métodos se encuentran disponibles para las aplicaciones nativas que pueden acceder libremente al hardware del dispositivo, sin embargo ahora también es posible acceder a esta información desde una aplicación web utilizando Javascript gracias a la integración del API de geolocalización de la W3C en los navegadores mas recientes (incluyendo los móviles).

  • Firefox (3.5+)
  • Chrome (5.0+)
  • Internet Explorer (9.0+)
  • Safari (5.0+)
  • Opera (10.6+)
  • iPhone (3.1+)
  • Android (2.0+)
  • BlackBerry (6+)

Para dar soporte a navegadores antíguos se requiere que se utilice una capa adicional como Google Gears que supla la falencia de esta tecnología.

En este artículo se explicará el API necesario para acceder al API de geolocalización mediante el uso del lenguaje Javascript utilizando un navegador moderno como los mencionados.

Verificar el soporte

El primer paso debe ser siempre verificar si el navegador web en el cual se despliega la aplicación tiene o no el soporte para esta tecnología, a partir de este resultado se deberá decidir que hacer.

if(navigator.geolocation)
{
    // Se cuenta con el soporte para geolocalización, entonces ...
}
else
{
    // No se cuenta con soporte para geolocalización, manejar la situación.
}

Solicitar la ubicación al navegador.

El siguiente paso consiste directamente en solicitarle al navegador web cual es la ubicación del dispositivo.  El llamado a esta función es asíncrono, es decir, no retorna inmediatamente un valor sino que invoca a una función específica (callback) cuando este se obtiene.  Así mismo, como el conocer la ubicación de un dispositivo (y por ende su usuario) tiene implicaciones en la privacidad de las personas, la especificación dispone que el usuario esté siempre facultado para aceptar o negar el acceso a esta información.  Por este motivo los navegadores desplegarán barras como la mostrada a continuación solicitando la confirmación final.

Permitir el acceso a la información de geolocalización en Chrome

Permitir el acceso a la información de geolocalización en Chrome

A continuación se muestra la invocación general de la función para obtener la geolocalización del dispositivo.

navigator.geolocation.getCurrentPosition(onSuccessGeolocating,
                                         onErrorGeolocating,
                                         options);

Los dos primeros parámetros corresponden a funciones Javascript que se ejecutarán según se tenga éxito o no durante el proceso de geolocalización (se analizarán a continuación), el tercer parámetro es opcional y corresponde con uno o varios de los modificadores descritos.

OpciónTipoValor por defectoDescripción
enableHighAccuracyBooleanofalseIntenta obtener la información mas precisa que sea posible.  Debe tenerse en cuenta que esta opción también toma mas tiempo y probablemente consume una mayor cantidad de batería del dispositivo.
maximumAgeEntero 0Acepta como resultado el último valor histórico siempre y cuando este no sea mas antíguo que el valor especificado en milisegundos.
timeoutEntero 0Espera máximo la cantidad de milisegundos especificada antes de abortar el procedimiento.

A continuación se muestra un ejemplo de implementación de esta función.  En este se definen las funciones onSuccessGeolocating y onErrorGeolocating para determinar la implementación del manejo de éxito y error respectivamente de la geolocalización, y define además que se intente realizar el procedimiento con la mayor precisión posible, se acepten valores en caché con máximo 5 segundos de antiguedad y se espere máximo 10 segundos para terminar el procedimiento.

navigator.geolocation.getCurrentPosition(onSuccessGeolocating,
                                         onErrorGeolocating,
                                         {
                                       		enableHighAccuracy: true,
                                       		maximumAge:         5000,
                                       		timeout:            10000
                                         });

Establecer que hacer con la información de geolocalización.

Si el procedimiento fue exitoso, se define la función onSuccessGeolocating referenciada en el paso inmediatamente anterior, en ella se establece que se deberá hacer con la información obtenida.

function onSuccessGeolocating(position)
{
    // ...
}

El objeto Position que se recibe a través de los parámetros de la función incluye la siguiente información.

AtributoDescripción
coordsInformación de la ubicación obtenida
timestampInformación del momento en que fue obtenida la información

A su vez, el objeto Coordinates incluye la siguiente información en su interior.

AtributoDescripción
latitudeValor de la latitud de la ubicación del dispositivo medida en grados decimales
longitudeValor de la longitud de la ubicación del dispositivo medido en grados decimales
altitudeValor de la altura geográfica de la ubicación del dispositivo medida en metros
accuracyPrecisión de la latitud y longitud medida en metros
altitudeAccuracyPrecisión de la altitud medida en metros
headingDirección en la que se mueve el dispositivo. Medida en grados desde 0 hasta 360. Su valor será NaN cuando el dispositivo se encuentra inmóvil o null si esta característica no es soportada
speedValor de la longitud de la ubicación del dispositivo

Esto significa que la información básica de la ubicación del dispositivo esta finalmente almacenada en position.coords.latitude y position.coords.longitude.

Establecer que hacer en caso de error.

En algunas ocasiones la geolocalización puede fallar, por ejemplo cuando se utiliza el GPS pero no se cuenta con la información de suficientes satélites o cuando el usuario impide el procedimiento.  Para manejar esta conducta se define la función onErrorGeolocating referenciada durante la invocación de navigator.geolocation.getCurrentPosition.

function onErrorGeolocating(error)
{
    // ...
}

La información del error puede obtenerse del objeto PositionError recibido por parámetro el cual cuenta con los siguientes atributos en su interior.

AtributoDescripción
codeCódigo numérico que referencia al tipo de error sucedido.  Su valor corresponde con una de las siguientes constantes 

PERMISSION_DENIED: no se permitió o no se tienen suficientes privilegios para acceder al servicio de geolocalización.

POSITION_UNAVAILABLE: el dispositivo no pudo determinar correctamente su ubicación.

TIMEOUT: el intento de geolocalización tomó mas tiempo del permitido (opción timeout).

messageTexto que describe el error sucedido.  Este mensaje se utiliza para depuración en desarrollo, no se debe utilizar para mostrarse al usuario final.

A continuación se muestra un ejemplo básico de implementación de esta función.

function onErrorGeolocating(error)
{
	switch(error.code)
	{
		case error.PERMISSION_DENIED:
			alert('ERROR: User denied access to track physical position!');
		break;
		case error.POSITION_UNAVAILABLE:
			alert("ERROR: There is a problem getting the position of the device!");
		break;
		case error.TIMEOUT:
			alert("ERROR: The application timed out trying to get the position of the device!");
		break;
		default:
			alert("ERROR: Unknown problem!");
		break;
	}
}

El prototipo.

Como demostración de esta API se incluye el siguiente prototipo el cual intenta obtener la ubicación actual del usuario y desplegarla en un mapa de Google Maps.  Se recomienda consultar su código fuente para complementar los contenidos de este artículo.

 

Demostración de geolocalización con Javascript

Demostración de geolocalización con Javascript

Enlaces.

Instalación de Windows XP en un netbook desde una unidad USB

Introducción.

Instalar Windows XP en una netbook (portátil liviano sin unidad de DVD) desde una memoria USB no fue tan fácil y placentero como fue la instalación de Windows 7.  Después de algunas pruebas estos fueron los pasos que se siguieron.

Crear la unidad USB de instalación.

Para crear la unidad USB de instalación se utilizó WinToFlash.  Este procedimiento es muy simple, sólo se debe especificar cual es la unidad en la que se encuentran los archivos (CDROM) de instalación de Windows y cual es la unidad (USB) hacia la cual se realizará la copia.

Instalación del sistema operativo.

Una vez creada la unidad USB de instalación se debe iniciar el sistema desde ella y realizar normalmente los pasos de instalación de Windows XP.

Corregir el inicio de la unidad USB.

Finalizada la instalación del sistema operativo se intenta reiniciar y falla mostrando un error relacionado con la falta de archivos del sistema, comúnmente hal.dll.  Esto aparentemente se debe a que el instalador consideró a la unidad USB  como primer disco y al disco duro real como segundo, generando estas referencias incorrectas en el archivo boot.ini.

Para corregir esto es necesario editar este archivo y modificar la referencia a la partición en la que buscará al sistema operativo durante su inicio.  Por facilidad (para mi) utilicé un Linux (Peppermint) que inicia desde LiveUSB que casualmente tenía preparado para otra prueba.  En el ambiente Windows  imagino que se requerirá de un disco de arranque que permita acceder a través de la consola de texto a los comandos básicos del DOS.

Este es un ejemplo de boot.ini en el que se supone que hay un Windows XP Home Edition instalado en la primera partición del primer disco duro del equipo (como habitualmente sucede).

[boot loader]
timeout=5
default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Home Edition" /fastdetect

El parámetro rdisk (marcado en rojo) es el que se genera incorrectamente y aparece inicialmente con el valor de 1 (segundo disco duro).

Cambiar la ruta de los archivos de instalación.

Una vez superado el problema anterior el sistema operativo deberá iniciar sin problemas.  De manera opcional elegí copiar los archivos del sistema operativo al disco duro del netbook para que estén disponibles si se hace necesaria la instalación de algún componente adicional sin que se necesite insertar nuevamente la unidad USB preparada al comienzo de este procedimiento.

Para lograr esto además de copiar físicamente los archivos del CDROM de instalación al un directorio del disco duro, es necesario actualizar la referencia que tiene el sistema operativo de esta ruta.  Para hacer esto se debe ejecutar el programa regedit (hágalo como Administrador si obtiene problemas de permisos) y acceda a la siguiente rama en el panel izquierdo.

HKEY_LOCAL_MACHINE > Software > Microsoft > Windows > CurrentVersion > Setup.

Ubicado en esa rama identifique la variable SourcePath en el panel derecho y modifique su valor a la ruta absoluta donde se encuentra el directorio \i386 de los archivos de instalación de Windows: c:\instaladores\windowsxp\i386 en mi caso específico.

Instalar unrar en GNU/Linux Fedora 15

Introducción.

Ahora que nuevamente he vuelto a la línea de Redhat instalando Fedora en uno de mis portátiles, muchos de los simples y habituales procedimientos son nuevos y ameritan documentarse.

Esta vez es la instalación de la herramienta unrar para descomprimir los paquetes que han sido comprimidos con su algoritmo asociado.  Al igual que en Ubuntu, esta herramienta no se encuentra instalada por defecto sin embargo a diferencia de este tampoco se encuentra en los repositorios estándar, por este motivo se debe realizar el procedimiento descrito a continuación.

Instalación.

Agregar los repositorios de RPMFusion.

# yum localinstall –nogpgcheck \
http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-stable.noarch.rpm \
http://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-stable.noarch.rpm

Instalar la herramienta deseada.

# yum install unrar

Evitando el reemplazo de los guiones y comillas dobles en WordPress

Introducción.

WordPress tiene una característica que consiste en reemplazar ciertos carácteres o cadenas en sus correspondencias mas bonitas, por ejemplo reemplaza los guiones dobles por un único guión mas largo que el normal.  Esto lo hace para embellecer los textos que se publican.

Este loable objetivo puede ser interesante en la mayoría de los casos pero es un total infortunio para quienes publicamos código fuente o textos para ejecutarse en la línea de comando los cuales deberán transcribirse de manera fiel o simplemente fallarán debido a que cualquier variación como las propuestas les harán perder su validez sintáctica.

Hace un tiempo encontré como solución modificar las líneas exactas en las cuales WordPress realiza esta inoportuna conversión, sin embargo estas líneas pertenecen a un archivo del núcleo de WordPress y desafortunadamente es sobreescrito durante las actualizaciones de WordPress y por ende las modificaciones se pierden con la misma regularidad.

Para solventar esto he encontrado una solución similar que se basa en la adaptación de un plugin ya existente, así que las modificaciones perdurarán a las actualizaciones de WordPress y sólo deberán repetirse ante una posible actualización del plugin, las cuales por supuesto suceden con una frecuencia mucho menor.

Procedimiento.

Instalar y activar el plugin de WordPress llamado untexturize.

Editar el contenido del archivo wpuntexturize.php.  Por facilidad se recomienda utilizar el mismo editor de Plugins que provee WordPress.

Identificar el código fuente de la función c2c_wpuntexturize y modificar su contenido de la siguiente manera.

$char_codes = array( '&#8216;', '&#8217;', '&#8220;', '&#8221;', '&#8242;', '&#8243;',
                     '&#8212;', ' &#8212; ', '&#8211;', ' &#8211; ', 'xn--');   // nuevo.
$replacements = array( "'", "'", '"', '"', "'", '"',
                       '---', ' -- ', '--', ' - ', 'xn&#8211;');    // nuevo.
return str_replace( $char_codes, $replacements, $text );

Si se nota, las líneas marcadas con el comentario nuevo han sido agregadas con respecto al código fuente original del plugin, estas líneas corresponden con la información de los reemplazos de los guíones facultando al plugin a regresarlos a su presentación original mas allá de sólo las comillas dobles las cuales son la funcionalidad propia del complemento.

A partir del momento en que se realicen estas modificaciones, las entradas del blog mostrarán correctamente las comillas y guíones dobles en sus textos.

Enlaces.

Como desvincular una aplicación de la terminal en la cual se abrió en GNU/Linux

Introducción.

Cuando se inician aplicaciones desde una terminal en GNU/Linux sus procesos quedan ligados a la terminal, de manera que cuando esta se destruye (cierra) los procesos asociados también se terminan de manera ineludible.

Esto es particularmente inoportuno cuando se desea dejar ejecutándose una aplicación durante un largo periodo de tiempo sin supervisión ni interacción humana.  Esto es muy frecuente cuando se realiza administración de los servidores o se desea realizar tareas de larga duración como la transferencia de archivos.  En ese orden de ideas es necesario mantener la conexión y la terminal desde donde se ejecutó la aplicación abiertas hasta que termine el procedimiento.

Para evitar este problema existen varias alternativas de solución.  A continuación se expone el procedimiento de desvincular la aplicación de la terminal en la cual se invocó.

El problema.

Al ejecutar una aplicación en una terminal su proceso, representado por su PID (identificador de proceso) queda asociado con el de la terminal en la cual se ejecutó.

$ gedit &

[1] 2643

Por ejemplo, en el caso anterior, al ejecutar el programa gedit (en background) se puede apreciar que su PID es 2643.  Si se verifica la información de dicho proceso se obtienen los siguientes datos adicionales.

$ ps -fea | grep 2643 jimezam

2643  2576 0 Jun03 pts/1    00:00:00 gedit

Nótese que su proceso padre (segunda columna) es el 2576.  Si se solicita mayor información acerca de dicho proceso se obtiene lo siguiente.

$ ps -fea | grep 2576

jimezam   2576 2571  0 Jun03 pts/1    00:00:00 bash
jimezam   2643  2576 0 Jun03 pts/1    00:00:00 gedit
jimezam   2809  2576 0 00:17 pts/1    00:00:00 ps -fea
jimezam   2810  2576 0 00:17 pts/1    00:00:00 grep –color=auto 2576

De lo anterior se colige que dicho proceso corresponde con una terminal (bash) e inclusive se pueden apreciar los procesos que se desprenden de ella, en este caso los siguientes 3 procesos mostrados.

Si se termina el proceso 2576 se terminarán automáticamente entonces los procesos 2643, 2809 y el 2810.

La solución.

Como se mencionó inicialmente, la solución a esta situación corresponde con la desvinculación (detach) del proceso específico con la terminal del cual fue lanzado.  Esto se logra con un comando interno del Bash llamado disown de la siguiente manera.

$ disown -h 2643

Después de ejecutada esta instrucción, la terminal de orígen (en este caso con 2576 como PID) puede ser cerrada sin interferir con la ejecución del gedit del ejemplo (con 2643 como PID).

Google Chrome y los puertos inseguros: ERR_UNSAFE_PORT

Introducción.

Aparentemente Google Chrome incluye características de seguridad obligatorias como esta que impide que el usuario acceda a servidores a través de ciertos puertos considerados inseguros aunque eso sea realmente lo que se desea.

Error puertos inseguros de Google Chrome

Error puertos inseguros de Google Chrome

A continuación se define el procedimiento necesario para indicarle a Chrome que efectivamente se desea acceder a esos puertos.

Procedimiento.

La única opción es indicarle a Chrome desde el momento de su ejecución cuales son los puertos que se consideran seguros para permitir conexiones mas allá de los estándar.  Para hacer esto es necesario indicar el parámetro –explicitly-allowed-ports seguido por la lista de puertos separados por comas.  Por ejemplo:

$ /usr/bin/google-chrome –explicitly-allowed-ports=4444,5555,6666

Por facilidad, especialmente en la plataforma Windows, se recomienda modificar el acceso directo a la aplicación para que la modificación perdure.

Modificar la contraseña del usuario root de MySQL 5

Introducción.

El procedimiento que se describe a continuación permite modificar la contraseña del usuario administrador (root)  de MySQL 5.  Es útil para los casos en que esta se olvida y por lo tanto ya no es posible acceder a sus funciones de administración.

Procedimiento.

Detener el servicio si se está ejecutando actualmente.

# service mysql5 stop

Iniciar el servicio con el modificador de skip-grant-tables.

# mysqld_safe –skip-grant-tables &

Realizar una conexión al motor de base de datos a través de la herramienta de línea de comando.

# mysql -u root

Realizar la actualización de la contraseña.  Téngase en cuenta que se deberá modificar la palabra NUEVO_PASSWORD por la nueva contarseña que se desee asignar al usuario root.

mysql> use mysql;
mysql> update user set password=PASSWORD("NUEVO_PASSWORD") where User='root';
mysql> flush privileges;
mysql> quit

Detener el servicio

# service mysql5 stop

Iniciarlo normalmente.

# service mysql5 start