Wie kann man mit VSIS3 über einen S3-Bucket effizient auf Dateien mit GDAL zugreifen?

17

Daher hat GDAL kürzlich eine neue Funktion hinzugefügt , mit der S3-Bucket-Dateien nach dem Zufallsprinzip gelesen werden können. Ich möchte GDAL-Bilder aus mehreren Kacheln eines Bildes zuschneiden, ohne die gesamte Datei herunterladen zu müssen. Ich habe nur eine sehr spärliche Dokumentation zum Konfigurieren und Zugreifen auf einen S3-Bucket durch GDAL gesehen und bin ein wenig verwirrt, wie ich anfangen soll. Wäre jemand so freundlich, ein extrem kurzes Beispiel / Tutorial zu geben, wie man das virtuelle Dateisystem für GDAL einrichten würde, um dieses Ziel zu erreichen? Bonuspunkte, wenn Ihre Lösung die Skripterstellung über Python ermöglicht!

Zur Verdeutlichung: Wir haben es bereits in Python gemacht. Das Problem mit Python ist, dass Sie das gesamte Image herunterladen müssen, um es damit zu betreiben. Die neueste Version von GDAL unterstützt die Montage des S3-Buckets. Wenn Sie also einen kleinen Teil des Bildes beschneiden möchten, können Sie diesen kleineren Teil direkt bearbeiten. Leider habe ich keine Dokumentation dazu gefunden, da das Feature erst im Januar im Stable-Zweig veröffentlicht wurde. Daher sollte die Lösung das VSI3-System in der neuesten Version von GDAL verwenden oder das System auf andere Weise intelligent einsetzen, um zu verhindern, dass der Benutzer das gesamte Image auf ein EBS-Laufwerk herunterladen muss, um es zu bearbeiten.

Das heißt, die Prämie wird für Antworten vergeben, die die in den neuesten Versionen von GDAL enthaltenen VSI-APIs verwenden, sodass nicht die gesamte Datei in den Arbeitsspeicher oder auf die Festplatte eingelesen werden muss. Außerdem sind die von uns verwendeten Buckets nicht immer öffentlich, sodass viele der veröffentlichten HTTP-Tricks in vielen unserer Situationen nicht funktionieren.

Skylion
quelle
Keine Erfahrung mit S3 / Eimern, aber dieser Beitrag kann von Interesse sein: Link . Ähnlich verwendet (?)
cm1
@ cm1 Danke, diese Dokumentation war bisher die beste Hilfe.
Skylion
Froh das zu hören. Ich denke, das ist eine großartige Frage, die Sie gestellt haben, und ich beobachte sie genau. Hoffe, Sie / Andere lösen und posten eine nette Lösung hier!
cm1

Antworten:

18

Ich habe festgestellt, dass es nützlich sein kann, die Tests durchzusehen, wenn etwas in GDAL nicht besonders gut dokumentiert ist.

Das /vsis3Testmodul enthält einige einfache Beispiele, jedoch keine Beispiele für das tatsächliche Lesen von Chunks.

Ich habe den folgenden Code basierend auf dem Testmodul zusammengestellt, kann ihn jedoch nicht testen, da für GDAL / vsis3 Anmeldeinformationen erforderlich sind und ich kein AWS-Konto habe.

"""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)
user2856
quelle
1
Woot wirkt wie ein Zauber! Hier ist ein Beispiel für das Zuschneiden von der Befehlszeile aus: 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 \ "/ bvetisf3/s from_s3.tif
Skylion
Wie sehen diese Werte aus, die Sie versteckt haben? Ich denke, KEY_ID ist eine kurze Textzeichenfolge, wie ein Benutzername. Was ist ACCESS_KEY? Es scheint so, als ob es das ist, was in einer PEM-Datei ist, aber das sind ungefähr 1000 Zeichen, also muss es etwas anderes sein.
Solx
Das sind nur Zeichenfolgen mit Zahlen und Buchstaben, wie ein Benutzername und ein Passwort. Sie können diese Zeichenfolgen erhalten, indem Sie die IAM-Rollen in AWS
RutgerH
9

Da dies /vsis3/in GDAL implementiert ist, können Sie auch rasterioWindows von S3-Datensätzen lesen. Dazu müssen entweder Ihre Anmeldeinformationen für Boto eingerichtet sein oder Sie müssen den Rasterios AWS-Sitzungshandler verwenden .

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.

Siehe auch rasterios windowed -rw- und VSI- Dokumente.

Kersten
quelle
1

Versuchen Sie, eine XML-Datei zum Speichern der WMS-Informationen zu verwenden. Weitere Informationen finden Sie in der GDAL WMS-Dokumentation .

Hier ist eine Beispiel-WMS-XML-Datei zum Abrufen von Daten aus Mapzens Elevation-API:

<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>

Sie können dann wie folgt einen Begrenzungsrahmen anclipsen:

gdalwarp -of "GTiff" -te -13648825.0817 4552130.7825 -13627575.5878 4565507.2624 mapzen_wms.xml test.tif
Clhenrick
quelle
Obwohl dies eine nützliche Antwort ist, werden die Metadaten bereits auf ähnliche Weise zwischengespeichert, wir möchten jedoch wissen, wie die VSI-API verwendet wird, damit wir kleine Teile großer Bilder schnell zuschneiden können.
Skylion
Ich bin nicht sicher, ob dies daran liegt, dass der Mapzen-API-Endpunkt ein gekacheltes WMS ist, aber der obige Code lief für mich in weniger als einer Minute. Sind Sie sicher, dass die VSI-API schneller sein wird?
Clhenrick
Wir arbeiten mit SEHR großen Rastern und großen Raster-Datasets, der Engpass ist definitiv IO. Auch die von uns verwendeten Buckets sind privat und erfordern Anmeldeinformationen, was bedeutet, dass die Verwendung der S3-HTTP-API in unserem Fall nicht funktioniert. Es ist nicht so, dass wir jedes Bild lesen müssen, es ist so, dass wir wissen, dass wir einen kleinen Teil eines sehr großen Bildes beschmutzen müssen.
Skylion
0

Ich weiß nicht viel über S3-Buckets, aber es scheint, dass es sich um ein Cloud-Speicherlaufwerk mit Authentifizierung mithilfe von http-REST-Diensten handelt. dh könnte als gewöhnlicher Befestigungspunkt mit einem zugehörigen URI verwendet werden.

Wenn Sie Teile von Bildern / Rastern zuschneiden möchten, muss die Datei ein geeignetes Format haben.

Schauen Sie sich die TMS-Spezifikation http://wiki.osgeo.org/wiki/Tile_Map_Service_Specification an

(Vielleicht könnte netCDF auch den Trick machen.)

GDAL liest und schreibt auch TMS-Formate. Grundsätzlich handelt es sich nur um eine Standardverzeichnisstruktur mit einigen Metadatendateien.

Jetzt besteht der Trick darin, die URL mit den geografischen Ausdehnungsparametern im Handumdrehen über den TMS-Treiber zu erstellen.

Sehen Sie sich die OpenLayers TMS-Treiberdokumentation an: http://dev.openlayers.org/docs/files/OpenLayers/Layer/TMS-js.html. Hier erfahren Sie, wie die Anforderungen basierend auf Position, Zoom und Umfang verarbeitet werden.

Natürlich kann es in Python gemacht werden. Sie müssen zuerst den entsprechenden "Montagepunkt" (oder Pfad) -URI mit viscurl erstellen (gemäß der Dokumentation) und dann nach dem Mounten zu der spezifischen Kachel gemäß der TMS-Spezifikation gehen (die eine Erweiterung des Pfads darstellt). .

Juan
quelle
Ich habe nur einige Klarstellungen hinzugefügt, um es von der Verwendung der S3-Oberfläche in Python zu unterscheiden.
Skylion