Как эффективно получить доступ к файлам с помощью GDAL из корзины S3 с помощью VSIS3?


19

Итак, GDAL недавно добавил новую функцию, которая позволяет произвольно читать файлы S3 Bucket. Я хочу обрезать изображения GDAL из нескольких фрагментов изображения, не загружая весь файл. Я только видел очень скудную документацию о том, как настроить и получить доступ к корзине S3 через GDAL, и я немного запутался, как начать? Будет ли кто-то достаточно любезен, чтобы предоставить чрезвычайно короткий пример / учебник о том, как можно настроить виртуальную файловую систему для GDAL для достижения этой цели? Бонусные баллы, если ваше решение позволяет создавать сценарии через Python!

Чтобы уточнить: мы уже сделали это на Python. Проблема с Python заключается в том, что вам нужно загрузить весь образ, чтобы работать с ним. Новейшая версия GDAL имеет поддержку для монтажа корзины S3, так что если нам нужно обрезать небольшую часть изображения, мы можем работать непосредственно с этой меньшей частью. Увы, поскольку эта функция была выпущена только в стабильной ветке в январе, я не нашел никакой документации по ней. Таким образом, решение должно использовать систему VSI3 в новейшей версии GDAL или иным образом разумно использовать систему, чтобы пользователю не требовалось загружать весь образ на диск EBS для работы с ним.

То есть награда будет присуждена за ответ, использующий API-интерфейсы VSI, обнаруженные в новейших версиях GDAL, так что весь файл не нужно будет читать в память или на диск. Кроме того, мы, используемые нами блоки, не всегда общедоступны, поэтому многие публикуемые трюки HTTP не будут работать во многих наших ситуациях.



Нет опыта работы с S3 / buckets, но этот пост может представлять интерес: ссылка . Используется аналогично (?)
— см1

@ cm1 Спасибо, эта документация до сих пор была лучшей помощью.
— Skylion

Рад это слышать. Я думаю, что это отличный вопрос, который вы задали, и я внимательно слежу. Надеюсь, что вы / другие решите и опубликуете хорошее решение здесь!
— cm1

Ответы:


18

Я обнаружил, что когда что-то не очень хорошо задокументировано в GDAL, просмотр их тестов может быть полезным.

У /vsis3тестового модуля есть несколько простых примеров, хотя у него нет примеров реального чтения фрагментов.

Я собрал код ниже, основанный на тестовом модуле, но я не могу протестировать, поскольку GDAL / vsis3 требует учетные данные, и у меня нет учетной записи 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 работает как шарм! Вот пример обрезки из командной строки: bdw: gdal_translate --config AWS_REGION "some_region" --config AWS_ACCESS_KEY_ID "KEY_ID" --config AWS_SECRET_ACCESS_KEY "ACCESS_KEY" \ -srcwin 000 000 10003e_set \ from_s3.tif
— Skylion

Как выглядят те ценности, которые вы спрятали? Я думаю, что KEY_ID является короткой текстовой строкой, как имя пользователя. Что такое ACCESS_KEY? Кажется, что это то, что находится в файле pem, но это около 1000 символов, так что это должно быть что-то еще.
— Solx

Это будут просто строки с цифрами и буквами, вроде имени пользователя и пароля. Вы можете получить эти строки, установив роли IAM в AWS
— RutgerH

10

Так /vsis3/как реализован в GDAL, вы также можете использовать rasterioдля чтения Windows наборов данных S3. Это требует либо учетные данные , которые будут созданы для Бота или с помощью rasterios AWS обработчика сеанса .

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.

Смотрите также растровые документы windowed -rw и VSI .


1

Попробуйте использовать файл XML для хранения информации WMS, более подробную информацию можно найти в документации по GDAL WMS .

Вот пример XML-файла WMS для извлечения данных из Elevation API 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>

Затем вы можете закрепить ограничивающую рамку следующим образом:

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

Хотя это полезный ответ, мы уже кэшируем метаданные подобным образом, но мы хотим знать, как использовать VSI API, чтобы мы могли быстро обрезать небольшие части больших изображений.
— Skylion

Я не уверен, что это потому, что конечная точка API Mapzen является плиточной WMS, но приведенный выше код запустился для меня менее чем за минуту. Вы уверены, что API VSI будет работать быстрее?
— Клэнрик

Мы работаем с ОЧЕНЬ большими растрами и большими наборами растровых данных, узким местом, безусловно, является IO. Кроме того, используемые нами хранилища являются частными и требуют учетных данных, что означает, что использование S3 http API не будет работать в нашем случае. Дело не в том, что мы должны читать каждое изображение, а в том, что мы знаем, что нужно обосрать небольшую часть очень большого изображения.
— Skylion

0

Я не очень разбираюсь в сегментах S3, но, похоже, это облачный накопитель с аутентификацией с использованием служб http REST. т.е. может быть использован в качестве обычной точки крепления, с соответствующей URI.

Если вы ищете обрезку частей изображения / растра, тогда файл должен быть в соответствующем формате.

Посмотрите на спецификацию TMS http://wiki.osgeo.org/wiki/Tile_Map_Service_Specification

(Возможно, netCDF также может помочь.)

GDAL также читает и записывает форматы TMS. По сути, это только стандартная структура каталогов с некоторыми файлами метаданных.

Теперь хитрость заключается в создании на лету URL-адреса с параметрами географического экстента через драйвер TMS.

Взгляните на документацию драйвера OpenLayers TMS: http://dev.openlayers.org/docs/files/OpenLayers/Layer/TMS-js.html Чтобы узнать, как он обрабатывает запросы на основе местоположения, масштаба и экстентов.

Конечно, это можно сделать на Python. Сначала необходимо создать соответствующий URI «точки монтирования» (или пути) с помощью viscurl (согласно документации), а затем, после монтирования, перейти к определенной плитке в соответствии со спецификацией TMS (которая является расширением пути). ,


Я просто добавил некоторые пояснения, чтобы отличить его от простого использования интерфейса S3 в Python.
— Skylion
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.