Як ефективно отримати доступ до файлів з GDAL з відра S3 за допомогою VSIS3?


19

Так, GDAL нещодавно додав нову функцію, яка дозволяє випадково читати файли з відра S3. Я хочу обрізати зображення GDAL з декількох плиток зображення, не завантажуючи весь файл. Я бачив дуже рідкісну документацію про те, як налаштувати та отримати доступ до відра S3, хоча GDAL, і я трохи не збентежений, як почати? Невже хтось буде досить люб'язним, щоб надати надзвичайно короткий приклад / підручник про те, як можна було б налаштувати віртуальну файлову систему для GDAL для досягнення цієї мети? Бонусні очки, якщо ваше рішення дозволяє сценаріювати через Python!

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

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



Немає досвіду використання S3 / відра, але ця публікація може зацікавити: посилання . Використовується аналогічно (?)
см1

@ cm1 Дякую, що документація була найкращою допомогою досі.
Skylion

Радий це чути. Я думаю, що це велике питання, яке ви задали, і я уважно спостерігаю. Сподіваємось, ви / інші вирішите і опублікуйте приємне рішення тут!
см1

Відповіді:


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
Вут працює як шарм! Ось приклад кадрування з командного рядка ДО РЕЧІ: 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 \ "/vsis3/bucket/file.ext" 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.

Дивіться також rasterios window -rw та VSI документи.


1

Спробуйте використовувати XML-файл для зберігання інформації про WMS, більш детальну інформацію ви можете знайти у документації на GDAL WMS .

Ось приклад XML-файлу WMS для отримання даних з API Ezention 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

Хоча це корисна відповідь, ми вже кешуємо метадані аналогічним чином, але ми хочемо знати, як використовувати API VSI, щоб ми могли швидко обрізати невеликі частини великих зображень.
Skylion

Я не впевнений, чи це тому, що кінцева точка API Mapzen є плитковою WMS, але вищевказаний код запустив для мене менше хвилини, ви впевнені, що API VSI буде швидше?
clhenrick

Ми працюємо з ДУЖЕ великими растрами та великими наборами растрових даних, вузьким місцем якого є, безумовно, IO. Також відряди, які ми використовуємо, є приватними і вимагають облікових даних, тобто використання API S3 http в нашому випадку не працюватиме. Справа не в тому, що ми повинні читати кожне зображення, це те, що ми знаємо, що нам потрібно зламати невелику частину дуже великого зображення.
Skylion

0

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

Якщо ви шукаєте обрізання частин зображень / растрових, то файл має бути у відповідному форматі.

Погляньте на специфікацію 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.