En el artículo anterior conseguimos información espacial de cada uno de los items, algo que ya adelantamos que nos abriría muchas posibilidades en el futuro. En este artículo haremos uso de dicha información para cruzarla con otras fuentes de datos y así obtener información más relevante.
Existen diversas formas de realizar las operaciones espaciales que vamos a efectuar. El criterio que se ha seguido para elegir una herramienta u otra depende exclusivamente de la experiencia previa que se tenga con la misma. En este caso particular, he elegido utilizar la base de datos relacional con soporte para operaciones espaciales spatialite.
Configuración
Una de las grandes ventajas de spatialite es su portabilidad. Se trata de una herramienta auto-contenida que puede ser ejecutada desde cualquier directorio. El paquete se encuentra en los repositorios de Debian y Ubuntu por que puede ser instalada mediante sudo apt install spatialite-gui. Esto instalará la librería junto con su entorno gráfico.
Una vez instalado se puede iniciar ejecutando spatialite-gui en la terminal. Esto nos abrirá una ventana con la interfaz gráfica.
Carga de datos
Los datos que queremos cruzar en este caso de estudio provienen del Instituto Nacional de Estadística y expresan el salario medio por hogar con un grano de de detalle a nivel de sección administrativa (subdivisiones inferiores a un barrio). El problema es que dichos datos no contienen información espacial alguna, se trata de una simple tabla de tres columnas: sección , salario-por-hogar y salario-por-persona.
Para atajar esto usaremos una tercera fuente de datos, una capa espacial que contiene las geometrías de dichas secciones y nos permitirá determinar a qué sección pertenece cada item.
En nuestra base de datos tendremos, entonces:
- Una capa de puntos con los items (pisos)
- Una capa de geometrías con los distritos
Carga de los distritos
Para cargar la capa de geometrías, importaremos el dataset descargado. Al tratarse de un dataset en formato Shapefile, podemos importarlo directamente clickando en el icono Load Shapefile. Si estuviera en otro formato no compatible, sería necesario buscar la forma de convertirlo a Shapefile u a otro formato compatible.
En el proceso de importación se requerirá elegir el nombre de la tabla destino (en nuestro caso distritos) y el nombre de la columna espacial (la llamaremos geom) así como otros parámetros específicos como el SRID. El SRID indica el sistema de proyección usado y debería estar documentado en la fuente del dataset o en algún metadato adjunto. En el caso de los datos de distritos obtenidos, su SRID es 3042.
Si no fuera posible averiguar el SRID, se puede probar a utilizar software especializado como Quantum GIS, mucho más potente y versatil, pero con una complejidad que escapa a este artículo. Otra ventaja de incluir este software en el proceso será la capacidad de visualizar los resultados proyectados sobre un mapa.
Carga de los items
La carga de los item se hará con otra de las opciones compatibles que ofrece spatialite-gui, la carga desde CSV. Esto se logra clickando en Load CSV/TXT, eligiendo el fichero CSV correspondiente y completando los datos de formato del mismo, como el separador usado (habitualmente coma o tabulador), el nombre (en nuestro caso points) o el SRID. En este caso, no encontraremos documentación alguna sobre el SRID ya que estos datos nos hemos generado nosotros. No obstante, sabemos que los datos lat y lon provienen de coordenadas globales, a las cuales les corresponde el SRID 4326.
La tabla creada carecerá de una columna espacial por lo que deberemos crearla ejecutando las siguientes dos intrucciones desde la consola SQL:
SELECT AddGeometryColumn('points','geom',4326,'POINT',2);
UPDATE points SET geom = MakePoint(lon, lat, 4326);
Esto debería resultar en la creación de una columna nueva llamada geom con los correspondientes puntos en formato espacial. Podemos comprobar el proceso expandiendo la tabla points en la vista en árbol hasta ver el atributo geom, hacer click sobre él y seleccionar Map Preview. Esta previsualización debería mostrar los puntos correspondientes a cada item.
Consulta espacial
El siguiente paso es realizar lo que en tratamiento de datos de conoce como lookup. Básicamente, trataremos de añadir a cada item el distrito en el que se encuentra buscando la geometría en la que se encuentra contenido. Para ello utilizaremos la función de spatialite within() que nos dice si una geometría A se encuentra contenida en una geometría B.
select p.id, p.title, d.cusec
from points as p, distritos as d
where within(ST_Transform(p.geom, 3042), d.geom)==1
AND d.cpro=50;
De este modo, el resultado es una lista de tres columnas con el id, titulo y distrito de cada item. El código de distrito será el que podremos usar para cruzar con cualquier otro dato externo, como la renta media que antes mencionábamos.
Para cruzar las tres tablas: points, el resultado con los códigos de distrito y la fuente de datos externa, se puede usar la propia base de datos mediante SQL o se puede exportar el resultado a CSV haciendo click derecho sobre él y posteriormente agregar todo en una hoja de cálculo como Libre Office Calc o Excel.
Distancias
Una de las ventajas de tener los datos cargados en la base de datos espacial es que, con poco esfuerzo extra, podemos lograr extraer datos muy interesantes. Por ejemplo distancias mínimas (reales geográficas, no aproximaciones euclídeas) a puntos, trazados o polígonos. En nuestro caso de estudio, ya que se está recolectando una base de datos de pisos de alquiler de interés, puede resultar interesante conocer la distancia tu centro de trabajo, a la boca de metro más cercana o al tranvía que atraviesa tu cuidad.
Para ello, la consulta es muy similar a la anterior en estructura, pero variando la función utilizada. Además, ya no cruzaremos dos geometrías existentes, sino que proveeremos una de ellas.
select
id,
ST_Distance(
ST_GeomFromText(
'LINESTRING(-0.8708779781997009 41.68653240939767,-0.8898465603530212 41.687109287806656,-0.8900182217299744 41.679096624709025,-0.8901898831069275 41.6703135999149,-0.8838586602971645 41.66353877155025,-0.8843736444280239 41.661230381694274,-0.881026247577438 41.66090976544719,-0.8815841470525356 41.65776764174951,-0.8842878137395473 41.65404819516039,-0.8805541787908169 41.652124259193606,-0.8857898507878872 41.64728209938806,-0.8910513469900252 41.644907918854656,-0.898046548100865 41.63743525238525,-0.905284253258742 41.63226155866651,-0.9126274231276739 41.62269179353281,-0.9201805237136114 41.615986573308966,-0.9274257600052351 41.619661240493386)',
4326
),
geom, 1
) as dist_tranv,
ST_Distance(
ST_GeomFromText('POINT(-0.8892394427357431 41.68358071844347)', 4326),
geom, 1
) as dist_cps
from points;
Las geometrías o los puntos pueden generarse desde cualquier editor on-line de WKT (este es el formato de texto en el que definimos los puntos o las líneas).
Igual que en el caso anterior, el resultado puede ser agregado en la propia base de datos o en una hola de cálculo, la decisión depende de las preferencias y conocimientos de cada uno.