Hướng dẫn này giải thích cách bạn có thể nhanh chóng bắt đầu đưa ra các truy vấn cho Earth Engine REST API từ Python bằng cách sử dụng Google Colab. Các khái niệm tương tự cũng áp dụng cho việc truy cập vào API từ các ngôn ngữ và môi trường khác.
Lưu ý: REST API có các tính năng mới và nâng cao có thể không phù hợp với một số người dùng. Nếu bạn mới sử dụng Earth Engine, vui lòng bắt đầu bằng hướng dẫn về JavaScript.
Trước khi bắt đầu
Hãy làm theo các hướng dẫn này để:
- Định cấu hình quyền truy cập vào Earth Engine
- Tạo một tài khoản dịch vụ
Thiết lập sổ tay Colab
Nếu bắt đầu hướng dẫn nhanh này từ đầu, bạn có thể tạo một sổ tay Colab mới bằng cách nhấp vào SỔ TAY MỚI trên trang bắt đầu của Colab rồi nhập các mẫu mã bên dưới vào một ô mã mới. Colab đã cài đặt Cloud SDK. Trong đó có công cụ dòng lệnh gcloud
mà bạn có thể dùng để quản lý các dịch vụ trên đám mây. Ngoài ra, hãy chạy sổ tay minh hoạ bằng cách nhấp vào nút ở đầu trang này.
Xác thực với Google Cloud
Điều đầu tiên cần làm là đăng nhập để bạn có thể đưa ra các yêu cầu đã xác thực cho Google Cloud.
Trong Colab, bạn có thể chạy:
PROJECT = 'my-project' !gcloud auth login --project {PROJECT}
(Hoặc nếu bạn đang chạy cục bộ, từ dòng lệnh, giả sử bạn đã cài đặt Cloud SDK:)
PROJECT='my-project' gcloud auth login --project $PROJECT
Chấp nhận lựa chọn đăng nhập bằng tài khoản người dùng Google của bạn và hoàn tất quy trình đăng nhập.
Lấy tệp khoá riêng tư cho tài khoản dịch vụ của bạn
Trước khi có thể dùng tài khoản dịch vụ để xác thực, bạn phải tải một tệp khoá riêng tư xuống. Để thực hiện việc đó trong Colab, hãy tải xuống máy ảo của sổ tay:
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}
Hoặc từ dòng lệnh:
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
Truy cập và kiểm thử thông tin đăng nhập
Giờ đây, bạn đã sẵn sàng gửi truy vấn đầu tiên đến Earth Engine API. Sử dụng khoá riêng tư để lấy thông tin xác thực. Sử dụng thông tin xác thực để tạo một phiên được uỷ quyền nhằm thực hiện các yêu cầu HTTP. Bạn có thể nhập mã này vào một ô mã mới trong sổ tay Colab. (Nếu đang sử dụng dòng lệnh, bạn cần đảm bảo rằng các thư viện cần thiết đã được cài đặt).
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))
Nếu bạn định cấu hình mọi thứ một cách chính xác, thì khi chạy lệnh này, bạn sẽ nhận được kết quả như sau:
{'id': 'LANDSAT',
'name': 'projects/earthengine-public/assets/LANDSAT',
'type': 'FOLDER'}
Chọn một tập dữ liệu
Bạn có thể tìm kiếm và khám phá các tập dữ liệu hiện có bằng Trình chỉnh sửa mã Earth Engine tại code.earthengine.google.com. Hãy tìm một số dữ liệu Sentinel 2. (Nếu đây là lần đầu tiên sử dụng Trình chỉnh sửa mã, bạn sẽ được nhắc cho phép trình chỉnh sửa này truy cập vào Earth Engine thay cho bạn khi bạn đăng nhập.) Trong Trình chỉnh sửa mã, hãy tìm "sentinel" trong hộp tìm kiếm ở trên cùng. Một số tập dữ liệu raster xuất hiện:

Nhấp vào "Sentinel-2: MultiSpectral Instrument (MSI), Level-1C" (Sentinel-2: Thiết bị đa phổ (MSI), Cấp 1C):

Các trang mô tả tập dữ liệu như trang này cung cấp thông tin quan trọng mà bạn cần để sử dụng bất kỳ tập dữ liệu nào trong Danh mục dữ liệu công khai của Earth Engine, bao gồm cả nội dung mô tả ngắn về tập dữ liệu, đường liên kết đến nhà cung cấp dữ liệu để biết thêm thông tin chi tiết, thông tin về mọi hạn chế sử dụng có thể áp dụng cho tập dữ liệu và mã nhận dạng tài sản Earth Engine của tập dữ liệu.
Trong trường hợp này, ở bên phải cửa sổ, chúng ta thấy đây là một thành phần bộ sưu tập hình ảnh có đường dẫn là COPERNICUS/S2
.
Truy vấn cho hình ảnh cụ thể
Tập dữ liệu Sentinel-2 này bao gồm hơn 2 triệu hình ảnh bao phủ toàn thế giới từ năm 2015 đến nay. Hãy đưa ra truy vấn projects.assets.listImages đối với bộ sưu tập hình ảnh để tìm một số dữ liệu từ tháng 4 năm 2017, có độ che phủ của mây thấp, bao gồm một điểm cụ thể ở Mountain View, California.
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))
Tập lệnh này truy vấn tập hợp để tìm hình ảnh phù hợp, giải mã phản hồi JSON thu được và in mã nhận dạng tài sản cũng như độ che phủ của đám mây cho từng tài sản hình ảnh phù hợp. Kết quả đầu ra sẽ có dạng như sau:
COPERNICUS/S2/20170420T184921_20170420T190203_T10SEG : 4.3166
COPERNICUS/S2/20170430T190351_20170430T190351_T10SEG : 0
Rõ ràng là có 2 hình ảnh về điểm này được chụp trong tháng này và có độ che phủ mây thấp.
Kiểm tra một hình ảnh cụ thể
Có vẻ như một trong các kết quả trùng khớp gần như không có mây. Hãy xem xét kỹ hơn thành phần đó, có mã nhận dạng là COPERNICUS/S2/20170430T190351_20170430T190351_T10SEG
. Xin lưu ý rằng tất cả thành phần danh mục công khai đều thuộc dự án earthengine-public
. Sau đây là một đoạn mã Python sẽ đưa ra truy vấn projects.assets.get để tìm nạp thông tin chi tiết của tài sản cụ thể đó theo mã nhận dạng, in các dải dữ liệu có sẵn và in thông tin chi tiết hơn về dải dữ liệu đầu tiên:
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))
Kết quả đầu ra sẽ có dạng như sau:
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"
}
Danh sách các dải dữ liệu tương ứng với những gì chúng ta thấy trước đó trong phần mô tả tập dữ liệu. Chúng ta có thể thấy rằng tập dữ liệu này có dữ liệu số nguyên 16 bit trong hệ toạ độ EPSG:32610 hoặc UTM Zone 10N. Dải tần đầu tiên có mã nhận dạng là B1
và độ phân giải là 60 mét/pixel. Điểm gốc của hình ảnh nằm ở vị trí (499980,4200000) trong hệ toạ độ này.
Giá trị âm của affineTransform.scaleY
cho biết nguồn gốc nằm ở góc tây bắc của hình ảnh, như thường lệ: chỉ số pixel y
tăng tương ứng với toạ độ không gian y
giảm (hướng về phía nam).
Tìm nạp giá trị pixel
Hãy đưa ra một truy vấn projects.assets.getPixels để tìm nạp một số dữ liệu từ các dải tần có độ phân giải cao của hình ảnh này. Trang mô tả tập dữ liệu cho biết các dải tần B2
, B3
, B4
và B8
có độ phân giải 10 mét trên mỗi pixel. Tập lệnh này tìm nạp ô dữ liệu 256x256 pixel ở trên cùng bên trái từ 4 dải tần đó. Việc tải dữ liệu ở định dạng numpy
NPY giúp bạn dễ dàng giải mã phản hồi thành một mảng dữ liệu Python.
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)
Kết quả đầu ra sẽ có dạng như sau:
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)]]
Để chọn một nhóm pixel khác trong hình ảnh này, bạn chỉ cần chỉ định affineTransform
cho phù hợp. Hãy nhớ rằng affineTransform
được chỉ định trong hệ thống tham chiếu toạ độ không gian của hình ảnh; nếu bạn muốn điều chỉnh vị trí của nguồn gốc theo toạ độ pixel, hãy sử dụng công thức đơn giản sau:
request_origin = image_origin + pixel_scale * offset_in_pixels
Tạo hình thu nhỏ
Chúng ta có thể sử dụng một cơ chế tương tự để tạo hình thu nhỏ RGB của hình ảnh này. Thay vì yêu cầu dữ liệu ở độ phân giải gốc, chúng ta sẽ chỉ định rõ ràng một khu vực và kích thước hình ảnh. Để lấy hình thu nhỏ của toàn bộ hình ảnh, chúng ta có thể sử dụng hình học dấu vết của hình ảnh làm khu vực yêu cầu. Cuối cùng, bằng cách chỉ định các dải hình ảnh màu đỏ, xanh lục và xanh dương cùng một dải giá trị dữ liệu thích hợp, chúng ta có thể thu được một hình ảnh thu nhỏ RGB hấp dẫn.
Kết hợp tất cả lại với nhau, đoạn mã Python sẽ có dạng như sau (sử dụng tiện ích hiển thị hình ảnh IPython
của Colab):
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)
Sau đây là hình thu nhỏ kết quả:
