水患發生頻率 (1984 年至 2015 年)

GSW 資料集包含許多資料層,以不同方式呈現地表水資料。首先,我們會以視覺化方式呈現水域出現頻率圖層,其中提供 1984 年 3 月至 2015 年 10 月期間,地表水出現的位置和頻率摘要。

本節教學課程將:

  1. 新增地圖圖層,以視覺化方式呈現地表水出現情形
  2. 說明如何查詢地圖圖層的值、
  3. 加入自訂樣式來改善視覺效果
  4. 使用門檻值建立二進位水體遮罩圖層、
  5. 將地圖中心設為世界各地的有趣地點,以及
  6. 說明如何重構指令碼,使其更易於閱讀和維護。

建立基本圖表

首先,請將下列陳述式複製到程式碼編輯器:

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

預設圖表
圖 1. 全球地表水出現資料層的預設視覺化。

在大多數區域,GSW 資料集會顯示為透明,因為未收集 Landsat 圖片的位置 (即海洋區域) 或 32 年內未偵測到水的位置會 遮蓋。

檢查值

如要探索水體出現圖層的值,請使用程式碼編輯器的檢查器分頁。請先點選「檢查器」分頁標籤,然後在地圖上點選要選取的位置。「檢查器」分頁會顯示您點選位置中每個圖層的資訊。

「檢查工具」分頁
圖 2. 「檢查器」分頁輸出內容範例。

在上述範例中,名為 value 的圖層值為 98。單位為百分點,因此該位置約有 98% 的時間分類為水域。這個值是每月地表水出現值的平均值,會根據季節變化進行正規化,詳情請參閱 資料使用手冊 (第 2 版) 。

重構以改善程式碼

我們的指令碼只包含兩個陳述式,但我們已經有機會重構程式碼,讓最終指令碼更容易閱讀和維護。目前,Map.addLayer() 陳述式會傳遞單一引數 occurrence,也就是要在地圖上顯示的 Earth Engine 圖片物件。不過,Map.addLayer() 方法也允許傳遞額外引數。如要快速查看可用的引數,請將游標移到左括號後方,然後按下「顯示程式碼建議」的鍵盤快速鍵,叫出 addLayer 方法的說明文件。(如要查看鍵盤快速鍵,請依序選取「說明」選單 ->「快速鍵」)。

Map.addLayer 引數
圖 3. 螢幕截圖:顯示 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)) 後,系統會根據出現次數值設定像素的不透明度/透明度。

再次執行指令碼,查看樣式變更後的結果。

地表水出現頻率
圖 4. 布宜諾斯艾利斯附近巴拉那三角洲的水域發生率螢幕截圖,其中 0% 最小值端點使用透明紅色,最大值端點則使用純藍色。

水域現在是藍色!進度!

建立門檻圖層

水體出現率圖片包含預期出現水體的頻率資訊,值介於 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'
});
90% 水遮罩
圖 5. 布宜諾斯艾利斯附近巴拉那三角洲 90% 水體遮罩的螢幕截圖。

前往世界各地的有趣景點

平移和縮放地圖來探索世界很有趣,但世界很大,有時直接跳到特定位置會比較方便。以下是一系列陳述式,提供地表水方面有趣地點的小型樣本。只要一次取消註解一個陳述式,指令碼就會在執行時前往該位置。

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

在下一節中,您將探索水域出現率隨時間變化的情形。