Lenguajes y herramientas Para poder cumplir con los objetivos del proyecto, hemos hecho uso de diferentes lenguajes de programación. En concreto, hemos utilizado: JavaScript, un lenguaje de Scripting del lado del cliente, que en la actualidad esta en auge, sobre todo por el uso de AJAX, que permite la combinación del lado del cliente con lenguajes del lado del servidor, teniendo en concreto la capacidad de realizar la comunicación asíncronamente. El otro lenguaje de programación que empleamos es PHP, del lado del servidor, es decir, que las páginas que tenemos en un servidor de páginas web, son preprocesadas por el intérprete de PHP cuando algún cliente realiza una petición, para mostrar la página resultado. Conjuntamente con PHP se suele utilizar un sistema gestor de bases de datos tal como MySql, ambos forman una solución muy atractiva para la implantación de sitios web, ya que, entre otras cosas forman una solución software libre y proporciona una alternativa muy potente frente a soluciones comerciales. El servidor que hemos utilizado para poder utilizar las páginas web y realizar el procesamiento de las páginas en PHP, es Apache, un servidor de páginas web gratuito, de gran difusión debido a su excelente rendimiento, así como por su configurabilidad y facilidad de uso. El sistema que desarrollamos esta compuesto por una solución que utiliza los dos lenguajes: PHP y JavaScript. La utilización de cada uno de estos lenguajes, es la siguiente: JavaScript: Del lado del cliente, realizamos la comunicación con la API proporcionada por google; ya sea para comunicarnos con el protocolo de mapas o con el motor de consultas. PHP: Del lado del servidor, lo utilizamos para comunicarnos con la base de datos que tenemos en el servidor local en MySql, lo programamos para que reciba las peticiones de la página programada en JavaScript. Obtención de los datos de los Restaurantes En el proceso de búsqueda de información para el proyecto, nos encontramos con un problema crucial: la búsqueda de información detallada de restaurantes, en la que deberíamos de obtener no sólo el nombre del restaurante y su dirección (entendida como ciudad, calle, número, código postal…etc), sino que además, debemos de obtener, primeramente, las coordenadas en latitud y longitud usadas por el protocolo GPS para ubicar los restaurantes; y finalmente, el resto de los campos y relaciones que hemos modelado en nuestra base de datos. Existen multitud de sitios en Internet en los que podemos consultar datos acerca de los restaurantes, (es precisamente, a partir de estos sitios donde hemos obtenido los atributos y relaciones que mejor modelan un esquema para una base de datos de restaurantes). Una referencia de los sitios web que hemos consultado se encuentra en [1]. El problema de la búsqueda A pesar de esta gran cantidad de datos, es realmente complejo extraer la información de estos sitios de manera automática. Es por ello, por lo que buscamos vías alternativas para conseguir los datos que deseamos: Conseguir una base de datos, preferentemente en formato digital, con restaurantes de la provincia de Granada, consultando a alguno de los organismos que regula la actividad hostelera en la provincia. Tratar de obtener estos datos, de forma semi-automática, mediante la realización de una aplicación que nos permitiera recoger esta multitud de datos que se encuentran en las páginas web. Estas dos opciones las llevamos en paralelo, consultando diversos organismos y páginas en Internet donde obtener información acerca de cómo capturar estos datos que se encuentran en las páginas web de guías de restaurantes. Tras un período de tiempo, en el que procedimos a la consulta de diversos organismos, comprendimos que la única opción que nos quedaba era la segunda; en parte por la necesidad que tenemos de obtener direcciones GPS de los restaurantes. Búsqueda a través de la API de Google En nuestro período de investigación de un método para obtener los datos a través de una aplicación que obtuviera la información de páginas web, nos encontramos con la API de Google, en la que podemos utilizar el motor de búsqueda de google, mediante la programación de un script en JavaScript, para realizar una consulta, con la ventaja que el conjunto de datos que se obtienen como resultado de la consulta, es accesible por el script que programamos. Lo más interesante, es que si buscamos un restaurante de algún tipo en Granada, p.e. Restaurantes Italianos en Granada, google nos devuelve una serie de restaurantes italianos, junto con sus posiciones GPS y una descripción básica. Dispositivo utilizado Siguiendo los ejemplos de uso de la API que podemos encontrar en [2], programamos un pequeño script que, con uso de JavaScript por un lado, y de un servidor con PHP y MySql ,nos permite, a través de AJAX pasar los datos que obtenemos de nuestro script al lado del servidor donde se almacena la información. Por lo tanto disponemos de un servidor con la base de datos de restaurantes en SQL ( en concreto, en MySql) junto con un servidor de páginas web Apache con soporte para PHP. Cada vez que añadamos un restaurante en nuestro Script, la información se pasará, a través del AJAX de JavaScript a un script programado en PHP , que se comunica directamente con nuestra base de datos. A continuación mostramos un pequeño esquema del funcionamiento de la aplicación programada: Servidor con MySql y Apache con módulo PHP. Página Web con JavaScript (AJAX) que realiza la consulta en google sobre los restaurantes Envía Datos al Script en PHP Envía datos al servidor Mysql Página web programada en PHP que conecta con la base de datos Mysql A pesar de este esfuerzo por conseguir los datos de los restaurantes de manera automática, otros datos, como la descripción, el resto de servicios que proporcionan, las tarjetas que aceptan…, la introducimos a partir de los datos que se encuentran en las Páginas Amarillas, a través de un pequeño formulario que realizamos en lenguaje PHP para facilitar la labor. Finalmente, tras un proceso de búsqueda con este sistema montado, el número de restaurantes obtenido no era superior a 70, por lo que buscamos otro método para ampliar nuestra base de datos. Introducción de datos manual Como hemos comentado en el apartado anterior, el sistema que desarrollamos para la introducción automática de restaurantes, nos limitó el conjunto de restaurantes a un número muy bajo, por lo que decidimos ampliar este conjunto mediante la utilización de alguno de los siguientes recursos: Realización de alguna otra aplicación mediante alguno de los lenguajes de script existentes (JavaScript, Python..etc) que tomen los datos de otras páginas. Introducción de más datos manualmente, a través de alguna de las guías como QDQ o Páginas Amarillas o de las páginas web de dichas empresas. Finalmente, por ser la opción más rápida, nos dispusimos a introducir un conjunto de restaurantes en el que hubiera por lo menos un restaurante de cada tipo de cocina, a partir de la guía de restaurantes de las Páginas Amarillas, utilizando el formulario empleado con anterioridad en la introducción de datos. Es ahora cuando se nos plantea otro problema, ya que sólo tenemos el campo de dirección del restaurante (calle, número, código postal..etc) pero no tenemos su localización GPS. De nuevo, acudimos a la API del google para realizar la transformación de dirección en coordenadas GPS, utilizando la API de lo que se llama Geocoder. Utilización del Geocoder Una vez tenemos introducidos los datos de los restaurantes manualmente, tenemos la necesidad de obtener, para cada dirección, compuesta por calle, número y código postal, una localización GPS. Para ello, programamos de nuevo una aplicación haciendo uso de la API de google, pasamos los datos de las direcciones y sus posiciones GPS a la base de datos de restaurantes. Proceso de obtención de Mapas Un punto fundamental en la aplicación que proponemos, es mostrar un mapa en el que se localice tanto la posición del usuario como la posición de los restaurantes cercanos. Para resolver el problema de mostrar un mapa de la ciudad en la que nos encontremos con la posición del usuario, hemos de resolver los siguientes puntos: Primeramente, hemos de obtener imágenes de calidad, de la ciudad para la que vamos a mostrar los mapas. También hemos de delimitar los límites de la ciudad en la que nos encontramos, dentro de un marco en el que permitiremos localizar objetos. Una vez tengamos las imágenes de la ciudad se nos plantea el problema de resolver la localización de los objetos en el mapa; es decir, el poder ser capaces de posicionar cualquier objeto dentro de este mapa, sabiendo sus coordenadas en latitud y longitud GPS. Finalizado el proceso de localización, tenemos el problema de pasar los mapas al dispositivo móvil, siendo evidente la necesidad de particionar la imagen del mapa de manera inteligente y de trasladar el posicionamiento de los objetos dentro del mapa, al PDA. Imágenes de mapas En principio buscamos sitios en Internet en los que poder obtener imágenes, ya sean de satélite o imágenes gráficas en las que se vean las calles así como información acerca de la dirección de las calles, …etc. Existen numerosos sitios gratuitos, en los que a través de una serie de coordenadas GPS, o a través de códigos postales o incluso direcciones de calles. Un listado de los sitios que hemos encontrado, se puede ver en [3]. La solución a la que llegamos es acudir de nuevo a Google, en concreto a GoogleMaps, y centrar la búsqueda en Granada, tras varias ampliaciones, llegamos al nivel de zoom adecuado, en el que se ven las calles, así como la dirección de las mismas. En un primer paso, realizamos una captura de pantalla, con el mapa del centro de Granada. De este mapa, conocemos las coordenadas GPS de la esquina superior izquierda y de la esquina inferior derecha. El mapa es el siguiente: El marco en el que localizaremos los objetos dentro del mapa son las coordenadas GPS: Esquina superior izquierda LAT: 37,18000, LNG: -3,61000 Esquina inferior derecha LAT: 37,17200 LNG: -3,59000 El siguiente paso es obtener un algoritmo para poder posicionar cualquier objeto dentro del mapa, lo que detallamos en el siguiente punto. Algoritmo de posicionamiento Como podemos observar, las coordenadas GPS funcionan de la siguiente manera: Latitud: Se corresponde de el eje y, aumentando conforme aumenta el valor en el eje y. Longitud: Se corresponde con el eje x, disminuyendo su valor conforme aumenta el valor en el eje x. Si utilizamos de nuevo, la funcionalidad de la API de google, podemos posicionar marcadores en posiciones GPS que nosotros especifiquemos. Como lo que queremos obtener es la relación entre coordenadas GPS y coordenadas de pantalla, como por ejemplo la relación entre latitud/ logitud y píxeles, posicionamos una cuadrícula de marcadores, siguiendo la siguiente razón: Cada nueva latitud es igual a la anterior, menos 0.002. Cada nueva longitud es igual a la anterior, menos 0.002. Donde la razón 0.002 la hemos obtenido experimentalmente, colocando diversos marcadores en posiciones separadas por cantidades de espacio (lat/long) arbitrarias, y llegando a la conclusión que la razón 0.002 es la mejor, también de cara a su implantación posterior en la pantalla de un dispositivo móvil. El siguiente paso es obtener la razón entre las coordenadas de pantalla y la latitud y la longitud, para poder posicionar cualquier objeto dentro de nuestro mapa. La solución más inmediata es medir mediante algún programa de manipulación gráfica, la distancia en píxeles de los marcadores que hemos posicionado, para así poder obtener su relación. La relación es la siguiente: Latitud: 0.001 = 95 píxeles. Longitud: 0.001 = 115 píxeles. Una vez hallada la relación, estamos en condiciones de establecer una ecuación que nos permita posicionar cualquier objeto dentro de los límites superior izquierdo e inferior derecho: Introducción de mapas en el PDA Para finalizar el proceso, hemos de ser capaces de llegar a una representación de los mapas en el dispositivo PDA, integrándolo con nuestra aplicación para búsqueda de restaurantes. Limitaciones iniciales A continuación enumeramos las limitaciones que tenemos en el dispositivo móvil, así como las funcionalidades proporcionadas por el lenguaje de programación, SuperWaba: Las imágenes que nos permite manipular la máquina virtual de SuperWaba son mapas de bits sin compresión (formato .bmp) con profundidad de color de 8 bits. El tamaño máximo de una imagen en este formato ha de ser de 65 Kb, en caso que sea mayor, el dispositivo no la carga. La librería de imágenes de SuperWaba en la versión que disponemos, cuenta con funciones para rotar, escalar y posicionar una de estas imágenes en pantalla. Si pasamos el primer mapa a formato de imagen bmp, obtenemos un archivo de varios megas, lo que nos impide cargarlo. Esta claro que hemos de fragmentar la imagen original en varias imágenes de tamaño tal que no supere el límite de los 65 Kb. Ahora bien, también se nos plantea el problema de qué tamaño en píxeles han de tener las imágenes resultado; ya que podemos pensar que una posible solución es recortar la imagen original en varias imágenes cuyo tamaño sea similar al tamaño de la pantalla del dispositivo móvil. Veamos lo que ocurriría en esta primera aproximación. Aproximaciones a la solución El tamaño en píxeles de la pantalla de nuestro dispositivo móvil es aproximadamente de 240 x 280, por lo que si dividimos en porciones de esta cantidad la imagen original, tendríamos una secuencia de imágenes así: De este modo, la imagen original de la ciudad, quedaría representada en nuestro dispositivo como una matriz de imágenes más pequeñas de este tamaño. Esta matriz tendría dos columnas y cinco filas, y de este modo podríamos direccionar una imagen dentro de nuestra matriz de imágenes. Llegados a este punto, tenemos el siguiente problema: supongamos que nos encontramos en la imagen de la izquierda, en una esquina inferior, y que la mayoría de los restaurantes se encuentran en la imagen de la derecha; esta claro que la solución que deberíamos de adoptar es mostrar una porción de la imagen de la izquierda y mostrar otra porción de la imagen de la derecha. En el peor caso tendríamos que mostrar porciones de cuatro imágenes: izquierda, derecha, inferior y superior; el problema principal es que si, adoptamos esta solución, hemos de implementar en la librería de imágenes que nos proporciona SuperWaba, unas funciones que nos permitan mostrar sólo una porción de la imagen, para poder manejar el caso que acabamos de describir. Solución Adoptada Investigando cómo muestran las imágenes de los mapas los distintos programas que hay, nos encontramos, en el caso de google, que toma imágenes de tamaño relativamente pequeño (en torno a 20 píxeles) para mostrar un mapa, con lo cual, una imagen de mapa, esta formada por multitud de imágenes más pequeñas. Quizá, la opción más inteligente, sea la de dividir la imagen que mostramos en el dispositivo móvil en porciones más pequeñas que su pantalla, de modo, que una imagen en pantalla este compuesta por, por ejemplo cuatro imágenes. Siguiendo este esquema, procedemos a obtener imágenes de tamaño 90 x 140 a partir de la imagen original. Para ello, utilizamos un sencillo script utilizando el programa Matlab. Obtenemos entonces un conjunto de 10 filas y 4 columnas de imágenes. Así, el problema que teníamos en el apartado anterior queda solucionado, ya que para posicionar un objeto en el mapa, solo tenemos que escoger la imagen dentro de la que se encuentra y posteriormente, las otras 3 imágenes más cercanas. En este ejemplo observamos como representamos las imágenes dentro del dispositivo móvil, con cuatro imágenes, de modo que solventamos todos los problemas que teníamos, ya que, las imágenes, al ser más pequeñas ocupan también menos espacio y nunca alcanzan el límite de los 65 Kb. Nombrando a cada imagen como sus índices i,j dentro de la posición que ocupan en la matriz, podemos formar la imagen del mapa rápidamente. Posicionamiento de objetos Una vez tenemos una manera de representar las imágenes de un mapa en nuestro dispositivo móvil, de modo que le digamos que nos muestre una zona de la cuidad pasándole una coordenada GPS, necesitamos una manera de representar objetos dentro de este mapa, de modo que podamos establecer su posición en coordenadas de pantalla. Esto nos va a servir, por ejemplo, para poder posicionar al usuario de la aplicación dentro del mapa y para posicionar los restaurantes que tiene cerca. Lo primero que hacemos es posicionar el usuario dentro de la matriz de imágenes que representa a la ciudad en la que nos encontremos. En concreto, para la ciudad de Granada, la matriz tiene las siguientes coordenadas en latitud y longitud, respecto a cada imagen formada: LAT LNG LAT 0 0 1 2 3 4 37,18000 37,17800 37,17600 37,17400 37,17200 LAT 4 37,18000 37,17800 37,17600 37,17400 37,17200 LNG LAT 1 -3,61000 -3,61000 -3,61000 -3,61000 -3,61000 37,18000 37,17800 37,17600 37,17400 37,17200 LNG LAT LNG -3,60800 -3,60800 -3,60800 -3,60800 -3,60800 37,18000 37,17800 37,17600 37,17400 37,17200 LNG LAT 5 -3,60200 -3,60200 -3,60200 -3,60200 -3,60200 37,18000 37,17800 37,17600 37,17400 37,17200 LAT 2 -3,60600 -3,60600 -3,60600 -3,60600 -3,60600 37,18000 37,17800 37,17600 37,17400 37,17200 LNG LAT 6 -3,60000 -3,60000 -3,60000 -3,60000 -3,60000 37,18000 37,17800 37,17600 37,17400 37,17200 LNG 3 -3,60400 -3,60400 -3,60400 -3,60400 -3,60400 LNG 7 -3,59800 -3,59800 -3,59800 -3,59800 -3,59800 37,18000 37,17800 37,17600 37,17400 37,17200 -3,59600 -3,59600 -3,59600 -3,59600 -3,59600 LAT LNG LAT 8 37,18000 37,17800 37,17600 37,17400 37,17200 LNG 9 -3,59400 -3,59400 -3,59400 -3,59400 -3,59400 37,18000 37,17800 37,17600 37,17400 37,17200 -3,59200 -3,59200 -3,59200 -3,59200 -3,59200 LAT 10 37,18000 37,17800 37,17600 37,17400 37,17200 LNG -3,59000 -3,59000 -3,59000 -3,59000 -3,59000 Las zonas en gris son los límites inferiores de las imágenes, es decir, que no son columnas y filas de imágenes, sino que nos sirven para posicionar inferiormente las imágenes. Con las tablas anteriores es fácil posicionar a un usuario dentro de un conjunto de cuatro imágenes. Siguiendo las relaciones indicadas en las tablas, podemos también posicionar un restaurante dentro de un archivo de imagen, siguiendo la fórmula dada anteriormente y que nos establece la relación entre píxeles y coordenadas GPS.