Come accedere in modo efficiente ai file con GDAL da un bucket S3 utilizzando VSIS3?


19

Pertanto, GDAL ha recentemente aggiunto una nuova funzionalità che consente la lettura casuale dei file bucket S3. Sto cercando di ritagliare le immagini GDAL da più riquadri di un'immagine senza dover scaricare l'intero file. Ho visto solo una documentazione molto scarsa su come configurare e accedere a un bucket S3 tramite GDAL e sono un po 'confuso su come iniziare? Qualcuno sarebbe abbastanza gentile da fornire un esempio / tutorial estremamente breve su come procedere per impostare il filesystem virtuale per GDAL al fine di raggiungere questo obiettivo? Punti bonus se la tua soluzione ne consente lo script tramite Python!

Per chiarire: l'abbiamo già fatto in Python. Il problema con Python è che devi scaricare l'intera immagine per farla funzionare. La versione più recente di GDAL ha il supporto per il montaggio della benna S3 in modo che se dobbiamo dire ritagliare una piccola porzione dell'immagine, possiamo operare direttamente su quella porzione più piccola. Purtroppo, dato che la funzione è stata rilasciata sul ramo stabile a gennaio, non ho trovato alcuna documentazione su di essa. Quindi la soluzione dovrebbe usare il sistema VSI3 nella versione più recente di GDAL o altrimenti utilizzare in modo intelligente il sistema per impedire all'utente di scaricare l'intera immagine su un'unità EBS per operare su di essa.

Vale a dire che la taglia verrà assegnata per rispondere che utilizza le API VSI trovate nelle versioni più recenti di GDAL in modo che non sia necessario leggere l'intero file in memoria o su disco. Inoltre, i bucket che utilizziamo non sono sempre pubblici, quindi molti dei trucchi HTTP pubblicati non funzioneranno in molte delle nostre situazioni.



Nessuna esperienza con S3 / bucket, ma questo post può essere interessante: link . Usato in modo simile (?)
cm1

@ cm1 Grazie, quella documentazione è stata finora il miglior aiuto.
Skylion,

Felice di sentirlo. Penso che questa sia un'ottima domanda che mi hai posto e lo sto osservando da vicino. Spero che voi / altri risolviate e pubblichiate una buona soluzione qui!
cm1

Risposte:


18

Ho scoperto che quando qualcosa non è particolarmente ben documentato in GDAL, guardare attraverso i loro test può essere utile.

Il /vsis3modulo di test ha alcuni semplici esempi, sebbene non abbia alcun esempio di lettura dei blocchi.

Ho messo insieme il codice riportato di seguito in base al modulo di test, ma non sono in grado di testare poiché GDAL / vsis3 richiede credenziali e non ho un account AWS.

"""This should read from the Sentinal-2 public dataset
   More info - http://sentinel-pds.s3-website.eu-central-1.amazonaws.com"""

from osgeo import gdal
import numpy as np

# These only need to be set if they're not already in the environment,
# ~/.aws/config, or you're running on an EC2 instance with an IAM role.
gdal.SetConfigOption('AWS_REGION', 'eu-central-1')
gdal.SetConfigOption('AWS_SECRET_ACCESS_KEY', 'MY_AWS_SECRET_ACCESS_KEY')
gdal.SetConfigOption('AWS_ACCESS_KEY_ID', 'MY_AWS_ACCESS_KEY_ID')
gdal.SetConfigOption('AWS_SESSION_TOKEN', 'MY_AWS_SESSION_TOKEN')

# 'sentinel-pds' is the S3 bucket name
path = '/vsis3/sentinel-pds/tiles/10/S/DG/2015/12/7/0/B01.jp2'
ds = gdal.Open(path)

band = ds.GetRasterBand(1)

xoff, yoff, xcount, ycount = (0, 0, 10, 10)
np_array = band.ReadAsArray(xoff, yoff, xcount, ycount)

2
Woot funziona come un fascino! Ecco un esempio di ritaglio dalla riga di comando btw: gdal_translate --config AWS_REGION "some_region" --config AWS_ACCESS_KEY_ID "KEY_ID" --config AWS_SECRET_ACCESS_KEY "ACCESS_KEY" \ -srcwin 000 000 1000 1000 \ "/vs//file/3vile/3x from_s3.tif
Skylion,

Che aspetto hanno quei valori che hai nascosto? Penso che KEY_ID sia una stringa di testo breve, come un nome utente. Che cos'è ACCESS_KEY? Sembra che sia quello che c'è in un file pem ma che è di circa 1000 caratteri, quindi deve essere qualcos'altro.
Solx

Quelle saranno solo stringhe con numeri e lettere come un nome utente e una password. Puoi ottenere quelle stringhe impostando i ruoli IAM in AWS
RutgerH

10

Dato che /vsis3/è implementato in GDAL puoi anche usare rasterioper leggere Windows di set di dati S3. Ciò richiede che le tue credenziali siano configurate per boto o che utilizzino il gestore della sessione AWS rasterios .

import rasterio

with rasterio.open('s3://landsat-pds/L8/139/045/LC81390452014295LGN00/LC81390452014295LGN00_B1.TIF') as ds:
    window = ds.read(window=((0, 100), (0, 100)))  # read a 100 by 100 window in the upper left corner.

Vedi anche rasterios windowed-rw e documenti VSI .


1

Prova a utilizzare un file XML per archiviare le informazioni WMS, maggiori dettagli sono disponibili nella documentazione GDAL WMS .

Ecco un esempio di file XML WMS per recuperare i dati dall'API Elevation di Mapzen:

<GDAL_WMS>
  <Service name="TMS">
    <ServerUrl>https://s3.amazonaws.com/elevation-tiles-prod/geotiff/${z}/${x}/${y}.tif</ServerUrl>
  </Service>
  <DataWindow>
    <UpperLeftX>-20037508.34</UpperLeftX>
    <UpperLeftY>20037508.34</UpperLeftY>
    <LowerRightX>20037508.34</LowerRightX>
    <LowerRightY>-20037508.34</LowerRightY>
    <TileLevel>14</TileLevel>
    <TileCountX>1</TileCountX>
    <TileCountY>1</TileCountY>
    <YOrigin>top</YOrigin>
  </DataWindow>
  <Projection>EPSG:3857</Projection>
  <BlockSizeX>512</BlockSizeX>
  <BlockSizeY>512</BlockSizeY>
  <BandsCount>1</BandsCount>
  <DataType>Int16</DataType>
  <ZeroBlockHttpCodes>403,404</ZeroBlockHttpCodes>
  <DataValues>
    <NoData>-32768</NoData>
  </DataValues>
  <Cache/>
</GDAL_WMS>

È quindi possibile agganciare un riquadro di selezione in questo modo:

gdalwarp -of "GTiff" -te -13648825.0817 4552130.7825 -13627575.5878 4565507.2624 mapzen_wms.xml test.tif

Sebbene questa sia una risposta utile, abbiamo già memorizzato nella cache i metadati in modo simile, ma vogliamo sapere come utilizzare l'API VSI in modo da poter ritagliare rapidamente piccole porzioni di immagini di grandi dimensioni.
Skylion,

Non sono sicuro se è perché l'endpoint dell'API Mapzen è un WMS affiancato ma il codice sopra è stato eseguito per me in meno di un minuto, sei sicuro che l'API VSI sarà più veloce?
Clhenrick,

Stiamo lavorando con raster MOLTO grandi e set di dati raster di grandi dimensioni, il collo di bottiglia è decisamente IO. Anche i bucket che utilizziamo sono privati ​​e richiedono credenziali, il che significa che l'utilizzo dell'API http S3 non funzionerà nel nostro caso. Non è che dobbiamo leggere ogni immagine, è che sappiamo che dobbiamo fare una piccola parte di un'immagine molto grande.
Skylion,

0

Non so molto sui bucket S3 ma sembra che sia un'unità di archiviazione cloud con autenticazione che utilizza i servizi REST http. cioè potrebbe essere usato come un normale punto di montaggio, con un uri associato.

Se stai cercando parti ritagliate di immagini / raster, il file deve essere in un formato appropriato.

Dai un'occhiata alla specifica TMS http://wiki.osgeo.org/wiki/Tile_Map_Service_Specification

(Forse netCDF potrebbe anche fare il trucco.)

GDAL legge e scrive anche formati TMS. Fondamentalmente è solo una struttura di directory standard con alcuni file di metadati.

Ora, il trucco è creare al volo l'URL con i parametri di estensione geografica tramite il driver TMS.

Dai un'occhiata alla documentazione del driver TMS OpenLayers: http://dev.openlayers.org/docs/files/OpenLayers/Layer/TMS-js.html Per vedere come gestisce le richieste in base a posizione, zoom ed estensioni.

Naturalmente può essere fatto in Python. È necessario prima creare l'URI "punto di montaggio" (o percorso) appropriato con viscurl (secondo la documentazione) e quindi, una volta montato, passare alla piastrella specifica in base alla specifica TMS (che è un'estensione del percorso) .


Ho appena aggiunto alcuni chiarimenti per differenziarlo dal semplice utilizzo dell'interfaccia S3 in Python.
Skylion,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.