1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico...

64
Introducción a PosGIS: Ejercicio práctico 1 Interoperatividad y análisis SQL de datos geográficos en PostGIS En esta práctica vamos a poner en práctica los conceptos aprendidos durante el exámen de las familias de funciones espaciales de PostGIS, apoyándonos en algunas funcionalidades de QGIS, especialmente en el ámbito de la interope- ratividad. También se utilizará Excel para la visualización de datos. El objetivo será solventar un sencillo problema de geomárketing y ubicación óptima de una infraestructura. El área de estudio será Barcelona, con un breve estudio previo en Madrid. Todos los datos de clientes son simulados. El problema Se ha identificado por experiencia previa que un determinado producto se vende muy bien entre las mujeres de 30 a 40 años que tienen hijas de 16. Se tienen datos de clientes reales para la zona de Madrid, y se quiere aprovechar la experiencia previa para seleccionar la mejor zona de implantación en Barcelona.

Transcript of 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico...

Page 1: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Introducción a PosGIS: Ejercicio práctico1

Interoperatividad y análisis SQL de datosgeográficos en PostGIS

En esta práctica vamos a poner en práctica los conceptos aprendidos durante el exámen de las familias de funciones espaciales de PostGIS, apoyándonos en algunas funcionalidades de QGIS, especialmente en el ámbito de la interope-ratividad. También se utilizará Excel para la visualización de datos. El objetivo será solventar un sencillo problema de geomárketing y ubicación óptima de una infraestructura. El área de estudio será Barcelona, con un breve estudio previo en Madrid. Todos los datos de clientes son simulados.

El problema

Se ha identificado por experiencia previa que un determinado producto se vende muy bien entre las mujeres de 30 a 40 años que tienen hijas de 16. Se tienen datos de clientes reales para la zona de Madrid, y se quiere aprovechar la experiencia previa para seleccionar la mejor zona de implantación en Barcelona.

Page 2: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

1. Descripción del problema

Una regla básica del geomárketing dictamina que cada producto tiene una distancia objetivo a la que es atractivo. Por ejemplo, los compradores están dispuestos a mo-verse decenas de kilómetros para comprar muebles, pero no se les ocurriría comprar pan en ningún lugar que no estuviera a dos pasos de su casa. La cuantificación de la proximidad es relativa al producto o servicio considerado. Por lo tanto, lo primero es encontrar el rango idóneo en el que el servicio o producto es atractivo o competitivo.

Una vez encontrada dicha distancia, se pasará a analizar las características demográ-ficas de la nueva zona de implantación, en este caso, Barcelona, con la idea de esta-blecer un sencillo modelo de atractivo que nos permita determinar cuáles son, entre un conjunto de posibilidades aportadas de antemano por un estudio inmobiliario, las mejores ubicaciones para ofertar el servicio.

Page 3: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

2. Análisis de los datos de Madrid

Los datos iniciales de los clientes y los puntos de venta de Madrid están en formato de texto delimitado por un caracter, en los ficheros clientes_madrid.csv y pv_madrid.csv respectivamente. Lo primero que tenemos que hacer, por tanto, es hallar una forma de importar estos datos en PostGIS.

Como suele ser usual, hay varias formas de hacerlo. Una de ellas es recurrir al co-mando COPY de PostgreSQL, pero la extensión DB Manager de QGIS ofrece muchas ventajas para hacerlo mucho más directas, y las vamos a aprovechar.

2.1 Preparación de la base de datos

Primero preparemos una base de datos para alojar el ejercicio. Con pgAdmin3 creamos una nueva base de datos llamada barcelona, bien sea con el interfaz gráfico (botón de-recho sobre Databases y después New Database...) o bien abriendo una ventana SQL y lanzando el comando:

CREATE DATABASE barcelona;

A continuación, conectamos a la base de datos recién creada y creamos un nuevo esquema que nos servirá para la importanción inicial de datos, llamado input. Igual que antes, podemos hacerlo desde pgAdmin3 con botón derecho sobre Schemas y después New Schema... o simplemente lanzando, en una ventana SQL conectada a la nueva base de datos, el comando SQL:

CREATE SCHEMA input;

A continuación, vamos a importar los datos.

Page 4: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

2.2 Importación de los datos de Madrid

Los datos de Madrid se componen de dos juegos básicos:

• lugares dónde se oferta el servicio;

• portal de residencia de los clientes de la zona.

Ambos juegos de datos vienen en formato de texto delimitado. Lo normal es que la delimitación sea con comas o tabuladores, pero en realidad puede usarse cualquier carácter como delimitador. En este caso, el carácter de delimitación es |. El esquema de datos de dichas fuentes de datos es:

• gid: un identificador, único y correlativo. Ideal como clave primaria;

• municipality: el municipio en el que se localiza el punto de prestación de servicio o el domicilio del cliente;

• st_x y st_y: coordenadas del punto, en sistema de coordenadas EPSG:4326 (WGS84 geográficas).

Importar estos datos en PostGIS se puede realizar de multitud de formas. Algunas son:

• con la librería GDAL;

• con el comando PostgreSQL COPY;

• con QGIS.

Page 5: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

2.3 La librería GDAL

La librería GDAL es una compleja librería escrita en C y C++ destinada a proporcionar operaciones ETL para software libre geomático. Entendemos por operaciones ETL (Ex-tract, Transform, and Load) aquellos procesos de lectura de fuentes de datos heterogé-neas, su transformación y su carga en otras fuentes de datos. Operaciones de intero-peratividad, en definitiva, que es en lo que se centra específicamente GDAL, dejando un poco de lado las operaciones de transformación.

Esta librería está diseñada para ser incorporada en otros programas. De hecho, tanto QGIS como PostGIS se sirven de ella para leer los formatos de datos que pueden leer. También se puede operar sobre ella directamente desde la línea de comandos gracias a un conjunto de comandos que incorpora, principalmente el ogr2ogr.

Es una librería difícil de utilizar, que sólo tiene uso en el contexto de la línea de comando o la integración, mediante programación, de su funcionalidad en otro programa, pero que es vital y tremendamente útil en escenarios de automatización de procesos. Como muestra, aquí se puede ver la sintaxis de un comando ogr2ogr que importaría uno de los CSV a nuestra PostGIS (la sintaxis exacta dependerá mucho de nuestro sistema operativo y la configuración de nuestra base de datos, obviamente):

ogr2ogr -overwrite \

-f PostgreSQL PG:”dbname=’barcelona’ \

host=’localhost’ port=’5432’ user=’postgres’ \

password=’postgres’” \

pv_madrid.csv -lco SCHEMA=input -nln pv_madrid \

-lco OVERWRITE=YES

Page 6: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

2.4 El comando COPY

En cuanto al comando COPY de PostgreSQL, decir que es el método estándar incorpo-rado en PostgreSQL para la importación y exportación de datos en formato CSV. Es un comando que se ejecuta desde una consola SQL, y también es muy útil para la automa-tización de procesos. Por ello, vamos a importar los puntos de prestación de servicio de Madrid por este método.

Lo primero que hay que destacar es que el comando COPY no crea una tabla por noso-tros. La tabla ha de existir previamente al lanzamiento del comando, y es responsabili-dad del diseñador de la base de datos que el esquema (es decir, los campos, su número y su tipo) de la tabla de destino tenga unas características apropiadas para acoger a los datos que pretendemos leer desde el CSV. Es decir, si la tabla tiene más o menos campos de los que tiene el CSV, fallará. Si un campo es incapaz de aguantar el tipo de dato que le llega desde el CSV, fallará, por ejemplo, en el caso de pretender meter un texto en un campo numérico. Por ello, crearemos primero la tabla con una sentencia SQL:

CREATE TABLE input.pv_madrid ( gid INTEGER, municipality VARCHAR(200), x DOUBLE PRECISION, y DOUBLE PRECISION );

Una vez creada la tabla, y a la vista de que puede, a priori, ser capaz de asimilar, por concordancia del número de campos y sobre todo, de su tipo, la información proceden-te del CSV, vamos a ubicar el fichero CSV en un lugar de fácil acceso para el servidor de base de datos. Copiaremos el CSV a un nuevo directorio creado directamente sobre C:\

Page 7: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

llamado barcelona. Una vez hecho esto, abrirmos una nueva ventana SQL en pgAd-min3 y ejecutamos el comando COPY:

COPY input.pv_madrid FROM ‘c:\barcelona\pv_madrid.csv’ WITH csv delimiter ‘|’ header;

donde:

• input.pv_madrid es el nombre de la tabla destino de la información;

• FROM indica que es una operación de lectura de CSV y carga en la base de datos;

• ’c:\barcelona\pv_madrid.csv’ indica la ubicación del CSV en nuestro sistema de ficheros;

• WITH marca el comienzo de las opciones de importación;

• csv indica que el fichero a leer tiene formato de delimitación por caracter;

• delimiter ‘|’ indica cual es ese caracter de delimitación;

• por último, header le indica al importador que la primera línea del fichero es una cabecera con los nombres de los campos, aunque estos son ignorados en última instancia. Los campos en la tabla no tienen por qué llamarse igual, tan sólo tienen que ser coincidentes en número y tipo.

Page 8: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Análogamente, la operación contraria, la de volcado de datos, obedece a la siguiente forma:

COPY input.pv_madrid TO ‘c:\Program Files\PostgreSQL\10\data\pv_madrid-export.csv’ WITH csv delimiter ‘|’ header;

Simplemente cambiando el FROM por un TO se realiza la operación contraria, con las mismas características descritas anteriormente. Sin embargo, como se puede deducir de la ruta de escritura del fichero, hay un enorme pero en esta operación. Tiene que ver con el hecho de que PostgreSQL es un programa servidor y, como tal, está sujeto, por parte del sistema operativo, a fuertes medidas de contención y seguridad. Cualquier programa que conecte con el exterior es una potencial amenaza porque abre una puer-ta a la intrusión, por ello se toman medidas muy estrictas en cuanto a qué recursos o lugares del sistema de ficheros puede acceder el mismo.

PostgreSQL sólo tiene permiso para escribir en su directorio de datos, no pudiendo hacerlo en ningún otro lugar. Recordemos que su directorio de datos está ubicado, por defecto, en c:\Program Files\PostgreSQL\10\data, y ese es el único lugar sobre el que podremos escribir. Muchísimo cuidado, por tanto, a la hora de entrar en dicho fichero y sacar la información escrita: cualquier modificación de los ficheros del almacén de datos de la PostgreSQL lo invalidará posiblemente sin solución. Entrar, mover el CSV y salir. ¡CUIDADO! :|

Page 9: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

2.5 Importación con QGIS

Vamos a examinar el último mecanismo de importación. Esta vez vamos a utilizar la extensión DB Manager de QGIS. Básicamente, QGIS se comporta en este contexto como un importador superflexible para PostGIS: cualquier información vectorial que QGIS pueda asimilar (gracias, por supuesto, a GDAL) puede ser exportable a PostGIS gracias a dicha extensión. Esto es genial porque podremos importar de esta manera Shapefiles, GeoJSON y cualquier otro formato que QGIS pueda leer, incluidos los nue-vos GeoPackages que de seguro constituyen el futuro de los formatos de intercambio en ficheros de información vectorial.

Con la importación mediante QGIS mataremos dos pájaros de un tiro, puesto que tam-bién realizaremos operaciones de transformación de datos que tendremos que realizar con SQL en el caso de la importación de datos de cliente que hemos realizado ante-riormente con el comando COPY. Vamos a importar los datos de clientes de Madrid, los vamos a georrefenciar, los vamos a proyectar en el sistema de referencia adecuado (EPSG:25830, ETRS89 UTM30N) y los vamos a importar directamente a PostGIS listos para usar. La desventaja de esto es que no es automatizable.

Para empezar, incorporemos la información a QGIS. Para ello, utilizaremos la herra-mienta de importación de texto delimitado, en la barra de herramientas de orígenes de datos.

Page 10: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Se nos abrirá una ventana en la que podremos configurar el proceso de importación.

Lo primero (File Name) es buscar en nuestro disco duro el fichero CSV, en este caso, clientes_madrid.csv. Después, en Layer name, le damos un nombre a la capa que se va a crear en la Tabla de contenidos de QGIS. Si fuera necesario, ajustamos el Enco-ding. Recordemos: UTF-8 para UNIX, Linux o Mac, ISO-8859-1 o LATIN1 para Windows, es cuestión de probar si no sale bien a la primera, no pasa nada. Después, el formato de delimitación. En nuestro caso, al estar delimitando con |, seleccionaremos la opción Custom delimiters y en Other delimiters introduciremos el caracter correspondiente.

Ahora pasamos a Geometry definition. Como son puntos, seleccionamos Point coor-dinates, y abajo los campos que contienen las coordenadas. Activamos la opción de Use spatial index y la opción Watch file, que es muy interesante, ya que crea un vínculo entre el proyecto de QGIS (.qgs) y el fichero, de forma que QGIS está vigilando los posibles cambios sobre el mismo para actualizar su información. En este caso no tiene

Page 11: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

mucha relevancia, puesto que nos vamos a llevar la información a PostGIS, pero vale la pena mencionarlo para otros escenarios.

Ya podemos pulsar Ok, con lo que QGIS nos solicita el sistema de coordenadas (EPSG:4326, WGS84 geográficas). La carga ha de ser en el sistema de referencia na-tivo, ya nos encargaremos de la reproyección más tarde. Con esto tendremos la capa creada en QGIS.

Page 12: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Ahora creamos una nueva conexión a PostGIS, de la forma usual:

Arrancamos el DB Manager desde el menú Database y en el explorador de objetos (Tree) seleccionamos la conexión a PostGIS que acabamos de definir. Con este con-texto, DB Manager ya puede importar cualquier información cargada actualmente en QGIS.

Page 13: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Pulsamos el botón de importar información y configuramos el proceso tal y cómo se muestra en la figura:

donde:

• en Input seleccionamos la capa que acabamos de generar a partir del CSV;

• en SCHEMA seleccionamos input. Por defecto, la herramienta asume el nombre de la capa a importar como nombre de la tabla a crear en la PostGIS;

Page 14: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

• marcamos Primary key y le asignamos un nombre, en este caso, id, para que nos genere una clave primaria autonumérica. Esto puede ser o no ser pertinente, pero nunca está de más. En cualquier caso, podremos postprocesarla después;

• marcamos Geometry column y le damos por nombre geom, para que nos genere la columna geométrica;

• marcamos tanto Source SRID como Target SRID para indicarle, respectivamen-te, el sistema nativo y el de destino. La herramienta reproyectará. Como origen, el consabido EPSG:4326 (WGS84 geo) y como destino EPSG:25830 (ETRS89 UTM30N);

• indicamos en Encoding que el encoding de destino es UTF-8;

• marcamos la conversión de los nombres de los atributos de la capa a nombres de campos de la base de datos en minúscula (recordemos que PostgreSQL odia las mayúsculas) con Convert field names to lowercase;

• finalmente, indicamos que se cree un índice espacial con Create spatial index.

Page 15: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Ya podemos pulsar en OK y la herramienta importará los datos. Podremos ver en el explorador de objetos del DB Manager el esquema input con las dos tablas creadas.

En resumen, esta herramienta es estupenda porque permite importar a PostGIS cual-quier fuente de datos que QGIS haya asimilado, con un control del proceso bastante considerable. Lo único malo que tiene es su falta de reproducibilidad, que la invalida para procesamiento automático. Para ello tendremos que recurrir al comando COPY, que sólo entiende CSV, o enzarzarnos en un combate desigual con la GDAL, que es bastante arisca al principio.

Page 16: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

2.6 Postprocesado de la información importada

Una vez la información está importada en PostGIS, vamos a postprocesarla un poco.

Para empezar, crearemos un nuevo esquema en el que contener la información ya postprocesada y lista para operar con ella. Crearemos un esquema llamado madrid con SQL:

CREATE SCHEMA madrid;

o desde el interfaz gráfico de pgAdmin3.

#T2#Tabla input.clientes_madrid#T2#

Esta tabla tiene poco que postprocesar, puesto que la herramienta de CSV de QGIS y la de importación del DB Manager se encargaron de gran parte del trabajo: creación de las geometrías puntuales y reproyección al sistema de referencia elegido para el proyecto. Sin embargo, tiene una serie de campos que ya no nos interesan y, por tanto, vamos a filtrarlos:

CREATE TABLE madrid.cliente AS SELECT gid,

municipality,

geom

FROM input.clientes_madrid;

Page 17: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

ALTER TABLE madrid.cliente ADD CONSTRAINT cliente_pkey PRIMARY KEY(gid);

CREATE INDEX cliente_geom_gist ON madrid.cliente USING gist(geom);

Repasemos:

• la primera sentencia crea una tabla (CREATE TABLE) llamada madrid.cliente a partir de una sentencia SQL sobre la tabla de importación input.clientes_madrid en la que simplemente seleccionamos las columnas que nos interesan, desechan-do el resto por redundantes;

• la segunda y tercera sentencias apuntalan y arman dicha nueva tabla con una clave primaria sobre el campo gid (segunda) y el preceptivo índice espacial sobre la columna geom (tercera). Recordemos que una tabla sin clave primaria es poco menos que inútil para casi todo y que sin el índice espacial todos los geoprocesos se vuelven muy poco eficientes.

Tabla input.pv_madrid

Esta tabla tiene algo más de tarea, puesto que, recordemos, fue importada con el co-mando COPY, por lo que no tiene ningún postprocesado realizado. Necesitamos limpiar la tabla de campos que no vayamos a utilizar y, lo más importante, generar puntos a partir de las coordenadas que tenemos. Comencemos por analizar esto último.

Tenemos dos campos double precision st_x y st_y con las coordenadas X,Y en sis-tema referencia EPSG:4326. Necesitamos construir con ellas puntos en sistema

Page 18: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

EPSG:25830. Vamos paso a paso.

Recordemos que tenemos una función en PostGIS, del tipo constructor de geometrías, que construye puntos a partir de coordenadas, st_makepoint. Usémosla:

SELECT st_makepoint(st_x, st_y) FROM input.pv_madrid;

Si lanzamos esto en pgAdmin3 veremos aparecer sendos BLOB de geometrías. Para asegurarnos de que son puntos, podemos lanzar la función st_geometrytype, que analiza una geometría y nos indica de qué tipo es, y la st_asewkt, que nos devuelve una versión legible de la misma:

SELECT st_geometrytype(st_makepoint(st_x, st_y)), st_asewkt(st_makepoint(st_x, st_y)) FROM input.pv_madrid;

del resultado arroja colegimos que:

• realmente son puntos (resultado de st_geometrytype ST_Point);

• dichos puntos no tienen sistema de referencia definido (no aparece en la salida de la función st_asewkt).

Por tanto tenemos que darle sistema de referencia con la función st_setsrid:

SELECT st_setsrid(st_makepoint(st_x, st_y), 4326) FROM input.pv_madrid;

Page 19: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Recordemos que la función st_setsrid atribuye a una geometría un sistema de refe-rencia sin más, no existe reproyección. Es decir, es una acción cuya validez y pertinen-cia nos corresponde a nosotros como analistas. Es perfectamente posible, con esta función, cambiarle el sistema de referencia a unas coordenadas proyectadas y pasarlo a geográficas, pero sin reproyección, ojo. Estamos dotando a los puntos creados por st_makepoint del sistema de referencia en el que están expresadas sus coordenadas, pero porque nosotros somos muy conscientes de las mismas.

Sin embargo, aquí no acaba la cosa, puesto que dicho sistema de referencia no es el elegido para el proyecto, que, recordemos, es el EPSG:25830, ETRS89 UTM30N. Por ello, hay que reproyectar:

SELECT st_transform( st_setsrid( st_makepoint(st_x, st_y), 4326 ), 25830

)

FROM input.pv_madrid;

si echamos un vistazo a dichas geometrías con st_asewkt:

SELECT st_asewkt( st_transform( st_setsrid( st_makepoint(st_x, st_y), 4326 ), 25830

)

)

FROM input.pv_madrid;

Page 20: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

obtendremos algo como esto:

SRID=25830;POINT(426064.067264661 4480772.01983851)

de lo que inferimos que son puntos, que están en EPSG:25830 y que las coordenadas tienen las características de dicho sistema.

Esto es muy típico de la operativa PostGIS y SQL en general: encadenar funciones. Repasemos:

• primero, hemos aplicado una función, st_makepoint, que solicita como argumen-tos dos números double precision que interpreta como coordenadas XY, y que devuelve una geometría puntual binaria;

• segundo, sobre dicho resultado, hemos aplicado la función st_setsrid, que espera recibir una geometría binaria como primer parámetro y un entero como segundo que representa el código EPSG del sistema de coordenadas a asignar a dicha geometría. La geometría que procesa st_setsrid es precisamente el resultado de la función st_makepoint: funciones que asumen como argumentos las salidas de procesamiento de otras funciones, y así hasta el infinito. Un encadenamiento de procesos atómicos de transformación de datos que nos llevan desde los datos originales a los datos procesados. La función st_setsrid devuelve la geometría que se le pasó como argumento, pero con el sistema de referencia fijado al EPSG proporcionado;

• tercero, la función st_transform admite como argumento, de forma similar a st_setsrid, una geometría binaria y un entero que representa al EPSG al que se quiere transformar la geometría. El hecho de que hayamos usado previamente st_setsrid sobre el resultado de st_makepoint se debe a que st_transform no puede trabajar si desconoce el sistema de referencia de origen de la geometría a transformar. Como pudimos ver anteriormente, st_makepoint devolvía una geometría puntual pero sin sistema de referencia. No es algo que podamos enviar a st_transform tal cual. st_transform, por tanto, va a recibir una geometría correcta desde el punto de vista del sistema de referencia (en EPSG:4326) y va a calcular la transforma-

Page 21: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

ción de la misma al sistema que se le pasa como argumento, 25830. st_transform devuelve, en última instancia, una geometría binaria transformada;

• por último, y como depuración, hemos pasado la salida de st_transform a st_asewkt, que pide una geometría binaria como argumento y devuelve su descrip-ción en formato Extended Well Known Text (EWKT).

Con ello termina el procesamiento de la geometría, así que ahora crearemos la tabla completa como hicimos con la anterior, input.clientes_madrid:

CREATE TABLE madrid.pv AS SELECT gid,

municipality,

st_transform( st_setsrid( st_makepoint(st_x, st_y), 4326 ), 25830

) AS geom FROM input.pv_madrid;

ALTER TABLE madrid.pv ADD CONSTRAINT pv_pkey PRIMARY KEY(gid);

CREATE INDEX pv_geom_gist ON madrid.pv USING gist(geom);

Con esto termina la importación y el postprocesado de la información de base.

Page 22: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

2.7 Análisis de los datos

Procedemos ahora a analizar los datos. Vamos a ver qué punto de prestación de servi-cio tiene cada cliente como más cercano, y estudiaremos el histograma de distancias en Excel para determinar una distancia de atractivo objetivo.

Todo análisis SQL comienza con un sencillo:

SELECT *

FROM madrid.pv;

que nos devolverá la lista de puntos de prestación de servicio. Como lo que queremos es relacionarlo con todos los clientes, utilizaremos un producto cartesiano, que crea todas las posibles parejas entre los registros de ambas tablas. Es decir, si tenemos 2 puntos de prestación y 1548 clientes, el resultado del producto cartesiano serán 2x1548=3096 combinaciones: cada punto de prestación relacionado con todos los posibles clientes:

SELECT *

FROM madrid.pv, madrid.cliente;

Page 23: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Ahora usamos la función st_distance de PostGIS para calcular la distancia entre el punto de prestación y el cliente:

SELECT *,

st_distance(a.geom, b.geom) AS d FROM madrid.pv a, madrid.cliente b;

Esto hará que tengamos, para cada punto de cliente, dos distancias: una al punto de prestación 1 y otro al punto de prestación 2. De ellas, una será más pequeña que la otra, y será esa la que nos interesará para el análisis. Por tanto, hay que descartar de alguna manera la mayor.

Para ello, vamos a usar una técnica avanzada de SQL que es el DISTINCT ON. El uso de DISTINCT es bien conocido: una sentencia SELECT DISTINCT eliminará de la solu-ción final todas las filas que estén repetidas, es decir, tengan, en todos sus campos, los mismos valores.

DISTINCT ON es similar, pero elimina las filas por coincidencias parciales en campos selectos. Es decir, podremos especificar que se eliminen de la solución final aquellas filas que coincidan sus valores, en un conjunto arbitrario de campos, con alguna fila ya presente en la solución final.

Para entender el uso operativo del DISTINCT ON debemos comprender que está íntimamente relacionado con el ORDER BY de la sentencia SQL. Antes de plantearnos siquiera el uso del DISTINCT ON tenemos que tener muy clara una estrategia de orde-nación de los resultados de la consulta que nos beneficie.

Page 24: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Aquí la tarea es encontrar, para un punto de cliente, qué punto de prestación tiene más cercano. Comencemos ordenando, por tanto, por el ID del cliente:

SELECT *,

st_distance(a.geom, b.geom) AS d FROM madrid.pv a, madrid.cliente b

ORDER BY b.gid;

Tendremos la consulta ordenada por el ID del cliente, de forma que, en ocasiones, la distancia al primero de los puntos de prestación será la más pequeña, pero en otras ocasiones será la segunda.

Dado que DISTINCT actúa eliminando cualquier fila repetida posterior a la primera encontrada con el criterio marcado por DISTINCT, la estrategia es colocar primero aquella distancia que sea menor, dejando la última la distancia mayor. De esta manera, siempre aparecerá, para un punto de cliente determinado, la asociación con el punto de prestación más cercano antes que la asociación con el más lejano en el orden de salida de la consulta final:

SELECT *,

st_distance(a.geom, b.geom) AS d FROM madrid.pv a, madrid.cliente b

ORDER BY b.gid, d;

Ahora nos hemos asegurado que la consulta está ordenada por el código del cliente, con la menor distancia sobre la mayor. Este es el razonamiento que utilizaremos siem-pre con el DISTINCT ON, puesto que éste hará que siempre prevalezca la primera fila encontrada en la ordenación (sobre la segunda, que sabemos que siempre es la más lejana).

Page 25: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

La regla para usar correctamente el DISTINCT ON, una vez el ORDER BY obedece a nuestros objetivos, es bien sencilla: los campos que pongamos en el DISTINCT ON deben ser un subconjunto de los presentes en el ORDER BY (o todos ellos, aunque en este caso sería absurdo), y deben aparecer desde el primer campo en el ORDER BY y en exactamente el mismo orden:

SELECT DISTINCT ON (b.gid) *,

st_distance(a.geom, b.geom) AS d FROM madrid.pv a, madrid.cliente b

ORDER BY b.gid, d;

Lo que estamos consiguiendo, finalmente, es:

• hacemos todas las posibles relaciones entre los puntos de prestación y de cliente, de forma que cada cliente estará relacionado con los dos puntos de prestación;

• calculamos la distancia entre ambos puntos, de forma que cada cliente tendrá un punto de prestación más cercano que otro;

• ordenamos convenientemente, primero por el identificador del punto de cliente, y después por la distancia que les separa a cada punto de prestación. De esta manera, para cada cliente, el primer registro en el que hace aparición en el resulta-do de la consulta será siempre el que le relaciona con el punto de prestación más cercano;

• implementamos el DISTINCT ON como un subconjunto de los campos presentes en el ORDER BY;

• por tanto, una vez obtenida la solución final de la ordenación, la base de datos encuentra el primer registro con un determinado ID de cliente, que, gracias a la ordenación, será el que le relaciona con el punto de prestación más cercano. Cuando encuentra el segundo registro vinculado al mismo ID de cliente, como

Page 26: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

el DISTINT ON está indicando que es precisamente ese campo en el que deben buscarse repeticiones, será descartado;

• obtendremos, por tanto, un único registro por cada ID de cliente, vinculado y con la distancia calculada al punto de prestación más cercano. Si nos fijamos, la con-sulta final arroja precisamente 1548 registros: los mismos que clientes tenemos.

Por último, para hacerlo más vistoso en QGIS, vamos a dibujar una línea entre cada punto de cliente y el punto de prestación que tiene más cercano, y lo fijamos en una vista:

CREATE OR REPLACE VIEW madrid.demanda_lineas AS SELECT DISTINCT ON (b.gid) row_number() OVER () AS gid, a.gid AS pv_gid, b.gid AS cliente_gid, st_distance(a.geom, b.geom) AS d, st_setsrid( st_makeline(a.geom, b.geom), 25830 ) AS geom FROM madrid.pv a, madrid.cliente b

ORDER BY b.gid, d;

En esta vista hemos creado una clave primaria con row_number(), puesto que se basa en un FROM con una relación muchos a muchos, que lo hace imprescindible, hemos seleccionado los dos gid de los elementos relacionados, hemos calculado la distancia y hemos creado una geometría lineal gracias a la función st_makeline, que demanda los puntos inicial y final de la línea (el punto cliente y el punto de prestación), a la que le hemos asignado el SRID correcto con st_setsrid. Podemos visualizarla en QGIS para tener una idea muy gráfica de cómo se distribuye la demanda de los puntos de presta-ción.

Page 27: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

2.8 Conexión desde Excel

Vamos a conectar nuestra base de datos a Excel para poder analizar nuestros datos con esta herramienta.

El vínculo entre PostgreSQL y Excel se realiza a través de un protocolo llamado ODBC (Open Database Connectivity). El ODBC es un protocolo diseñado para conectar siste-mas de información entre sí. Cada origen de datos de un sistema de información (base de datos, hojas de cálculo, incluso ficheros de texto delimitado) para el que alguien haya escrito un driver ODBC podrá conectarse con cualquier otro sistema que también entienda dicho estándar, creándose de esta manera una pasarela de datos estándar entre ambos.

Durante la instalación de PostgreSQL, en el paso de selección e instalación de software adicional en el StackBuilder, instalamos, junto a la PostGIS, los driver ODBC de Post-greSQL. Un Windows con dichos drivers instalados, por tanto, será capaz de comunicar nuestro servidor PostgreSQL con cualquier otro software que entienda el estándar. Es el caso de Excel (y de Access, dicho sea de paso), por lo que vamos a crear una conexión viva entre nuestra vista de distribución de la demanda y una hoja de cálculo.

Page 28: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Definición del origen de datos ODBC

Para usar ODBC con nuestro servidor debemos primero definir, a nivel de sistema ope-rativo, un origen de datos ODBC que apunte a nuestra base de datos barcelona.

Para ello, buscamos en Windows el programa ODBC Data Sources, versión 64 ó 32 bits, según sea nuestro sistema. Al abrirlo, nos encontraremos con un interfaz algo confuso:

Page 29: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Aquí se muestran los orígenes de datos ODBC definidos por el usuario. Por defecto veremos el de Excel y el de Access, que sirven para conectar a dichos sistemas desde otros. Lo que queremos hacer es crear uno para nuestra base de datos barcelona en nuestro servidor PostgreSQL, de forma que otros programas puedan acceder a la mis-ma. Para ello, pulsamos en Add... y se abrirá este otro interfaz:

En él se nos solicita que elijamos el driver sobre el que queremos basar el nuevo origen de datos. Aquí aparecerán los drivers ODBC instalados en el sistema, y si todo fué bien, encontraremos dos driver PostgreSQL: uno para ANSI y otro para UNICODE. Seleccio-namos el UNICODE.

Page 30: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

A continuación se nos pide que definamos la conexión a la PostgreSQL a la que nos queremos conectar. Como siempre, tendremos que proporcionarle los cinco paráme-tros de conexión a PostgreSQL, más un nombre para identificar en el sistema el nuevo origen:

• Data Source: un nombre descriptivo para el origen de datos;

• Description: una descripción opcional del origen de datos;

• Database: la base de datos a la que nos queremos conectar (barcelona);

• Server: el servidor o host al que nos queremos conectar (localhost);

• Port: puerto del servidor PostgreSQL (5432);

• User Name: nombre de usuario (postgres);

• Password: contraseña de usuario (postgres).

Page 31: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Cuando esté así configurada, probamos su validez pulsando en Test. Si todo va bien, obtendremos una confirmación de conexión y podremos pulsar en Save para grabarla.

Ya tenemos el origen de datos listo a nivel de sistema. Este origen podría ser consu-mido por cualquier software que entendiera el estándar ODBC, que son muchos. En Windows es especialmente interesante para interconectar Access, Excel y PostgreSQL.

Uso del origen en Excel

Abrimos el Excel y vamos a conectar con la vista de distribución de la demanda. El pro-cedimiento descrito a continuación está destinado a la version 2016 del Excel, en otras puede variar, pero el espíritu es el mismo.

Abrimos una nueva hoja de cálculo y nos vamos al menú Datos. Allí seleccionamos Obtener datos, y de las opciones presentadas, Desde otras fuentes / Desde ODBC.

Page 32: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Nos aparecerá a continuación un cuadro de diálogo en el que se podrá seleccionar los distintos orígenes de datos presentes en el sistema. Si todo va bien, veremos el origen recién creado, barcelona. Lo seleccionamos y pulsamos Aceptar.

Se abrirá un cuadro de diálogo llamado Navegador. En él, podremos entrar en la base de datos y buscar, en el esquema madrid, la vista creada para el análisis de distancia, demanda_lineas. Una vez seleccionada, en la parte derecha veremos una vista de los datos de la tabla. Como no queremos importar todas las columnas (la geometría es completamente inútil, por ejemplo), pulsamos Editar.

Page 33: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Pasaremos a un diseñador llamado Editor de consultas. En ella podremos hacer manipulaciones que condicionarán la importación, pero lo único que vamos a hacer es eliminar todas las columnas que no sean d, que es el dato que queremos estudiar. Lo haremos haciendo click derecho sobre los nombres de las columnas y seleccionando Quitar. Una vez a nuestro gusto, pulsamos en Cerrar y cargar y los datos se cargarán en la hoja de cálculo.

Page 34: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Lo interesante de este procedimiento es que el vínculo entre la base de datos y la hoja Excel es dinámico, por lo que cualquier cambio en la base de datos puede ser refresca-do en la hoja de cálculo pulsando en Actualizar.

Page 35: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Análisis en Excel

Ahora pasamos a una operativa 100% Excel en la que no vamos a entrar en detalles. Simplemente lo que hacemos con los datos es seleccionar la columna d y crear un his-tograma de frecuencias con los mismos. Después de jugar un rato con ellos, decidimos que una buena distancia objetivo son 3000 metros, que es donde se acumula el grueso de las distancias.

Con esta información final pasamos a crear un modelo de bonanza de localización en Barcelona, en función de los requisitos demográficos y esta distancia umbral que hemos encontrado analizando una experiencia previa.

Page 36: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

3. Análisis de los datos de Barcelona

Una vez identificada la distancia objetivo a partir de la experiencia previa en Madrid vamos a estudiar la idoneidad de ubicación de puntos de servicio en Barcelona. Como siempre, primero perderemos una buena e exasperante cantidad de tiempo incorpo-rando los datos de diversas fuentes en nuestra base de datos. Es lo que se conoce en ciencia de datos como la fase de Data Wrangling, y conlleva a menudo más tiempo que los análisis en sí.

3.1 Las fuentes de datos

Para esta parte del ejercicio disponemos de información en diversos formatos:

• bcn_hogares.accdb: una base de datos Access que contiene información sobre los hogares de Barcelona, así como una tabla con las coordenadas de 10 locales identificados como potenciales puntos de prestación de servicio cuya idoneidad se analizará. Los hogares han sido elaborados a partir de los portales proporcio-nados por el portal de datos abiertos de la propia ciudad de Barcelona y filtrados con ayuda del catastro en aquellas ubicaciones donde existía una construcción de al menos una planta;

• bcn_barrios.geojson: información de contexto territorial. Barrios y distritos de Bar-celona, extraídos asimismo del portal anteriormente citado, en formato GeoJSON;

• bcn_construcciones.geojson: construcciones de Barcelona, obtenidas del catas-tro y con la altura en plantas procesadas. Como contexto;

• bcn_red_arcos.shp: una Shapefile con los arcos del callejero de Barcelona, obteni-da del proyecto CARTOCIUDAD;

• bcn_sec_censales_mujerse.geojson: secciones censales de Barcelona en GeoJ-SON con la información demográfica de los dos rangos de edad de mujeres que nos interesan. Obtenida de los datos del padrón proporcionados por el Instituto Nacional de Estadística.

Page 37: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Vamos a cargar cada una de estas fuentes.

Carga de GeoJSON y Shapefiles

Para la carga de estos formatos, legibles directamente por QGIS, vamos a utilizar, como hemos hecho en otras ocasiones, la extensión DB Manager. Para ello, cargamos las ca-pas bcn_barrios.geojson, bcn_red_arcos.shp, bcn_construcciones.geojson y bcn_sec_censales_mujeres.geojson en QGIS. Las construcciones del catastro tardarán un poco.

Page 38: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Las cargamos sobre el esquema input, seleccionando en la importación las opciones Primary key, Geometry column, Create spatial index y Convert field names to lower-case. Los nombres que les daremos a las tablas serán los siguientes:

• bcn_barrios.geojson: input.bcn_barrio

• bcn_construcciones.geojson: input.bcn_construccion

• bcn_red_arcos.shp: input.bcn_red_arco

• bcn_sec_censales_mujeres.geojson: input.bcn_src_censal_mujeres

Page 39: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

A continuación, creamos un nuevo esquema bcn para contener los datos postprocesa-dos:

CREATE SCHEMA bcn;

y ahora posprocesamos los datos que hemos importado en input y los guardamos en dicho esquema:

CREATE TABLE bcn.bcn_sec_censal_mujeres AS SELECT seccion,

poblacion_total,

mujeres_5_19,

mujeres_35_49,

geom

FROM input.bcn_sec_censal_mujeres;

ALTER TABLE bcn.bcn_sec_censal_mujeres ADD CONSTRAINT bcn_sec_censal_mujeres_pkey PRIMARY KEY(seccion);

CREATE INDEX bcn_sec_censal_mujeres_geom_gist ON bcn.bcn_sec_censal_mujeres USING gist(geom);

Page 40: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

CREATE TABLE bcn.bcn_barrio AS SELECT gid,

c_distrito,

n_distrito,

c_barrio,

n_barrio,

geom

FROM input.bcn_barrio;

ALTER TABLE bcn.bcn_barrio ADD CONSTRAINT bcn_barrio_pkey PRIMARY KEY(gid);

CREATE INDEX bcn_barrio_geom_gist ON bcn.bcn_barrio USING gist(geom);

CREATE TABLE bcn.bcn_construccion AS SELECT gid,

constru,

height,

volume,

geom

FROM input.bcn_construccion;

ALTER TABLE bcn.bcn_construccion ADD CONSTRAINT bcn_construccion_pkey PRIMARY KEY(GID);

Page 41: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

CREATE INDEX bcn_construccion_geom_gist ON bcn.bcn_construccion USING gist(geom);

CREATE TABLE bcn.bcn_red_arco AS SELECT gid,

c_distrito,

n_distrito,

tipo_via,

nombre_via,

geom

FROM input.bcn_red_arco;

ALTER TABLE bcn.bcn_red_arco ADD CONSTRAINT bcn_red_arco_pkey PRIMARY KEY(gid);

CREATE INDEX bcn_red_arco_geom_gist ON bcn.bcn_red_arco USING gist(geom);

Page 42: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Ahora ya nos podemos olvidar de las fuentes originales de datos, eliminar el proyecto QGIS en el que las hemos cargado, abrir otro nuevo y cargar las mismas capas, pero esta vez desde PostGIS. Veremos cómo la velocidad de lectura desde PostGIS es infinitamente superior a la lectura desde los GeoJSON, especialmente en la capa de construcciones.

Page 43: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Importación de datos desde Access

Ahora vamos a ver cual es el procedimiento para importar datos desde una base de datos Access. Al igual que hicimos en su momento con Excel, utilizaremos el enlace ODBC que creamos en su momento hacia la base de datos. A diferencia de Excel, que sólo permitía una comunicación desde la base de datos hacia la hoja de cálculo, en Access la comunicación es bidireccional, y utilizaremos el puente ODBC para cargar información directamente desde la Access a la PostgreSQL.

Para ello, abrimos la base de datos Access bcn_hogares.accdb. Observaremos que en la base de datos tan sólo hay dos objetos: una tabla llamada Bcn_hogar_points y otra llamada Bcn_locales. Si las abrimos, veremos que son catálogos de puntos con coor-denadas X,Y, expresadas en EPSG:25831.

Antes de proceder a la importación de datos desde Access tenemos que crear un tablas en PostgreSQL que acojan a los datos. La Access no va a hacer este trabajo por nosotros. Por lo tanto, en el esquema input, creamos tablas acordes con el esquema de las tablas de Access:

Page 44: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

CREATE TABLE input.bcn_hogares ( gid INTEGER, st_x DOUBLE PRECISION, st_y DOUBLE PRECISION );

CREATE TABLE input.bcn_locales ( gid INTEGER, x DOUBLE PRECISION, y DOUBLE PRECISION );

Ahora vamos a la barra de herramientas del Access llamada Datos externos y, de forma similar a como hicimos en Excel, seleccionamos Nuevo origen de datos, Desde otros orígenes, Base de datos ODBC.

En Excel, la comunicación fué desde la base de datos hacia la hoja de cálculo: ODBC leía una tabla y con ella rellenaba celdas de la hoja. En este caso, es algo distinto: va-mos a vincular en Access las dos tablas que hemos creado anteriormente en input, de forma que sea la propia Access la que escriba sobre ellas la información que tiene en

Page 45: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

sus propias tablas. Este vínculo puede hacerse dinámico, por lo que el Access siempre verá a la base de datos actualizada, por lo que su nivel de automatización y reproducibi-lidad es alto.

En el primer cuadro de diálogo, seleccionamos la opción Vincular al origen de datos creando una tabla vinculada, que hace precisamente lo que hemos descrito:

Page 46: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

A continuación, seleccionamos Machine Data Source y ahí encontraremos el origen ODBC hacia la base de datos PostgreSQL que creamos cuando exportamos a Excel, ya que está definido a nivel de sistema y es, por tanto, reutilizable por todas las aplicacio-nes ODBC:

Page 47: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Access conectará con el origen ODBC y leerá las tablas que hay en él. Allí estarán las dos tablas que hemos preparado en el esquema input. Pulsando el control, las selec-cionamos las dos:

Page 48: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Seguidamente Access nos preguntará, para cada una de la tablas seleccionadas, cua-les son sus columnas claves primaria. En ambos casos indicaremos que es el campo gid:

Page 49: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Finalmente, ya tendremos las dos tablas vinculadas en la Access, marcadas con un símbolo especial. El vínculo es dinámico, por lo que siempre veremos desde Access el estado actual de los datos en PostgreSQL. Esto hace que la relación entre PostgreSQL y Access sea bastante eficaz:

Ahora tenemos que hacer que Access cargue, desde sus propias tablas, la información en las tablas vacías y vinculadas residentes en PostgreSQL. Para ello utilizaremos una vista de actualización de Access. Nos vamos la barra de herramientas Crear, y allí, pulsamos en Diseño de consulta:

Page 50: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

nos saldrá primero un cuadro de diálogo llamado Mostrar tabla que cerraremos, ya que pertenece al constructor visual de consultas de Access pero a nosotros lo que nos va es el SQL. No usar botones donde hay un lenguaje, eso es así. Así que le damos al bo-tón SQL de la esquina superior izquierda y Access nos proporcionará una consola SQL, en la que escribiremos la siguiente consulta y pulsamos en Ejecutar:

INSERT INTO input_bcn_hogares SELECT * FROM Bcn_hogar_points

Access procesará la consulta y, al ser un INSERT, preguntará si queremos anexar las nuevas filas a la tabla, a lo que contestamos que sí.

Page 51: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Acto seguido repetimos el procedimiento con la consulta de locales:

INSERT INTO input_bcn_locales SELECT * FROM Bcn_locales

y, si examinamos de nuevo las tablas vinculadas en Access o en PostgreSQL, veremos que los datos han sido transferidos de un sistema a otro. Ya podemos cerrar la Access. Las vinculaciones se mantendrán en el archivo Access, y siempre que el origen de datos ODBC esté creado en el sistema con el mismo nombre y apuntando a la base de datos, este proceso es reproducible.

Ahora hay que postprocesar esta importación de datos, de forma similar a como he-mos hecho otras veces:

CREATE TABLE bcn.bcn_hogar AS SELECT gid,

st_setsrid(st_makepoint(st_x, st_y), 25831) AS geom FROM input.bcn_hogares;

ALTER TABLE bcn.bcn_hogar ADD CONSTRAINT bcn_hogar_pkey PRIMARY KEY(gid);

CREATE INDEX bcn_hogar_geom_gist ON bcn.bcn_hogar USING gist(geom);

Page 52: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

CREATE TABLE bcn.bcn_local AS SELECT gid,

st_setsrid(st_makepoint(x, y), 25831) AS geom FROM input.bcn_locales;

ALTER TABLE bcn.bcn_local ADD CONSTRAINT bcn_local_pkey PRIMARY KEY(gid);

CREATE INDEX bcn_local_geom_gist ON bcn.bcn_local USING gist(geom);

Page 53: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

3.2 Análisis

El análisis que vamos a realizar es muy sencillo: vamos a aplicar sobre las secciones censales, que es el mayor nivel de desagregación al que se han conseguido los datos de efectivos demográficos, un índice que nos ayude a valorar la idoneidad de dicha sección censal en cuanto al perfil demográfico. Después, extrapolaremos por topología dichos resultados a todos los hogares presentes en la sección censal.

El indicador que vamos a crear es muy básico. Dividiremos a las adolescentes por las madres para obtener un ratio de adolescentes por madre. Cuando más alto, mejor, más probabilidad hay de encontrar en la sección censal dicha estructura familiar. Después, lo multiplicaremos por el total de la población de la sección, como medida de los efec-tivos totales o de probabilidad total. Es más atractiva una sección con una probabilidad de tener la estructura familiar adecuada, pero con más población, que lo contrario.

Creamos el indicador como una consulta:

CREATE OR REPLACE VIEW bcn.vw__indicador_censal AS SELECT seccion,

round(mujeres_5_19::NUMERIC/mujeres_35_49*

poblacion_total*0.01, 2) AS i, geom

FROM bcn.bcn_sec_censal_mujeres

ORDER BY i DESC;

Page 54: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

y sobre esta consulta hacemos la transposición del indicador i a los hogares:

CREATE OR REPLACE VIEW bcn.vw__indicador_hogar AS SELECT b.gid,

a.i,

b.geom

FROM bcn.vw__indicador_censal a INNER JOIN bcn.bcn_hogar b ON st_contains(a.geom, b.geom);

Page 55: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Ahora, una vez creado el indicador a nivel de hogar, vamos a proceder al análisis propia-mente dicho. Vamos primero a alterar la tabla bcn_local para incorporar un campo adicional que llamaremos activo, de tipo booleano, para indicar si un local participa o no en el análisis:

ALTER TABLE bcn.bcn_local ADD COLUMN activo BOOLEAN;

UPDATE bcn.bcn_local SET activo=true;

Page 56: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

La primera sentencia crea la nueva columna, la segunda, actualiza el valor de dicha columna, para todos los registros, a true, es decir, todos los locales van a participar, a priori, en el análisis.

Ahora vamos a crear la vista que va a generar el análisis. Es un estudio de proximidad, muy similar al realizado para el estudio preliminar de Madrid, en el sentido de que usa la misma técnica del DISTINCT ON. Paso a paso:

SELECT *

FROM bcn.vw__indicador_hogar a INNER JOIN bcn.bcn_local b ON st_dwithin(a.geom, b.geom, 3000) WHERE activo;

Esta primera sentencia crea la relación topológica entre los locales y los hogares. Cada local se relaciona con todos los puntos de hogar (independientemente, todavía, de que dicho local sea el más cercano) que tenga a una distancia de menos de 3000 metros. El WHERE nos asegura que sólo los locales activos participan en el análisis.

A continuación seleccionamos las columnas que nos van a servir para el análisis:

SELECT a.gid AS gid_hogar, b.gid AS gid_local, a.i

FROM bcn.vw__indicador_hogar a INNER JOIN bcn.bcn_local b ON st_dwithin(a.geom, b.geom, 3000) WHERE activo;

Page 57: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Hemos seleccionado la clave del hogar, la del local y el índice de dicho hogar. Ahora vamos a calcular alguna información adicional que nos va a ayudar al análisis y a su visualización:

SELECT row_number() OVER () AS gid, a.gid AS gid_hogar, b.gid AS gid_local, a.i,

st_distance(a.geom, b.geom) AS d, b.geom AS geom_local, st_setsrid(st_makeline(a.geom, b.geom), 25831) AS geom_line FROM bcn.vw__indicador_hogar a INNER JOIN bcn.bcn_local b ON st_dwithin(a.geom, b.geom, 3000) WHERE activo;

Hemos creado una clave primaria con row_number() (ya que la relación en el FROM es de cardinalidad muchos a muchos), hemos calculado la distancia entre ambos puntos relacionados, hemos arrastrado la geometría del local y por último hemos creado una recta entre ambos puntos, para comprobar cartográficamente la relación.

Ahora tenemos que implementar el análisis de proximidad por medio del DISTINCT ON. Recordemos que el DISTINCT ON se basa en una correcta ordenación de los datos. Debemos pensar en cual es la ordenación correcta.

Page 58: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Tenemos locales y tenemos hogares. La idea es ver qué local está más cercano a cada hogar, puesto que un mismo hogar puede tener varios locales a menos de 3000 me-tros. Por ello, el primer término de ordenación es el del gid del hogar:

SELECT row_number() OVER () AS gid, a.gid AS gid_hogar, b.gid AS gid_local, a.i,

st_distance(a.geom, b.geom) AS d, b.geom AS geom_local, st_setsrid(st_makeline(a.geom, b.geom), 25831) AS geom_line FROM bcn.vw__indicador_hogar a INNER JOIN bcn.bcn_local b ON st_dwithin(a.geom, b.geom, 3000) WHERE activo ORDER BY gid_hogar;

Como podemos ver para un hogar determinado (el gid 6180):

hogar local distancia

---

6180 1 1517.34621522526

6180 3 87.2513386997463

6180 5 2878.25149027377

6180 10 1917.94807591913

Page 59: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

por lo que el siguiente término de ordenación es la distancia:

SELECT row_number() OVER () AS gid, a.gid AS gid_hogar, b.gid AS gid_local, a.i,

st_distance(a.geom, b.geom) AS d, b.geom AS geom_local, st_setsrid(st_makeline(a.geom, b.geom), 25831) AS geom_line FROM bcn.vw__indicador_hogar a INNER JOIN bcn.bcn_local b ON st_dwithin(a.geom, b.geom, 3000) WHERE activo ORDER BY gid_hogar, d;

que arroja un resultado:

hogar local distancia

---

6180 3 87.2513386997463

6180 1 1517.34621522526

6180 10 1917.94807591913

6180 5 2878.25149027377

Page 60: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Ahora el primer local de la lista es el más cercano, por lo que ya podemos aplicar el DISTINCT ON, que recordemos debe ser un subconjunto de los campos, en el mismo orden, encontrados en el ORDER BY. Como además esta consulta es bastante pesa-da, la vamos a transformar en una vista materializada, para poder utilizarla com más comodidad:

CREATE MATERIALIZED VIEW bcn.mvw__local_influencia AS SELECT DISTINCT ON (gid_hogar) row_number() OVER () AS gid, a.gid AS gid_hogar, b.gid AS gid_local, a.i,

st_distance(a.geom, b.geom) AS d, b.geom AS geom_local, st_setsrid(st_makeline(a.geom, b.geom), 25831) AS geom_line FROM bcn.vw__indicador_hogar a INNER JOIN bcn.bcn_local b ON st_dwithin(a.geom, b.geom, 3000) WHERE activo ORDER BY gid_hogar, d;

Page 61: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Esta vista materializada nos proporciona la influencia de cada local activo, pero ahora tenemos que hacer un sumatorio del total del indicador por hogar para hallar el atracti-vo total del área de influencia del local. Sobre la vista anterior:

CREATE MATERIALIZED VIEW bcn.mvw__local_influencia_total AS SELECT gid_local AS gid, sum(i) AS total_i, geom_local AS geom FROM bcn.mvw__local_influencia

GROUP BY gid_local, geom_local;

Examinamos los resultados:

SELECT * FROM bcn.mvw__local_influencia_total ORDER BY total_i;

Page 62: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

y observamos que el que menos influencia total tiene es el local 6:

Local Influencia

---

6 27042.32

1 27160.00

8 28371.00

2 29028.92

10 35174.39

4 48326.03

7 52842.70

5 53578.02

3 57526.28

9 88869.68

Editamos la capa bcn_local en QGIS y desactivamos el local 6, poniendo a false el cam-po activo de dicho local, o lanzando la sentencia SQL:

UPDATE bcn.bcn_local SET activo=false WHERE gid=6;

y ahora relanzamos el análisis:

REFRESH MATERIALIZED VIEW bcn.mvw__local_influencia; REFRESH MATERIALIZED VIEW bcn.mvw__local_influencia_total;

Page 63: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner
Page 64: 1 ntroducción a osS: Ejercicio práctico · ntroducción a osS: 1 Ejercicio práctico nteroperatividad y análisis S de datos geográficos en PostGIS En esta práctica vamos a poner

Volvemos a lanzar el análisis, eliminando el último hasta quedarnos con 3 locales:

Local Influencia

---

4 116498.10

9 124541.84

3 132979.27