Analizaremos proyectos existentes realizados con dicha tecnología, con un enfoque en los datos utilizados, y cómo el SQL geoespacial ayuda a ofrecer valor añadido sobre los mismos. Asimismo, veremos posibles vías de enriquecimiento de los proyectos, mediante la utilización de la BBVA Data API, y otras fuentes de datos abiertos
En el presente post, hablaremos del Visor de Rutas Arqueológicas de la ciudad de Córdoba, realizado por la división geo de Almagre, consultora especializada en servicios basados en sistemas de información geográfica.
El visor permite, de manera sencilla e intuitiva, visitar un total de 79 puntos representativos de la ciudad de Córdoba, desde el punto de vista arqueológico.
También podemos reproducir algunas de las rutas temáticas que el Grupo de Investigación Sisifo, de la Universidad de Córdoba, lleva realizando desde 2011
Veremos a continuación un pequeño análisis del modelo de datos utilizado para implementar estas funcionalidades, así como algunos sencillos snippets de código SQL geoespacial, usados para crear rutas entre puntos.
Modelo de datos
Sin entrar en particularidades concretas sobre la implementación de este proyecto, podemos resumir su modelo de datos en 3 entidades lógicas:
– Entidad punto: contiene un punto de interés geográfico, junto con su información asociada
– Entidad ruta: contiene una línea, geográficamente localizada en un área concreta, entre un punto de inicio y un punto de fin
– Entidad punto_en: Es el pegamento entre las entidades anteriores. Básicamente, contiene referencias a puntos junto con la ruta a la que pertenecen. De manera que una ruta tendrá varios puntos, y un mismo punto puede pertenecer a mismas rutas
Dichas entidades lógicas se mapean con entidades físicas en el almacén de datos de CartoDB. Estas entidades físicas no son otra cosa que tablas dentro del gestor de bases de datos PostgreSQL.
En el siguiente esquema, se aprecian las relaciones entre las entidades existentes
En cuanto a la implantación física del modelo de datos, podríamos hacerlo utilizando la sentencia CREATE TABLE, de PostgreSQL, en nuestra instalación de PostgreSQL / PostGIS local. Pero dado que estamos trabajando con CartoDB, tenemos a nuestra disposición una interfaz que nos permite hacer esta operación de manera sencilla, con unos pocos clicks de ratón.
Empezamos por entrar en nuestra cuenta de CartoDB (click aquí para conseguir una cuenta de CartoDB gratis), dirigirnos al dashboard, y añadir una nueva tabla, mediante el botón de create table, que tiene este aspecto
Veremos que tenemos varias opciones. Elegimos Empty table
Eso nos creará una tabla sin nombre, que posteriormente podremos renombrar de manera sencilla, haciendo doble click en su título, y poniendo el que queramos. Por ejemplo, puntos
Hecho esto, se nos creará una tabla con una serie de campos por defecto. Campos que nos bastarán para los propósitos de nuestro ejemplo: crear una tabla de puntos con información asociada:
Haremos lo propio con nuestra tabla de líneas. Los pasos serán los mismos que en el ejemplo anterior, pero esta vez, la tabla creada la llamaremos rutas
Por último, tendríamos que crear una tercera tabla, para almacenar la relación entre puntos y rutas, y permitir:
– que un punto pertenezca a diferentes rutas de la tabla de rutas
– que una ruta utilice varios puntos de la tabla de puntos
No obstante, para simplificar nuestro ejemplo, trabajaremos exclusivamente con las tablas puntos y rutas. Serán suficiente para crear una ruta de ejemplo de manera sencilla, como veremos a continuación
Conectando nuestros puntos
Ya podemos comenzar a añadir puntos y rutas a nuestras tablas. Empezaremos con los puntos
Añadiendo puntos en la tabla de puntos
Como el propio wizard nos indica, podríamos empezar a añadir puntos de dos maneras:
– Haciendo click en el símbolo de +, a la izquierda de la primera fila
– Utilizando el botón de Add row, del menú lateral derecho
No obstante, existe una tercera vía, que en nuestro caso será la que usaremos, por resultar más rápida:
– Añadir varios puntos de golpe mediante una sentencia SQL
Para ello, escribiremos una sentencia SQL en la consola que tenemos disponible en el menú lateral derecho
En esta consola podremos escribir la siguiente sentencia INSERT, que añadirá varios puntos de golpe
INSERT INTO puntos(the_geom, name, description) VALUES ('0101000020E61000008CEF51A0CB1713C06E31C36F58F04240', 'Punto 1', 'Punto 1 de la ruta'),
('0101000020E6100000B32B46C0951E13C0443BE104AAF04240', 'Punto 2', 'Punto 2 de la ruta'),
('0101000020E6100000F3D71A00602313C02BE5EFBD43F14240', 'Punto 3', 'Punto 3 de la ruta'),
('0101000020E61000002C2E2BA0922313C027E5C5F44AF14240', 'Punto 4', 'Punto 4 de la ruta'),
('0101000020E61000001B134120C01B13C058B9823399F14240', 'Punto 5', 'Punto 5 de la ruta'),
('0101000020E61000001E322760221F13C011142629BCF14240', 'Punto 6', 'Punto 6 de la ruta'),
('0101000020E610000086012AA0791E13C0958CCEBFFEF14240', 'Punto 7', 'Punto 7 de la ruta')
Ya que tenemos algunos puntos en el mapa, podemos verlos directamente desde la vista de mapas de nuestra tabla:
Estos son nuestros puntos en la ciudad de Córdoba, desde la vista de mapa de CartoDB
Añadiendo líneas en nuestra tabla de rutas
Vamos a proceder a rellenar nuestra tabla de rutas. Para ello, nos aprovecharemos de los puntos ya creados, y dibujaremos una línea que pase por todos ellos, mediante otra sentencia SQL.
Básicamente, haremos uso de la instrucción ST_MakeLine de PostGIS, para construir una línea a partir de un conjunto de puntos. La sentencia es como sigue:
insert into rutas(the_geom, name, description) select st_makeline(the_geom), 'Ruta 1', 'Esta es la ruta 1' from puntos
Con esta consulta, creamos una línea en la tabla rutas que sigue todos los puntos de la tabla puntos. Vemos en la siguiente captura como, efectivamente, la línea pasa por todos los puntos, formando una ruta
Cabe destacar que hemos realizado una pequeña trampa en la construcción de esta ruta. Para el lector familiarizado con las funciones geoespaciales de PostGIS, posiblemente sea algo obvio. En cualquier caso, merece la pena comentarlo.
En la construcción de la ruta, hemos utilizado la versión agregada de la función ST_MakeLine de PostGIS. El concepto agregación en el contexto de una función significa que la función toma como argumento un conjunto de elementos, en lugar de uno solo. En nuestro ejemplo, ese conjunto no es otra cosa que todos los puntos de nuestra tabla de puntos.
El truco está en el orden en que obtenemos esos puntos. Para que ST_MakeLine pueda trabajar con un conjunto de puntos, necesitamos que dichos puntos estén ordenados por su posición espacial. Así la línea se irá trazando de manera natural. En nuestro caso, cuando insertamos los puntos, ya los insertamos en orden, para evitar tener que especificar ORDER BY en la consulta SELECT posterior. Por eso la línea pasa ordenadamente por todos los puntos, sin saltarse ninguno.
Podríamos haber añadido nuestros puntos manualmente, mediante la opción de “Add feature”, disponible en la vista de mapa, en la parte inferior derecha. Está representada con este icono:
La única restricción es que tendríamos que añadirlos en orden para poder realizar la llamada a ST_MakeLine de la forma en la que la hemos hecho. De lo contrario, nos tocaría ordenar los puntos al ejecutar la consulta SELECT, como ya hemos mencionado.
De esta forma, mediante un par de sencillas sentencias SQL, hemos construido un sistema básico de creación de rutas que pasen por unos puntos predefinidos. Los siguientes pasos consistirían en:
– Enriquecer la información que podemos obtener al pinchar en uno de los puntos
– Ofrecer un menú para visualizar las rutas de manera sencilla
Aunque, como veremos a continuación, también sería posible enriquecer una aplicación como ésta añadiendo nuevas fuentes de datos externas.
Ampliando el proyecto: API BBVA
Ahora que ya sabemos cómo construir un sistema básico de puntos de interés y rutas que unan esos puntos, vamos a ver cómo enriquecer la aplicación obteniendo datos de terceros.
Concretamente, podríamos añadir datos sobre compras hechas con tarjetas de crédito en las zonas cercanas a los puntos de interés. Nos podría servir, por ejemplo, para generar una capa adicional, conteniendo un mapa coroplético que contabilizara gastos en ciertas categorías interesantes. Por ejemplo:
– Queremos saber los gastos hechos en bares y restaurantes en los alrededores de los puntos marcados en la ruta. Así podríamos detectar, por ejemplo, si hay algún punto en el que fuera interesante abrir establecimientos de comida, por su cercanía a un punto de interés arqueológico, potencial fuente de turismo.
– Queremos saber los gastos hechos en combustible en los alrededores de los puntos de interés más alejados del centro de la ciudad. De esa manera, detectaríamos la necesidad de existencia de gasolineras en ciertas zonas.
Añadir una capa de esta naturaleza sería algo bastante sencillo. En un post anterior, ya aprendimos cómo leer datos de la API de BBVA y cargarlos en una tabla de CartoDB. Teniendo los datos cargados en CartoDB, añadir una capa más a nuestra visualización es algo casi trivial.
Por supuesto, no solo estamos limitados a trabajar desde dentro de la plataforma de CartoDB, cargando datos en una tabla. También podemos integrar directamente los datos de la API de BBVA en nuestras aplicaciones web realizadas con CartoDB.js. Podemos cargar capas existentes en nuestra cuenta de CartoDB y, al mismo tiempo, añadir marcadores con datos provenientes la API DE BBVA en formato JSON.
En este caso particular, no disponemos de datos pertenecientes a la API del BBVA de la zona que nos interesa (Córdoba), pero los ejemplos comentados son ilustrativos de la intención que se persigue.
Ampliando el proyecto: Otras APIs
Por supuesto, nuestro proyecto puede seguir ampliándose mediante el uso de otras fuentes de datos. Una fuente que es especialmente interesante para combinar con la API de datos de BBVA es la API de Foursquare. Esto es porque, a la información de gastos hechos con tarjeta, podemos añadirle la de establecimientos donde, posiblemente, esos gastos han tenido lugar.
En nuestro caso particular, sí que tenemos información disponible en Foursquare de la zona de Córdoba. Por ejemplo, podemos hacer una petición de establecimientos cercanos al punto 1 de nuestra ruta (el enlace anterior exige autenticación con Foursquare).
Es muy sencillo crear una aplicación web haciendo uso de la API de CartoDB y, al mismo tiempo, integrar puntos de interés provenientes de Foursquare. Proporcionamos en este enlace un ejemplo básico. Basta con introducir nuestras claves CLIENT_ID y CLIENT_SECRET de Foursquare. El cómo hacerlo queda fuera del ámbito de este artículo, pero puede obtenerse más información en la web para desarrolladores de Foursquare.
A continuación, se muestra una captura del aspecto de esta aplicación
Si te interesa el mundo de las APIs, puedes descubrir más sobre las APIs de BBVA aquí.