Слой перехода воды фиксирует изменения между тремя классами наличия воды (не вода, сезонная вода и постоянная вода), а также двумя дополнительными классами для эфемерной воды (эфемерная постоянная и эфемерная сезонная).
В этом разделе руководства вы узнаете:
- добавить слой карты для визуализации перехода воды;
- создать сгруппированный редуктор для суммирования площади каждого класса перехода в пределах указанной интересующей области;
- создайте диаграмму, на которой будет показана площадь по классам перехода.
Базовая визуализация
В разделе 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
), а вторая полоса содержит информацию о классе перехода.
Затем мы обобщаем переходы между классами в интересующем регионе (roi) с помощью метода
ee.Image.reduceRegion
и
сгруппированного редуктора
, который суммирует площадь в пределах каждого класса перехода:
Редактор кода (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 – значения классов переходов с определениями цветов.
Две вспомогательные функции можно поместить в новый раздел кода под названием "Вспомогательные функции".
Редактор кода (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 создает список цветов, соответствующих классам переходов, в формате, который используется в круговой диаграмме.
Затем мы применим функцию createFeature к каждому словарю в списке (roi_stats), используя ee.List.map, чтобы применить вспомогательную функцию к каждому элементу списка.
Редактор кода (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)', });
На этом руководство по набору данных Global Surface Water завершено. Обратите внимание, что в этом руководстве показано, как работать только с тремя слоями данных (наличие, интенсивность изменений и переход), доступными в наборе данных Global Surface Water. О других доступных слоях данных можно узнать в руководстве пользователя по данным (версия 2).
Желаем успехов!