La innovación, nuestra razón de ser
Antes de nada, y para los que no lo tengáis muy claro, los datos espaciales son aquellos que incluyen información tanto geográfica como política. Incluyendo puntos de interés – POIS –, regiones en el mapa – líneas, polígonos, etc. – e información administrativa como fronteras de municipios, provincias, etc.
En sí mismo, es un mundo, y una disciplina de software compleja con muchos aspectos a considerar. Nosotros en Proxia® nos hemos limitado a un conjunto pequeño de funcionalidades, relacionadas con dotar de capacidades espaciales a la información que alojamos, en concreto:
Cuando decidí abordar este problema, tuve que dar respuesta a distintas cuestiones, entre ellas donde delegar la lógica de agrupación de estos puntos de interés. Si bien existen librerías JavaScript (Google, Leaflet, etc.) que hacen estas funciones, no me pareció una solución adecuada, puesto que:
Ahora bien, realizar esto en servidor es meterse en un terreno resbaladizo, puesto que si no queremos penalizar la experiencia de usuario, tenemos que optimizar el tiempo de procesamiento.
Dar una respuesta acertada exige conocer, en mayor o menor medida, como funcionan las herramientas con las que vamos a trabajar, es decir las herramientas de representación: Google Maps, Leaflet, Bing Maps, etc.
Como os comentaba, para recuperar los POIS – o las regiones - de forma efectiva debemos conocer como funcionan las herramientas de mapas. Sin extenderme mucho, existen dos aspectos a tener en cuenta:
Como os podéis imaginar, no vamos a tener un mapa completo de la Tierra para cada nivel de zoom, no resulta muy práctico porque ocuparía demasiado y además en un mapa no vemos toda la Tierra sino un área concreta. Por ello los proveedores de mapas dividen el plano en rejillas, cada una de esas cuadriculas la llaman tile en Inglés (azulejo).
De esta forma, la obtención de los POIs pasa, simplificadamente, por saber que cuadrículas nos están pidiendo (es una función del nivel de zoom y de las fronteras visibles del mapa en pantalla) y para cada posible cuadrícula que POIS se van a encontrar dentro del mismo. En el caso de las regiones, saber si una región está en una cuadrícula es sólo saber si alguno de sus puntos está contenido dentro de las fronteras de la misma.
No es que sea una tarea excesivamente compleja, a fin de cuenta es disponer de varias capas de acceso por clave-valor a fin de ir rápido en la recuperación de los datos.
Como podéis ver, los niveles de zoom más bajos contienen más POIS por cuadrícula, a medida que aumentamos el nivel de zoom el número de POIS decrece.
Lógicamente, no tiene sentido almacenar en cada capa toda la información de todos los POIS puesto que desperdiciaríamos mucho espacio. Por ello utilizamos una capa adicional con los datos de los POIS que pueden, a su vez, contener datos adicionales tal y como: tipo de POI, municipio, etc. Buscar POIS, por tanto, no es más que encontrar las cuadrículas, recuperar los POIS y luego aplicar los filtros indicados por el usuario.
Os podrías preguntar, ¿dónde se almacena todo esto? ¿se guarda en la Base de datos? La respuesta es no. En la Base de datos almacenamos la información básica, que durante el arranque del sistema utilizamos para construir toda esta serie de capas.
Este proceso, introduce un problemilla adicional, ¿cómo puede el sistema reaccionar ante la creación de un nuevo POI o ante el borrado o modificación de los existentes? Indicaros aquí, que tenemos un sistema de mensajería broadcast del que ya os hablaré en otro post.
Una vez seleccionados los POIS que nos interesan tenemos que agruparlos a fin de evitar, como os decía antes, un mapa lleno de chinchetas que no respeta ningún tipo de patrón en cuanto a experiencia de usuario.
Podéis pensar que, desde el punto de vista técnico, la solución tampoco es muy compleja, a fin de cuentas, lo único que hay que hacer es encontrar los POIS más próximos y agruparlos. En realidad, tiene un poquito más de truco, no mucho, pero un poquito:
Por otra parte, agrupar por agrupar puede ser un sinsentido. ¿Tendrías un mismo grupo para, por ejemplo, información de centros de salud y alojamientos? La respuesta es que, probablemente, no, al menos para niveles de zoom medios. De esta forma y en aras de mejorar la experiencia de usuario debemos introducir tipos de grupos y agrupar la información en base a ellos.
Con Proxia® damos una respuesta a estas cuestiones, permitiendo al administrador no sólo definir tipos de grupos sino estructurarlos de forma jerárquica. Gracias a todo esto conseguimos una experiencia de agrupación igual para todos los dispositivos, basada en el nivel de zoom y sobre el conjunto de POIS seleccionados de la fase de obtención.
En este caso no hablamos de pintar en un mapa, sino de recuperar información en base a criterios como en los alrededores, en este municipio, a 25 kms, etc. Podéis verlo como un típico servicio de recomendaciones: los usuarios que compraron esto, también compraron esto otro.
Si nos centramos en la recuperación de información en base a criterios administrativos, puedo deciros que es una tarea simple. No hay más que almacenar la dirección postal codificada (país, región, provincia, municipio, núcleo) y cuando el usuario solicite algo buscar las coincidencias. Para la codificación, como muchos de vosotros, hemos utilizado la base de datos del INE, y, en Portugal, versiones adaptadas de sus tablas de Freguesías.
El caso de las búsquedas en base a distancias la cosa se complica un poco. La razón, calcular las distancias no es fácil. Y ya no os hablo de la distancia real, mediante carretera, que es complejísimo, sino sólo de distancia radial. Sólo recordaros aquí que la Tierra no es plana, por tanto, el cálculo de distancia no es aplicar el teorema de Pitágoras, sino que tenemos que aplicar algoritmos como la formula del semiverseno.
Nuestra aproximación, un proceso batch que nos permita almacenar estas relaciones precomputadas. Esto nos da potencia y flexibilidad como para retornar la información relacionada en tiempos muy cortos.
Imagenes de mapas cortesía de OpenStreetMaps, otros iconos empleados: