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 Image 物件,並儲存在名為 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 });
在下一節中,您將探索水域出現率隨時間變化的情形。