События инициируются взаимодействием пользователя с виджетом или программным изменением виджета. Чтобы что-то сделать при возникновении события, зарегистрируйте функцию обратного вызова в виджете либо с помощью onClick()
(для ui.Map
или ui.Button
), либо с onChange()
(все остальное). Вы также можете указать обратный вызов в конструкторе. Параметры обратных вызовов событий различаются в зависимости от виджета и типа события. Например, ui.Textbox
передает введенное в данный момент строковое значение в свои функции обратного вызова события «click». Проверьте ссылку 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
, для первой полосы устанавливается текущее значение, а функция onChange
bandSelect
запускается автоматически. Также обратите внимание на использование метода evaluate()
для асинхронного получения значения ComputedObject
, возвращаемого bandNames()
. Подробнее читайте в разделе «Асинхронные события» .
Не слушая
Метод unlisten()
предоставляет возможность удалять функции обратного вызова, зарегистрированные в виджете. Это полезно для предотвращения запуска событий, которые должны происходить только один раз или при определенных обстоятельствах. Возвращаемое значение onClick()
или onChange()
— это идентификатор, который можно передать в unlisten()
, чтобы виджет прекратил вызывать функцию. Чтобы отменить регистрацию всех событий или событий определенного типа, вызовите 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 см. на этой странице ). Чтобы не зависать весь пользовательский интерфейс во время вычисления этого значения, вы можете использовать функцию 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()
. По завершении вычислений отображается результат. Тем временем отображается сообщение, указывающее, что вычисление продолжается.