Hoy en día y gracias a la directiva INSPIRE, disponemos de una gran cantidad de recursos para realizar descargas de imágenes de satélite y todo tipo de información geográfica. Esto se canaliza a través de los servicios que ponen a disposición pública diferentes entidades a través de las Infraestructuras de Datos Espaciales (IDE). Esta información no sólo se pone a disposición pública para consultarla y descargarla totalmente gratis, también se hace un esfuerzo para que el acceso a la misma se haga de forma estandarizada y esta estandarización nos facilita mucho la labor de automatización de tareas.

Muchas veces, cuando queremos disponer de imágenes de satélite, no queremos solamente una, o la que queremos es de tal tamaño que los servidores no nos ofrecen la posibilidad de acceder a descargas tan grandes. En este segundo caso recurriremos a descargar un mosaico formado por múltiples imágenes de igual tamaño.

Los servidores de las IDE ponen a nuestra disposición los dos métodos de peticiones Http (HttpGet y HttpPost) para automatizar de forma sencilla la descarga de los datos usaremos las segundas. Las peticiones HttpGet permiten añadir parámetros a la url, conformando lo que se conoce como uri. Para ello, tras la dirección url se marca el principio de la cadena de peticiones con el signo de cerrar interrogación “?” y en ella aparecen parejas de datos con el nombre y el valor separados por un “=”, separando cada pareja de nombre de dato y valor de la siguiente por un “&”, esto permite que, por ejemplo, un script de JavaScript incorpore como variables los datos de los parámetros añadidos a la url. Por ejemplo, si queremos saber qué capas tiene un servicio WMS, podemos realizar una petición HttpGet al servidor de la IDE de la ciudad de Munich, para que nos diga qué servicios ofrece mediando la petición GetCapabilities.

URL:
https://geoportal.muenchen.de/geoserver/gsm/wms?

Cadena de peticiones:
SERVICE=WMS&REQUEST=GetCapabilities

URI:
https://geoportal.muenchen.de/geoserver/gsm/wms?SERVICE=WMS&REQUEST=GetCapabilities

Como resultado nos arrojará un documento XML con información sobre el servicio y los datos que pone a nuestra disposición. Entre estos datos están las capas y sus nombres, los sistemas de coordenadas disponibles, los límites de las capas, las resoluciones de las mismas, etc…

De los datos contenidos en este XML podemos extraer todo lo necesario para construir una petición GetMap al servidor que nos devuelva un ráster con la imagen deseada. Podríamos obtener una imagen cuadrada de mil píxeles de lado de cada uno de los recuadros de 200×200 metros mostrados en la imagen anterior por medio de la siguiente petición HttpGet:

https://geoportal.muenchen.de/geoserver/gsm/wms?SERVICE=WMS&REQUEST=GetMap&VERSION=1.0.0&srs=EPSG:32632&STYLES=&bbox=685483,5335385,685683,5335585&layers=luftbild&format=image/png&width=1000&height=1000

Esta petición incorpora los siguientes parámetros: tipo de servicio (SERVICE=WMS), la petición (REQUEST=GetMap), la versión (VERSION=1.0.0), sistema de referencia (srs=EPSG:32632), coordenadas límite de la imagen a descargar (bbox=685483,5335385,685683,5335585), nombre de la capa (layers=luftbild), formato en el que se descarga la imagen (format=image/png) y número de píxeles de ancho y alto que tendrá la imagen descargada (width=1000&height=1000). Este cuadrado de 200x200m sobre el terreno y de mil píxeles de lado, nos da el mismo tañao de píxel original de la ortofoto (20cm). Si la petición está bien formulada, el navegador nos la abrirá directamente y si es incorrecta nos descargará un mensaje un archivo de texto que contendrá el mensaje de error.

Vemos que realizar esta petición para conseguir una imagen es relativamente sencillo, pero podemos darnos cuenta de que, si queremos hacer esto a mano para obtener todas las imágenes correspondientes a los 121 recuadros mostrados al principio de este post, empezaría a ser una tarea titánica. No digamos ya si nos adentrásemos en números mayores.

Para hacer esta tarea asequible y que “dé igual ocho que ochenta”, vamos a preparar con Python un pequeño script que nos descargará todas estas imágenes a la carpeta que indiquemos y que distinguirá cada imagen en si nombre de fichero según su posición en la cuadrícula descargada.

Usaremos las librerías “requests” y “time” para realizar las peticiones y poder gestionar el tiempo con el que las hace para evitar que, si realizamos demasiadas en un espacio de tiempo muy corto, nuestras peticiones sean detectadas como un ataque al servidor. También elegiremos la carpeta de destino de nuestras ortofotos.

Luego introduciremos las coordenadas máximas y mínimas de toda la superficie de la que queremos descargar los datos el tamaño en metros del lado del cuadrado de los “parches” que vamos a descargar. Con ellos obtendríamos ya las coordenadas límite del primer recuadro a descargar, sumando el lado a las coordenada mínimas x e y, iniciando también el contador que nos dará la posición de cada imagen dentro de la cuadrícula, en este caso, al ser la primera tendrá la posición 1, 1.

Ahora crearemos un bucle que iterará primero por los recuadros siguiendo el eje de las X hasta que la X máxima de los recuadros a descargar, pasando en cada parada en las X por otro bucle que iterará todos los recuadros contenidos entra los valores mínimo y máximo para las coordenadas Y.

Mientras el bucle de las X se dedica a actualizar los contadores y la coordenadas al final de cada bucle sobre el eje Y, es este último el que irá parando individualmente en cada recuadro del que solicitaremos su descarga, es por ello que este segundo bucle contendrá, además de la actualización de las coordenada y contadores correspondientes a cada parada una coordenada Y, todo el código correspondiente a completar la petición al servidor. Por eso digo que aquí sucede la magia.

Como veis esa “magia” tiene poco de magia y tan siquiera es algo muy complejo y lo que hace es ir situando para cada petición las coordenadas x e y máximas y mínimas para cada parche y crear el nombre del archivo usando el contador de repeticiones de cada bucle countX y countY. Además incorporamos unos “print” para que se nos vaya mostrando el progreso de ejecución del script y tras cada petición de descarga al servidor esperamos 5 segundos para realizar la siguiente petición y evitar así un posible “baneo” de nuestra IP por realizar demasiadas peticiones simultáneas. Si esta espera de 5 segundos, seguramente con números bastante inferiores sigamos evitando ser excluidos.

Ahora podríamos, por ejemplo, incorporar estas imágenes a un entrenamiento supervisado creando máscaras sobre el mismo lugar y extrayendo los parches de coordenadas análogas. Si queremos reconstruir una imagen más grande uniendo todas las imágenes descargadas, no tendríamos que seguir el procedimiento “unpatchify” descrito en la entrada anterior del blog:

División de Imágenes en Python con Patchify.

1 estrella2 estrellas3 estrellas4 estrellas5 estrellas (2 votos, promedio: 5,00 de 5)

Cargando...

Formación de calidad impartida por profesionales