水類別轉換

水轉移層會擷取三種水出現類別 (非水、季節性水和永久性水) 之間的變化,以及兩種額外類別的短暫水 (短暫永久性和短暫季節性)。

本教學課程的這一節將:

  1. 新增地圖圖層,以視覺化呈現水資源轉移情況、
  2. 建立分組縮減器,用於加總指定感興趣區域內每個轉移類別的面積,以及
  3. 建立圖表,依轉移類別匯總區域。

基本視覺化

在指令碼的「Asset List」(資產清單) 部分,新增下列陳述式,建立名為 transition 的單一波段圖片物件:

程式碼編輯器 (JavaScript)

var transition = gsw.select('transition');

GSW 圖片包含轉換類別編號和名稱的中繼資料,以及用於設定轉換類別樣式的預設調色盤。將轉換層新增至地圖時,系統會自動使用這些視覺化參數。

在指令碼的「地圖圖層」部分底部,新增下列陳述式,加入顯示轉換類別的新地圖圖層:

程式碼編輯器 (JavaScript)

Map.setCenter(105.26, 11.2134, 9);     // Mekong River Basin, SouthEast Asia
Map.addLayer({
  eeObject: transition,
  name: 'Transition classes (1984-2015)',
});

執行指令碼時,系統會顯示轉移層。

地表水轉移類別
圖 10:湄公河三角洲的螢幕截圖,顯示地表水類別轉換的差異很大。

轉場類別的地圖鍵為:

符號 標籤
0 不是水
1 永久
2 新永久
3 永久遺失
4 季節音樂
5 新季節性
6 遺失季節性內容
7 季節性到永久性
8 永久性轉為季節性
9 暫時永久
10 季節性限時內容

依轉換類別匯總面積

在本節中,我們將再次使用幾何多邊形工具定義感興趣的區域。如要分析新地點,請先選取並刪除您繪製的原始多邊形,以免系統合併區域並提供結果。如要瞭解如何修改幾何圖形,請參閱程式碼編輯器說明文件的「 幾何圖形工具」一節。

在本範例中,我們會在湄公河三角洲內繪製新的多邊形。

投資報酬率 (ROI) 轉換類別
圖 11:越南的湄公河三角洲,使用程式碼編輯器的多邊形繪圖工具建立感興趣的區域。

如要計算圖片部分涵蓋的面積,我們將使用 ee.Image.pixelArea 方法,在轉換圖片物件中新增額外頻帶,以平方公尺為單位識別每個像素的大小。

程式碼編輯器 (JavaScript)

var area_image_with_transition_class = ee.Image.pixelArea().addBands(transition);

產生的圖片物件 (area_image_with_transition_class) 是雙波段圖片,第一個波段包含以平方公尺為單位的面積資訊 (由 ee.Image.pixelAreacode> 方法產生),第二個波段則包含轉移類別資訊。

接著,我們使用 ee.Image.reduceRegion 方法和 分組縮減器 ,彙整感興趣區域 (roi) 內的類別轉換,以計算每個轉換類別內的總面積:

程式碼編輯器 (JavaScript)

var reduction_results = area_image_with_transition_class.reduceRegion({
  reducer: ee.Reducer.sum().group({
    groupField: 1,
    groupName: 'transition_class_value',
  }),
  geometry: roi,
  scale: 30,
  bestEffort: true,
});
print('reduction_results', reduction_results);

控制台分頁的輸出內容現在會顯示 reduction_results。請注意,您需要展開樹狀結構幾個層級,才能查看區域摘要資料。

分組減少結果
圖 12:「控制台」分頁的輸出內容,顯示分組縮減的結果。

雖然 reduction_results 物件確實包含每個轉場效果類別涵蓋的區域資訊,但並不容易解讀。下一節將說明如何更輕鬆地查看結果。

建立摘要圖表

在本節中,我們將製作圖表,以便更清楚地歸納結果。 首先,請按照下列方式擷取轉場效果類別清單和區域:

程式碼編輯器 (JavaScript)

var roi_stats = ee.List(reduction_results.get('groups'));

分組縮減器 (reduction_results) 的結果是包含字典清單的字典。清單中每個轉換類別都有一個字典。 這些陳述式會使用 ee.Dictionary.get 方法,從該字典中擷取分組的縮減函式結果,並將結果轉換為 ee.List 資料型別,以便存取個別字典。

如要使用 程式碼編輯器的繪圖函式,我們將建構包含必要資訊的 FeatureCollection。為此,我們首先要建立兩個查閱字典和兩個輔助函式。建立查閱字典的程式碼可以放在「計算」部分的頂端,如下所示:

程式碼編輯器 (JavaScript)

//////////////////////////////////////////////////////////////
// Calculations
//////////////////////////////////////////////////////////////

// Create a dictionary for looking up names of transition classes.
var lookup_names = ee.Dictionary.fromLists(
    ee.List(gsw.get('transition_class_values')).map(numToString),
    gsw.get('transition_class_names')
);
// Create a dictionary for looking up colors of transition classes.
var lookup_palette = ee.Dictionary.fromLists(
    ee.List(gsw.get('transition_class_values')).map(numToString),
    gsw.get('transition_class_palette')
);

lookup_names 字典會將轉場效果類別值與名稱建立關聯,而 lookup_palette 字典則會將轉場效果類別值與顏色定義建立關聯。

這兩個輔助函式可以放在名為「輔助函式」的新程式碼區段中。

程式碼編輯器 (JavaScript)

//////////////////////////////////////////////////////////////
// Helper functions
//////////////////////////////////////////////////////////////

// Create a feature for a transition class that includes the area covered.
function createFeature(transition_class_stats) {
  transition_class_stats = ee.Dictionary(transition_class_stats);
  var class_number = transition_class_stats.get('transition_class_value');
  var result = {
      transition_class_number: class_number,
      transition_class_name: lookup_names.get(class_number),
      transition_class_palette: lookup_palette.get(class_number),
      area_m2: transition_class_stats.get('sum')
  };
  return ee.Feature(null, result);   // Creates a feature without a geometry.
}

// Create a JSON dictionary that defines piechart colors based on the
// transition class palette.
// https://developers.google.com/chart/interactive/docs/gallery/piechart
function createPieChartSliceDictionary(fc) {
  return ee.List(fc.aggregate_array("transition_class_palette"))
    .map(function(p) { return {'color': p}; }).getInfo();
}

// Convert a number to a string. Used for constructing dictionary key lists
// from computed number objects.
function numToString(num) {
  return ee.Number(num).format();
}

函式 createFeature 會採用字典 (內含區域和水域轉換類別),並傳回適合繪製圖表的特徵。函式 createPieChartSliceDictionary 會建立與轉移類別對應的顏色清單,並使用圓餅圖預期的格式。

接下來,我們將使用 ee.List.map,對清單 (roi_stats) 中的每個字典套用 createFeature 函式,將輔助函式套用至清單的每個元素。

程式碼編輯器 (JavaScript)

var transition_fc = ee.FeatureCollection(roi_stats.map(createFeature));
print('transition_fc', transition_fc);

現在我們有了包含要在圖表上顯示屬性的 FeatureCollection,可以建立圖表物件並將其列印到控制台。

程式碼編輯器 (JavaScript)

// Add a summary chart.
var transition_summary_chart = ui.Chart.feature.byFeature({
    features: transition_fc,
    xProperty: 'transition_class_name',
    yProperties: ['area_m2', 'transition_class_number']
  })
  .setChartType('PieChart')
  .setOptions({
    title: 'Summary of transition class areas',
    slices: createPieChartSliceDictionary(transition_fc),
    sliceVisibilityThreshold: 0  // Don't group small slices.
  });
print(transition_summary_chart);

slices 選項會為圓餅圖切片上色,以便使用為轉場效果類別定義的預設調色盤 (如先前地圖鍵表格所示)。sliceVisibilityThreshold 選項可避免將小切片歸入「其他」類別。產生的圖表應與圖 13 所示類似。

水資源轉型類別摘要圖表
圖 13:圖表:總結水轉場效果類別的相對大小。

最終腳本

本節的完整指令碼如下:

程式碼編輯器 (JavaScript)

//////////////////////////////////////////////////////////////
// Asset List
//////////////////////////////////////////////////////////////

var gsw = ee.Image('JRC/GSW1_0/GlobalSurfaceWater');
var occurrence = gsw.select('occurrence');
var change = gsw.select("change_abs");
var transition = gsw.select('transition');
var roi = ee.Geometry.Polygon(
        [[[105.531921, 10.412183],
          [105.652770, 10.285193],
          [105.949401, 10.520218],
          [105.809326, 10.666006]]]);
//////////////////////////////////////////////////////////////
// Constants
//////////////////////////////////////////////////////////////

var VIS_OCCURRENCE = {
    min: 0,
    max: 100,
    palette: ['red', 'blue']
};
var VIS_CHANGE = {
    min: -50,
    max: 50,
    palette: ['red', 'black', 'limegreen']
};
var VIS_WATER_MASK = {
  palette: ['white', 'black']
};

//////////////////////////////////////////////////////////////
// Helper functions
//////////////////////////////////////////////////////////////

// Create a feature for a transition class that includes the area covered.
function createFeature(transition_class_stats) {
  transition_class_stats = ee.Dictionary(transition_class_stats);
  var class_number = transition_class_stats.get('transition_class_value');
  var result = {
      transition_class_number: class_number,
      transition_class_name: lookup_names.get(class_number),
      transition_class_palette: lookup_palette.get(class_number),
      area_m2: transition_class_stats.get('sum')
  };
  return ee.Feature(null, result);   // Creates a feature without a geometry.
}

// Create a JSON dictionary that defines piechart colors based on the
// transition class palette.
// https://developers.google.com/chart/interactive/docs/gallery/piechart
function createPieChartSliceDictionary(fc) {
  return ee.List(fc.aggregate_array("transition_class_palette"))
    .map(function(p) { return {'color': p}; }).getInfo();
}

// Convert a number to a string. Used for constructing dictionary key lists
// from computed number objects.
function numToString(num) {
  return ee.Number(num).format();
}

//////////////////////////////////////////////////////////////
// Calculations
//////////////////////////////////////////////////////////////

// Create a dictionary for looking up names of transition classes.
var lookup_names = ee.Dictionary.fromLists(
    ee.List(gsw.get('transition_class_values')).map(numToString),
    gsw.get('transition_class_names')
);
// Create a dictionary for looking up colors of transition classes.
var lookup_palette = ee.Dictionary.fromLists(
    ee.List(gsw.get('transition_class_values')).map(numToString),
    gsw.get('transition_class_palette')
);

// Create a water mask layer, and set the image mask so that non-water areas
// are transparent.
var water_mask = occurrence.gt(90).mask(1);

// Generate a histogram object and print it to the console tab.
var histogram = ui.Chart.image.histogram({
  image: change,
  region: roi,
  scale: 30,
  minBucketWidth: 10
});
histogram.setOptions({
  title: 'Histogram of surface water change intensity.'
});
print(histogram);

// Summarize transition classes in a region of interest.
var area_image_with_transition_class = ee.Image.pixelArea().addBands(transition);
var reduction_results = area_image_with_transition_class.reduceRegion({
  reducer: ee.Reducer.sum().group({
    groupField: 1,
    groupName: 'transition_class_value',
  }),
  geometry: roi,
  scale: 30,
  bestEffort: true,
});
print('reduction_results', reduction_results);

var roi_stats = ee.List(reduction_results.get('groups'));

var transition_fc = ee.FeatureCollection(roi_stats.map(createFeature));
print('transition_fc', transition_fc);

// Add a summary chart.
var transition_summary_chart = ui.Chart.feature.byFeature({
    features: transition_fc,
    xProperty: 'transition_class_name',
    yProperties: ['area_m2', 'transition_class_number']
  })
  .setChartType('PieChart')
  .setOptions({
    title: 'Summary of transition class areas',
    slices: createPieChartSliceDictionary(transition_fc),
    sliceVisibilityThreshold: 0  // Don't group small slices.
  });
print(transition_summary_chart);

//////////////////////////////////////////////////////////////
// Initialize Map Location
//////////////////////////////////////////////////////////////

// Uncomment one of the following statements to center the map on
// a particular location.
// 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,
  shown: false
});
Map.addLayer({
  eeObject: change,
  visParams: VIS_CHANGE,
  name: 'occurrence change intensity',
  shown: false
});
Map.addLayer({
  eeObject: transition,
  name: 'Transition classes (1984-2015)',
});

全球地表水資料集教學課程到此結束。請注意,本教學課程僅說明如何使用全球地表水資料集中的三種資料層 (發生次數、變化強度和轉移)。如要瞭解其他可用的資料層,請參閱 資料使用者指南 (第 2 版)

祝您分析順利!