事件

事件會在使用者與小工具互動或對小工具進行程式變更時觸發。如要在事件發生時執行某些動作,請使用 onClick() (適用於 ui.Mapui.Button) 或 onChange() (其他所有情況) 在小工具上註冊回呼函式。您也可以在建構函式中指定回呼。事件回呼的參數會因小工具和事件類型而異。舉例來說,ui.Textbox 會將目前輸入的字串值傳遞至「點擊」事件回呼函式。請查看「Docs」分頁中的 API 參考資料,瞭解傳遞至各小工具回呼函式的參數類型。

以下範例說明單一使用者指定要顯示的圖片時,會產生多個事件。當使用者選取圖片時,另一個選取小工具會更新圖片的頻帶,並在地圖中顯示第一個頻帶:

程式碼編輯器 (JavaScript)

// Load some images.
var dem = ee.Image('NASA/NASADEM_HGT/001');
var veg = ee.Image('NOAA/VIIRS/001/VNP13A1/2022_06_02')
  .select(['EVI', 'EVI2', 'NDVI']);

// Make a drop-down menu of bands.
var bandSelect = ui.Select({
  placeholder: 'Select a band...',
  onChange: function(value) {
    var layer = ui.Map.Layer(imageSelect.getValue().select(value));
    // Use set() instead of add() so the previous layer (if any) is overwritten.
    Map.layers().set(0, layer);
  }
});

// Make a drop down menu of images.
var imageSelect = ui.Select({
  items: [
    {label: 'NASADEM', value: dem},
    {label: 'VIIRS Veg', value: veg}
  ],
  placeholder: 'Select an image...',
  onChange: function(value) {
    // Asynchronously get the list of band names.
    value.bandNames().evaluate(function(bands) {
      // Display the bands of the selected image.
      bandSelect.items().reset(bands);
      // Set the first band to the selected band.
      bandSelect.setValue(bandSelect.items().get(0));
    });
  }
});

print(imageSelect);
print(bandSelect);

請注意,當使用者選取圖片時,圖片的頻帶名稱清單會載入至 bandSelect 小工具,第一個頻帶會設為目前的值,而 bandSelectonChange 函式會自動觸發。請注意,evaluate() 會使用 bandNames() 傳回的 ComputedObject 值,以非同步方式取得該值。詳情請參閱「非同步事件」一節。

取消收聽

unlisten() 方法可移除在小工具上註冊的回呼函式。這項功能可避免觸發只會發生一次或在特定情況下發生的事件。onClick()onChange() 的傳回值是可傳遞至 unlisten() 的 ID,可讓小工具停止呼叫函式。如要註銷所有事件或特定類型的事件,請分別呼叫 unlisten() 並傳遞無參數或事件類型 (例如 'click''change') 參數。以下範例說明 unlisten() 如何協助開啟及關閉面板:

程式碼編輯器 (JavaScript)

// Create a panel, initially hidden.
var panel = ui.Panel({
  style: {
    width: '400px',
    shown: false
  },
  widgets: [
    ui.Label('Click on the map to collapse the settings panel.')
  ]
});

// Create a button to unhide the panel.
var button = ui.Button({
  label: 'Open settings',
  onClick: function() {
    // Hide the button.
    button.style().set('shown', false);
    // Display the panel.
    panel.style().set('shown', true);

    // Temporarily make a map click hide the panel
    // and show the button.
    var listenerId = Map.onClick(function() {
      panel.style().set('shown', false);
      button.style().set('shown', true);
      // Once the panel is hidden, the map should not
      // try to close it by listening for clicks.
      Map.unlisten(listenerId);
    });
  }
});

// Add the button to the map and the panel to root.
Map.add(button);
ui.root.insert(0, panel);

請注意,unlisten() 會停止 Map 監聽點擊事件,以便在面板已關閉時關閉面板。

非同步事件

如果要在小工具中使用 Earth Engine 結果 (例如縮減作業的數值輸出結果),就必須從伺服器取得值。(如要進一步瞭解 Earth Engine 中的用戶端與伺服器,請參閱這個頁面)。如要避免在計算該值時讓整個 UI 掛起,您可以使用 evaluate() 函式以非同步方式取得該值。evaluate() 函式會開始要求值,並在值就緒時呼叫回呼函式,以便使用結果執行某些動作。舉例來說,假設應用程式要取得某個時間點的 NDVI 時間序列平均值:

程式碼編輯器 (JavaScript)

// Load and display an NDVI image.
var ndvi = ee.ImageCollection('LANDSAT/COMPOSITES/C02/T1_L2_8DAY_NDVI')
    .filterDate('2014-01-01', '2015-01-01');
var vis = {min: 0, max: 1, palette: ['99c199', '006400']};
Map.addLayer(ndvi.median(), vis, 'NDVI');

// Configure the map.
Map.setCenter(-94.84497, 39.01918, 8);
Map.style().set('cursor', 'crosshair');

// Create a panel and add it to the map.
var inspector = ui.Panel([ui.Label('Click to get mean NDVI')]);
Map.add(inspector);

Map.onClick(function(coords) {
  // Show the loading label.
  inspector.widgets().set(0, ui.Label({
    value: 'Loading...',
    style: {color: 'gray'}
  }));

  // Determine the mean NDVI, a long-running server operation.
  var point = ee.Geometry.Point(coords.lon, coords.lat);
  var meanNdvi = ndvi.reduce('mean');
  var sample = meanNdvi.sample(point, 30);
  var computedValue = sample.first().get('NDVI_mean');

  // Request the value from the server.
  computedValue.evaluate(function(result) {
    // When the server returns the value, show it.
    inspector.widgets().set(0, ui.Label({
      value: 'Mean NDVI: ' + result.toFixed(2),
    }));
  });
});

使用者點選地圖上的某個點時,伺服器就會觸發 reduceRegion() 呼叫。這項作業可能需要一段時間。為避免應用程式在 Earth Engine 運算期間遭到封鎖,這個範例會將回呼函式註冊至結果,具體來說是 computedValue.evaluate()。運算完成後,系統會顯示結果。同時,系統會顯示訊息,指出運算程序正在進行中。