GSW 資料集包含許多資料層,以不同方式呈現地表水資料。首先,我們會顯示水體出現次數圖層,其中彙整了 1984 年 3 月至 2015 年 10 月期間,地表水體出現的位置和頻率。
本教學課程的這一節將:
- 新增地圖圖層,顯示地表水出現情形,
- 說明如何查詢地圖圖層的值,
- 加入自訂樣式,改善視覺化效果
- 使用閾值建立二進位水遮罩圖層,
- 將地圖中心設為世界各地有趣的地點,以及
- 說明如何重構指令碼,讓指令碼更容易閱讀及維護。
建立基本圖表
首先,請將下列陳述式複製到程式碼編輯器:
程式碼編輯器 (JavaScript)
var gsw = ee.Image('JRC/GSW1_0/GlobalSurfaceWater'); var occurrence = gsw.select('occurrence'); Map.addLayer(occurrence);
第一條陳述式會參照 GSW 資料集的 Earth Engine 影像物件,並將其儲存在名為 gsw
的變數中。第二個陳述式會選取 GSW 資料集中的單一層,並將其儲存在名為 occurrence
的變數中。第三個陳述式會將發生次數圖片新增至程式碼編輯器的互動式地圖。
按一下程式碼編輯器的「Run」按鈕,幾秒後您應該會看到地圖,沿海地區會以灰色標示,如圖 1 所示。

在大多數區域,GSW 資料集會顯示為透明,因為系統會 遮蓋未收集 Landsat 圖像的位置 (即海洋區域),或 32 年內任何觀測結果都未偵測到水的位置。
檢查值
如要探索水體出現次數圖層的值,請使用程式碼編輯器的檢查器分頁。 首先按一下檢查器分頁,然後按一下地圖選取位置。檢查器分頁會顯示您點選位置的每個圖層資訊。

在上述範例中,名為 value
的圖層值為 98。單位為百分點,因此大約有 98% 的時間,該位置分類為水域。這個值是每月地表水出現次數值的平均值,可根據季節性變化進行標準化,詳情請參閱
資料使用者指南 (第 2 版)
。
重構程式碼以提升品質
我們的指令碼只包含兩個陳述式,但我們已有機會重構程式碼,讓最終指令碼更容易閱讀及長期維護。目前,Map.addLayer()
陳述式會傳遞單一引數 occurrence
,這是要在地圖上顯示的 Earth Engine 圖片物件。不過,Map.addLayer()
方法也允許將額外引數傳遞給它。如要快速查看可用的引數,請將游標放在左括號後,然後按下「顯示程式碼建議」的鍵盤快速鍵,叫出 addLayer
方法的說明文件。(如要查看鍵盤快速鍵,請依序選取「說明」選單 ->「快速鍵」。)

鍵盤快速鍵顯示有五個引數可傳遞至 Map.addLayer
:eeObject
、visParams
、name
、shown
和 opacity
。在目前的指令碼中,我們傳遞的是單一變數 occurrence
,系統會將其解讀為第一個引數 eeObject
。如要同時傳遞變數物件和命名圖層的額外引數,我們可以重構程式碼,使用「具名引數」(eeObject
和 name
),這些引數會從
JSON 資料結構
內傳遞至方法,如下所示:
程式碼編輯器 (JavaScript)
Map.addLayer({eeObject: occurrence, name: 'Water Occurrence (1984-2015)'});
再次執行程式碼,確認重構變更後仍可正常運作。 產生的對應應維持不變。
新增視覺化參數
接下來,我們會改善預設的視覺化參數,這些參數會讓水呈現灰色。新增陳述式來建立變數 VIS_OCCURRENCE
,並將其做為額外引數傳遞至 addLayer 方法。
程式碼編輯器 (JavaScript)
var VIS_OCCURRENCE = { min: 0, max: 100, palette: ['red', 'blue'] };
程式碼編輯器 (JavaScript)
Map.addLayer({ eeObject: occurrence.updateMask(occurrence.divide(100)), name: 'Water Occurrence (1984-2015)', visParams: VIS_OCCURRENCE });
JSON 結構 VIS_OCCURRENCE
中儲存的視覺化參數表示,最小值 0% 應使用紅色,最大值 100% 應使用藍色。新增 .updateMask(occurrence.divide(100))
會根據出現次數值設定像素的不透明度/透明度。
再次執行指令碼,並查看樣式變更後的修訂結果。

水域現在會以藍色顯示!進展!
建立閾值圖層
水資源發生頻率圖片包含預期水資源發生頻率的資訊,使用 0% 到 100% 的值範圍。不過,根據特定發生百分比 (即門檻值) 定義二元水層 (即「水」與「非水」) 通常很有用。我們會使用這個簡單的二進位層,做為其他 GSW 層的乾淨背景層。您可以使用下列陳述式建立這個門檻層,這些陳述式會使用 90% 的門檻值來區分水和非水區域。
首先,我們定義新的視覺化變數 VIS_WATER_MASK
,用於保存水遮罩的樣式資訊:
程式碼編輯器 (JavaScript)
var VIS_WATER_MASK = { palette: ['white', 'black'] };
接著,我們使用大於比較運算子 .gt(90)
計算水遮罩層,然後使用 .unmask()
方法將先前遮罩的區域設為零:
程式碼編輯器 (JavaScript)
// Create a water mask layer, and set the image mask so that non-water areas // are opaque. var water_mask = occurrence.gt(90).unmask(0);
最後,將圖層新增至地圖。如要將這個圖層顯示在所有其他圖層下方,請在任何其他 Map.addLayer
陳述式之前,加入下列陳述式。
程式碼編輯器 (JavaScript)
Map.addLayer({ eeObject: water_mask, visParams: VIS_WATER_MASK, name: '90% occurrence water mask' });

前往世界各地有趣的地方
平移和縮放地圖來探索世界很有趣,但世界很大,有時直接跳到特定位置會很有幫助。以下是一系列陳述,提供一些有趣的地面水位置樣本。 一次只取消註解其中一個陳述式,指令碼執行時就會前往該位置。
程式碼編輯器 (JavaScript)
// Uncomment one of the following statements to center the map. // Map.setCenter(-90.162, 29.8597, 10); // New Orleans, USA // Map.setCenter(-114.9774, 31.9254, 10); // Mouth of the Colorado River, Mexico // Map.setCenter(-111.1871, 37.0963, 11); // Lake Powell, USA // Map.setCenter(149.412, -35.0789, 11); // Lake George, Australia // Map.setCenter(105.26, 11.2134, 9); // Mekong River Basin, SouthEast Asia // Map.setCenter(90.6743, 22.7382, 10); // Meghna River, Bangladesh // Map.setCenter(81.2714, 16.5079, 11); // Godavari River Basin Irrigation Project, India // Map.setCenter(14.7035, 52.0985, 12); // River Oder, Germany & Poland // Map.setCenter(-59.1696, -33.8111, 9); // Buenos Aires, Argentina Map.setCenter(-74.4557, -8.4289, 11); // Ucayali River, Peru
以上只是幾個有趣的例子。歡迎自行新增!
再次重構...
在繼續處理 GSW 資料集的下一層之前,我們要再進行一些程式碼重構。具體來說,我們會將類似的陳述式歸為一組,並新增一些註解,將程式碼分成資產、常數、計算、地圖置中和新增地圖圖層等部分。
以下是最終重構的指令碼:
程式碼編輯器 (JavaScript)
////////////////////////////////////////////////////////////// // Asset List ////////////////////////////////////////////////////////////// var gsw = ee.Image('JRC/GSW1_0/GlobalSurfaceWater'); var occurrence = gsw.select('occurrence'); ////////////////////////////////////////////////////////////// // Constants ////////////////////////////////////////////////////////////// var VIS_OCCURRENCE = { min: 0, max: 100, palette: ['red', 'blue'] }; var VIS_WATER_MASK = { palette: ['white', 'black'] }; ////////////////////////////////////////////////////////////// // Calculations ////////////////////////////////////////////////////////////// // Create a water mask layer, and set the image mask so that non-water areas // are opaque. var water_mask = occurrence.gt(90).unmask(0); ////////////////////////////////////////////////////////////// // Initialize Map Location ////////////////////////////////////////////////////////////// // Uncomment one of the following statements to center the map. // Map.setCenter(-90.162, 29.8597, 10); // New Orleans, USA // Map.setCenter(-114.9774, 31.9254, 10); // Mouth of the Colorado River, Mexico // Map.setCenter(-111.1871, 37.0963, 11); // Lake Powell, USA // Map.setCenter(149.412, -35.0789, 11); // Lake George, Australia // Map.setCenter(105.26, 11.2134, 9); // Mekong River Basin, SouthEast Asia // Map.setCenter(90.6743, 22.7382, 10); // Meghna River, Bangladesh // Map.setCenter(81.2714, 16.5079, 11); // Godavari River Basin Irrigation Project, India // Map.setCenter(14.7035, 52.0985, 12); // River Oder, Germany & Poland // Map.setCenter(-59.1696, -33.8111, 9); // Buenos Aires, Argentina Map.setCenter(-74.4557, -8.4289, 11); // Ucayali River, Peru ////////////////////////////////////////////////////////////// // Map Layers ////////////////////////////////////////////////////////////// Map.addLayer({ eeObject: water_mask, visParams: VIS_WATER_MASK, name: '90% occurrence water mask', shown: false }); Map.addLayer({ eeObject: occurrence.updateMask(occurrence.divide(100)), name: 'Water Occurrence (1984-2015)', visParams: VIS_OCCURRENCE });
在下一節中,您將瞭解水體出現頻率的變化。