Появление воды (1984-2015)

Набор данных GSW содержит множество слоёв, которые представляют данные о поверхностных водах различными способами. Начнём с визуализации слоя, отражающего наличие воды, который предоставляет сводку о том, где и как часто происходили поверхностные воды за весь период с марта 1984 года по октябрь 2015 года.

В этом разделе руководства будут:

  1. добавить слой карты для визуализации наличия поверхностных вод,
  2. показать, как запрашивать значения слоя карты,
  3. добавить пользовательские стили для улучшения визуализации,
  4. создать бинарный слой маски воды, используя пороговое значение,
  5. центрировать карту на интересных частях мира и
  6. показать, как реорганизовать скрипт, чтобы сделать его более читабельным и удобным для обслуживания.

Создание базовой визуализации

Начните с копирования следующих операторов в редактор кода:

Редактор кода (JavaScript)

var gsw = ee.Image('JRC/GSW1_0/GlobalSurfaceWater');
var occurrence = gsw.select('occurrence');
Map.addLayer(occurrence);

Первый оператор ссылается на объект изображения Earth Engine для набора данных GSW и сохраняет его в переменной gsw . Второй оператор выбирает один слой набора данных GSW и сохраняет его в переменной occurrence . Третий оператор добавляет изображение случайного события на интерактивную карту редактора кода.

Нажмите кнопку «Запустить» в редакторе кода, и через несколько секунд вы увидите карту с серыми линиями вдоль береговых линий, аналогичную той, что представлена на рисунке 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
});

В следующем разделе вы изучите, как изменялась распространенность воды с течением времени.