ক্লাউড জিওটিফ-ব্যাকড আর্থ ইঞ্জিন সম্পদ

আর্থ ইঞ্জিন ক্লাউড অপটিমাইজড জিওটিফ (COG) দ্বারা সমর্থিত অ্যাসেটসমূহকে সাপোর্ট করে। COG-সমর্থিত অ্যাসেটের একটি সুবিধা হলো, অ্যাসেট তৈরির সময়েই ইমেজের স্থানিক এবং মেটাডেটা ফিল্ডগুলো ইনডেক্স করা হয়, যা কালেকশনে ইমেজটিকে আরও বেশি পারফর্ম্যান্ট করে তোলে। সাধারণ ব্যবহারের ক্ষেত্রে, COG-সমর্থিত অ্যাসেটের পারফরম্যান্স ইনজেস্ট করা অ্যাসেটের পারফরম্যান্সের সাথে তুলনীয়।

উল্লেখ্য যে, একটি একক অ্যাসেট একাধিক COG দ্বারা সমর্থিত হতে পারে (উদাহরণস্বরূপ, প্রতিটি ব্যান্ডের জন্য একটি করে COG থাকতে পারে)। তবে, একটি একক ব্যান্ডের জন্য অনেকগুলো COG টাইল ব্যবহার করা সমর্থিত নয়।

(বিকল্পভাবে, আর্থ ইঞ্জিন সরাসরি গুগল ক্লাউড স্টোরেজের COG থেকে ছবি লোড করতে পারে ( আরও জানুন )। তবে, ee.Image.loadGeoTIFF মাধ্যমে লোড করা এবং কোনো ইমেজ কালেকশনে যোগ করা ছবির ওপর ফিল্টারিং অপারেশন চালানোর জন্য সেটির GeoTiff ফাইলটি পড়ার প্রয়োজন হবে।)

COG-সমর্থিত সম্পদ তৈরি করতে,

  1. আপনার COG ফাইলগুলি একটি GCS বাকেটে রাখুন (অনুমোদিত অঞ্চলগুলির জন্য অবস্থান দেখুন)।
  2. একটি ছবি আপলোড ম্যানিফেস্ট লিখুন
  3. আপলোড কমান্ড পাঠাতে earthengine কমান্ড-লাইন ইউটিলিটি ব্যবহার করুন:
earthengine upload external_image --manifest my_manifest.json

একটি Tileset সহ নমুনা চিত্র ম্যানিফেস্ট

সবচেয়ে সরল ImageManifest হলো সেটি, যাতে একটিমাত্র Tileset থাকে। যদি কোনো ব্যান্ড নির্দিষ্ট করা না থাকে, তাহলে ফলাফলস্বরূপ অ্যাসেটটিতে GeoTIFF-এর সমস্ত ব্যান্ড থাকবে এবং ব্যান্ডের নামগুলো GeoTIFF-এ এনকোড করা থাকবে (এই ক্ষেত্রে, "vis-red", "vis-green", এবং "vis-blue")।

request = {
  'imageManifest': {
    'name': f'projects/{ee_project}/assets/cogdemo1',
    'tilesets': [
      { 'id': '0', 'sources': [ { 'uris': [
        'gs://ee-docs-demos/COG_demo.tif'] } ] }
    ],
    'properties': {
      'version': '1.1'
    },
    'startTime': '2016-01-01T00:00:00.000000000Z',
    'endTime': '2016-12-31T15:01:23.000000000Z',
  },
}

pprint(request)

একাধিক Tileset

tilesetId এবং tilesetBandIndex ফিল্ড ব্যবহার করে একটি ImageManifest এ একাধিক Tileset নির্দিষ্ট করা সম্ভব, যেখানে ফলাফলস্বরূপ অ্যাসেটের প্রতিটি ব্যান্ড একটি Tileset এর কোনো একটি ব্যান্ডের দ্বারা সমর্থিত হয়। এটি তখন উপযোগী হয় যখন বিভিন্ন ব্যান্ডের রেজোলিউশন বা ডেটা টাইপ ভিন্ন হয়। যেকোনো উপলব্ধ Tileset থেকে ব্যান্ডগুলোকে যেকোনো ক্রমে তালিকাভুক্ত করা যেতে পারে। নিম্নলিখিত উদাহরণে:

  • "b4b3b2.tif"-এর স্কেল ১০ মিটার, অপরদিকে "b5b6b7"-এর স্কেল ২০ মিটার।
  • ফলাফলস্বরূপ অ্যাসেটটির ব্যান্ড ক্রম ইনপুট COG-গুলো থেকে মিশ্রিত করা হয় (যেমন, আউটপুট ব্যান্ড ০ Tileset ০ থেকে এবং আউটপুট ব্যান্ড ১ Tileset ১ থেকে আসে)।
request = {
  'imageManifest': {
    'name': f'projects/{ee_project}/assets/cogdemo2',
    'uriPrefix': 'gs://ee-docs-demos/external_image_demo/',
    'tilesets': [
      { 'id': '0', 'sources': [ { 'uris': ['b4b3b2.tif'] } ] },
      { 'id': '1', 'sources': [ { 'uris': ['b5b6b7.tif'] } ] },
    ],
    'bands': [
      { 'id': 'red', 'tilesetId': '0', 'tilesetBandIndex': 0 },
      { 'id': 'rededge3', 'tilesetId': '1', 'tilesetBandIndex': 2 },
      { 'id': 'rededge2', 'tilesetId': '1', 'tilesetBandIndex': 1 },
      { 'id': 'green', 'tilesetId': '0', 'tilesetBandIndex': 1 },
      { 'id': 'blue', 'tilesetId': '1', 'tilesetBandIndex': 0 },
      { 'id': 'rededge1', 'tilesetId': '0', 'tilesetBandIndex': 2 },
    ],
  },
}

pprint(request)

COG-সমর্থিত সম্পদ সম্পর্কিত বিশদ বিবরণ

অবস্থান

ক্লাউড স্টোরেজ বাকেটের অবস্থান অবশ্যই নিম্নলিখিতগুলির মধ্যে একটি হতে হবে:

  • মার্কিন যুক্তরাষ্ট্রের বহু-অঞ্চল
  • যেকোনো মার্কিন দ্বৈত-অঞ্চল যাতে ইউএস-সেন্ট্রাল১ অন্তর্ভুক্ত আছে
  • অঞ্চল US-CENTAL1

স্টোরেজ ক্লাস

বাকেটটির স্টোরেজ ক্লাস অবশ্যই 'স্ট্যান্ডার্ড স্টোরেজ' হতে হবে।

শেয়ার করার অনুমতি

COG-সমর্থিত আর্থ ইঞ্জিন অ্যাসেট এবং এর অন্তর্নিহিত ডেটার ACL আলাদাভাবে পরিচালিত হয়। সহযোগীদের সাথে পড়ার জন্য COG-সমর্থিত অ্যাসেট শেয়ার করার সময়, আর্থ ইঞ্জিন অ্যাসেট এবং এর অন্তর্নিহিত COG ফাইল উভয় ক্ষেত্রেই রিড অ্যাক্সেস দেওয়া হয়েছে কিনা, তা নিশ্চিত করার দায়িত্ব মালিকের।

১. গুগল ক্লাউড স্টোরেজ বাকেটকে পড়ার অনুমতি দিন।

সহযোগীদের COG-সমর্থিত অ্যাসেটগুলো পড়ার জন্য, তাদের প্রথমে Google Cloud Storage বাকেটে থাকা অন্তর্নিহিত COG ফাইলগুলোতে রিড অ্যাক্সেস থাকতে হবে। এই অনুমতিগুলো ছাড়া, Earth Engine তাদের জন্য ডেটা পুনরুদ্ধার করতে পারবে না। যদি Google Cloud Storage-এর ডেটা কোনো Earth Engine ব্যবহারকারীর কাছে দৃশ্যমান না হয়, তাহলে Earth Engine "Failed to load the GeoTIFF at gs://my-bucket/my-object#123456 " এই ধরনের একটি এরর দেখাবে (যেখানে 123456 হলো অবজেক্টটির জেনারেশন)।

বিশেষত, সহযোগীদের নিম্নলিখিত অনুমতিগুলো থাকতে হবে:

  • বাকেটের মেটাডেটা ও অবস্থান পুনরুদ্ধার করতে এবং আর্থ ইঞ্জিনকে অ্যাসেটের উৎস সঠিকভাবে নির্ণয় করতে সাহায্য করার জন্য বাকেটটিতে storage.buckets.get ব্যবহার করুন।
  • বাকেটের উপর storage.objects.get করুন (প্রকৃত COG-সমর্থিত অ্যাসেট ডেটা পড়ার জন্য)।

এই অনুমতিগুলো অন্যান্য রোলের পাশাপাশি যথাক্রমে 'Storage Legacy Bucket Reader' এবং 'Storage Legacy Object Reader' রোল দ্বারা প্রদান করা হয়।

সহযোগীদের এই ভূমিকাগুলো অর্পণ করতে:

  1. বাকেট পারমিশন পেজে যান: https://console.cloud.google.com/storage/browser/{MY-BUCKET};tab=permissions
  2. " অ্যাক্সেস দিন " এ ক্লিক করুন
  3. যাদের পঠন অ্যাক্সেস দেওয়া উচিত, সেই সমস্ত প্রিন্সিপালদের (যেমন, ব্যবহারকারী, গ্রুপ, পরিষেবা অ্যাকাউন্ট) যুক্ত করুন।
  4. নিম্নলিখিত ভূমিকাগুলি অর্পণ করুন:
    • "স্টোরেজ লিগ্যাসি বাকেট রিডার" (যা storage.buckets.get এবং অন্যান্য বাকেট-স্তরের পঠন অনুমতি প্রদান করে)।
    • "স্টোরেজ লিগ্যাসি অবজেক্ট রিডার" (যা storage.objects.get প্রদান করে)।
    • (বিকল্পভাবে, আপনি শুধু storage.buckets.get এবং storage.objects.get পারমিশনসহ একটি নতুন কাস্টম রোল তৈরি করে সেটি অ্যাসাইন করতে পারেন।)
  5. সংরক্ষণ করুন

২. পড়ার জন্য আর্থ ইঞ্জিন অ্যাসেটটি শেয়ার করুন।

আপনার সহযোগীদের মূল GCS বাকেট এবং অবজেক্টগুলিতে প্রয়োজনীয় অনুমতি আছে কিনা তা নিশ্চিত করার পর, আপনাকে অবশ্যই আর্থ ইঞ্জিন অ্যাসেটটিও শেয়ার করতে হবে। আর্থ ইঞ্জিন অ্যাসেটের অনুমতি নির্ধারণ সম্পর্কে আরও তথ্যের জন্য, আর্থ ইঞ্জিন অ্যাসেট ম্যানেজমেন্ট গাইডটি দেখুন।

প্রজন্ম

যখন একটি COG-সমর্থিত অ্যাসেট তৈরি করা হয়, তখন আর্থ ইঞ্জিন ম্যানিফেস্টে উল্লেখিত TIFF-গুলোর মেটাডেটা পড়ে এবং একটি অ্যাসেট স্টোর এন্ট্রি তৈরি করে। সেই এন্ট্রির সাথে যুক্ত প্রতিটি URI-এর একটি জেনারেশন থাকতে পারে। জেনারেশন সম্পর্কে বিস্তারিত জানতে অবজেক্ট ভার্সনিং ডক্স দেখুন। যদি একটি জেনারেশন উল্লেখ করা থাকে, উদাহরণস্বরূপ gs://foo/bar#123 , তাহলে আর্থ ইঞ্জিন সেই URI-টি হুবহু সংরক্ষণ করবে। যদি কোনো জেনারেশন উল্লেখ না করা থাকে, তাহলে আর্থ ইঞ্জিন ImportExternalImage কল করার সময়কার TIFF-এর জেনারেশনসহ সেই URI-টি সংরক্ষণ করবে।

এর মানে হলো, GCS-এ থাকা কোনো এক্সটার্নাল অ্যাসেটের অন্তর্ভুক্ত TIFF ফাইল যদি আপডেট করা হয় (যার ফলে এর জেনারেশন পরিবর্তিত হয়), তাহলে Earth Engine একটি "Failed to load the GeoTIFF at gs://my-bucket/my-object#123456 " এরর দেখাবে, কারণ প্রত্যাশিত অবজেক্টটি আর বিদ্যমান থাকবে না (যদি না বাকেটটিতে একাধিক অবজেক্ট ভার্সন ব্যবহারের সুবিধা থাকে)। এই পলিসিটি অ্যাসেটের মেটাডেটাকে অবজেক্টের মেটাডেটার সাথে সিঙ্ক করে রাখার জন্য ডিজাইন করা হয়েছে।

কনফিগারেশন

একটি COG যেভাবে কনফিগার করা উচিত, সেই অনুযায়ী TIFF ফাইলটি অবশ্যই নিম্নরূপ হতে হবে:

  • টাইল করা, যেখানে টাইলের মাপগুলো হলো:

    • ২৫৬x২৫৬
    • ৫১২x৫১২
    • ১০২৪x১০২৪
    • ২০৪৮x২০৪৮
  • এমনভাবে সাজানো হয়েছে যাতে সমস্ত IFD শুরুতে থাকে।

সর্বোত্তম পারফরম্যান্সের জন্য:

  • ৫১২x৫১২ বা তার চেয়ে বড় মাপের টাইল ব্যবহার করুন।
  • ঘাত ২ এর সংক্ষিপ্ত বিবরণ অন্তর্ভুক্ত করুন।

আপনার উদ্দিষ্ট ব্যবহারের ধরনের ওপর নির্ভর করে, 'ইন্টারলিভ' তৈরির বিকল্পটি পারফরম্যান্সকে প্রভাবিত করতে পারে। আমরা সব পরিস্থিতিতে ব্যান্ড ইন্টারলিভ ব্যবহার করার পরামর্শ দিই।

সর্বোত্তম কনফিগারেশন সম্পর্কে আরও বিস্তারিত জানতে এই পৃষ্ঠাটি দেখুন।

নিম্নলিখিত gdal_translate কমান্ডটি একটি রাস্টারকে ব্যান্ড-ইন্টারলিভড, zstd-কম্প্রেসড, ক্লাউড অপটিমাইজড GeoTIFF-এ রূপান্তর করবে যা আর্থ ইঞ্জিনে (Earth Engine) ভালোভাবে কাজ করবে:

gdal_translate in.tif out.tif \
  -co COPY_SRC_OVERVIEWS=YES \
  -co TILED=YES \
  -co BLOCKXSIZE=512 \
  -co BLOCKYSIZE=512 \
  -co COMPRESS=ZSTD \
  -co ZSTD_LEVEL=22 \
  -co INTERLEAVE=BAND \
  -co NUM_THREADS=ALL_CPUS

একটি প্রেডিক্টর নির্দিষ্ট করে আউটপুট ফাইলের আকার আরও কমানো যেতে পারে (পূর্ণসংখ্যা ডেটা টাইপের জন্য -co PREDICTOR=2 এবং ফ্লোটিং পয়েন্ট ডেটা টাইপের জন্য -co PREDICTOR=3 )।

GDAL >= 3.11 ব্যবহারকারীদের জন্য, COG ড্রাইভার ওভারভিউ তৈরি এবং সংরক্ষণ করার বিষয়ে চিন্তা না করেই ফাইল তৈরি করতে পারে।

gdal_translate in.tif out.tif \
  -of COG \
  -co OVERVIEWS=IGNORE_EXISTING \
  -co COMPRESS=ZSTD \
  -co LEVEL=22 \
  -co PREDICTOR=2 \
  -co INTERLEAVE=BAND \
  -co NUM_THREADS=ALL_CPUS \

REST API ব্যবহার করে ক্লাউড জিওটিফ-সমর্থিত অ্যাসেট তৈরি করা

দ্রষ্টব্য: REST API-তে নতুন এবং উন্নত বৈশিষ্ট্য রয়েছে যা সকল ব্যবহারকারীর জন্য উপযুক্ত নাও হতে পারে। আপনি যদি Earth Engine-এ নতুন হন, তাহলে আমরা জাভাস্ক্রিপ্ট গাইড দিয়ে শুরু করার পরামর্শ দিই।

REST API ব্যবহার করে একটি COG-সমর্থিত অ্যাসেট তৈরি করতে, Earth Engine-এর ImportExternalImage এন্ডপয়েন্টে একটি POST রিকোয়েস্ট পাঠান। নিচে যেমন দেখানো হয়েছে, আপনার ইউজার ফোল্ডারে অ্যাসেট তৈরি করার জন্য এই রিকোয়েস্টটির অনুমোদন থাকতে হবে।

একটি অনুমোদিত সেশন শুরু করুন

আপনার ইউজার ফোল্ডারে একটি আর্থ ইঞ্জিন অ্যাসেট তৈরি করতে হলে, অনুরোধ করার সময় আপনাকে নিজের পরিচয়ে প্রমাণীকরণ করতে হবে। আপনি আর্থ ইঞ্জিন অথেন্টিকেটর থেকে ক্রেডেনশিয়াল ব্যবহার করে একটি AuthorizedSession শুরু করতে পারেন। এরপর আপনি সেই AuthorizedSession ব্যবহার করে আর্থ ইঞ্জিনে অনুরোধ পাঠাতে পারবেন।

import ee
import json
from pprint import pprint
from google.auth.transport.requests import AuthorizedSession

ee.Authenticate()  #  or !earthengine authenticate --auth_mode=gcloud

# Specify the cloud project you want associated with Earth Engine requests.
ee_project = 'your-project'

session = AuthorizedSession(
    ee.data.get_persistent_credentials().with_quota_project(ee_project)
)

অনুরোধকারী শরীর

অনুরোধের মূল অংশটি একটি ImageManifest এর ইনস্ট্যান্স। এখানেই COG-এর পাথ এবং অন্যান্য প্রয়োজনীয় প্রোপার্টিগুলো নির্দিষ্ট করা থাকে।

একটি ImageManifest কীভাবে কনফিগার করতে হয়, তার বিস্তারিত জানতে এই নির্দেশিকাটি দেখুন। এক বা একাধিক Tileset সংজ্ঞায়িত করা সম্ভব, যার প্রতিটির পেছনে এক বা একাধিক ব্যান্ড থাকতে পারে। ImportExternalImage এর ক্ষেত্রে, প্রতি Tileset এ সর্বাধিক একটি ImageSource সমর্থিত।

COG রপ্তানি করার বিস্তারিত তথ্যের জন্য এই ডকুমেন্টটি দেখুন।

অনুরোধ পাঠান

Earth Engine projects.images.importExternal এন্ডপয়েন্টে POST রিকোয়েস্টটি পাঠান।

url = f'https://earthengine.googleapis.com/v1alpha/projects/{ee_project}/image:importExternal'

response = session.post(
  url = url,
  data = json.dumps(request)
)

pprint(json.loads(response.content))