Panduan proses debug

Algoritma yang Anda buat di Earth Engine berjalan di cloud Google, yang didistribusikan di banyak komputer. Proses debug dapat menjadi tantangan karena error dapat terjadi dalam kode sisi klien atau eksekusi sisi server petunjuk yang dienkode, dan disebabkan oleh masalah penskalaan serta error sintaksis atau logika. Bit program yang berjalan di suatu tempat di cloud tidak tersedia untuk diperiksa, kecuali jika Anda memintanya. Dokumen ini menyajikan strategi, alat, dan solusi proses debug untuk membantu Anda menyelesaikan error umum dan men-debug skrip Earth Engine.

Error sintaksis

Error sintaksis terjadi saat kode Anda melanggar aturan bahasa pemrograman (JavaScript atau Python di Earth Engine). Error ini mencegah kode Anda berjalan dan biasanya terdeteksi sebelum dieksekusi. Jika Anda mengalami error sintaksis, tinjau dengan cermat baris yang ditandai atau pesan error, dan lihat referensi seperti Referensi Bahasa Python atau Panduan Gaya JavaScript Google. Linter kode juga dapat membantu mengidentifikasi dan memperbaiki masalah ini.

Error sisi klien

Meskipun kodenya benar secara sintaksis, mungkin ada error yang terkait dengan konsistensi atau logika skrip. Contoh berikut menunjukkan error dari penggunaan variabel dan metode yang tidak ada.

Error — kode ini tidak berfungsi.

Editor Kode (JavaScript)

// Load a Sentinel-2 image.
var image = ee.Image('USGS/SRTMGL1_003');

// Error: "bandNames" is not defined in this scope.
var display = image.visualize({bands: bandNames, min: 0, max: 9000});

// Error: image.selfAnalyze is not a function
var silly = image.selfAnalyze();

Penyiapan Python

Lihat halaman Lingkungan Python untuk mengetahui informasi tentang Python API dan penggunaan geemap untuk pengembangan interaktif.

import ee
import geemap.core as geemap

Colab (Python)

# Load a Sentinel-2 image.
image = ee.Image('USGS/SRTMGL1_003')

# NameError: name 'band_names' is not defined.
display = image.visualize(bands=band_names, min=0, max=9000)

# AttributeError: 'Image' object has no attribute 'selfAnalyze'.
silly = image.selfAnalyze()

Error pertama memberi tahu Anda bahwa variabel bandNames tidak ditentukan dalam cakupan tempat variabel tersebut dirujuk. Sebagai solusi, tetapkan variabel, atau berikan argumen daftar untuk parameter bands. Error kedua menunjukkan apa yang terjadi saat fungsi selfAnalyze() yang tidak ada dipanggil. Karena itu bukan metode sebenarnya pada gambar, error akan memberi tahu Anda bahwa itu bukan fungsi. Dalam kedua kasus tersebut, error mendeskripsikan masalah.

Pemutaran jenis objek tidak diketahui

Error "...is not a function" dapat terjadi karena Earth Engine tidak mengetahui jenis variabel. Manifestasi umum masalah ini disebabkan oleh:

  • Melakukan sesuatu pada objek yang ditampilkan oleh first() (jenis elemen dalam koleksi tidak diketahui).
  • Melakukan sesuatu pada objek yang ditampilkan oleh get() (jenis elemen yang disimpan dalam properti tidak diketahui).
  • Melakukan sesuatu pada argumen fungsi (dalam fungsi) saat jenis argumen tidak diketahui.

Untuk contoh yang pertama:

Error — kode ini tidak berfungsi.

Editor Kode (JavaScript)

var collection = ee.FeatureCollection('USDOS/LSIB_SIMPLE/2017');

// Error: collection.first(...).area is not a function
var area = collection.first().area();

Penyiapan Python

Lihat halaman Lingkungan Python untuk mengetahui informasi tentang Python API dan penggunaan geemap untuk pengembangan interaktif.

import ee
import geemap.core as geemap

Colab (Python)

collection = ee.FeatureCollection('USDOS/LSIB_SIMPLE/2017')

# AttributeError: 'Element' object has no attribute 'area'.
area = collection.first().area()

Solusi dalam semua kasus adalah mentransmisikan objek dari jenis yang tidak diketahui dengan konstruktor jenis yang diketahui. Melanjutkan contoh sebelumnya, solusinya adalah melakukan transmisi ke ee.Feature:

Solusi — gunakan transmisi.

Editor Kode (JavaScript)

var area = ee.Feature(collection.first()).area();

Penyiapan Python

Lihat halaman Lingkungan Python untuk mengetahui informasi tentang Python API dan penggunaan geemap untuk pengembangan interaktif.

import ee
import geemap.core as geemap

Colab (Python)

area = ee.Feature(collection.first()).area()

(Perlu diperhatikan bahwa Anda dapat memanggil metode apa pun di Element dengan aman di sini karena itulah yang dianggap Earth Engine).

Hindari mencampur fungsi klien dan server

Contoh berikut kurang jelas:

Error — kode ini tidak melakukan hal yang Anda inginkan

Editor Kode (JavaScript)

// Don't mix EE objects and JavaScript objects.
var image = ee.Image('USGS/SRTMGL1_003');
var nonsense = image + 2;

// You can print this, but it's not what you were hoping for.
print(nonsense);

// Error: g.eeObject.name is not a function
Map.addLayer(nonsense);

Penyiapan Python

Lihat halaman Lingkungan Python untuk mengetahui informasi tentang Python API dan penggunaan geemap untuk pengembangan interaktif.

import ee
import geemap.core as geemap

Colab (Python)

# Don't mix EE objects and Python objects.
image = ee.Image('USGS/SRTMGL1_003')
nonsense = image + 2

# TypeError: unsupported operand type(s) for +: 'Image' and 'int'.
display(nonsense)

# TypeError: unsupported operand type(s) for +: 'Image' and 'int'.
m = geemap.Map()
m.add_layer(nonsense)
m

Misalkan penulis kode ini ingin menambahkan 2 ke setiap piksel dalam gambar, ini bukan cara yang tepat untuk melakukannya. Secara khusus, kode ini salah menggabungkan objek sisi server (image) dengan operator sisi klien (+). Hasilnya mungkin mengejutkan. Dalam kasus pertama, pencetakan nonsense di Editor Kode JavaScript akan melakukan operasi yang diminta (+) dengan mengonversi image dan 2 menjadi string, lalu menggabungkannya. String yang dihasilkan tidak disengaja (di Python, TypeError ditampilkan). Dalam kasus kedua, menambahkan nonsense ke peta, error g.eeObject.name is not a function misterius ditampilkan di Editor Kode JavaScript karena objek yang ditambahkan ke peta, nonsense, adalah string, bukan objek EE (di Python, TypeError ditampilkan). Untuk menghindari kemungkinan hasil yang tidak diinginkan dan error yang tidak informatif, jangan gabungkan objek dan fungsi server dengan objek, primitif, atau fungsi klien. Solusinya adalah menggunakan fungsi server.

Solusi — gunakan fungsi server.

Editor Kode (JavaScript)

Map.addLayer(image.add(2));

Penyiapan Python

Lihat halaman Lingkungan Python untuk mengetahui informasi tentang Python API dan penggunaan geemap untuk pengembangan interaktif.

import ee
import geemap.core as geemap

Colab (Python)

m = geemap.Map()
m.add_layer(image.add(2))
m

Lihat halaman Klien versus Server untuk mengetahui detail selengkapnya.

Kunci browser Editor Kode JavaScript

Browser macet atau terkunci dapat terjadi saat JavaScript yang berjalan di klien memerlukan waktu terlalu lama, atau saat menunggu sesuatu dari Earth Engine. Dua sumber umum error ini adalah loop for dan/atau getInfo() dalam kode Editor Kode JavaScript Anda, dengan skenario terburuk getInfo() di dalam loop for. Loop for dapat menyebabkan browser terkunci karena kode berjalan di komputer Anda. Di sisi lain, getInfo() secara sinkron meminta hasil komputasi dari Earth Engine, yang memblokir hingga hasilnya diterima. Jika komputasi memerlukan waktu lama, pemblokiran dapat menyebabkan browser Anda terkunci. Hindari loop for dan getInfo() saat bekerja di Code Editor. Lihat halaman Klien versus Server untuk mengetahui detail selengkapnya.

Error sisi server

Meskipun konsistensi logis dalam kode klien, mungkin ada bug yang hanya terlihat saat runtime di server. Contoh berikut menunjukkan hal yang terjadi saat mencoba mendapatkan band yang tidak ada.

Error — kode ini tidak berfungsi.

Editor Kode (JavaScript)

// Load a Sentinel-2 image.
var s2image = ee.Image(
    'COPERNICUS/S2_HARMONIZED/20160625T100617_20160625T170310_T33UVR');

// Error: Image.select: Pattern 'nonBand' did not match any bands.
print(s2image.select(['nonBand']));

Penyiapan Python

Lihat halaman Lingkungan Python untuk mengetahui informasi tentang Python API dan penggunaan geemap untuk pengembangan interaktif.

import ee
import geemap.core as geemap

Colab (Python)

# Load a Sentinel-2 image.
s2image = ee.Image(
    'COPERNICUS/S2_HARMONIZED/20160625T100617_20160625T170310_T33UVR'
)

# EEException: Image.select: Band pattern 'non_band' did not match any bands.
print(s2image.select(['non_band']).getInfo())

Dalam contoh ini, error memberi tahu Anda bahwa tidak ada band bernama nonBand. Solusi yang mungkin jelas adalah menentukan nama band yang ada. Anda dapat menemukan nama band dengan mencetak gambar dan memeriksanya di konsol, atau dengan mencetak daftar nama band yang ditampilkan oleh image.bandNames().

Ketetapan

Objek sisi server yang Anda buat di Earth Engine immutable. (Setiap ee.Object adalah Object sisi server). Artinya, jika Anda ingin membuat perubahan pada objek, Anda harus menyimpan status yang diubah ke dalam variabel baru. Misalnya, hal berikut tidak akan berfungsi untuk menetapkan properti pada gambar Sentinel-2:

Error — kode ini tidak melakukan hal yang Anda inginkan.

Editor Kode (JavaScript)

var s2image = ee.Image(
    'COPERNICUS/S2_HARMONIZED/20160625T100617_20160625T170310_T33UVR');
s2image.set('myProperty', 'This image is not assigned to a variable');

// This will not result in an error, but will not find 'myProperty'.
print(s2image.get('myProperty')); // null

Penyiapan Python

Lihat halaman Lingkungan Python untuk mengetahui informasi tentang Python API dan penggunaan geemap untuk pengembangan interaktif.

import ee
import geemap.core as geemap

Colab (Python)

s2image = ee.Image(
    'COPERNICUS/S2_HARMONIZED/20160625T100617_20160625T170310_T33UVR'
)
s2image.set('my_property', 'This image is not assigned to a variable')

# This will not result in an error, but will not find 'my_property'.
display(s2image.get('my_property'))  # None

Dalam contoh ini, s2image.set() menampilkan salinan gambar dengan properti baru, tetapi gambar yang disimpan dalam variabel s2image tidak berubah. Anda perlu menyimpan gambar yang ditampilkan oleh s2image.set() dalam variabel baru. Contoh:

Solusi — tangkap hasilnya dalam variabel.

Editor Kode (JavaScript)

s2image = s2image.set('myProperty', 'OK');
print(s2image.get('myProperty')); // OK

Penyiapan Python

Lihat halaman Lingkungan Python untuk mengetahui informasi tentang Python API dan penggunaan geemap untuk pengembangan interaktif.

import ee
import geemap.core as geemap

Colab (Python)

s2image = s2image.set('my_property', 'OK')
display(s2image.get('my_property'))  # OK

Fungsi yang dipetakan

Konteks lain tempat fungsi klien dan server tidak tercampur adalah dalam fungsi yang dipetakan. Secara khusus, operasi yang ditentukan oleh fungsi yang dipetakan berjalan di cloud, sehingga fungsi klien seperti getInfo dan Export (serta print dan metode di Map dan Chart di JavaScript Code Editor) tidak akan berfungsi dalam fungsi yang dipetakan. Contoh:

Error — kode ini tidak berfungsi.

Editor Kode (JavaScript)

var collection = ee.ImageCollection('MODIS/006/MOD44B');

// Error: A mapped function's arguments cannot be used in client-side operations
var badMap3 = collection.map(function(image) {
  print(image);
  return image;
});

Penyiapan Python

Lihat halaman Lingkungan Python untuk mengetahui informasi tentang Python API dan penggunaan geemap untuk pengembangan interaktif.

import ee
import geemap.core as geemap

Colab (Python)

collection = ee.ImageCollection('MODIS/006/MOD44B')

# Error: A mapped function's arguments cannot be used in client-side operations.
bad_map_3 = collection.map(lambda image: print(image.getInfo()))

Error yang agak samar ini dihasilkan dari proses yang digunakan Earth Engine untuk mengubah kode ini menjadi kumpulan petunjuk yang dapat dijalankan di server Google. Fungsi sisi klien dan struktur kontrol tidak dapat digunakan untuk beroperasi pada gambar argumen yang diteruskan ke fungsi yang dipetakan. Untuk menghindari error ini, hindari penggunaan fungsi sisi klien dalam fungsi yang dipetakan. Lihat halaman Klien versus Server untuk mempelajari lebih lanjut perbedaan antara fungsi klien dan server.

Fungsi yang dipetakan memiliki persyaratan tambahan. Misalnya, fungsi yang dipetakan harus menampilkan sesuatu:

Error — kode ini tidak berfungsi.

Editor Kode (JavaScript)

var collection = ee.ImageCollection('MODIS/006/MOD44B');

// Error: User-defined methods must return a value.
var badMap1 = collection.map(function(image) {
  // Do nothing.
});

Penyiapan Python

Lihat halaman Lingkungan Python untuk mengetahui informasi tentang Python API dan penggunaan geemap untuk pengembangan interaktif.

import ee
import geemap.core as geemap

Colab (Python)

collection = ee.ImageCollection('MODIS/006/MOD44B')

# Error: User-defined methods must return a value.
bad_map_1 = collection.map(lambda image: None)

Solusi yang mungkin jelas adalah menampilkan sesuatu. Namun, fungsi ini tidak dapat menampilkan jenis apa pun. Secara khusus, fungsi yang dipetakan di ImageCollection atau FeatureCollection harus menampilkan Image atau Feature. Misalnya, Anda tidak dapat menampilkan tanggal dari fungsi yang dipetakan di atas ImageCollection:

Error — kode ini tidak berfungsi.

Editor Kode (JavaScript)

var collection = ee.ImageCollection('MODIS/006/MOD44B');

var badMap2 = collection.map(function(image) {
  return image.date();
});

// Error: Collection.map: A mapped algorithm must return a Feature or Image.
print(badMap2);

Penyiapan Python

Lihat halaman Lingkungan Python untuk mengetahui informasi tentang Python API dan penggunaan geemap untuk pengembangan interaktif.

import ee
import geemap.core as geemap

Colab (Python)

collection = ee.ImageCollection('MODIS/006/MOD44B')

bad_map_2 = collection.map(lambda image: image.date())

# EEException: Collection.map:
# A mapped algorithm must return a Feature or Image.
print(bad_map_2.getInfo())

Untuk menghindarinya, tampilkan gambar input dengan kumpulan properti baru. Kemudian, jika Anda memerlukan daftar tanggal gambar dalam koleksi, Anda dapat menggunakan aggregate_array():

Solusi — tetapkan properti.

Editor Kode (JavaScript)

var collection = ee.ImageCollection('MODIS/006/MOD44B');

var okMap2 = collection.map(function(image) {
  return image.set('date', image.date());
});
print(okMap2);

// Get a list of the dates.
var datesList = okMap2.aggregate_array('date');
print(datesList);

Penyiapan Python

Lihat halaman Lingkungan Python untuk mengetahui informasi tentang Python API dan penggunaan geemap untuk pengembangan interaktif.

import ee
import geemap.core as geemap

Colab (Python)

collection = ee.ImageCollection('MODIS/006/MOD44B')

ok_map_2 = collection.map(lambda image: image.set('date', image.date()))
print(ok_map_2.getInfo())

# Get a list of the dates.
dates_list = ok_map_2.aggregate_array('date')
print(dates_list.getInfo())

Error prosedural

Pola diterapkan ke Gambar tanpa band

Error "Pattern 'my_band' was applied to an Image with no bands" berarti ada panggilan ee.Image.select() untuk Image dengan daftar band kosong. Berikut ini yang dapat Anda lakukan untuk mengatasinya:

  • Jika gambar dihasilkan dari ImageCollection dengan reducer atau menggunakan panggilan first() atau toBands(), pastikan koleksi sumber tidak kosong.
  • Jika gambar dihasilkan dari kamus menggunakan ee.Dictionary().toImage(), pastikan kamus tidak kosong.
  • Jika gambar bersifat mandiri, pastikan gambar tersebut memiliki data (dan bukan hanya ee.Image(0)).

Error penskalaan

Meskipun skrip mungkin benar secara sintaksis, tanpa error logika, dan mewakili kumpulan petunjuk yang valid untuk server, dalam melakukan paralelisasi dan menjalankan komputasi, objek yang dihasilkan mungkin terlalu besar, terlalu banyak, atau memerlukan waktu terlalu lama untuk dikomputasi. Dalam hal ini, Anda akan mendapatkan error yang menunjukkan bahwa algoritma tidak dapat diskalakan. Error ini biasanya paling sulit didiagnosis dan diatasi. Contoh jenis error ini mencakup:

  • Waktu tunggu komputasi habis
  • Terlalu banyak agregasi serentak
  • Batas memori pengguna terlampaui
  • Terjadi error internal

Meningkatkan penskalaan kode akan memungkinkan Anda mendapatkan hasil lebih cepat, dan juga meningkatkan ketersediaan resource komputasi untuk semua pengguna. Setiap jenis error dibahas di bagian berikut, setelah penjelasan singkat tentang reduceRegion(), fungsi yang biasa digunakan yang terkenal karena dapat menyebabkan setiap jenis error penskalaan.

reduceRegion()

Meskipun reduceRegion() dengan rakus menggunakan cukup piksel untuk memicu berbagai error yang menarik, ada juga parameter yang dimaksudkan untuk mengontrol komputasi, sehingga Anda dapat mengatasi error tersebut. Misalnya, pertimbangkan pengurangan yang tidak disarankan berikut:

Error — kode ini tidak berfungsi.

Editor Kode (JavaScript)

var absurdComputation = ee.Image(1).reduceRegion({
  reducer: 'count',
  geometry: ee.Geometry.Rectangle([-180, -90, 180, 90], null, false),
  scale: 100,
});

// Error: Image.reduceRegion: Too many pixels in the region.
//        Found 80300348117, but only 10000000 allowed.
print(absurdComputation);

Penyiapan Python

Lihat halaman Lingkungan Python untuk mengetahui informasi tentang Python API dan penggunaan geemap untuk pengembangan interaktif.

import ee
import geemap.core as geemap

Colab (Python)

absurd_computation = ee.Image(1).reduceRegion(
    reducer='count',
    geometry=ee.Geometry.Rectangle([-180, -90, 180, 90], None, False),
    scale=100,
)

# EEException: Image.reduceRegion: Too many pixels in the region.
#        Found 80300348117, but only 10000000 allowed.
print(absurd_computation.getInfo())

Contoh konyol ini hanya untuk demonstrasi. Tujuan error ini adalah untuk menanyakan kepada Anda apakah Anda benar-benar ingin mengurangi 80300348117 (yaitu 80 miliar) piksel. Jika tidak, tingkatkan scale (ukuran piksel dalam meter) sebagaimana mestinya, atau tetapkan bestEffort ke benar (true), untuk menghitung ulang skala yang lebih besar secara otomatis. Lihat halaman reduceRegion() untuk mengetahui detail selengkapnya tentang parameter ini.

Waktu tunggu komputasi habis

Misalnya, Anda memerlukan semua piksel tersebut dalam komputasi. Jika demikian, Anda dapat meningkatkan parameter maxPixels agar komputasi berhasil. Namun, Earth Engine memerlukan waktu untuk menyelesaikan komputasi. Akibatnya, error "waktu tunggu komputasi habis" mungkin ditampilkan:

Buruk — jangan lakukan ini!

Editor Kode (JavaScript)

var ridiculousComputation = ee.Image(1).reduceRegion({
  reducer: 'count',
  geometry: ee.Geometry.Rectangle([-180, -90, 180, 90], null, false),
  scale: 100,
  maxPixels: 1e11
});

// Error: Computation timed out.
print(ridiculousComputation);

Penyiapan Python

Lihat halaman Lingkungan Python untuk mengetahui informasi tentang Python API dan penggunaan geemap untuk pengembangan interaktif.

import ee
import geemap.core as geemap

Colab (Python)

ridiculous_computation = ee.Image(1).reduceRegion(
    reducer='count',
    geometry=ee.Geometry.Rectangle([-180, -90, 180, 90], None, False),
    scale=100,
    maxPixels=int(1e11),
)

# Error: Computation timed out.
print(ridiculous_computation.getInfo())

Artinya, Earth Engine menunggu sekitar lima menit sebelum menghentikan komputasi. Mengekspor memungkinkan Earth Engine melakukan komputasi di lingkungan dengan waktu operasi yang diizinkan lebih lama (tetapi tidak lebih banyak memori). Karena nilai yang ditampilkan dari reduceRegion() adalah kamus, Anda dapat menggunakan kamus untuk menetapkan properti fitur dengan geometri null:

Bagus — gunakan Export.

Editor Kode (JavaScript)

Export.table.toDrive({
  collection: ee.FeatureCollection([
    ee.Feature(null, ridiculousComputation)
  ]),
  description: 'ridiculousComputation',
  fileFormat: 'CSV'
});

Penyiapan Python

Lihat halaman Lingkungan Python untuk mengetahui informasi tentang Python API dan penggunaan geemap untuk pengembangan interaktif.

import ee
import geemap.core as geemap

Colab (Python)

task = ee.batch.Export.table.toDrive(
    collection=ee.FeatureCollection([ee.Feature(None, ridiculous_computation)]),
    description='ridiculous_computation',
    fileFormat='CSV',
)
# task.start()

Terlalu banyak agregasi serentak

Bagian "agregasi" dari error ini mengacu pada operasi yang tersebar di beberapa mesin (seperti pengurangan yang mencakup lebih dari satu kartu). Earth Engine memiliki batas untuk mencegah terlalu banyak agregasi tersebut dijalankan secara serentak. Dalam contoh ini, error "Terlalu banyak agregasi serentak" dipicu oleh pengurangan dalam peta:

Buruk — jangan lakukan ini!

Editor Kode (JavaScript)

var collection = ee.ImageCollection('LANDSAT/LT05/C02/T1')
    .filterBounds(ee.Geometry.Point([-123, 43]));

var terribleAggregations = collection.map(function(image) {
  return image.set(image.reduceRegion({
    reducer: 'mean',
    geometry: image.geometry(),
    scale: 30,
    maxPixels: 1e9
  }));
});

// Error: Quota exceeded: Too many concurrent aggregations.
print(terribleAggregations);

Penyiapan Python

Lihat halaman Lingkungan Python untuk mengetahui informasi tentang Python API dan penggunaan geemap untuk pengembangan interaktif.

import ee
import geemap.core as geemap

Colab (Python)

collection = ee.ImageCollection('LANDSAT/LT05/C02/T1').filterBounds(
    ee.Geometry.Point([-123, 43])
)


def apply_mean_aggregation(image):
  return image.set(
      image.reduceRegion(
          reducer='mean',
          geometry=image.geometry(),
          scale=30,
          maxPixels=int(1e9),
      )
  )


terrible_aggregations = collection.map(apply_mean_aggregation)

# EEException: Computation timed out.
print(terrible_aggregations.getInfo())

Dengan asumsi bahwa tujuan kode ini adalah untuk mendapatkan statistik gambar untuk setiap gambar, salah satu kemungkinan solusinya adalah dengan Export hasilnya. Misalnya, dengan menggunakan fakta bahwa ImageCollection juga merupakan FeatureCollection, metadata yang terkait dengan gambar dapat diekspor sebagai tabel:

Bagus — gunakan Export.

Editor Kode (JavaScript)

Export.table.toDrive({
  collection: terribleAggregations,
  description: 'terribleAggregations',
  fileFormat: 'CSV'
});

Penyiapan Python

Lihat halaman Lingkungan Python untuk mengetahui informasi tentang Python API dan penggunaan geemap untuk pengembangan interaktif.

import ee
import geemap.core as geemap

Colab (Python)

task = ee.batch.Export.table.toDrive(
    collection=terrible_aggregations,
    description='terrible_aggregations',
    fileFormat='CSV',
)
# task.start()

Batas memori pengguna terlampaui

Salah satu cara untuk melakukan paralelisasi algoritma di Earth Engine adalah dengan membagi input menjadi ubin, menjalankan komputasi yang sama secara terpisah di setiap ubin, lalu menggabungkan hasilnya. Akibatnya, semua input yang diperlukan untuk menghitung kartu output harus sesuai dengan memori. Misalnya, jika input adalah gambar dengan banyak band, hal itu dapat menghabiskan banyak memori jika semua band digunakan dalam komputasi. Untuk menunjukkan, contoh ini menggunakan terlalu banyak memori dengan memaksa (tidak perlu) seluruh koleksi gambar ke dalam kartu:

Buruk — jangan lakukan ini!

Editor Kode (JavaScript)

var bands = ['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7'];
var memoryHog = ee.ImageCollection('LANDSAT/LT05/C02/T1').select(bands)
  .toArray()
  .arrayReduce(ee.Reducer.mean(), [0])
  .arrayProject([1])
  .arrayFlatten([bands])
  .reduceRegion({
    reducer: 'mean',
    geometry: ee.Geometry.Point([-122.27, 37.87]).buffer(1000),
    scale: 1,
    bestEffort: true,
  });

// Error: User memory limit exceeded.
print(memoryHog);

Penyiapan Python

Lihat halaman Lingkungan Python untuk mengetahui informasi tentang Python API dan penggunaan geemap untuk pengembangan interaktif.

import ee
import geemap.core as geemap

Colab (Python)

bands = ['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7']
memory_hog = (
    ee.ImageCollection('LANDSAT/LT05/C02/T1')
    .select(bands)
    .toArray()
    .arrayReduce(ee.Reducer.mean(), [0])
    .arrayProject([1])
    .arrayFlatten([bands])
    .reduceRegion(
        reducer=ee.Reducer.mean(),
        geometry=ee.Geometry.Point([-122.27, 37.87]).buffer(1000),
        scale=1,
        bestEffort=True,
    )
)

# EEException: User memory limit exceeded.
print(memory_hog.getInfo())

Kode yang sangat buruk ini menunjukkan salah satu alasan untuk tidak menggunakan array kecuali jika Anda benar-benar perlu (lihat juga bagian 'Menghindari konversi jenis yang tidak perlu'). Saat koleksi tersebut dikonversi menjadi array raksasa, array harus dimuat ke dalam memori sekaligus. Karena merupakan deret gambar dalam waktu yang lama, array-nya besar dan tidak akan muat di memori.

Salah satu solusi yang memungkinkan adalah menetapkan parameter tileScale ke nilai yang lebih tinggi. Nilai tileScale yang lebih tinggi akan menghasilkan ubin yang lebih kecil dengan faktor tileScale^2. Misalnya, hal berikut memungkinkan komputasi berhasil:

Editor Kode (JavaScript)

var bands = ['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7'];
var smallerHog = ee.ImageCollection('LANDSAT/LT05/C02/T1').select(bands)
  .toArray()
  .arrayReduce(ee.Reducer.mean(), [0])
  .arrayProject([1])
  .arrayFlatten([bands])
  .reduceRegion({
    reducer: 'mean',
    geometry: ee.Geometry.Point([-122.27, 37.87]).buffer(1000),
    scale: 1,
    bestEffort: true,
    tileScale: 16
  });

print(smallerHog);

Penyiapan Python

Lihat halaman Lingkungan Python untuk mengetahui informasi tentang Python API dan penggunaan geemap untuk pengembangan interaktif.

import ee
import geemap.core as geemap

Colab (Python)

bands = ['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7']
smaller_hog = (
    ee.ImageCollection('LANDSAT/LT05/C02/T1')
    .select(bands)
    .toArray()
    .arrayReduce(ee.Reducer.mean(), [0])
    .arrayProject([1])
    .arrayFlatten([bands])
    .reduceRegion(
        reducer=ee.Reducer.mean(),
        geometry=ee.Geometry.Point([-122.27, 37.87]).buffer(1000),
        scale=1,
        bestEffort=True,
        tileScale=16,
    )
)

print(smaller_hog.getInfo())

Namun, solusi yang lebih disukai adalah tidak menggunakan array yang tidak perlu, sehingga Anda tidak perlu mengutak-atik tileScale sama sekali:

Bagus — hindari Array.

Editor Kode (JavaScript)

var bands = ['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7'];
var okMemory = ee.ImageCollection('LANDSAT/LT05/C02/T1').select(bands)
  .mean()
  .reduceRegion({
    reducer: 'mean',
    geometry: ee.Geometry.Point([-122.27, 37.87]).buffer(1000),
    scale: 1,
    bestEffort: true,
  });

print(okMemory);

Penyiapan Python

Lihat halaman Lingkungan Python untuk mengetahui informasi tentang Python API dan penggunaan geemap untuk pengembangan interaktif.

import ee
import geemap.core as geemap

Colab (Python)

bands = ['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7']
ok_memory = (
    ee.ImageCollection('LANDSAT/LT05/C02/T1')
    .select(bands)
    .mean()
    .reduceRegion(
        reducer=ee.Reducer.mean(),
        geometry=ee.Geometry.Point([-122.27, 37.87]).buffer(1000),
        scale=1,
        bestEffort=True,
    )
)

print(ok_memory.getInfo())

Kecuali jika diperlukan untuk mengatasi error memori, Anda tidak boleh menetapkan tileScale karena ubin yang lebih kecil juga menghasilkan overhead paralelisasi yang lebih besar.

Error internal

Anda mungkin mengalami error yang terlihat seperti:

Jika Anda mendapatkan error ini, klik link "Laporkan error" yang muncul di konsol Editor Kode JavaScript. Anda juga dapat Mengirim masukan dari tombol Bantuan. Error ini dapat disebabkan oleh error logis dalam skrip Anda yang hanya terlihat saat runtime atau masalah pada cara kerja internal Earth Engine. Dalam kedua kasus tersebut, error tidak informatif dan harus dilaporkan agar dapat diperbaiki.

Error internal menyertakan ID request, seperti berikut:

String ini berfungsi sebagai ID unik untuk membantu tim Earth Engine mengidentifikasi masalah tertentu. Sertakan string ini dalam laporan bug.

Metode proses debug

Anda telah membuat kode analisis, menjalankannya, dan mendapatkan error. Selanjutnya bagaimana? Bagian ini menjelaskan teknik proses debug umum untuk mengisolasi masalah dan memperbaikinya.

Memeriksa variabel dan lapisan peta

Misalkan Anda memiliki analisis yang sangat kompleks yang menghasilkan error. Jika tidak jelas tempat terjadinya error, strategi awal yang baik adalah mencetak atau memvisualisasikan objek perantara dan memeriksanya untuk memastikan struktur objek konsisten dengan logika dalam skrip Anda. Secara khusus, Anda dapat memeriksa nilai piksel lapisan yang ditambahkan ke peta dengan alat Editor Kode atau geemap inspector. Jika Anda mencetak sesuatu, pastikan untuk meluaskan propertinya dengan zippy (▶). Beberapa hal yang perlu diperiksa meliputi:

  • Nama band. Apakah nama band gambar cocok dengan kode Anda?
  • Nilai piksel. Apakah data Anda memiliki rentang yang tepat? Apakah data tersebut disamarkan dengan benar?
  • Null. Apakah ada yang null yang seharusnya tidak null?
  • Ukuran. Apakah ukurannya nol padahal seharusnya tidak?

aside()

Menempatkan setiap langkah perantara dalam analisis ke dalam variabel agar dapat dicetak dan diperiksa akan merepotkan. Untuk mencetak nilai perantara dari rantai pemanggilan fungsi yang panjang, Anda dapat menggunakan metode aside(). Contoh:

Editor Kode (JavaScript)

var image = ee.Image(ee.ImageCollection('COPERNICUS/S2')
    .filterBounds(ee.Geometry.Point([-12.29, 168.83]))
    .aside(print)
    .filterDate('2011-01-01', '2016-12-31')
    .first());

Penyiapan Python

Lihat halaman Lingkungan Python untuk mengetahui informasi tentang Python API dan penggunaan geemap untuk pengembangan interaktif.

import ee
import geemap.core as geemap

Colab (Python)

image = ee.Image(
    ee.ImageCollection('COPERNICUS/S2_HARMONIZED')
    .filterBounds(ee.Geometry.Point([-12.29, 168.83]))
    .aside(display)
    .filterDate('2011-01-01', '2016-12-31')
    .first()
)

Ingat, aside(print) (JavaScript Code Editor) dan aside(display) (Python geemap) memanggil fungsi sisi klien, dan akan tetap gagal dalam fungsi yang dipetakan. Anda juga dapat menggunakan aside dengan fungsi yang ditentukan pengguna. Contoh:

Editor Kode (JavaScript)

var composite = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA')
    .filterBounds(ee.Geometry.Point([106.91, 47.91]))
    .map(function(image) {
      return image.addBands(image.normalizedDifference(['B5', 'B4']));
    })
    .aside(Map.addLayer, {bands: ['B4', 'B3', 'B2'], max: 0.3}, 'collection')
    .qualityMosaic('nd');

Map.setCenter(106.91, 47.91, 11);
Map.addLayer(composite, {bands: ['B4', 'B3', 'B2'], max: 0.3}, 'composite');

Penyiapan Python

Lihat halaman Lingkungan Python untuk mengetahui informasi tentang Python API dan penggunaan geemap untuk pengembangan interaktif.

import ee
import geemap.core as geemap

Colab (Python)

m = geemap.Map()
m.set_center(106.91, 47.91, 11)

composite = (
    ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA')
    .filterBounds(ee.Geometry.Point([106.91, 47.91]))
    .map(lambda image: image.addBands(image.normalizedDifference(['B5', 'B4'])))
    .aside(m.add_layer, {'bands': ['B4', 'B3', 'B2'], 'max': 0.3}, 'collection')
    .qualityMosaic('nd')
)

m.add_layer(composite, {'bands': ['B4', 'B3', 'B2'], 'max': 0.3}, 'composite')
m

Menjalankan fungsi di first()

Pencetakan dan visualisasi berguna untuk proses debug jika tersedia, tetapi saat men-debug fungsi yang dipetakan ke koleksi, Anda tidak dapat mencetak dalam fungsi, seperti yang dijelaskan di bagian fungsi yang dipetakan. Dalam hal ini, sebaiknya isolasi elemen yang bermasalah dalam koleksi dan uji fungsi yang dipetakan pada setiap elemen. Saat menguji fungsi tanpa memetakan, Anda dapat menggunakan pernyataan cetak untuk memahami masalahnya. Perhatikan contoh berikut.

Error — kode ini tidak berfungsi.

Editor Kode (JavaScript)

var image = ee.Image(
    'COPERNICUS/S2_HARMONIZED/20150821T111616_20160314T094808_T30UWU');

var someFeatures = ee.FeatureCollection([
  ee.Feature(ee.Geometry.Point([-2.02, 48.43])),
  ee.Feature(ee.Geometry.Point([-2.80, 48.37])),
  ee.Feature(ee.Geometry.Point([-1.22, 48.29])),
  ee.Feature(ee.Geometry.Point([-1.73, 48.65])),
]);

var problem = someFeatures.map(function(feature) {

  var dictionary = image.reduceRegion({
    reducer: 'first',
    geometry: feature.geometry(),
    scale: 10,
  });

  return feature.set({
    result: ee.Number(dictionary.get('B5'))
                .divide(dictionary.get('B4'))
  });
});

// Error in map(ID=2):
//  Number.divide: Parameter 'left' is required.
print(problem);

Penyiapan Python

Lihat halaman Lingkungan Python untuk mengetahui informasi tentang Python API dan penggunaan geemap untuk pengembangan interaktif.

import ee
import geemap.core as geemap

Colab (Python)

image = ee.Image(
    'COPERNICUS/S2_HARMONIZED/20150821T111616_20160314T094808_T30UWU'
)

some_features = ee.FeatureCollection([
    ee.Feature(ee.Geometry.Point([-2.02, 48.43])),
    ee.Feature(ee.Geometry.Point([-2.80, 48.37])),
    ee.Feature(ee.Geometry.Point([-1.22, 48.29])),
    ee.Feature(ee.Geometry.Point([-1.73, 48.65])),
])


# Define a function to be mapped over the collection.
def function_to_map(feature):
  dictionary = image.reduceRegion(
      reducer=ee.Reducer.first(), geometry=feature.geometry(), scale=10
  )

  return feature.set(
      {'result': ee.Number(dictionary.get('B5')).divide(dictionary.get('B4'))}
  )


problem = some_features.map(function_to_map)

# EEException: Error in map(ID=2):
#  Number.divide: Parameter 'left' is required.
print(problem.getInfo())

Untuk men-debug hal ini, Anda harus memeriksa error. Untungnya, error yang berguna ini memberi tahu Anda bahwa ada masalah dengan fitur dengan ID=2. Untuk menyelidiki lebih lanjut, sebaiknya refactor kode sedikit. Secara khusus, Anda tidak dapat memiliki pernyataan cetak dalam fungsi saat dipetakan ke koleksi, seperti yang dijelaskan dalam bagian ini. Tujuan proses debug adalah untuk mengisolasi fitur yang bermasalah, dan menjalankan fungsi dengan beberapa pernyataan cetak di dalamnya. Dengan gambar dan fitur yang sama seperti yang digunakan sebelumnya:

Editor Kode (JavaScript)

// Define a function to be mapped over the collection.
var functionToMap = function(feature) {

  var dictionary = image.reduceRegion({
    reducer: 'first',
    geometry: feature.geometry(),
    scale: 10,
  });

  // Debug:
  print(dictionary);

  return feature.set({
    result: ee.Number(dictionary.get('B5'))
                .divide(dictionary.get('B4'))
  });
};

// Isolate the feature that's creating problems.
var badFeature = ee.Feature(someFeatures
    .filter(ee.Filter.eq('system:index', '2'))
    .first());

// Test the function with print statements added.
functionToMap(badFeature);

// Inspect the bad feature in relation to the image.
Map.centerObject(badFeature, 11);
Map.addLayer(badFeature, {}, 'bad feature');
Map.addLayer(image, {bands: ['B4', 'B3', 'B2'], max: 3000}, 'image');

Penyiapan Python

Lihat halaman Lingkungan Python untuk mengetahui informasi tentang Python API dan penggunaan geemap untuk pengembangan interaktif.

import ee
import geemap.core as geemap

Colab (Python)

# Define a function to be mapped over the collection.
def function_to_map(feature):
  dictionary = image.reduceRegion(
      reducer=ee.Reducer.first(), geometry=feature.geometry(), scale=10
  )

  # Debug:
  display(dictionary)

  return feature.set(
      {'result': ee.Number(dictionary.get('B5')).divide(dictionary.get('B4'))}
  )


# Isolate the feature that's creating problems.
bad_feature = ee.Feature(
    some_features.filter(ee.Filter.eq('system:index', '2')).first()
)

# Test the function with print statements added.
function_to_map(bad_feature)

# Inspect the bad feature in relation to the image.
m = geemap.Map()
m.center_object(bad_feature, 11)
m.add_layer(bad_feature, {}, 'bad feature')
m.add_layer(image, {'bands': ['B4', 'B3', 'B2'], 'max': 3000}, 'image')
m

Sekarang, karena fungsi hanya dijalankan pada satu fitur, Anda dapat menempatkan panggilan cetak (`display` untuk geemap Python) di dalamnya. Periksa objek yang dicetak untuk menemukan (ah ha!) bahwa objek yang ditampilkan oleh reduceRegion() memiliki null untuk setiap band. Hal ini menjelaskan mengapa pembagian gagal: karena Anda tidak dapat membagi null dengan null. Mengapa null sejak awal? Untuk menyelidiki, tambahkan gambar input dan fitur yang buruk ke peta, lalu pusatkan pada fitur buruk. Dengan demikian, Anda menemukan bahwa masalahnya disebabkan oleh titik yang berada di luar batas gambar. Berdasarkan penemuan ini, kode yang di-debug adalah:

Editor Kode (JavaScript)

var functionToMap = function(feature) {
  var dictionary = image.reduceRegion({
    reducer: 'first',
    geometry: feature.geometry(),
    scale: 10,
  });
  return feature.set({
    result: ee.Number(dictionary.get('B5'))
                .divide(dictionary.get('B4'))
  });
};

var noProblem = someFeatures
    .filterBounds(image.geometry())
    .map(functionToMap);

print(noProblem);

Penyiapan Python

Lihat halaman Lingkungan Python untuk mengetahui informasi tentang Python API dan penggunaan geemap untuk pengembangan interaktif.

import ee
import geemap.core as geemap

Colab (Python)

def function_to_map(feature):
  dictionary = image.reduceRegion(
      reducer=ee.Reducer.first(), geometry=feature.geometry(), scale=10
  )

  return feature.set(
      {'result': ee.Number(dictionary.get('B5')).divide(dictionary.get('B4'))}
  )


no_problem = some_features.filterBounds(image.geometry()).map(function_to_map)

display(no_problem)

Profiler

Profiler memberikan informasi tentang waktu EECU dan penggunaan memori (per algoritma dan aset) yang dihasilkan dari komputasi yang dilakukan saat diaktifkan. Cari entri di bagian atas profiler untuk mengetahui informasi tentang operasi yang paling banyak menggunakan resource. Untuk skrip yang berjalan lama atau tidak efisien, entri di bagian atas profiler memberikan petunjuk tentang tempat untuk memfokuskan upaya guna mengoptimalkan skrip. Catatan penting: profiler itu sendiri memengaruhi performa skrip, jadi Anda hanya boleh menjalankannya jika diperlukan.