วิธีเข้าถึงไฟล์อย่างมีประสิทธิภาพด้วย GDAL จาก S3 bucket ด้วย VSIS3


19

ดังนั้น GDAL จึงได้เพิ่มคุณสมบัติใหม่ที่ช่วยให้สามารถอ่านไฟล์ที่ฝากข้อมูล S3 ได้แบบสุ่ม ฉันกำลังมองหาการครอบตัดภาพ GDAL จากหลายไทล์ของภาพโดยไม่ต้องดาวน์โหลดไฟล์ทั้งหมด ฉันเห็นเอกสารกระจัดกระจายมากเกี่ยวกับวิธีการกำหนดค่าและเข้าถึง S3 bucket แต่ GDAL และสับสนเล็กน้อยเกี่ยวกับวิธีเริ่มต้นอย่างไร ใครบางคนจะใจดีพอที่จะให้ตัวอย่าง / การสอนสั้น ๆ อย่างมากเกี่ยวกับวิธีการตั้งค่าระบบไฟล์เสมือนสำหรับ GDAL เพื่อให้บรรลุเป้าหมายนี้ แต้มโบนัสหากโซลูชันของคุณอนุญาตให้เขียนสคริปต์ผ่าน Python!

เพื่อชี้แจง: เราได้ทำไปแล้วใน Python ปัญหาของ Python คือคุณต้องดาวน์โหลดทั้งรูปภาพเพื่อใช้งานได้ GDAL รุ่นใหม่ล่าสุดมีการสนับสนุนการติดตั้งที่ฝากข้อมูล S3 เพื่อที่ว่าหากเราต้องการพูดว่าครอบตัดส่วนเล็ก ๆ ของภาพเราสามารถทำงานโดยตรงกับส่วนที่เล็กลง อนิจจาเนื่องจากฟีเจอร์นี้เปิดตัวเฉพาะในสาขาที่มั่นคงในเดือนมกราคมฉันจึงไม่พบเอกสารใด ๆ เลย ดังนั้นโซลูชันควรใช้ระบบ VSI3 ใน GDAL รุ่นใหม่ล่าสุดหรือใช้ระบบอย่างชาญฉลาดเพื่อป้องกันผู้ใช้ไม่จำเป็นต้องดาวน์โหลดภาพทั้งหมดไปยังไดรฟ์ EBS เพื่อทำงานกับมัน

กล่าวคือจะได้รับรางวัลเงินรางวัลเพื่อตอบว่าใช้ VSI APIs ที่พบใน GDAL รุ่นใหม่ล่าสุดเพื่อให้ไฟล์ทั้งหมดไม่จำเป็นต้องอ่านในหน่วยความจำหรือดิสก์ นอกจากนี้เราถังที่เราใช้นั้นไม่เปิดเผยต่อสาธารณะดังนั้นเทคนิค HTTP จำนวนมากที่โพสต์จะไม่ทำงานในหลาย ๆ สถานการณ์ของเรา


อาจจะเป็นที่สนใจ: github.com/mapbox/rasterio/issues/511และgist.github.com/perrygeo/9239b9ab64731cacbb35
Chad Cooper

ประสบการณ์กับ S3 / ถัง แต่โพสต์นี้ไม่อาจจะเป็นที่น่าสนใจ: การเชื่อมโยง ใช้แบบเดียวกัน (?)
cm1

@ 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 ใช้งานได้อย่างมีเสน่ห์! นี่คือตัวอย่างการปลูกพืชจากบรรทัดคำสั่ง btw: gdal_translate --config AWS_REGION "some_region" - ตั้งค่า AWS_ACCESS_KEY_ID "KEY_ID" - ตั้งค่า AWS_SECRET_ACCESS_KEY "ACCESS_KEY" \ -srcwin 000 000 1,000 1,000 \ " from_s3.tif
Skylion

คุณค่าเหล่านั้นที่คุณซ่อนไว้เป็นอย่างไร ฉันคิดว่า KEY_ID เป็นสตริงข้อความสั้น ๆ เช่นชื่อผู้ใช้ ACCESS_KEY คืออะไร ดูเหมือนว่ามันเป็นสิ่งที่อยู่ในไฟล์ pem แต่มีความยาวประมาณ 1,000 ตัวอักษรดังนั้นมันต้องเป็นอย่างอื่น
Solx

สิ่งเหล่านี้จะเป็นเพียงสตริงที่มีตัวเลขและตัวอักษรเช่นชื่อผู้ใช้และรหัสผ่าน คุณสามารถรับสตริงเหล่านั้นได้โดยการตั้งค่าบทบาทของ IAM ใน AWS
RutgerH

10

เนื่องจาก/vsis3/มีการใช้งานใน GDAL คุณจึงสามารถใช้rasterioอ่านชุดข้อมูล Windows S3 ได้ นี้ต้องใช้ทั้งข้อมูลประจำตัวของคุณจะได้รับการตั้งค่าสำหรับBotoหรือใช้ 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 windowed-rwและVSI docs


1

ลองใช้ไฟล์ XML ในการจัดเก็บข้อมูล WMS ในรายละเอียดเพิ่มเติมในเอกสาร GDAL WMS

นี่คือตัวอย่างไฟล์ WMS XML เพื่อดึงข้อมูลจาก 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

ฉันไม่แน่ใจว่าเป็นเพราะจุดสิ้นสุดของ Mapzen API เป็น WMS แบบเรียงต่อกันหรือไม่ แต่โค้ดด้านบนใช้สำหรับฉันภายในไม่กี่นาทีคุณแน่ใจหรือไม่ว่า VSI API จะเร็วขึ้นหรือไม่
clhenrick

เรากำลังทำงานกับ rasters ขนาดใหญ่มากและชุดข้อมูล raster ขนาดใหญ่คอขวดเป็นแน่นอน IO ถังที่เราใช้นั้นเป็นแบบส่วนตัวและต้องการความหมายของข้อมูลรับรองโดยใช้ S3 http API จะไม่ทำงานในกรณีของเรา ไม่ใช่ว่าเราจะต้องอ่านทุกภาพมันเป็นที่เรารู้ว่าเราต้องอึส่วนเล็ก ๆ ของภาพที่มีขนาดใหญ่มาก
Skylion

0

ฉันไม่รู้มากเกี่ยวกับถัง S3 แต่ดูเหมือนว่าเป็นไดรฟ์เก็บข้อมูลบนคลาวด์ที่มีการตรวจสอบสิทธิ์โดยใช้บริการ http REST ie สามารถใช้เป็นจุดติดตั้งทั่วไปที่มี 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.