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.
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.
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.jp2
a tif
. Estos últimos ocupan algo más del doble para 3 bandas y píxeles de 8 bits.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.
Para Archivos Con Un Nombre Tal que T30SUG_20220212T110151_TCI_10m.jp2. ↩︎