Chuyển đổi cấp nước

Lớp chuyển đổi nước ghi lại những thay đổi giữa 3 loại nước (không phải nước, nước theo mùa và nước vĩnh cửu) cùng với 2 loại nước bổ sung cho nước tạm thời (nước vĩnh cửu tạm thời và nước theo mùa tạm thời).

Phần này của hướng dẫn sẽ:

  1. thêm một lớp bản đồ để trực quan hoá quá trình chuyển đổi nước,
  2. tạo một hàm giảm được nhóm để tính tổng diện tích của từng lớp chuyển đổi trong một vùng quan tâm được chỉ định và
  3. tạo biểu đồ tóm tắt khu vực theo lớp chuyển đổi.

Hình ảnh trực quan cơ bản

Trong phần Danh sách tài sản của tập lệnh, hãy thêm câu lệnh sau để tạo một đối tượng hình ảnh một dải tần có tên là transition:

Trình soạn thảo mã (JavaScript)

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

Hình ảnh GSW chứa siêu dữ liệu về số và tên lớp chuyển đổi, cũng như một bảng màu mặc định để tạo kiểu cho các lớp chuyển đổi. Khi lớp chuyển đổi được thêm vào bản đồ, các thông số trực quan hoá này sẽ tự động được sử dụng.

Ở cuối phần Lớp bản đồ trong tập lệnh, hãy thêm câu lệnh sau đây để thêm một lớp bản đồ mới hiển thị các lớp chuyển đổi:

Trình soạn thảo mã (JavaScript)

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

Khi bạn chạy tập lệnh, lớp chuyển đổi sẽ xuất hiện.

Lớp chuyển đổi nước mặt
Hình 10. Ảnh chụp màn hình đồng bằng sông Mê Kông, cho thấy sự biến đổi lớn trong các chuyển đổi lớp nước mặt.

Khoá bản đồ cho các lớp chuyển đổi là:

Giá trị Biểu tượng Hãng nhạc
0 Không phải nước
1 Vĩnh viễn
2 Vĩnh viễn mới
3 Mất vĩnh viễn
4 Bản phát hành theo mùa
5 Sản phẩm theo mùa mới
6 Mất dữ liệu theo mùa
7 Từ theo mùa sang vĩnh viễn
8 Từ vĩnh viễn sang theo mùa
9 Tạm thời nhưng vĩnh viễn
10 Tạm thời theo mùa

Tóm tắt diện tích theo Lớp chuyển tiếp

Trong phần này, chúng ta sẽ một lần nữa sử dụng công cụ đa giác hình học để xác định một khu vực quan tâm. Nếu muốn phân tích một vị trí mới, trước tiên, bạn cần chọn và xoá đa giác ban đầu mà bạn đã vẽ để không nhận được kết quả từ các khu vực kết hợp. Hãy xem phần Công cụ hình học trong tài liệu về Trình chỉnh sửa mã để biết thông tin về cách sửa đổi hình học.

Trong ví dụ này, chúng ta sẽ vẽ một đa giác mới trong đồng bằng sông Mê Kông.

Lớp chuyển đổi có ROI
Hình 11. Đồng bằng sông Mekong ở Việt Nam, với một khu vực quan tâm được tạo bằng công cụ vẽ đa giác của Trình chỉnh sửa mã.

Để tính toán diện tích được bao phủ bởi các phần của hình ảnh, chúng ta sẽ thêm một dải bổ sung vào đối tượng hình ảnh chuyển đổi để xác định kích thước của từng pixel theo mét vuông bằng phương thức ee.Image.pixelArea.

Trình soạn thảo mã (JavaScript)

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

Đối tượng hình ảnh thu được (area_image_with_transition_class) là một hình ảnh gồm 2 dải, trong đó dải đầu tiên chứa thông tin về diện tích theo đơn vị mét vuông (do phương thức ee.Image.pixelAreacode> tạo ra) và dải thứ hai chứa thông tin về lớp chuyển đổi.

Sau đó, chúng tôi tóm tắt các quá trình chuyển đổi lớp trong một khu vực quan tâm (roi) bằng phương thức ee.Image.reduceRegion và một trình giảm tốc được nhóm có chức năng cộng diện tích trong mỗi lớp chuyển đổi:

Trình soạn thảo mã (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);

Giờ đây, kết quả đầu ra trên thẻ bảng điều khiển sẽ hiển thị reduction_results. Xin lưu ý rằng bạn sẽ cần mở rộng cây này thêm vài cấp để xem dữ liệu tóm tắt theo khu vực.

Kết quả giảm được nhóm
Hình 12. Kết quả đầu ra trên thẻ Bảng điều khiển, cho thấy kết quả của việc giảm kích thước theo nhóm.

Mặc dù đối tượng reduction_results có chứa thông tin về khu vực mà mỗi lớp chuyển đổi bao phủ, nhưng không dễ đọc. Trong phần tiếp theo, chúng ta sẽ giúp bạn dễ dàng xem kết quả hơn.

Tạo biểu đồ tóm tắt

Trong phần này, chúng ta sẽ tạo một biểu đồ để tóm tắt kết quả một cách hiệu quả hơn. Để bắt đầu, trước tiên, chúng ta sẽ trích xuất danh sách các lớp chuyển đổi có các vùng như sau:

Trình soạn thảo mã (JavaScript)

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

Kết quả của hàm giảm được nhóm (reduction_results) là một từ điển chứa danh sách các từ điển. Mỗi lớp chuyển đổi có một từ điển trong danh sách. Các câu lệnh này sử dụng phương thức ee.Dictionary.get để trích xuất kết quả của hàm giảm được nhóm từ từ điển đó và truyền kết quả sang kiểu dữ liệu ee.List, nhờ đó chúng ta có thể truy cập vào từng từ điển.

Để sử dụng các hàm lập biểu đồ của Trình chỉnh sửa mã, chúng ta sẽ tạo một FeatureCollection chứa thông tin cần thiết. Để làm việc này, trước tiên, chúng ta sẽ tạo 2 từ điển tra cứu và 2 hàm trợ giúp. Bạn có thể đặt mã tạo từ điển tra cứu ở đầu phần "Calculations" (Tính toán) như sau:

Trình soạn thảo mã (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')
);

Từ điển lookup_names liên kết các giá trị lớp chuyển đổi với tên của chúng, trong khi từ điển lookup_palette liên kết các giá trị lớp chuyển đổi với các định nghĩa về màu sắc.

Bạn có thể đặt hai hàm trợ giúp này trong một phần mã mới có tên là "Hàm trợ giúp".

Trình soạn thảo mã (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();
}

Hàm createFeature lấy một từ điển (chứa diện tích và lớp chuyển tiếp nước) rồi trả về một Đối tượng phù hợp để lập biểu đồ. Hàm createPieChartSliceDictionary tạo một danh sách màu tương ứng với các lớp chuyển đổi, sử dụng định dạng mà biểu đồ hình tròn mong đợi.

Tiếp theo, chúng ta sẽ áp dụng hàm createFeature cho từng từ điển trong danh sách (roi_stats), bằng cách sử dụng ee.List.map để áp dụng hàm trợ giúp cho từng phần tử trong danh sách.

Trình soạn thảo mã (JavaScript)

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

Giờ đây, khi đã có một FeatureCollection chứa các thuộc tính mà chúng ta muốn hiển thị trên biểu đồ, chúng ta có thể tạo một đối tượng biểu đồ và in đối tượng đó ra bảng điều khiển.

Trình soạn thảo mã (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);

Lựa chọn slices tô màu các lát của biểu đồ hình tròn để chúng sử dụng bảng màu mặc định được xác định cho các lớp chuyển đổi (được trình bày trước đó trong bảng khoá bản đồ). Lựa chọn sliceVisibilityThreshold sẽ ngăn các lát nhỏ được nhóm lại với nhau thành danh mục "khác". Biểu đồ kết quả sẽ tương tự như biểu đồ trong Hình 13.

Biểu đồ tóm tắt lớp chuyển đổi nước
Hình 13. Biểu đồ tóm tắt kích thước tương đối của các lớp chuyển đổi nước.

Tập lệnh cuối cùng

Toàn bộ kịch bản cho phần này là:

Trình soạn thảo mã (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)',
});

Đến đây là kết thúc hướng dẫn về tập dữ liệu Nước mặt toàn cầu. Xin lưu ý rằng hướng dẫn này chỉ trình bày cách sử dụng 3 lớp dữ liệu (sự xuất hiện, cường độ thay đổi và chuyển đổi) có trong tập dữ liệu Nước mặt toàn cầu. Bạn có thể đọc về các lớp dữ liệu khác có trong Hướng dẫn sử dụng dữ liệu (phiên bản 2).

Chúc bạn sử dụng Analytics vui vẻ!