Widżety

Do tworzenia interfejsu użytkownika możesz używać różnych widżetów. Te widżety obejmują przyciski, pola wyboru, suwaki, pola tekstowe i menu wyboru. Widżety można wydrukować lub dodać do panelu tylko raz. W następnych sekcjach opisujemy podstawowe funkcje, wygląd i wygodę korzystania z widżetów. Więcej informacji o stylach widżetów znajdziesz w sekcji Styl. W poniższych przykładach widżety są tylko dodawane do konsoli.print() Szczegółowe informacje o dodawaniu widżetów do paneli znajdziesz na stronie Panele i schematy.

ui.Label

Etykiety to po prostu obszary, na których wyświetla się tekst. Na przykład ten kod drukuje etykietę:

Edytor kodu (JavaScript)

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

Wygląda to mniej więcej tak:

ui_label.png

Długie etykiety można podzielić, wstawiając znak nowego wiersza (\n) i ustawiając argument właściwości stylu whiteSpace na 'pre':

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

ui.Button

Przycisk to interaktywny widżet interfejsu użytkownika, który można kliknąć. Możesz określić funkcję, która ma być wywoływana („funkcja wywołania zwrotnego”), gdy użytkownik kliknie przycisk. (więcej informacji o obsługiwaniu zdarzeń za pomocą funkcji wywołania zwrotnego znajdziesz na stronie Zdarzenia). W tym przykładzie po kliknięciu przycisku jest drukowany bieżący środek mapy:

Edytor kodu (JavaScript)

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

Wygląda to mniej więcej tak:

ui_button.png

ui.Checkbox

Pole wyboru to element, który pozwala użytkownikowi zaznaczyć (lub odznaczyć) pole. Gdy stan pola wyboru ulegnie zmianie, wywołania zarejestrowane w widżecie otrzymają wartość logiczną wskazującą, czy pole wyboru jest teraz zaznaczone. Na przykład:

Edytor kodu (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);

Wydrukowane pole wyboru powinno wyglądać mniej więcej tak:

ui_checkbox.png

Zaznacz to pole, aby włączyć warstwę wyświetlaną na mapie. Podobnie jak w przypadku innych komponentów interfejsu użytkownika, mapę w Edytorze kodu można modyfikować programowo. Więcej informacji o obiekcie Mapa znajdziesz na stronie Panele i układy.

ui.Slider

Suwak to widżet, który pozwala użytkownikowi dostosować suwak, aby uzyskać liczbę w zakresie suwaka. Skonfiguruj zakres za pomocą konstruktora lub ustawiając właściwości suwaka. W tym przykładzie suwak służy do ustawienia przezroczystości pierwszej warstwy na mapie:

Edytor kodu (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);

Suwak powinien wyglądać mniej więcej tak:

ui_slider.png

Pamiętaj, że wartość suwaka jest wyświetlana po jego prawej stronie.

ui.DateSlider

Widżet DateSlider działa podobnie jak widżet Slider, ale obsługuje daty w sposób jawny. Tag DateSlider skonfigurowany tak, aby wybierać dzień w czerwcu 2018 r., wygląda tak:

DateSlider.png

Parametr DateSlider jest przydatny do filtrowania kolekcji, jak w tym przykładzie, w którym tworzymy roczne dane złożone na podstawie zbioru DateRange określonego w parasterze DateSlider:

Edytor kodu (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

Pole tekstowe to miejsce na tekst wpisywany przez użytkownika. Na przykład:

Edytor kodu (JavaScript)

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

Pole tekstowe powinno wyglądać mniej więcej tak:

ui_textbox.png

Pamiętaj, że funkcja wywołania zwrotnego jest wywoływana tylko wtedy, gdy użytkownik skończy wpisywać tekst (i wciśnie Return) lub kliknie poza polem tekstowym.

ui.Select

Widget Select to menu, z którego użytkownik może wybrać jedną opcję. Poniższy przykład pokazuje menu, które umożliwia użytkownikowi wybranie lokalizacji:

Edytor kodu (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);

Widżet „Wybierz” powinien wyglądać mniej więcej tak:

ui_select.png

ui.Chart

Wykresy w pakiecie ui.Chart działają podobnie jak wykresy w pakiecie Chart. W szczególności ui.Chart to cienka powłoka otaczająca instancję ChartWrapper interfejsu Google Visualization API. Więcej informacji o modyfikowaniu obiektów ChartWrapper znajdziesz w tej dokumentacji. Więcej informacji o funkcjach pomocniczych wykresów w Earth Engine znajdziesz w dokumentacji dotyczącej wykresów.

ui.Thumbnail

Za pomocą widżetu miniatury możesz wyświetlić podgląd obiektów ee.Image i ee.ImageCollection. Jeśli podasz wartość ee.Image, widżet wyświetli obraz statyczny, a jeśli ee.ImageCollection, wyświetli animację z jednym obrazem na wejście. Podobnie jak w przypadku parametrów ee.Image.getThumbURL() i ee.ImageCollection.getVideoThumbURL() możesz określić parametry, aby kontrolować format i wymiary otrzymanej miniatury:

Edytor kodu (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'}
}));

Miniatura powinna wyglądać mniej więcej tak:

ui_thumbnail.png

ui.Map

ui.Map to widżet mapy. (domyślny edytor kodu Map jest w rzeczywistości wystąpieniem tej klasy). Podobnie jak w przypadku innych widżetów, możesz wydrukować mapę na konsoli. manipulować zawartością mapy przez czyszczenie, pobieranie lub ustawianie poszczególnych warstw; W tym przykładzie do konsoli jest wypisywana mapa z oznaczonymi na niej granicami mapy w Edytorze kodu:

Edytor kodu (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);

Mapa w ramce powinna wyglądać mniej więcej tak:

ui_map.png

W tym przykładzie użytkownik musi kliknąć dużą mapę, aby uzyskać wstawioną mapę, na której można rysować.

Manipulowanie warstwami na mapie jest też możliwe przez wywołanie funkcji layers() na instancji mapy. Funkcja layers() zwraca obiekt ui.data.ActiveList, który jest podobny do tablicy. Gdy zmienisz ustawienie, warstwy na mapie również się zmienią. Więcej informacji znajdziesz w sekcji ui.Map.Layer.

ui.Map.Layer

Warstwy nie są elementami, które można stylizować, tak jak w przypadku elementu ui.Button. To tylko dane warstwy na mapie. Ten przykład pokazuje aktualizowanie mapy przez utworzenie warstwy i zaktualizowanie jej właściwości na podstawie danych wejściowych użytkownika:

Edytor kodu (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

Jeśli chcesz wyświetlić (np. w aplikacji) stosunkowo kosztowną warstwę obliczeniową, możesz wyeksportować dane do zasobnika Cloud Storage ze względu na wydajność. Te statyczne warstwy służące tylko do wizualizacji mogą zwiększyć szybkość działania aplikacji i skryptów. W tym celu możesz utworzyć stałą warstwę wyświetlania za pomocą Export.map.toCloudStorage(). Aby użyć zestawu płytek wyeksportowanego wcześniej przez Export.map.toCloudStorage(), utwórz nowy ui.Map.Layer z wybranego zasobnika Cloud Storage i ścieżki:

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

Podczas uruchamiania skryptu, który wczytuje warstwę Cloud Storage, może pojawić się komunikat ostrzeżenia:

Ostrzeżenie dotyczące warstwy chmur

ui.Map.DrawingTools

Domyślnie do Map w Edytorze kodu jest dodawany zestaw narzędzi do rysowania geometrii. Możesz zmienić działanie tych narzędzi w domyślnym Map, wywołując funkcję Map.drawingTools(). Aby na przykład ukryć narzędzia do rysowania:

Edytor kodu (JavaScript)

Map.drawingTools().setShown(false);

Nowo utworzone mapy nie mają domyślnie narzędzi do rysowania, ale można je włączyć, wywołując metodę drawingTools() na mapie:

Edytor kodu (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]);

Warstwy geometryczne narysowane za pomocą narzędzi do rysowania są umieszczane w ui.data.ActiveList, do którego można uzyskać dostęp, wywołując funkcję Map.drawingTools().layers(). Lista warstw geometrii reaguje na zdarzenia podobnie jak inne aktywne listy, na przykład lista warstw w Map zwracana przez Map.layers(). Ten przykład pokazuje, jak ustawić widoczność warstw geometrii rysowanych przez narzędzia (które są domyślnie widoczne):

Edytor kodu (JavaScript)

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

Aby dodać warstwę do narzędzi do rysowania za pomocą kodu, możesz wywołać metodę addLayer narzędzi do rysowania lub dodać warstwę bezpośrednio do listy warstw:

Edytor kodu (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);

Stan narzędzi do rysowania jest również przenoszony podczas publikowania aplikacji. Jeśli narzędzia do rysowania są widoczne lub ukryte, będą również widoczne lub ukryte w aplikacji. Geometria z importowanych plików zostanie również przeniesiona do aplikacji.

ui.Map.GeometryLayer

GeometryLayer to zbiór geometrii, który działa jak pojedyncza geometria Geometry, GeometryCollection lub FeatureCollection dodana do sekcji importowania na początku skryptu i do której można się odwoływać w kodzie.

GeometryLayers narysowane za pomocą narzędzi do rysowania mają domyślne zachowanie, które możesz zastąpić, podając nowe funkcje wywołania zwrotnego. Załóżmy na przykład, że chcesz, aby zmiany interaktywne geometrii uruchamiały zdarzenie. Aby wdrożyć określone działanie, możesz ustawić metodę onEdit(), onErase() lub onDraw() w narzędziach, aby reagować na działania użytkowników. Ten przykład pokazuje, jak wywołać obliczenie i zaktualizować etykietę za pomocą wyniku obliczeń, gdy użytkownik dodaje, edytowanie lub usuwa geometrię:

Edytor kodu (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);
}

Pamiętaj, że setLinked() służy do przełączania połączenia między narzędziami do rysowania geometrii a sekcją Importy w Edytorze kodu. W tym przykładzie narzędzia do geometrii są odłączone, aby zapobiec tworzeniu importów. toGeometry służy do konwertowania warstwy na ee.Geometry. Jeśli zaimportowana warstwa reprezentuje warstwę Feature lub FeatureCollection, możesz pobrać podstawowy obiekt EE za pomocą parametru getEeObject(). Zwróć też uwagę na użycie funkcji ui.util.debounce, aby zapobiec wywoływaniu funkcji wywołania zwrotnego przy każdym ruchu geometrii. W szczególności funkcja nie zostanie uruchomiona, dopóki nie upłynie 100 milisekund od ostatniego zdarzenia. Dzięki temu funkcja działa tylko wtedy, gdy użytkownik wykonał już działanie polegające na edycji.

Warstwa geometryczna w importach jest powiązana z elementem Geometry lub GeometryCollection, więc może zawierać tylko geometrie o tym samym stanie geodezyjnym, ponieważ format GeoJSON zezwala na jeden stan geodezyjny dla kolekcji geometrii (więcej informacji znajdziesz na stronie Geometria geodezyjna a płaska). Konwertowanie warstwy geometrii na warstwę FeatureCollection przez naciśnięcie ikony koła zębatego obok nazwy warstwy umożliwi dodawanie geometrii geodezyjnej i płaskiej do tej samej warstwy. Jednak konwertowanie go z powrotem na Geometry spowoduje błąd. Aby tego uniknąć, przeprowadź konwersję na FeatureCollection lub usuń geometrie, aż w warstwie pozostanie tylko jeden stan geodezyjny.

ui.Map.Linker

Podobnie jak warstwa, łącznik nie jest elementem sterowanym przez styl. Jest to narzędzie działające w tle, które można wykorzystać do synchronizacji ruchu wielu instancji ui.Map:

Edytor kodu (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

ui.SplitPanel przydaje się do porównywania elementów obok siebie. Zaletą ui.SplitPanel w porównaniu z dwoma zwykłymi panelami jest to, że można użyć uchwytu do przeprowadzenia przejścia między panelami w ui.SplitPanel. W tym przykładzie użyto ui.SplitPanel do wyświetlenia różnic spektralnych blizn po oparzeniu:

Edytor kodu (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]);

Zwróć uwagę, że w konstrukcie ui.SplitPanel parametr wipe ma wartość true, aby umożliwić użytkownikowi przesuwanie uchwytu w kierunku jednej lub drugiej wizualizacji.

Stylowanie widżetów

Styl widżetu jest kontrolowany przez słownik jego właściwości stylów. Aby uzyskać dostęp do słownika, kliknij style() na widżecie. Obiekt zwracany przez funkcję style() jest wystąpieniem klasy ui.data.ActiveDictionary. Oznacza to, że ustawienie właściwości w słowniku stylu automatycznie aktualizuje sposób wyświetlania widżetu. Dozwolone klucze w słowniku stylów poszczególnych widżetów znajdziesz w dokumentacji dotyczącej wywołania style().

Style widżetu można ustawić za pomocą konstruktora, wywołując funkcję style().set() lub style() z argumentem słownika. Na przykład:

Edytor kodu (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);

Zwróć uwagę, że w tym przykładzie styl etykiety jest najpierw określany przez wywołanie funkcji style().set() z argumentami klucza i wartości, a potem przez wywołanie funkcji style().set() z argumentem słownika. Drugie wywołanie nie zastępuje pierwszego; dodaje i zastępuje poszczególne właściwości stylu, a nie cały słownik stylów.

Więcej informacji o opcjach stylizacji widżetów znajdziesz w tym pliku z odniesieniem do arkusza stylów Cascading Style Sheet (CSS), który zawiera style wymienione w dokumentacji style() dotyczącej poszczególnych widżetów. Pamiętaj, że style dozwolone dla widżetów Earth Engine różnią się od stylów CSS w kilku miejscach, w szczególności fontSizefontWeight zamiast font-stylefont-weight.

Słownik stylów zawiera też klucze, które kontrolują położenie widżetu. Więcej informacji o używaniu właściwości pozycyjnych znajdziesz na stronie Panele i schematy.