活动

事件由用户与微件互动或对微件进行程序化更改触发。如需在事件发生时执行操作,请使用 onClick()(对于 ui.Mapui.Button)或 onChange()(对于所有其他情况)在 widget 上注册回调函数。您还可以在构造函数中指定回调。事件回调的参数因 widget 和事件类型而异。例如,ui.Textbox 会将当前输入的字符串值传递给其“click”事件回调函数。请查看文档标签页中的 API 参考文档,了解传递给每个 widget 的回调函数的参数类型。

以下示例演示了由指定要显示的图片这一单个用户操作产生的多个事件。当用户选择某个图片时,另一个选择 widget 会更新为显示该图片的波段,并在地图中显示第一个波段:

// 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() 方法可用于移除在 widget 上注册的回调函数。这对于防止触发应仅发生一次或仅在特定情况下发生的事件非常有用。onClick()onChange() 的返回值是一个 ID,可传递给 unlisten() 以使 widget 停止调用该函数。如需取消注册所有事件或特定类型的事件,请分别调用不带参数或带事件类型(例如 'click''change')参数的 unlisten()。以下示例演示了 unlisten() 以便于打开和关闭面板:

// 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 监听点击事件,以便在面板已关闭时关闭面板。

异步事件

如果您要在 widget 中使用 Earth Engine 结果(例如缩减操作的数值输出),则需要从服务器获取该值。(如需详细了解 Earth Engine 中的客户端与服务器,请参阅此页面)。为避免在计算该值时挂起整个界面,您可以使用 evaluate() 函数异步获取该值。evaluate() 函数会发起对值的请求,并在值准备就绪时调用回调函数以对结果执行某些操作。例如,假设有一个应用用于获取某个时间点的 NDVI 时间序列的平均值:

// 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()。计算完成后,系统会显示结果。在此期间,系统会显示一条消息,指明计算正在进行中。