水體轉換層會擷取三種水體出現類別 (非水體、季節性水體和永久性水體) 之間的變化,以及兩種額外的短暫水體類別 (短暫永久性水體和短暫季節性水體)。
本節教學課程將:
- 新增地圖圖層,以視覺化方式呈現水體變化,
- 建立分組歸納器,加總指定感興趣區域內各個轉換類別的面積。
- 建立圖表,依轉換類別匯總面積。
基本視覺化
在指令碼的「Asset List」部分,新增下列陳述式,建立名為 transition 的單一波段圖片物件:
程式碼編輯器 (JavaScript)
var transition = gsw.select('transition');
GSW 圖片包含轉換類別編號和名稱的中繼資料,以及用於設定轉換類別樣式的預設調色盤。將轉換圖層新增至地圖時,系統會自動使用這些視覺化參數。
在指令碼的「Map Layers」部分底部,新增下列陳述式,加入顯示轉換類別的新地圖圖層:
程式碼編輯器 (JavaScript)
Map.setCenter(105.26, 11.2134, 9); // Mekong River Basin, SouthEast Asia Map.addLayer({ eeObject: transition, name: 'Transition classes (1984-2015)', });
執行指令碼時,系統會顯示轉場圖層。
轉場類別的地圖索引鍵為:
| 值 | 符號 | 標籤 |
|---|---|---|
| 0 | 非水 | |
| 1 | 永久 | |
| 2 | 新永久 | |
| 3 | 永久遺失 | |
| 4 | 應景 | |
| 5 | 全新季節性 | |
| 6 | 遺失季節性 | |
| 7 | 從季節性轉為永久 | |
| 8 | 永久到季節性 | |
| 9 | 暫時永久 | |
| 10 | 限時季節性 |
按轉換類別匯總面積
在本節中,我們會再次使用幾何多邊形工具定義感興趣區域。如要分析新位置,請先選取並刪除原本繪製的多邊形,以免取得合併區域的結果。如要瞭解如何修改幾何圖形,請參閱程式碼編輯器說明文件的「 幾何圖形工具」一節。
在本範例中,我們會在湄公河三角洲內繪製新的多邊形。
為了計算圖片部分區域涵蓋的面積,我們會在轉換圖片物件中新增一個額外的波段,並使用 ee.Image.pixelArea 方法,以平方公尺為單位識別每個像素的大小。
程式碼編輯器 (JavaScript)
var area_image_with_transition_class = ee.Image.pixelArea().addBands(transition);
產生的圖片物件 (area_image_with_transition_class) 是雙波段圖片,第一個波段包含以平方公尺為單位的區域資訊 (由
ee.Image.pixelArea
方法產生),第二個波段則包含轉換類別資訊。
接著,我們使用
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。請注意,您必須展開樹狀結構幾個層級,才能查看區域摘要資料。
雖然 reduction_results 物件確實包含每個轉換類別涵蓋區域的資訊,但並不容易閱讀。下一節將說明如何更輕鬆地查看結果。
建立摘要圖表
在本節中,我們將製作圖表,更清楚地總結結果。 首先,我們需要擷取轉換類別清單,其中包含以下區域:
程式碼編輯器 (JavaScript)
var roi_stats = ee.List(reduction_results.get('groups'));
分組歸納器 (reduction_results) 的結果是包含字典清單的字典。清單中每個轉換類別都有一個字典。這些陳述式會使用
ee.Dictionary.get
方法,從該字典中擷取分組的歸納器結果,並將結果轉換為 ee.List 資料類型,以便存取個別字典。
為了使用 程式碼編輯器的圖表函式,我們會建構包含必要資訊的 FeatureCollection。為此,我們首先建立兩個查詢字典和兩個輔助函式。建立查詢字典的程式碼可以放在「Calculations」部分的頂端,如下所示:
程式碼編輯器 (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 字典則會將轉場類別值與顏色定義建立關聯。
這兩個輔助函式可以放在名為「Helper functions」的新程式碼區段中。
程式碼編輯器 (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 類似。
最終腳本
本節的完整指令碼如下:
程式碼編輯器 (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 版)。
祝您分析順利!