این راهنما توضیح میدهد که چگونه میتوانید با استفاده از Google Colab به سرعت شروع به صدور پرسوجوها برای Earth Engine REST API از پایتون کنید. همین مفاهیم برای دسترسی به API از زبان ها و محیط های دیگر اعمال می شود.
توجه: REST API دارای ویژگی های جدید و پیشرفته ای است که ممکن است برای همه کاربران مناسب نباشد. اگر با Earth Engine تازه کار هستید، لطفاً با راهنمای جاوا اسکریپت شروع کنید.
قبل از شروع
این دستورالعمل ها را دنبال کنید تا:
- پیکربندی دسترسی Earth Engine
- یک حساب کاربری ایجاد کنید
نوت بوک کولب خود را تنظیم کنید
اگر این شروع سریع را از ابتدا شروع می کنید، می توانید با کلیک بر روی NEW NOTEBOOK از صفحه شروع Colab، یک نوت بوک جدید Colab ایجاد کنید و نمونه کدهای زیر را در سلول کد جدید وارد کنید. Colab قبلاً Cloud SDK را نصب کرده است. این شامل ابزار خط فرمان gcloud
است که میتوانید برای مدیریت سرویسهای Cloud از آن استفاده کنید. یا، نوت بوک دمو را از دکمه ابتدای این صفحه اجرا کنید.
احراز هویت در Google Cloud
اولین کاری که باید انجام دهید این است که وارد شوید تا بتوانید درخواست های احراز هویت شده را به Google Cloud ارسال کنید.
در Colab می توانید اجرا کنید:
PROJECT = 'my-project' !gcloud auth login --project {PROJECT}
(یا اگر به صورت محلی اجرا می کنید، از طریق خط فرمان، با فرض اینکه Cloud SDK را نصب کرده اید:)
PROJECT='my-project' gcloud auth login --project $PROJECT
گزینه ورود با استفاده از حساب کاربری گوگل خود را بپذیرید و مراحل ورود را تکمیل کنید.
یک فایل کلید خصوصی برای حساب سرویس خود دریافت کنید
قبل از اینکه بتوانید از حساب سرویس برای احراز هویت استفاده کنید، باید یک فایل کلید خصوصی را دانلود کنید. برای انجام این کار در Colab، بارگیری در نوت بوک VM:
SERVICE_ACCOUNT='foo-name@project-name.iam.gserviceaccount.com' KEY = 'my-secret-key.json' !gcloud iam service-accounts keys create {KEY} --iam-account {SERVICE_ACCOUNT}
یا به طور متناوب از خط فرمان:
SERVICE_ACCOUNT='foo-name@project-name.iam.gserviceaccount.com' KEY='my-secret-key.json' gcloud iam service-accounts keys create $KEY --iam-account $SERVICE_ACCOUNT
دسترسی و آزمایش اعتبار شما
اکنون آماده ارسال اولین درخواست خود به Earth Engine API هستید. از کلید خصوصی برای دریافت اعتبار استفاده کنید. از اعتبارنامه ها برای ایجاد یک جلسه مجاز برای درخواست HTTP استفاده کنید. می توانید این را در سلول کد جدید نوت بوک Colab خود وارد کنید. (اگر از خط فرمان استفاده می کنید، باید از نصب کتابخانه های لازم اطمینان حاصل کنید).
from google.auth.transport.requests import AuthorizedSession from google.oauth2 import service_account credentials = service_account.Credentials.from_service_account_file(KEY) scoped_credentials = credentials.with_scopes( ['https://www.googleapis.com/auth/cloud-platform']) session = AuthorizedSession(scoped_credentials) url = 'https://earthengine.googleapis.com/v1alpha/projects/earthengine-public/assets/LANDSAT' response = session.get(url) from pprint import pprint import json pprint(json.loads(response.content))
اگر همه چیز به درستی پیکربندی شده باشد، با اجرای آن خروجی به شکل زیر تولید می شود:
{'id': 'LANDSAT',
'name': 'projects/earthengine-public/assets/LANDSAT',
'type': 'FOLDER'}
یک مجموعه داده را انتخاب کنید
میتوانید مجموعه دادههای موجود را با استفاده از ویرایشگر کد Earth Engine در code.earthengine.google.com جستجو و کاوش کنید. بیایید به دنبال برخی از داده های Sentinel 2 باشیم. (اگر این اولین باری است که از ویرایشگر کد استفاده میکنید، از شما خواسته میشود که هنگام ورود به سیستم، مجوز دسترسی به Earth Engine را از طرف شما صادر کنید.) در ویرایشگر کد، «سنتینل» را در کادر جستجو در بالا جستجو کنید. چندین مجموعه داده شطرنجی ظاهر می شود:

روی "Sentinel-2: MultiSpectral Instrument (MSI), Level-1C" کلیک کنید:

صفحات شرح مجموعه داده مانند این شامل اطلاعات مهمی است که برای استفاده از هر مجموعه داده در کاتالوگ داده های عمومی Earth Engine نیاز دارید، از جمله شرح مختصری از مجموعه داده، پیوندهایی به ارائه دهنده داده برای دریافت جزئیات بیشتر، اطلاعات مربوط به هرگونه محدودیت استفاده که ممکن است برای مجموعه داده اعمال شود، و شناسه دارایی Earth Engine مجموعه داده.
در این حالت در سمت راست پنجره می بینیم که این یک دارایی مجموعه تصویر است که مسیر آن COPERNICUS/S2
است.
پرس و جو برای تصاویر خاص
این مجموعه داده Sentinel-2 شامل بیش از دو میلیون تصویر است که جهان را از سال 2015 تا کنون پوشش می دهد. بیایید یک درخواست projects.assets.listImages در برابر مجموعه تصاویر صادر کنیم تا برخی از دادههای آوریل 2017 را با پوشش ابری کم که شامل نقطه خاصی در Mountain View، کالیفرنیا است، پیدا کنیم.
import urllib coords = [-122.085, 37.422] project = 'projects/earthengine-public' asset_id = 'COPERNICUS/S2' name = '{}/assets/{}'.format(project, asset_id) url = 'https://earthengine.googleapis.com/v1alpha/{}:listImages?{}'.format( name, urllib.parse.urlencode({ 'startTime': '2017-04-01T00:00:00.000Z', 'endTime': '2017-05-01T00:00:00.000Z', 'region': '{"type":"Point", "coordinates":' + str(coords) + '}', 'filter': 'CLOUDY_PIXEL_PERCENTAGE < 10', })) response = session.get(url) content = response.content for asset in json.loads(content)['images']: id = asset['id'] cloud_cover = asset['properties']['CLOUDY_PIXEL_PERCENTAGE'] print('%s : %s' % (id, cloud_cover))
این اسکریپت مجموعه را برای تصاویر منطبق جستجو می کند، پاسخ JSON حاصل را رمزگشایی می کند و شناسه دارایی و پوشش ابری را برای هر دارایی تصویر منطبق چاپ می کند. خروجی باید به شکل زیر باشد:
COPERNICUS/S2/20170420T184921_20170420T190203_T10SEG : 4.3166
COPERNICUS/S2/20170430T190351_20170430T190351_T10SEG : 0
ظاهراً دو تصویر از این نقطه وجود دارد که در این ماه گرفته شده اند و دارای پوشش ابری کم هستند.
یک تصویر خاص را بررسی کنید
به نظر می رسد که یکی از موارد مشابه اساساً پوشش ابری صفر دارد. بیایید نگاهی دقیقتر به آن دارایی بیندازیم که شناسه آن COPERNICUS/S2/20170430T190351_20170430T190351_T10SEG
است. توجه داشته باشید که تمام دارایی های کاتالوگ عمومی متعلق به پروژه earthengine-public
است. در اینجا یک قطعه Python است که یک درخواست projects.assets.get برای واکشی جزئیات آن دارایی خاص توسط ID، چاپ باندهای داده موجود و چاپ اطلاعات دقیق تر در مورد باند اول صادر می کند:
asset_id = 'COPERNICUS/S2/20170430T190351_20170430T190351_T10SEG' name = '{}/assets/{}'.format(project, asset_id) url = 'https://earthengine.googleapis.com/v1alpha/{}'.format(name) response = session.get(url) content = response.content asset = json.loads(content) print('Band Names: %s' % ','.join(band['id'] for band in asset['bands'])) print('First Band: %s' % json.dumps(asset['bands'][0], indent=2, sort_keys=True))
خروجی باید چیزی شبیه به این باشد:
Band Names: B1,B2,B3,B4,B5,B6,B7,B8,B8A,B9,B10,B11,B12,QA10,QA20,QA60
First Band: {
"dataType": {
"precision": "INTEGER",
"range": {
"max": 65535
}
},
"grid": {
"affineTransform": {
"scaleX": 60,
"scaleY": -60,
"translateX": 499980,
"translateY": 4200000
},
"crsCode": "EPSG:32610",
"dimensions": {
"height": 1830,
"width": 1830
}
},
"id": "B1",
"pyramidingPolicy": "MEAN"
}
لیست باندهای داده با آنچه قبلاً در توضیحات مجموعه داده دیدیم مطابقت دارد. میتوانیم ببینیم که این مجموعه دادههای 16 بیتی در سیستم مختصات EPSG:32610 یا UTM Zone 10N دارد. این باند اول دارای شناسه B1
و وضوح 60 متر در هر پیکسل است. مبدا تصویر در موقعیت (499980,4200000) در این سیستم مختصات است.
مقدار منفی affineTransform.scaleY
نشان می دهد که مبدأ در گوشه شمال غربی تصویر است، همانطور که معمولاً اتفاق می افتد: افزایش شاخص های پیکسل y
با کاهش مختصات فضایی y
(به سمت جنوب) مطابقت دارد.
واکشی مقادیر پیکسل
بیایید یک درخواست projects.assets.getPixels برای واکشی برخی از دادهها از باندهای وضوح بالای این تصویر صادر کنیم. صفحه توضیحات مجموعه داده می گوید که باندهای B2
، B3
، B4
و B8
دارای وضوح 10 متر در هر پیکسل هستند. این اسکریپت کاشی 256x256 پیکسل بالای سمت چپ داده ها را از آن چهار باند واکشی می کند. بارگیری داده ها در قالب numpy
NPY رمزگشایی پاسخ را در آرایه داده پایتون آسان می کند.
import numpy import io name = '{}/assets/{}'.format(project, asset_id) url = 'https://earthengine.googleapis.com/v1alpha/{}:getPixels'.format(name) body = json.dumps({ 'fileFormat': 'NPY', 'bandIds': ['B2', 'B3', 'B4', 'B8'], 'grid': { 'affineTransform': { 'scaleX': 10, 'scaleY': -10, 'translateX': 499980, 'translateY': 4200000, }, 'dimensions': {'width': 256, 'height': 256}, }, }) pixels_response = session.post(url, body) pixels_content = pixels_response.content array = numpy.load(io.BytesIO(pixels_content)) print('Shape: %s' % (array.shape,)) print('Data:') print(array)
خروجی باید به شکل زیر باشد:
Shape: (256, 256)
Data:
[[( 899, 586, 351, 189) ( 918, 630, 501, 248) (1013, 773, 654, 378) ...,
(1014, 690, 419, 323) ( 942, 657, 424, 260) ( 987, 691, 431, 315)]
[( 902, 630, 541, 227) (1059, 866, 719, 429) (1195, 922, 626, 539) ...,
( 978, 659, 404, 287) ( 954, 672, 426, 279) ( 990, 678, 397, 304)]
[(1050, 855, 721, 419) (1257, 977, 635, 569) (1137, 770, 400, 435) ...,
( 972, 674, 421, 312) (1001, 688, 431, 311) (1004, 659, 378, 284)]
...,
[( 969, 672, 375, 275) ( 927, 680, 478, 294) (1018, 724, 455, 353) ...,
( 924, 659, 375, 232) ( 921, 664, 438, 273) ( 966, 737, 521, 306)]
[( 920, 645, 391, 248) ( 979, 728, 481, 327) ( 997, 708, 425, 324) ...,
( 927, 673, 387, 243) ( 927, 688, 459, 284) ( 962, 732, 509, 331)]
[( 978, 723, 449, 330) (1005, 712, 446, 314) ( 946, 667, 393, 269) ...,
( 949, 692, 413, 271) ( 927, 689, 472, 285) ( 966, 742, 516, 331)]]
برای انتخاب مجموعه ای متفاوت از پیکسل ها از این تصویر، کافی است affineTransform
بر این اساس مشخص کنید. به یاد داشته باشید که affineTransform
در سیستم مرجع مختصات فضایی تصویر مشخص شده است. اگر می خواهید مکان مبدا را در مختصات پیکسل تنظیم کنید، از این فرمول ساده استفاده کنید:
request_origin = image_origin + pixel_scale * offset_in_pixels
ایجاد یک تصویر بند انگشتی
ما میتوانیم از مکانیزم مشابهی برای تولید یک تصویر کوچک RGB از این تصویر استفاده کنیم. به جای درخواست داده با وضوح اصلی آن، یک منطقه و ابعاد تصویر را به صراحت مشخص می کنیم. برای به دست آوردن یک تصویر کوچک از کل تصویر، می توانیم از هندسه ردپای تصویر به عنوان منطقه درخواست استفاده کنیم. در نهایت، با تعیین نوارهای تصویر قرمز، سبز و آبی و محدوده مناسبی از مقادیر داده، می توانیم یک تصویر کوچک RGB جذاب به دست آوریم.
با کنار هم گذاشتن همه اینها، قطعه پایتون به این شکل است (با استفاده از ویجت نمایش تصویر Colab IPython
):
url = 'https://earthengine.googleapis.com/v1alpha/{}:getPixels'.format(name) body = json.dumps({ 'fileFormat': 'PNG', 'bandIds': ['B4', 'B3', 'B2'], 'region': asset['geometry'], 'grid': { 'dimensions': {'width': 256, 'height': 256}, }, 'visualizationOptions': { 'ranges': [{'min': 0, 'max': 3000}], }, }) image_response = session.post(url, body) image_content = image_response.content from IPython.display import Image Image(image_content)
در اینجا تصویر بند انگشتی حاصل آمده است:
