martes, 4 de octubre de 2016

SQL Espacial y PostGIS para apps móviles

SQL Espacial para aplicaciones móviles

El SQL espacial es la base para desarrollar aplicaciones basadas en la localización, que permitan a sus usuarios consultar elementos que se encuentren a su alrededor, o cerca de un lugar, expresado éste por su nombre (París, Parque Nacional de Ordesa, Francia, etc). Recientemente hemos publicado varias aplicaciones Android que precisamente hacen uso del SQL espacial.

En estas aplicaciones, como por ejemplo en "Rutas MTB", los usuarios pueden realizar dos tipos de búsquedas relacionadas con la localización:
  • Búsqueda "Cerca de tí".
  • Búsqueda de "elementos cerca de una referencia geográfica".
Antes de ver el detalle de como implementar estas búsquedas con SQL, hay que hacer una aclaración: los datos a consultar residen en un servidor. Desde la app móvil se envían peticiones a un servicio web que reside en el servidor, y éste es el que hace las consultas a la base de datos y envía a las aplicaciones el resultado en formato JSON.

La otra alternativa (datos en el móvil) haría que el tamaño de la aplicación para su descarga fuese excesivo.


Captura de pantalla de la app "Rutas Senderismo" de la búsqueda por referencia geográfica.

SQL para implementar la búsqueda "Cerca de tí".

Esta consulta es la más sencilla, pues tan solo necesitamos tener nuestros datos en una tabla, y que ésta tenga una columna geométrica. Supongamos que esta tabla se llame MAPAS, y la columna geométrica GEOMETRY. Nuestra posición nos la proporciona el dispositivo móvil (ya sea en Java, Javascript, o cualquier otra plataforma de desarrollo para dispositivos móviles). 
Si el GPS nos da la posición latitud = 41, longitud = 1, la consulta que se ejecutaría en el servidor sería:

SELECT  t.TITLE, t.DESCRIPTION, FROM MAPAS AS t WHERE MBRIntersects( t.GEOMETRY, GeomFromText('POLYGON((1 41, 1 41, 1 41, 1 41,  1 41))') 

Tan simple como una operación MBRIntersects entre la geometría de nuestros datos, y una geometría construída "al vuelo" con la coordenada que nos ha dado nuestro GPS.
 

SQL para implementar la búsqueda de "elementos cerca de una referencia geográfica".


En este caso, además de la tabla con los datos principales (MAPAS), necesitamos tener una tabla con la referencias geográficas (topónimos) que se vaya a usar como referencia. Para cada referencia geográfica, esta tabla tiene que tener un nombre (por ejemplo: Sevilla (España), Estados Unidos, Parque Nacional de Ordesa, etc), y una geometría. Por ejemplo, GEOGRAPHIC_REFERENCES, NAME y GEOMETRIA.

El proceso para realizar la búsqueda es muy simple: a partir del texto introducido por el usuario, localizamos la referencia geográfica que casa con dicho texto, cogemos su geometría, y hacemos una búsqueda espacial cruzando las dos capas.

El SQL que expresa estas condiciones es el siguiente:

SELECT SQL_CALC_FOUND_ROWS X.* FROM (SELECT  t.TITLE, t.DESCRIPTION FROM MAPAS AS t JOIN GEOGRAPHIC_FILTER AS g ON MBRIntersects( t.GEOMETRIA, g.GEOMETRIA )  WHERE g.name = 'Madrid' ) AS X


Es decir, hacemos una operación JOIN SQL entre las dos tablas (la de los datos y la de las referencias geométricas), usando como condición de unión que intersecten sus geometrías (ON MBRIntersects(g1,g2) ) y luego filtramos los resultados por el texto de búsqueda (WHERE g.name = "Madrid").

En este enlace podemos ver un ejemplo de esta consulta en funcionamiento, localizando rutas de mountain bike en el entorno de Barcelona (España)

Si queréis probar como funciona en la aplicación, podéis instalar alguna de las siguientes aplicaciones:

Rutas MTB

Rutas Senderismo