Widget

Esistono diversi widget che puoi utilizzare per creare le tue UI. Questi widget includono pulsanti, caselle di controllo, cursori, caselle di testo e menu di selezione. I widget possono essere stampati o aggiunti a un riquadro solo una volta. Le sezioni seguenti illustrano la funzionalità di base, l'aspetto e la resa dei widget. Per ulteriori informazioni su come applicare uno stile ai widget, consulta la sezione Stile. Gli esempi riportati di seguito print() semplicemente i widget nella console. Per informazioni dettagliate sull'aggiunta di widget ai riquadri, consulta la pagina Riquadri e layout.

ui.Label

Le etichette sono semplicemente aree in cui viene visualizzato il testo. Ad esempio, il seguente codice stampa un'etichetta:

Editor di codice (JavaScript)

var label = ui.Label('Cool label!');
print(label);

che ha il seguente aspetto:

ui_label.png

Suddividi le etichette lunghe inserendo un nuovo carattere di a capo (\n) e impostando l'argomento della proprietà di stile whiteSpace su 'pre':

print(ui.Label('Here is a:\nnew line', {whiteSpace: 'pre'}));

ui.Button

Un pulsante è un widget dell'interfaccia utente interattivo su cui è possibile fare clic. Puoi specificare una funzione da chiamare (la funzione "callback") quando un utente fa clic sul pulsante. Per ulteriori informazioni sulla gestione degli eventi con le funzioni di callback, consulta la pagina Eventi. L'esempio seguente stampa il centro corrente della mappa quando viene fatto clic sul pulsante:

Editor di codice (JavaScript)

var button = ui.Button({
  label: 'Get Map Center',
  onClick: function() {
    print(Map.getCenter());
  }
});
print(button);

che ha il seguente aspetto:

ui_button.png

ui.Checkbox

Una casella di controllo è un widget che consente a un utente di selezionare (o deselezionare) una casella. Quando lo stato della casella di controllo cambia, ai callback registrati al widget viene passato un valore booleano che indica se la casella di controllo è ora selezionata. Ad esempio:

Editor di codice (JavaScript)

var checkbox = ui.Checkbox('Show SRTM layer', true);

checkbox.onChange(function(checked) {
  // Shows or hides the first map layer based on the checkbox's value.
  Map.layers().get(0).setShown(checked);
});

Map.addLayer(ee.Image('CGIAR/SRTM90_V4'));
print(checkbox);

La casella di controllo stampata dovrebbe avere il seguente aspetto:

ui_checkbox.png

Tieni presente che la selezione della casella attiva un livello visualizzato sulla mappa. Come per gli altri componenti dell'interfaccia utente, la mappa dell'editor di codice può essere manipolata tramite programmazione. Scopri di più sull'oggetto Map nella pagina Riquadri e layout.

ui.Slider

Un dispositivo di scorrimento è un widget che consente a un utente di regolare un dispositivo di scorrimento per ottenere un numero compreso nell'intervallo del dispositivo di scorrimento. Configura l'intervallo utilizzando il costruttore o impostando le proprietà del dispositivo di scorrimento. L'esempio seguente utilizza il cursore per impostare l'opacità del primo livello della mappa:

Editor di codice (JavaScript)

var slider = ui.Slider();

slider.setValue(0.9);  // Set a default value.
slider.onChange(function(value) {
  Map.layers().get(0).setOpacity(value);
});

Map.addLayer(ee.Image(255), {palette: 'blue'});
print(slider);

Il cursore dovrebbe avere il seguente aspetto:

ui_slider.png

Tieni presente che il valore del dispositivo di scorrimento viene visualizzato a destra.

ui.DateSlider

Il widget DateSlider è simile al widget Slider, ma gestisce le date in modo esplicito. Un DateSlider configurato per selezionare un giorno di giugno 2018 ha il seguente aspetto:

DateSlider.png

DateSlider è utile per filtrare le raccolte, come mostrato nell'esempio seguente, che crea un composito annuale in base al valore DateRange impostato in DateSlider:

Editor di codice (JavaScript)

// Use a DateSlider to create annual composites of this collection.
var collection = ee.ImageCollection('LANDSAT/LC08/C02/T1');
// Use the start of the collection and now to bound the slider.
var start = ee.Image(collection.first()).date().get('year').format();
var now = Date.now();
var end = ee.Date(now).format();

// Run this function on a change of the dateSlider.
var showMosaic = function(range) {
  var mosaic = ee.Algorithms.Landsat.simpleComposite({
    collection: collection.filterDate(range.start(), range.end())
  });
  // Asynchronously compute the name of the composite.  Display it.
  range.start().get('year').evaluate(function(name) {
    var visParams = {bands: ['B4', 'B3', 'B2'], max: 100};
    var layer = ui.Map.Layer(mosaic, visParams, name + ' composite');
    Map.layers().set(0, layer);
  });
};

// Asynchronously compute the date range and show the slider.
var dateRange = ee.DateRange(start, end).evaluate(function(range) {
  var dateSlider = ui.DateSlider({
    start: range['dates'][0],
    end: range['dates'][1],
    value: null,
    period: 365,
    onChange: showMosaic,
    style: {width: '180px'}
  });
  Map.add(dateSlider.setValue(now));
});

// Initialize the map location at southern Africa.
Map.setCenter(23.861, -27.144, 6);

ui.Textbox

Una casella di testo è un luogo in cui raccogliere il testo inserito dall'utente. Ad esempio:

Editor di codice (JavaScript)

var textbox = ui.Textbox({
  placeholder: 'Enter text here...',
  onChange: function(text) {
    print('So what you are saying is ' + text + '?');
  }
});
print(textbox);

La casella di testo dovrebbe avere il seguente aspetto:

ui_textbox.png

Tieni presente che il callback viene attivato solo quando l'utente ha terminato di inserire il testo (e premuto Invio) o quando l'utente fa clic al di fuori della casella di testo.

ui.Select

Il widget di selezione rappresenta un menu a discesa di opzioni tra cui l'utente può scegliere. L'esempio seguente mostra un menu a discesa che consente a un utente di selezionare una località:

Editor di codice (JavaScript)

var places = {
  MTV: [-122.0849, 37.3887],
  PEK: [116.4056, 39.9097],
  ZRH: [8.536, 47.376]
};

var select = ui.Select({
  items: Object.keys(places),
  onChange: function(key) {
    Map.setCenter(places[key][0], places[key][1]);
  }
});

// Set a place holder.
select.setPlaceholder('Choose a location...');

print(select);

Il widget selezionato dovrebbe avere il seguente aspetto:

ui_select.png

ui.Chart

I grafici nel pacchetto ui.Chart si comportano in modo simile ai grafici nel pacchetto Chart. Nello specifico, un ui.Chart è un guscio sottile attorno a un'istanza di ChartWrapper dell'API Google Visualization. Per ulteriori informazioni sulla manipolazione degli oggetti ChartWrapper, consulta questo riferimento. Per ulteriori informazioni sulle funzioni di supporto dei grafici in Earth Engine, consulta la documentazione dei grafici.

ui.Thumbnail

Il widget delle miniature può essere utilizzato per visualizzare l'anteprima degli oggetti ee.Image e ee.ImageCollection. Se viene fornito un ee.Image, il widget mostrerà un'immagine statica; se viene fornito un ee.ImageCollection, mostrerà un'animazione con un frame per immagine nell'input. Come per ee.Image.getThumbURL() e ee.ImageCollection.getVideoThumbURL(), puoi specificare parametri per controllare il formato e le dimensioni della miniatura risultante:

Editor di codice (JavaScript)

// Create a box around an area in the Brazilian Amazon.
var box = ee.Geometry.Polygon([[
  [-62.9564, 2.5596], [-62.9550, 2.4313], [-62.8294, 2.4327], [-62.8294, 2.5596]
]]);

// Visualize the image in RGB.
var image = ee.Image('LANDSAT/LE07/C02/T1_L2/LE07_233058_20011113')
                .select(['SR_B[1-3]'])  // blue, green, red reflectance
                .multiply(0.0000275).add(-0.2)  // apply scaling factors
                .visualize({
                  bands: ['SR_B3', 'SR_B2', 'SR_B1'],
                  min: 0,
                  max: 0.12,
                  gamma: 1.3
                });

// Print a thumbnail to the console.
print(ui.Thumbnail({
  image: image,
  params: {dimensions: '256x256', region: box, format: 'png'},
  style: {height: '300px', width: '300px'}
}));

La miniatura dovrebbe avere il seguente aspetto:

ui_thumbnail.png

ui.Map

Un ui.Map è un widget mappa. Infatti, la mappa Editor di codice predefinita è un'istanza di questa classe. Come per gli altri widget, puoi stampare una mappa nella console. Manipolare i contenuti della mappa cancellando, ottenendo o impostando singoli livelli. L'esempio seguente stampa nella console una mappa che mostra i limiti della mappa dell'editor di codice:

Editor di codice (JavaScript)

// Make a little map.
var map = ui.Map();

// Make the little map display an inset of the big map.
var createInset = function() {
  var bounds = ee.Geometry.Rectangle(Map.getBounds());
  map.centerObject(bounds);
  map.clear();
  map.addLayer(bounds);
};

// Run it once to initialize.
createInset();

// Get a new inset map whenever you click on the big map.
Map.onClick(createInset);

// Display the inset map in the console.
print(map);

La mappa in rilievo dovrebbe avere il seguente aspetto:

ui_map.png

In questo esempio, l'utente deve fare clic sulla mappa grande per visualizzare l'insetto nella mappa piccola.

Puoi anche manipolare i livelli sulla mappa chiamando layers() sull'istanza della mappa. layers() restituisce un ui.data.ActiveList, un oggetto simile a un array. Quando viene modificata, cambiano anche i livelli della mappa. Scopri di più nella sezione ui.Map.Layer.

ui.Map.Layer

Un livello non è un widget personalizzabile come un ui.Button. Si tratta solo di una rappresentazione dei dati del livello sulla mappa. L'esempio seguente mostra come aggiornare una mappa creando un livello e aggiornandone le proprietà in base all'input dell'utente:

Editor di codice (JavaScript)

var consoleMap = ui.Map({
  lon: -2.0174,
  lat: 48.6474,
  zoom: 13
});

// Create a Layer from this Sentinel-2 image
var image = ee.Image('COPERNICUS/S2/20150821T111616_20160314T094808_T30UWU');
var visParams = {bands: ['B4', 'B3', 'B2'], max: 2048, gamma: 1};
var layer = ui.Map.Layer(image, visParams);

// Update the map by updating the layers list.
var layers = consoleMap.layers();
layers.add(layer);

// Make a textbox to accept a gamma value.
// Update the layer when the gamma value is entered.
var gammaBox = ui.Textbox({
  value: 1,
  onChange: function(value) {
    // visParams is NOT an ActiveDictionary, so set it again.
    visParams.gamma = value;
    layer.setVisParams(visParams);
  }
});

print(ui.Label('Enter a gamma value:'));
print(gammaBox);
print(consoleMap);

ui.Map.CloudStorageLayer

Se vuoi visualizzare (ad es. in un'app) un livello di calcolo relativamente costoso, ti consigliamo di esportare i dati in un bucket Cloud Storage per motivi di prestazioni. Questi livelli statici solo per la visualizzazione possono rendere le tue app e i tuoi script più reattivi. A questo scopo, puoi creare un livello di visualizzazione statico utilizzando Export.map.toCloudStorage(). Per utilizzare un insieme di riquadri esportato in precedenza da Export.map.toCloudStorage(), crea un nuovo ui.Map.Layer da un bucket Cloud Storage e un percorso specificati:

Map.add(ui.Map.CloudStorageLayer({
  bucket: 'earthenginepartners-hansen',
  path: 'tiles/gfc_v1.4/loss_year',
  maxZoom: 12,
  suffix: '.png'
}));

Quando esegui uno script che carica un livello Cloud Storage, potresti visualizzare il messaggio di avviso:

Avviso sul livello di nuvole

ui.Map.DrawingTools

Esiste un insieme di strumenti di disegno geometrico che viene aggiunto per impostazione predefinita a Map nell'editor di codice. Puoi modificare il comportamento di questi strumenti nel valore predefinito Map chiamando Map.drawingTools(). Ad esempio, per nascondere gli strumenti di disegno:

Editor di codice (JavaScript)

Map.drawingTools().setShown(false);

Per impostazione predefinita, le mappe appena create non dispongono degli strumenti di disegno, ma possono essere attivati chiamando il metodo drawingTools() sulla mappa:

Editor di codice (JavaScript)

var map = ui.Map();
// Prints true since drawingTools() adds drawing tools to the map.
print(map.drawingTools().getShown());
// Replace the default Map with the newly created map.
ui.root.widgets().reset([map]);

I livelli di geometria disegnati dagli strumenti di disegno vengono inseriti in un ui.data.ActiveList a cui puoi accedere chiamando Map.drawingTools().layers(). L'elenco dei livelli di geometria risponde agli eventi come gli altri elenchi attivi, ad esempio l'elenco dei livelli in Map restituito da Map.layers(). L'esempio seguente mostra come impostare la visibilità dei livelli geometrici disegnati dagli strumenti (che vengono visualizzati per impostazione predefinita):

Editor di codice (JavaScript)

Map.drawingTools().layers().forEach(function(layer) {
  layer.setShown(false);
});

Per aggiungere un livello in modo programmatico agli strumenti di disegno, puoi chiamare il metodo addLayer sugli strumenti di disegno o aggiungere un livello direttamente all'elenco dei livelli:

Editor di codice (JavaScript)

var geometries = [ee.Geometry.Point([0,0]), ee.Geometry.Rectangle([[0,0], [1,1]])];
Map.drawingTools().addLayer(geometries, 'my_geometry1', 'red');

var layer = ui.Map.GeometryLayer(geometries, 'my_geometry2', 'blue');
Map.drawingTools().layers().add(layer);

Lo stato degli strumenti di disegno viene mantenuto anche quando pubblichi un'app. Se hai visualizzato o nascosto gli strumenti di disegno, verranno visualizzati o nascosti anche nell'app. Anche le geometrie nelle importazioni verranno trasferite nell'app.

ui.Map.GeometryLayer

Un GeometryLayer è una raccolta di geometrie che agisce come un singolo Geometry, GeometryCollection o FeatureCollection che viene aggiunto alla sezione delle importazioni nella parte superiore dello script e a cui è possibile fare riferimento nel codice.

I GeometryLayer disegnati dagli strumenti di disegno hanno un comportamento predefinito che puoi override fornendo nuove funzioni di callback. Ad esempio, supponiamo che tu voglia attivare un evento con le modifiche interattive alle geometrie. Per implementare un determinato comportamento, puoi impostare i metodi onEdit(), onErase() o onDraw() sugli strumenti per rispondere alle azioni dell'utente. L'esempio seguente mostra come attivare un calcolo e aggiornare un'etichetta con il risultato del calcolo quando l'utente aggiunge/modifica/cancella una geometria:

Editor di codice (JavaScript)

// Load elevation data.
var srtm = ee.Image('USGS/SRTMGL1_003');
Map.addLayer(srtm, {min: 0, max: 5000}, 'SRTM');

// Make a label to display mean elevation at drawn points.
var label = new ui.Label('Draw points to calculate mean elevation');
var inspector = new ui.Panel([label]);
Map.add(inspector);
// Don't make imports that correspond to the drawn points.
Map.drawingTools().setLinked(false);
// Limit the draw modes to points.
Map.drawingTools().setDrawModes(['point']);
// Add an empty layer to hold the drawn points.
Map.drawingTools().addLayer([]);
// Set the geometry type to be point.
Map.drawingTools().setShape('point');
// Enter drawing mode.
Map.drawingTools().draw();

// This function gets called when the geometry layer changes.
// Use debounce to call the function at most every 100 milliseconds.
var getAverageElevation = ui.util.debounce(function() {
  var points = Map.drawingTools().layers().get(0).toGeometry();
  var elevation = srtm.reduceRegion({
    reducer: ee.Reducer.mean(),
    geometry: points,
    scale: 30
  }).get('elevation');
  // Asynchronously evaluate the mean elevation.
  elevation.evaluate(showElevation);
}, 100);

// Set the callback function on changes of the geometry layer.
Map.drawingTools().onEdit(getAverageElevation);
Map.drawingTools().onDraw(getAverageElevation);
Map.drawingTools().onErase(getAverageElevation);

// Set the label to the result of the mean reduction.
function showElevation(elevation) {
  inspector.clear();
  var elevationLabel = ui.Label('Mean elevation: ' + elevation);
  inspector.add(elevationLabel);
}

Tieni presente che setLinked() viene utilizzato per attivare/disattivare la connessione tra gli strumenti di disegno geometrico e la sezione Importazioni dell'editor di codice. In questo esempio, gli strumenti di geometria sono scollegati per impedire la creazione di importazioni. toGeometry viene utilizzato per convertire il livello in un ee.Geometry. Se il livello importato rappresenta un Feature o un FeatureCollection, puoi recuperare l'oggetto EE sottostante utilizzando getEeObject(). Tieni presente anche l'utilizzo di ui.util.debounce per impedire che ogni movimento di una geometria attivi la funzione di callback. Nello specifico, la funzione non verrà attivata finché non saranno trascorsi 100 millisecondi dall'ultimo evento. In questo modo, la funzione viene eseguita solo quando l'utente ha completato l'azione di modifica.

Un livello di geometria nelle importazioni è associato a un Geometry o GeometryCollection, pertanto può contenere solo geometrie con lo stesso stato geodesico perché il formato GeoJSON consente un solo stato geodesico per la raccolta di geometrie (per ulteriori informazioni, consulta la pagina Geometrie geodesiche e planari). Se converti il livello di geometria in un FeatureCollection facendo clic sull'icona a forma di ingranaggio accanto al nome del livello, potrai aggiungere geometrie geodesiche e piane allo stesso livello. Tuttavia, la conversione in un Geometry produrrà un errore. Per evitare questo problema, converti in un FeatureCollection o elimina le geometrie finché non è presente un solo stato geodetico nel livello.

ui.Map.Linker

Come un livello, un linker non è un widget personalizzabile. Si tratta di un'utilità dietro le quinte che può essere utilizzata per sincronizzare il movimento di più istanze ui.Map:

Editor di codice (JavaScript)

// Add two maps to the screen.
var left = ui.Map();
var right = ui.Map();
ui.root.clear();
ui.root.add(left);
ui.root.add(right);

// Link the "change-bounds" event for the maps.
// When the user drags one map, the other will be moved in sync.
ui.Map.Linker([left, right], 'change-bounds');

ui.SplitPanel

Un ui.SplitPanel è utile per confrontare elementi uno accanto all'altro. Il vantaggio di un ui.SplitPanel rispetto a due riquadri normali è che è possibile utilizzare un handle per eseguire una transizione di scorrimento tra i riquadri in un ui.SplitPanel. L'esempio seguente utilizza un ui.SplitPanel per mostrare le differenze spettrali delle cicatrici da bruciatura:

Editor di codice (JavaScript)

// Load an image of the Santa Rosa, California 2017 fires.
var image = ee.Image('LANDSAT/LC08/C02/T1_TOA/LC08_045033_20171011');

// Add a color-SWIR composite to the default Map.
Map.setCenter(-122.6624, 38.5011, 12);
Map.addLayer(image, {bands: ['B7', 'B5', 'B3'], max: 0.3}, 'color-SWIR');

// Make another map and add a color-NIR composite to it.
var linkedMap = ui.Map();
linkedMap.addLayer(image, {bands: ['B5', 'B4', 'B3'], max: 0.3}, 'color-NIR');
// Add a thermal image to the map.
linkedMap.addLayer(image, {
  bands: ['B11'],
  min: 290,
  max: 305,
  palette: ['gray', 'white', 'yellow', 'red']
}, 'Thermal');

// Link the default Map to the other map.
var linker = ui.Map.Linker([ui.root.widgets().get(0), linkedMap]);

// Make an inset map and add it to the linked map.
var inset = ui.Map();
inset.style().set({position: 'bottom-right', width: '300px', height: '250px'});
inset.setControlVisibility({all: false, mapTypeControl: true});
linkedMap.add(inset);

// Register a function to the linked map to update the inset map.
linkedMap.onChangeBounds(function() {
  var bounds = ee.Geometry.Rectangle(Map.getBounds());
  inset.centerObject(bounds);
  inset.layers().set(0, bounds);
});

// Create a SplitPanel which holds the linked maps side-by-side.
var splitPanel = ui.SplitPanel({
  firstPanel: linker.get(0),
  secondPanel: linker.get(1),
  orientation: 'horizontal',
  wipe: true,
  style: {stretch: 'both'}
});

// Set the SplitPanel as the only thing in root.
ui.root.widgets().reset([splitPanel]);

Tieni presente che il parametro wipe è impostato su true nel costruttore ui.SplitPanel per consentire all'utente di scorrere il cursore avanti e indietro tra le due visualizzazioni.

Widget di stile

Lo stile di un widget è controllato dal dizionario delle proprietà di stile del widget. Puoi accedere al dizionario chiamando style() sul widget. L'oggetto restituito da style() è un'istanza di ui.data.ActiveDictionary. Ciò significa che l'impostazione delle proprietà del dizionario di stile aggiorna automaticamente il modo in cui viene visualizzato il widget. Le chiavi consentite per il dizionario di stili di ciascun widget sono descritte nella documentazione di riferimento del widget per la chiamata style().

Gli stili del widget possono essere impostati con il costruttore, chiamando style().set() o chiamando style() con un argomento del dizionario. Ad esempio:

Editor di codice (JavaScript)

var redLabel = ui.Label('Big, Red Label');

redLabel.style().set('color', 'red');
redLabel.style().set('fontWeight', 'bold');
redLabel.style().set({
  fontSize: '32px',
  padding: '10px'
});

print(redLabel);

Tieni presente che in questo esempio lo stile dell'etichetta viene applicato prima chiamando style().set() con gli argomenti chiave e valore, poi chiamando style().set() con un argomento dizionario. La seconda chiamata non sostituisce la prima, ma aggiunge e sostituisce le singole proprietà di stile anziché sostituire l'intero dizionario di stili.

Per ulteriori informazioni sulle opzioni di stile per i widget, consulta questa documentazione di riferimento su Cascading Style Sheets (CSS) per gli stili elencati nella documentazione di style() per ogni widget. Tieni presente che gli stili consentiti per i widget di Earth Engine sono diversi dagli stili CSS in diversi punti, in particolare fontSize e fontWeight per font-style e font-weight, rispettivamente.

Il dizionario di stili contiene anche chiavi che controllano la posizione del widget. Per ulteriori informazioni su come utilizzare le proprietà di posizione, consulta la pagina Riquadri e layout.