小工具

您可以使用各種小工具來建構 UI。這些小工具包括按鈕、核取方塊、滑桿、文字方塊和選單。小工具只能列印或新增至面板一次。以下各節說明小工具的基本功能、外觀和觸感。如要進一步瞭解如何設定小工具樣式,請參閱「樣式」一節。以下範例只是將小工具 print() 到控制台。如要進一步瞭解如何在面板中新增小工具,請參閱「面板和版面配置」頁面。

ui.Label

標籤只是顯示文字的區域,例如,下列程式碼會列印標籤:

程式碼編輯器 (JavaScript)

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

大致如下所示:

ui_label.png

插入換行字元 (\n),並將 whiteSpace 樣式屬性引數設為 'pre',藉此分割長標籤:

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

ui.Button

按鈕是可點選的互動式 UI 小工具。您可以指定在使用者按下按鈕時要呼叫的函式 (即「回呼」函式)。(如要進一步瞭解如何使用回呼函式處理事件,請參閱「事件」頁面)。以下範例會在按下按鈕時,輸出地圖目前的中心:

程式碼編輯器 (JavaScript)

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

大致如下所示:

ui_button.png

ui.Checkbox

核取方塊是一種小工具,可讓使用者勾選 (或取消勾選) 方塊。當核取方塊的狀態變更時,系統會將布林值傳遞至註冊至小工具的回呼,指出核取方塊目前是否已勾選。例如:

程式碼編輯器 (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);

列印出來的核取方塊應如下所示:

ui_checkbox.png

請注意,勾選這個方塊會開啟地圖上顯示的圖層。如同其他 UI 元件,程式碼編輯器的 Map 可透過程式碼操作。如要進一步瞭解地圖物件,請參閱面板和版面配置頁面。

ui.Slider

滑桿是一種小工具,可讓使用者調整滑桿,取得滑桿範圍內的數字。使用建構函式或設定滑桿的屬性,設定範圍。以下範例使用滑桿設定 地圖上第一個圖層的不透明度:

程式碼編輯器 (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);

滑桿應如下所示:

ui_slider.png

請注意,滑桿值會顯示在滑桿右側。

ui.DateSlider

DateSlider 小工具與 Slider 小工具類似,但會明確處理日期。DateSlider 已設定為選取 2018 年 6 月的某一天,其外觀如下所示:

DateSlider.png

DateSlider 可用於篩選集合,如以下範例所示,這個範例會根據 DateSlider 中的 DateRange 集合,建構年度複合式:

程式碼編輯器 (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

文字方塊是收集使用者輸入文字的地方。例如:

程式碼編輯器 (JavaScript)

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

文字方塊應如下所示:

ui_textbox.png

請注意,回呼只會在使用者輸入文字 (並按下 return) 或點選離開文字方塊時觸發。

ui.Select

選取小工具代表下拉式選單,使用者可從中選擇所需選項。以下範例說明下拉式選單,可讓使用者選取位置:

程式碼編輯器 (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);

選取的小工具應如下所示:

ui_select.png

ui.Chart

ui.Chart 套件中的圖表與 Chart 套件中的圖表行為類似。具體來說,ui.Chart 是 Google Visualization API ChartWrapper 例項周圍的薄殼。如要進一步瞭解如何操控 ChartWrapper 物件,請參閱這份參考資料。如要進一步瞭解 Earth Engine 中的圖表輔助函式,請參閱 圖表說明文件

ui.Thumbnail

縮圖小工具可用於預覽 ee.Imageee.ImageCollection 物件。當小工具收到 ee.Image 時,就會顯示靜態圖片;當小工具收到 ee.ImageCollection 時,就會顯示動畫,其中每個輸入圖片都有一個影格。如同 ee.Image.getThumbURL()ee.ImageCollection.getVideoThumbURL(),您可以指定參數來控制產生的縮圖格式和尺寸:

程式碼編輯器 (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'}
}));

縮圖應如下所示:

ui_thumbnail.png

ui.Map

ui.Map 是地圖小工具。(事實上,預設的程式碼編輯器 Map 就是這個類別的例項)。如同其他小工具,您可以將地圖輸出至控制台。清除、取得或設定個別圖層,以便操控地圖內容。以下範例會將地圖輸出至主控台,顯示程式碼編輯器 Map 的邊界:

程式碼編輯器 (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);

插圖地圖應如下所示:

ui_map.png

在這個範例中,使用者需要點選大地圖,才能取得小地圖中的內嵌圖形。

您也可以在地圖例項上呼叫 layers(),藉此操作地圖上的圖層。layers() 會傳回 ui.data.ActiveList,也就是陣列類型的物件。變更後,地圖上的圖層也會隨之變更。詳情請參閱 ui.Map.Layer 章節

ui.Map.Layer

層並非可設定樣式的小工具,例如 ui.Button。這只是地圖上圖層的資料表示法。以下範例說明如何建立圖層,並根據使用者輸入內容更新圖層屬性,以便更新地圖:

程式碼編輯器 (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

如果您想顯示 (例如在應用程式中) 運算成本較高的圖層,建議您基於效能考量,將資料匯出至 Cloud Storage 值區。這些靜態的純視覺化圖層可讓應用程式和指令碼更有反應。您可以使用 Export.map.toCloudStorage() 建立靜態顯示層。如要使用先前由 Export.map.toCloudStorage() 匯出的圖塊集,請從指定的 Cloud Storage 值區和路徑建立新的 ui.Map.Layer

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

執行載入 Cloud Storage 圖層的指令碼時,您可能會看到以下警告訊息:

雲層警告

ui.Map.DrawingTools

預設會在程式碼編輯器的 Map 中新增一組幾何圖形繪製工具。您可以呼叫 Map.drawingTools(),變更預設 Map 中這些工具的行為。例如,如要隱藏繪圖工具:

程式碼編輯器 (JavaScript)

Map.drawingTools().setShown(false);

根據預設,新建立的地圖不會取得繪圖工具,但您可以在地圖上呼叫 drawingTools() 方法來啟用這些工具:

程式碼編輯器 (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]);

繪圖工具繪製的幾何圖形圖層會放入 ui.data.ActiveList,您可以呼叫 Map.drawingTools().layers() 存取該圖層。幾何圖形圖層清單會回應其他有效清單的事件,例如 Map.layers() 傳回的 Map 上圖層清單。以下範例說明如何設定工具繪製的幾何圖形圖層 (預設顯示) 的顯示/隱藏狀態:

程式碼編輯器 (JavaScript)

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

如要以程式輔助方式將圖層新增至繪圖工具,您可以呼叫繪圖工具的 addLayer 方法,或直接將圖層新增至圖層清單:

程式碼編輯器 (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);

發布 應用程式時,繪圖工具的狀態也會一併保留。如果您已顯示或隱藏繪圖工具,這些工具也會在應用程式中顯示或隱藏。匯入內容中的幾何圖形也會在應用程式中保留。

ui.Map.GeometryLayer

GeometryLayer 是幾何圖形的集合,可做為單一 GeometryGeometryCollectionFeatureCollection,會新增至指令碼頂端的匯入區段,並可在程式碼中參照。

繪圖工具繪製的 GeometryLayer 具有預設行為,您可以提供新的回呼函式來覆寫。舉例來說,假設您想要透過互動式變更幾何圖形來觸發事件。如要實作特定行為,您可以設定工具的 onEdit()onErase()onDraw() 方法,以便回應使用者動作。以下範例說明如何在使用者新增/編輯/刪除幾何圖形時,觸發運算並更新標籤的運算結果:

程式碼編輯器 (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);
}

請注意,setLinked() 是用來切換幾何圖形繪圖工具與程式碼編輯器的「Imports」部分之間的連線。在這個例子中,幾何圖形工具已取消連結,以免建立匯入作業。toGeometry 用於將圖層轉換為 ee.Geometry。如果匯入的圖層代表 FeatureFeatureCollection,您可以使用 getEeObject() 擷取底層 EE 物件。請注意,您也可以使用 ui.util.debounce 避免每個幾何圖形的移動都觸發回呼函式。具體來說,函式會在上一個事件後 100 毫秒才會觸發。這有助於確保函式只在使用者完成編輯動作時才執行。

匯入內容中的幾何圖形圖層會與 GeometryGeometryCollection 建立關聯,因此只能包含具有相同地理座標狀態的幾何圖形,因為 GeoJSON 格式只允許單一地理座標狀態的幾何圖形集合 (詳情請參閱「地理座標與平面幾何圖形」)。按下圖層名稱旁的齒輪圖示,即可將幾何圖層轉換為 FeatureCollection,這樣一來,您就能在同一圖層中新增大地測量和平面幾何圖形。不過,將其轉換回 Geometry 會產生錯誤。為避免這種情況,請將其轉換為 FeatureCollection 或刪除幾何圖形,直到圖層中只剩下一個大地測狀態為止。

ui.Map.Linker

與圖層一樣,連結器不是可設定樣式的小工具。這是一個幕後公用程式,可用於同步處理多個 ui.Map 例項的移動:

程式碼編輯器 (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 可用於並排比較項目。ui.SplitPanel 相較於兩個一般面板的優點在於,您可以使用手把在 ui.SplitPanel 中的面板之間實現擦除轉場效果。以下範例使用 ui.SplitPanel 顯示燒傷疤痕的光譜差異:

程式碼編輯器 (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]);

請注意,在 ui.SplitPanel 建構函式中,wipe 參數已設為 true,以便讓使用者在兩個圖表之間來回滑動手把。

設定小工具樣式

小工具的樣式由小工具的樣式屬性字典控制。您可以透過在小工具上呼叫 style() 來存取字典。style() 傳回的物件是 ui.data.ActiveDictionary 的例項。也就是說,設定樣式字典的屬性時,系統會自動更新小工具的顯示方式。每個小工具樣式字典的許可鍵,詳見 style() 呼叫的小工具參考文件。

您可以透過呼叫 style().set() 或搭配字典引數呼叫 style(),使用建構函式設定小工具的樣式。例如:

程式碼編輯器 (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);

請注意,在本範例中,標籤的樣式會先透過鍵和值引數呼叫 style().set(),然後再透過字典引數呼叫 style().set()。第二個呼叫不會覆寫第一個呼叫,而是會新增及取代個別樣式屬性,而非取代整個樣式字典。

如要進一步瞭解小工具的樣式選項,請參閱這份層疊樣式表單 (CSS) 參考資料,瞭解 style() 文件中列出的每個小工具樣式。請注意,Earth Engine 小工具允許的樣式與 CSS 樣式在某些地方有所不同,特別是 font-stylefont-weight 分別為 fontSizefontWeight

樣式字典也會包含用於控制小工具位置的鍵。如要進一步瞭解如何使用位置屬性,請參閱「面板和版面配置」頁面。