Mosaico Temporal con Geoserver

Geoserver permite crear mosaicos a partir de un conjunto de raster georreferenciados. Pueden ser tanto espaciales como temporales. Este último caso es el que nos interesa.

Archivos de configuración

Se necesitan dos archivos de configuración de forma obligatoria, tres de forma opcional:

  • datastore.properties, opcional, para configurar la conexión de la base de datos donde se almacenarán los datos del mosaico. Si se omite Geoserver crear un shapefile. En la documentación recomiendan usarlo siempre en producción.

  • indexer.properties, donde el usuario especifica la información que Geoserver usa para crear la tabla con los índices. Hemos usado el siguiente archivo, copiado de la documentación, sin mayores problemas:

    TimeAttribute=ingestion
    Schema=*the_geom:Polygon,location:String,ingestion:java.util.Date
    PropertyCollectors=TimestampFileNameExtractorSPI[timeregex](ingestion)
    
  • timeregex.properties, para definir la expresión regular que extraerá las fechas de los archivos. Para sentinel1 la siguiente expresión hace el trabajo:

    regex=[0-9]{8}T[0-9]{6}
    

Estos dos (o tres) archivos hay que almacenarlos en la misma carpeta donde se guardan todos los archivos del mosaico. No es necesario tener todos los archivos del mosaico de inicio, sino que podemos añadir a posterior usando la API de Geoserver.

Creación de Mosaico con la interfaz de Geoserver

  • [opcional] Creamos un nuevo espacio de trabajo.
    • También podemos usar uno existente si ya tenemos uno al cual queremos asociar nuestro nuevo mosaico
  • Añadimos un almacén de datos.
    • Tenemos que seleccionar el espacio de trabajo del que depende.
    • La fuente de datos es ImageMosaic.
    • Podemos especificar el mismo nombre para distintos espacios de trabajo. Muy útil si por ejemplo queremos tener un mosaico temporal con imágenes de Sentinel en varios de nuestros proyectos/espacios de trabajo.
    • Especificamos la carpeta donde queremos crear el store, en la cual tendremos al menos timeregex.properties e indexer .properties. También necesitamos algún archivo de Sentinel para que pueda detectar las características cartográficas que definirán el almacén.
    • Guardamos (no aplicamos) para poder pasar directamente a publicar.
    • Publicamos y en la pestaña Dimensiones habilitamos Hora y elegimos la forma de presentación.
  • Si queremos usar directamente los archivos de Sentinel tenemos que instalar el plugin de GDAL. Otra opción es pasar los archivos jp2 a tif. Estos últimos ocupan algo más del doble para 3 bandas y píxeles de 8 bits.

Creación de Mosaico con la API de Geoserver

Podemos crear un mosaico al completo usando la API que expone geoserver. Como condición inicial Necesitamos tener los archivos *.properties de configuración del mosaico comprimidos en un archivo zip.

  • Creamos un mosaico vacío:

    curl -u admin:geoserver \
         -XPUT \
         --write-out %{http_code} \
         -H "Content-type:application/zip" \
         --data-binary @properties.zip \
         "http://localhost:8080/geoserver/rest/workspaces/$WS_NAME/coveragestores/STORE_NAME/file.imagemosaic?configure=none"
    

    Con esto ya se encarga de crear la carpeta con el nombre del store.

    Podemos llamar a la API con JavaScript y Axios mediante

    const url = `${this.conn.url}workspaces/${wsName}/coveragestores/${stName}/file.imagemosaic?configure=none`;
    
    const stats = fs.statSync(propertiesPath);
    const fileSizeInBytes = stats.size;
    const readStream = fs.createReadStream(propertiesPath);
    
    const response = await axios(url, {
      method: 'PUT',
      headers: {
        Authorization: auth,
        'Content-Type': 'application/zip',
        'Content-length': fileSizeInBytes,
      },
      data: readStream,
    });
    
  • Añadimos archivos a demanda.

curl -v -u admin:geoserver \
     -POST \
     -H "Content-type: text/plain" \
     -d "file:///home/nando/Software/geoserver/data_dir/data/sentinel/S2A_Cordoba_000/T30SUG_20220612T105631Z_10m_RGB.tiff" \
     "http://localhost:8080/geoserver/rest/workspaces/$WS_NAME/coveragestores/$STORE_NAME/external.imagemosaic"

Con JavasScript y Axios:

const url = `${baseUrl}workspaces/${wsName}/coveragestores/${stName}/external.imagemosaic`,
const response = await axios(url, {
  method: 'POST',
  headers: {
    Authorization: auth,
    'Content-Type': 'text/plain',
  },
  data: filePath,
});

De esta forma el archivo no se añade a la carpeta, sino que se referencia en la tabla del mosaico la ubicación que se le pasa con filePath.


  1. Para Archivos Con Un Nombre Tal que T30SUG_20220212T110151_TCI_10m.jp2↩︎