คู่มือการแก้ไขข้อบกพร่อง

อัลกอริทึมที่สร้างขึ้นใน Earth Engine จะทำงานใน Google Cloud ซึ่งกระจายอยู่ในคอมพิวเตอร์หลายเครื่อง การแก้ไขข้อบกพร่องอาจเป็นเรื่องยากเนื่องจากข้อผิดพลาดอาจเกิดขึ้นในโค้ดฝั่งไคลเอ็นต์หรือการดำเนินการคำสั่งที่โค้ดฝั่งเซิร์ฟเวอร์ และอาจเกิดจากปัญหาการปรับขนาด รวมถึงข้อผิดพลาดทางไวยากรณ์หรือตรรกะ ข้อมูลโค้ดของโปรแกรมที่ทำงานอยู่ในระบบคลาวด์จะไม่สามารถตรวจสอบได้ เว้นแต่คุณจะขอ เอกสารนี้แสดงกลยุทธ์ เครื่องมือ และโซลูชันการแก้ไขข้อบกพร่องเพื่อช่วยคุณแก้ไขข้อผิดพลาดที่พบได้ทั่วไปและแก้ไขข้อบกพร่องของสคริปต์ Earth Engine

ข้อผิดพลาดทางไวยากรณ์

ข้อผิดพลาดทางไวยากรณ์จะเกิดขึ้นเมื่อโค้ดของคุณไม่เป็นไปตามกฎของภาษาโปรแกรม (JavaScript หรือ Python ใน Earth Engine) ข้อผิดพลาดเหล่านี้จะทําให้โค้ดไม่ทํางานและมักจะตรวจพบได้ก่อนการดําเนินการ หากพบข้อผิดพลาดทางไวยากรณ์ ให้ตรวจสอบบรรทัดที่ไฮไลต์หรือข้อความแสดงข้อผิดพลาดอย่างละเอียด และดูแหล่งข้อมูลต่างๆ เช่น ข้อมูลอ้างอิงภาษา Python หรือ คู่มือสไตล์ Google JavaScript เครื่องมือตรวจสอบโค้ดยังช่วยระบุและแก้ไขปัญหาเหล่านี้ได้ด้วย

ข้อผิดพลาดฝั่งไคลเอ็นต์

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

ข้อผิดพลาด — รหัสนี้ใช้ไม่ได้

เครื่องมือแก้ไขโค้ด (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();

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

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()

ข้อผิดพลาดแรกแจ้งว่าคุณไม่ได้กําหนดตัวแปร bandNames ในขอบเขตที่มีการอ้างอิง วิธีแก้ปัญหาคือให้ตั้งค่าตัวแปรหรือระบุอาร์กิวเมนต์ลิสต์สําหรับพารามิเตอร์ bands ข้อผิดพลาดที่ 2 แสดงสิ่งที่เกิดขึ้นเมื่อมีการเรียกใช้ฟังก์ชัน selfAnalyze() ที่ไม่มีอยู่ เนื่องจากไม่ใช่เมธอดจริงในรูปภาพ ข้อผิดพลาดจึงแจ้งว่าไม่ใช่ฟังก์ชัน ไม่ว่าในกรณีใด ข้อผิดพลาดจะอธิบายถึงปัญหา

การแคสต์ประเภทออบเจ็กต์ที่ไม่รู้จัก

ข้อผิดพลาด "...is not a function" อาจเกิดจาก Earth Engine ไม่รู้จักประเภทของตัวแปร ปัญหานี้อาจเกิดจากสาเหตุต่อไปนี้

  • การดำเนินการกับออบเจ็กต์ที่ first() แสดงผล (ไม่ทราบประเภทขององค์ประกอบในคอลเล็กชัน)
  • การดำเนินการกับออบเจ็กต์ที่ get() แสดงผล (ไม่ทราบประเภทขององค์ประกอบที่จัดเก็บไว้ในพร็อพเพอร์ตี้)
  • การดำเนินการกับอาร์กิวเมนต์ของฟังก์ชัน (ในฟังก์ชัน) เมื่อไม่ทราบประเภทของอาร์กิวเมนต์

ตัวอย่างของกรณีแรก

ข้อผิดพลาด — รหัสนี้ใช้ไม่ได้

เครื่องมือแก้ไขโค้ด (JavaScript)

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

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

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

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()

ทางออกในทุกกรณีคือการแคสต์ออบเจ็กต์ประเภทที่ไม่รู้จักด้วยคอนสตรัคเตอร์ของประเภทที่รู้จัก ต่อจากตัวอย่างก่อนหน้า วิธีแก้ปัญหาคือการแคสต์ไปยัง ee.Feature ดังนี้

วิธีแก้ปัญหา - ใช้แคสต์

เครื่องมือแก้ไขโค้ด (JavaScript)

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

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

import ee
import geemap.core as geemap

Colab (Python)

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

(โปรดทราบว่าคุณสามารถเรียกใช้เมธอดใดก็ได้ใน Element ที่นี่ได้อย่างปลอดภัยเนื่องจาก Earth Engine จะคิดว่าเป็นเช่นนั้น)

หลีกเลี่ยงการผสมฟังก์ชันของไคลเอ็นต์และเซิร์ฟเวอร์

ตัวอย่างต่อไปนี้ไม่ชัดเจนนัก

ข้อผิดพลาด — โค้ดนี้ไม่ทํางานตามที่คุณต้องการ

เครื่องมือแก้ไขโค้ด (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);

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

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

สมมติว่าผู้เขียนโค้ดนี้ตั้งใจจะเพิ่ม 2 ลงในพิกเซลทุกพิกเซลในรูปภาพ นี่เป็นวิธีที่ไม่ถูกต้อง กล่าวโดยละเอียดคือ โค้ดนี้ผสมออบเจ็กต์ฝั่งเซิร์ฟเวอร์ (image) เข้ากับโอเปอเรเตอร์ฝั่งไคลเอ็นต์ (+) อย่างไม่ถูกต้อง ผลลัพธ์ที่ได้อาจทำให้ประหลาดใจ ในกรณีแรก การพิมพ์ nonsense ในเครื่องมือแก้ไขโค้ด JavaScript จะดำเนินการตามคำขอ (+) โดยแปลงทั้ง image และ 2 เป็นสตริง แล้วต่อสตริงเข้าด้วยกัน สตริงที่ได้จะไม่เป็นไปตามที่ต้องการ (ใน Python ระบบจะแสดง TypeError) ในกรณีที่ 2 การเพิ่ม nonsense ลงในแผนที่ ระบบจะแสดงข้อผิดพลาด g.eeObject.name is not a function ที่เป็นสัญลักษณ์ในเครื่องมือแก้ไขโค้ด JavaScript เนื่องจากออบเจ็กต์ที่เพิ่มลงในแผนที่ nonsense เป็นสตริง ไม่ใช่ออบเจ็กต์ EE (ใน Python ระบบจะแสดง TypeError) อย่าผสมออบเจ็กต์และฟังก์ชันเซิร์ฟเวอร์เข้ากับออบเจ็กต์ พรอมิต หรือฟังก์ชันไคลเอ็นต์ เพื่อหลีกเลี่ยงผลลัพธ์ที่ไม่ต้องการและข้อผิดพลาดที่ไม่มีข้อมูล ตัวอย่างนี้ใช้วิธีแก้ปัญหาด้วยการใช้ฟังก์ชันเซิร์ฟเวอร์

วิธีแก้ปัญหา - ใช้ฟังก์ชันเซิร์ฟเวอร์

เครื่องมือแก้ไขโค้ด (JavaScript)

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

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

import ee
import geemap.core as geemap

Colab (Python)

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

ดูรายละเอียดเพิ่มเติมได้ที่หน้าไคลเอ็นต์กับเซิร์ฟเวอร์

การล็อกเบราว์เซอร์ของเครื่องมือแก้ไขโค้ด JavaScript

เบราว์เซอร์อาจค้างหรือล็อกเมื่อ JavaScript ที่ทำงานในไคลเอ็นต์ใช้เวลานานเกินไป หรือเมื่อรอข้อมูลจาก Earth Engine แหล่งที่มาที่พบบ่อย 2 แหล่งของข้อผิดพลาดนี้ ได้แก่ บรรทัดวน for และ/หรือ getInfo() ในโค้ดเครื่องมือแก้ไขโค้ด JavaScript โดยกรณีที่เลวร้ายที่สุดคือ getInfo() อยู่ภายในบรรทัดวน for วง For อาจทําให้เบราว์เซอร์ล็อกเนื่องจากโค้ดทํางานบนเครื่องของคุณ ในทางกลับกัน getInfo() จะส่งคําขอผลลัพธ์การคํานวณจาก Earth Engine แบบซิงค์กัน ซึ่งจะบล็อกจนกว่าจะได้ผลลัพธ์ หากการประมวลผลใช้เวลานาน การบล็อกอาจทำให้เบราว์เซอร์ล็อก หลีกเลี่ยงทั้งวงวน for และ getInfo() while เมื่อทํางานในเครื่องมือแก้ไขโค้ด ดูรายละเอียดเพิ่มเติมที่หน้าไคลเอ็นต์กับเซิร์ฟเวอร์

ข้อผิดพลาดฝั่งเซิร์ฟเวอร์

แม้ว่าโค้ดไคลเอ็นต์จะมีความสอดคล้องกันทางตรรกะ แต่อาจมีข้อบกพร่องที่ปรากฏขึ้นเมื่อรันไทม์บนเซิร์ฟเวอร์เท่านั้น ตัวอย่างต่อไปนี้แสดงสิ่งที่จะเกิดขึ้นเมื่อพยายามรับวงดนตรีที่ไม่มีอยู่

ข้อผิดพลาด — รหัสนี้ใช้ไม่ได้

เครื่องมือแก้ไขโค้ด (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']));

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

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())

ในตัวอย่างนี้ ข้อผิดพลาดจะแจ้งว่าไม่มีแบนด์ชื่อ nonBand วิธีแก้ปัญหาที่ชัดเจนที่สุดคือระบุชื่อวงที่มีอยู่ คุณสามารถดูชื่อวงได้โดยพิมพ์รูปภาพและตรวจสอบในคอนโซล หรือพิมพ์รายการชื่อวงที่ image.bandNames() แสดง

การเปลี่ยนแปลงไม่ได้

ออบเจ็กต์ฝั่งเซิร์ฟเวอร์ที่คุณสร้างใน Earth Engine จะimmutable (ee.Object ใดๆ คือ Object ฝั่งเซิร์ฟเวอร์) ซึ่งหมายความว่าหากต้องการทําการเปลี่ยนแปลงออบเจ็กต์ คุณต้องบันทึกสถานะที่เปลี่ยนแปลงลงในตัวแปรใหม่ ตัวอย่างเช่น คำสั่งนี้จะใช้ไม่ได้กับการตั้งค่าพร็อพเพอร์ตี้ในรูปภาพ Sentinel-2

ข้อผิดพลาด — รหัสนี้ไม่ทํางานตามที่คุณต้องการ

เครื่องมือแก้ไขโค้ด (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

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

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

ในตัวอย่างนี้ s2image.set() จะแสดงผลสําเนาของรูปภาพที่มีพร็อพเพอร์ตี้ใหม่ แต่รูปภาพที่จัดเก็บไว้ในตัวแปร s2image จะไม่มีการเปลี่ยนแปลง คุณต้องบันทึกรูปภาพที่ s2image.set() แสดงผลไว้ในตัวแปรใหม่ เช่น

วิธีแก้ปัญหา - บันทึกผลลัพธ์ไว้ในตัวแปร

เครื่องมือแก้ไขโค้ด (JavaScript)

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

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

import ee
import geemap.core as geemap

Colab (Python)

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

ฟังก์ชันที่แมป

บริบทอีกรูปแบบหนึ่งที่ฟังก์ชันของไคลเอ็นต์และเซิร์ฟเวอร์ไม่ผสมกันคือในฟังก์ชันที่แมป กล่าวโดยละเอียดคือ การดำเนินการที่ระบุโดยฟังก์ชันที่แมปจะทำงานในระบบคลาวด์ ดังนั้นฟังก์ชันไคลเอ็นต์ เช่น getInfo และ Export (รวมถึง print และเมธอดใน Map และ Chart ในเครื่องมือแก้ไขโค้ด JavaScript) จะไม่ทำงานในฟังก์ชันที่แมป เช่น

ข้อผิดพลาด — รหัสนี้ใช้ไม่ได้

เครื่องมือแก้ไขโค้ด (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;
});

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

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()))

ข้อผิดพลาดที่ค่อนข้างคลุมเครือนี้เป็นผลมาจากกระบวนการที่ Earth Engine ใช้เปลี่ยนโค้ดนี้ให้เป็นชุดคำสั่งที่ทำงานได้ในเซิร์ฟเวอร์ของ Google ไม่สามารถใช้ฟังก์ชันและโครงสร้างการควบคุมฝั่งไคลเอ็นต์เพื่อดำเนินการกับรูปภาพอาร์กิวเมนต์ที่ส่งไปยังฟังก์ชันที่แมปได้ หลีกเลี่ยงข้อผิดพลาดนี้โดยหลีกเลี่ยงการใช้ฟังก์ชันฝั่งไคลเอ็นต์ในฟังก์ชันที่แมป ดูข้อมูลเพิ่มเติมเกี่ยวกับความแตกต่างระหว่างฟังก์ชันของไคลเอ็นต์และเซิร์ฟเวอร์ได้ในหน้าไคลเอ็นต์กับเซิร์ฟเวอร์

ฟังก์ชันที่แมปมีข้อกำหนดเพิ่มเติม เช่น ฟังก์ชันที่แมปต้องแสดงผลบางอย่าง

ข้อผิดพลาด — รหัสนี้ใช้ไม่ได้

เครื่องมือแก้ไขโค้ด (JavaScript)

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

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

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

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)

วิธีแก้ปัญหาที่ชัดเจนที่สุดคือการคืนสินค้า แต่ไม่สามารถแสดงผลสิ่งต่างๆ ได้ทุกประเภท กล่าวอย่างเจาะจงคือ ฟังก์ชันที่แมปกับ ImageCollection หรือ FeatureCollection ต้องแสดงผล Image หรือ Feature ตัวอย่างเช่น คุณจะแสดงผลวันที่จากฟังก์ชันที่แมปกับ ImageCollection ไม่ได้ในกรณีต่อไปนี้

ข้อผิดพลาด — รหัสนี้ใช้ไม่ได้

เครื่องมือแก้ไขโค้ด (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);

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

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())

หากต้องการหลีกเลี่ยงปัญหานี้ ให้แสดงผลรูปภาพอินพุตด้วยชุดพร็อพเพอร์ตี้ใหม่ จากนั้นหากต้องการดูรายการวันที่ของรูปภาพในคอลเล็กชัน ให้ใช้ aggregate_array() ดังนี้

วิธีแก้ปัญหา - ตั้งค่าพร็อพเพอร์ตี้

เครื่องมือแก้ไขโค้ด (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);

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

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())

ข้อผิดพลาดเกี่ยวกับกระบวนการ

ใช้ลายกับรูปภาพที่ไม่มีแถบ

ข้อผิดพลาด "Pattern 'my_band' was applied to an Image with no bands" หมายความว่ามีการเรียก ee.Image.select() สำหรับรูปภาพที่มีรายการแบนด์ว่าง สิ่งที่คุณทำได้เพื่อแก้ไขปัญหามีดังนี้

  • หากรูปภาพสร้างขึ้นจาก ImageCollection ที่มีตัวลดหรือใช้การเรียก first() หรือ toBands() ให้ตรวจสอบว่าคอลเล็กชันต้นทางไม่ได้ว่างเปล่า
  • หากรูปภาพสร้างขึ้นจากพจนานุกรมโดยใช้ ee.Dictionary().toImage() ให้ตรวจสอบว่าพจนานุกรมนั้นไม่ว่างเปล่า
  • หากรูปภาพเป็นแบบสแตนด์อโลน ให้ตรวจสอบว่ารูปภาพมีข้อมูล (ไม่ใช่แค่ ee.Image(0))

ข้อผิดพลาดในการปรับขนาด

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

  • การคํานวณหมดเวลา
  • การรวมข้อมูลพร้อมกันมากเกินไป
  • เกินขีดจำกัดหน่วยความจำของผู้ใช้
  • เกิดข้อผิดพลาดภายใน

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

reduceRegion()

แม้ว่า reduceRegion() จะใช้พิกเซลอย่างตะกละตะกลามจนทำให้เกิดข้อผิดพลาดที่หลากหลาย แต่ก็มีพารามิเตอร์ที่ควบคุมการประมวลผลเพื่อให้คุณแก้ไขข้อผิดพลาดได้ ตัวอย่างเช่น ลองพิจารณาการลดขนาดที่ไม่แนะนําต่อไปนี้

ข้อผิดพลาด — รหัสนี้ใช้ไม่ได้

เครื่องมือแก้ไขโค้ด (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);

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

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())

ตัวอย่างที่ไร้สาระนี้เป็นเพียงการสาธิตเท่านั้น ข้อผิดพลาดนี้มีไว้เพื่อถามว่าคุณต้องการลดพิกเซล 80300348117 (80 พันล้านพิกเซล) จริงๆ หรือไม่ หากไม่ ให้เพิ่ม scale (ขนาดพิกเซลเป็นเมตร) ให้สอดคล้องกัน หรือตั้งค่า bestEffort เป็น "จริง" เพื่อคํานวณขนาดที่ใหญ่ขึ้นอีกครั้งโดยอัตโนมัติ ดูรายละเอียดเพิ่มเติมเกี่ยวกับพารามิเตอร์เหล่านี้ได้ที่หน้า reduceRegion()

การคํานวณหมดเวลา

สมมติว่าคุณต้องการใช้พิกเซลทั้งหมดในการคํานวณ หากเป็นเช่นนั้น คุณสามารถเพิ่มพารามิเตอร์ maxPixels เพื่อให้การคํานวณสําเร็จ อย่างไรก็ตาม Earth Engine จะใช้เวลาสักครู่ในการประมวลผลให้เสร็จสมบูรณ์ ด้วยเหตุนี้ ระบบจึงอาจแสดงข้อผิดพลาด "หมดเวลาคํานวณ" ดังนี้

ไม่ดี - อย่าทำเช่นนี้

เครื่องมือแก้ไขโค้ด (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);

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

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())

ข้อผิดพลาดนี้หมายความว่า Earth Engine รอประมาณ 5 นาทีก่อนที่จะหยุดการคำนวณ การส่งออกช่วยให้ Earth Engine ดำเนินการคํานวณในสภาพแวดล้อมที่มีเวลาทํางานที่อนุญาตนานขึ้น (แต่ไม่ได้เพิ่มหน่วยความจํา) เนื่องจากค่าที่แสดงผลจาก reduceRegion() คือพจนานุกรม คุณจึงใช้พจนานุกรมเพื่อตั้งค่าพร็อพเพอร์ตี้ขององค์ประกอบที่มีเรขาคณิต Null ได้ ดังนี้

ดี ให้ใช้ Export

เครื่องมือแก้ไขโค้ด (JavaScript)

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

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

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()

การรวมข้อมูลพร้อมกันมากเกินไป

ส่วน "การรวม" ของข้อผิดพลาดนี้หมายถึงการดำเนินการที่กระจายอยู่ในเครื่องหลายเครื่อง (เช่น การลดที่ครอบคลุมมากกว่า 1 ไทล์) Earth Engine มีขีดจํากัดเพื่อป้องกันไม่ให้การรวมข้อมูลดังกล่าวทํางานพร้อมกันมากเกินไป ในตัวอย่างนี้ ข้อผิดพลาด "การรวมข้อมูลพร้อมกันมากเกินไป" เกิดจากการดำเนินการลดภายในแผนที่

ไม่ดี - อย่าทำเช่นนี้

เครื่องมือแก้ไขโค้ด (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);

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

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())

สมมติว่าวัตถุประสงค์ของโค้ดนี้คือรับสถิติรูปภาพสำหรับรูปภาพแต่ละรูป หนึ่งในวิธีแก้ปัญหาที่เป็นไปได้คือExportผลลัพธ์ ตัวอย่างเช่น เมื่อใช้ข้อเท็จจริงที่ว่า ImageCollection เป็น FeatureCollection ด้วย ข้อมูลเมตาที่เชื่อมโยงกับรูปภาพจะส่งออกเป็นตารางได้ดังนี้

ดี ให้ใช้ Export

เครื่องมือแก้ไขโค้ด (JavaScript)

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

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

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()

เกินขีดจำกัดหน่วยความจำของผู้ใช้

วิธีหนึ่งในการทำให้อัลกอริทึมทำงานแบบขนานใน Earth Engine คือแยกอินพุตออกเป็นไทล์ เรียกใช้การคํานวณเดียวกันแยกกันในแต่ละไทล์ แล้วรวมผลลัพธ์ ด้วยเหตุนี้ ข้อมูลขาเข้าทั้งหมดที่จําเป็นสําหรับคํานวณข้อมูลในผลลัพธ์จึงต้องพอดีกับหน่วยความจํา เช่น เมื่ออินพุตเป็นภาพที่มีหลายย่านความถี่ การดำเนินการอาจใช้หน่วยความจํามากหากใช้ย่านความถี่ทั้งหมดในการคำนวณ ตัวอย่างนี้ใช้หน่วยความจํามากเกินไปโดยบังคับให้ทั้งคอลเล็กชันรูปภาพแสดงเป็นไทล์ (ไม่จําเป็น) ดังต่อไปนี้

ไม่ดี - อย่าทำเช่นนี้

เครื่องมือแก้ไขโค้ด (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);

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

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())

โค้ดที่ไม่ดีมากๆ นี้แสดงให้เห็นเหตุผลข้อหนึ่งว่าทำไมคุณไม่ควรใช้อาร์เรย์ เว้นแต่ว่าจำเป็นจริงๆ (ดูส่วน "หลีกเลี่ยงการเปลี่ยนประเภทโดยไม่จำเป็น" ด้วย) เมื่อแปลงคอลเล็กชันนั้นเป็นอาร์เรย์ขนาดใหญ่มาก จะต้องโหลดอาร์เรย์ลงในหน่วยความจําพร้อมกัน เนื่องจากเป็นชุดรูปภาพที่ยาว อาร์เรย์จึงมีขนาดใหญ่และจะไม่พอดีกับหน่วยความจำ

วิธีแก้ปัญหาที่เป็นไปได้อย่างหนึ่งคือการตั้งค่าพารามิเตอร์ tileScale เป็นค่าที่สูงขึ้น ค่า tileScale ที่สูงขึ้นจะทำให้การ์ดมีขนาดเล็กลงตามค่า tileScale^2 ตัวอย่างเช่น เงื่อนไขต่อไปนี้ช่วยให้การคํานวณสําเร็จ

เครื่องมือแก้ไขโค้ด (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);

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

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())

อย่างไรก็ตาม วิธีที่แนะนำคืออย่าใช้อาร์เรย์โดยไม่จำเป็น เพื่อที่คุณจะได้ไม่ต้องยุ่งกับ tileScale เลย

ดี — หลีกเลี่ยงการใช้อาร์เรย์

เครื่องมือแก้ไขโค้ด (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);

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

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())

คุณไม่ควรตั้งค่า tileScale เว้นแต่จำเป็นต่อการแก้ไขข้อผิดพลาดเกี่ยวกับหน่วยความจำ เนื่องจากการ์ดขนาดเล็กจะส่งผลให้มีค่าใช้จ่ายในการขนานกันมากขึ้น

ข้อผิดพลาดภายใน

คุณอาจพบข้อผิดพลาดที่มีลักษณะดังนี้

หากพบข้อผิดพลาดนี้ ให้คลิกลิงก์ "รายงานข้อผิดพลาด" ซึ่งปรากฏในคอนโซลเครื่องมือแก้ไขโค้ด JavaScript นอกจากนี้ คุณยังส่งความคิดเห็นจากปุ่มความช่วยเหลือได้ด้วย ข้อผิดพลาดนี้อาจเกิดจากข้อผิดพลาดเชิงตรรกะในสคริปต์ของคุณซึ่งจะปรากฏขึ้นเมื่อรันไทม์เท่านั้น หรือเกิดจากปัญหาเกี่ยวกับวิธีการทำงานของ Earth Engine ไม่ว่าในกรณีใด ข้อผิดพลาดนี้ไม่มีข้อมูลและควรรายงานเพื่อให้แก้ไขได้

ข้อผิดพลาดภายในจะมีรหัส request ดังต่อไปนี้

สตริงเหล่านี้ทำหน้าที่เป็นตัวระบุที่ไม่ซ้ำกันเพื่อช่วยทีม Earth Engine ระบุปัญหาที่เฉพาะเจาะจง ใส่สตริงนี้ในรายงานข้อบกพร่อง

วิธีการแก้ไขข้อบกพร่อง

คุณได้เขียนโค้ดการวิเคราะห์ เรียกใช้ และพบข้อผิดพลาด ฉันควรทำอย่างไรต่อไป ส่วนนี้จะอธิบายเทคนิคการแก้ไขข้อบกพร่องทั่วไปเพื่อแยกปัญหาและแก้ไข

ตรวจสอบตัวแปรและเลเยอร์แผนที่

สมมติว่าคุณมีการวิเคราะห์ที่ซับซ้อนมากซึ่งทำให้เกิดข้อผิดพลาด หากไม่แน่ใจว่าข้อผิดพลาดเกิดขึ้นที่ใด กลยุทธ์เริ่มต้นที่ดีคือการพิมพ์หรือแสดงภาพออบเจ็กต์กลางและตรวจสอบเพื่อให้แน่ใจว่าโครงสร้างของออบเจ็กต์สอดคล้องกับตรรกะในสคริปต์ กล่าวโดยละเอียดคือ คุณสามารถตรวจสอบค่าพิกเซลของเลเยอร์ซึ่งเพิ่มลงในแผนที่ด้วยเครื่องมือแก้ไขโค้ดหรือเครื่องมือตรวจสอบ geemap หากคุณพิมพ์สิ่งใดสิ่งหนึ่ง ให้ขยายพร็อพเพอร์ตี้ด้วยไอคอนซิป (▶) สิ่งที่ควรตรวจสอบมีดังนี้

  • ชื่อวง ชื่อแถบของรูปภาพตรงกับรหัสของคุณไหม
  • ค่าพิกเซล ข้อมูลของคุณมีช่วงถูกต้องไหม มีการปกปิดข้อมูลอย่างเหมาะสมหรือไม่
  • Null มีข้อมูลใดเป็นค่า Null ที่ไม่ควรจะเป็นหรือไม่
  • ขนาด ขนาดเป็น 0 หรือไม่ควรจะเป็น

aside()

การใส่ขั้นตอนกลางทั้งหมดในการวิเคราะห์ลงในตัวแปรเพื่อให้พิมพ์และตรวจสอบได้นั้นอาจเป็นเรื่องยุ่งยาก หากต้องการพิมพ์ค่ากลางจากเชนการเรียกใช้ฟังก์ชันที่ยาว ให้ใช้เมธอด aside() เช่น

เครื่องมือแก้ไขโค้ด (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());

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

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()
)

โปรดทราบว่า aside(print) (เครื่องมือแก้ไขโค้ด JavaScript) และ aside(display) (geemap ของ Python) กำลังเรียกใช้ฟังก์ชันฝั่งไคลเอ็นต์ และจะใช้งานไม่ได้ในฟังก์ชันที่แมป นอกจากนี้ คุณยังใช้ aside กับฟังก์ชันที่ผู้ใช้กำหนดได้ด้วย เช่น

เครื่องมือแก้ไขโค้ด (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');

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

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

เรียกใช้ฟังก์ชันใน first()

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

ข้อผิดพลาด — รหัสนี้ใช้ไม่ได้

เครื่องมือแก้ไขโค้ด (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);

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

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())

หากต้องการแก้ไขข้อบกพร่องนี้ คุณต้องตรวจสอบข้อผิดพลาด แต่ข้อผิดพลาดที่มีประโยชน์นี้จะช่วยแจ้งให้คุณทราบว่าฟีเจอร์ ID=2 มีปัญหา หากต้องการตรวจสอบเพิ่มเติม คุณควรปรับโค้ดใหม่เล็กน้อย กล่าวโดยละเอียดคือ คุณไม่สามารถมีคำสั่งพิมพ์ในฟังก์ชันเมื่อมีการแมปกับคอลเล็กชัน ตามที่อธิบายไว้ในส่วนนี้ เป้าหมายในการแก้ไขข้อบกพร่องคือการแยกฟีเจอร์ที่มีปัญหาออก และเรียกใช้ฟังก์ชันที่มีคำสั่งพิมพ์อยู่ ใช้รูปภาพและฟีเจอร์เดียวกันกับที่เคยใช้ก่อนหน้านี้

เครื่องมือแก้ไขโค้ด (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');

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

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

ตอนนี้ เนื่องจากฟังก์ชันจะทำงานกับองค์ประกอบเพียงรายการเดียว คุณจึงใส่การเรียกใช้การพิมพ์ ("display" สำหรับ geemap ของ Python) ไว้ด้านในได้ ตรวจสอบออบเจ็กต์ที่พิมพ์แล้วเพื่อดูว่าออบเจ็กต์ที่ reduceRegion() แสดงผลเป็นค่า Null สำหรับทุกย่านความถี่ ด้วยเหตุนี้การหารจึงดำเนินการไม่สำเร็จ เนื่องจากคุณไม่สามารถหาร Null ด้วย Null เหตุใดจึงเป็นค่า Null ตั้งแต่แรก หากต้องการตรวจสอบ ให้เพิ่มรูปภาพอินพุตและองค์ประกอบที่ไม่ถูกต้องลงในแผนที่ แล้วจัดให้องค์ประกอบที่ไม่ถูกต้องอยู่ตรงกลาง เมื่อทำเช่นนั้น คุณพบว่าปัญหาเกิดจากจุดอยู่นอกขอบเขตของรูปภาพ จากข้อมูลนี้ โค้ดที่แก้ไขข้อบกพร่องแล้วมีดังนี้

เครื่องมือแก้ไขโค้ด (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);

การตั้งค่า Python

ดูข้อมูลเกี่ยวกับ Python API และการใช้ geemap สําหรับการพัฒนาแบบอินเทอร์แอกทีฟได้ที่หน้า สภาพแวดล้อม Python

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)

เครื่องมือสร้างโปรไฟล์

เครื่องมือวิเคราะห์จะแสดงข้อมูลเกี่ยวกับเวลาที่ใช้ EECU และการใช้หน่วยความจํา (ต่ออัลกอริทึมและชิ้นงาน) ซึ่งเกิดจากการคำนวณที่ดำเนินการขณะที่เปิดใช้ มองหารายการที่ด้านบนของเครื่องมือวิเคราะห์เพื่อดูข้อมูลเกี่ยวกับการดําเนินการที่ต้องใช้ทรัพยากรมากที่สุด สําหรับสคริปต์ที่ทำงานเป็นเวลานานหรือไม่มีประสิทธิภาพ รายการที่ด้านบนของเครื่องมือวิเคราะห์จะบอกเป็นเบาะแสว่าควรมุ่งเน้นที่ส่วนใดเพื่อเพิ่มประสิทธิภาพสคริปต์ หมายเหตุสำคัญ: เครื่องมือวิเคราะห์จะส่งผลต่อประสิทธิภาพของสคริปต์ คุณจึงควรเรียกใช้เมื่อจำเป็นเท่านั้น