Наличие воды (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);

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

Нажмите кнопку Run (Запустить) в редакторе кода. Через несколько секунд вы увидите карту с серыми областями вдоль береговых линий, как на рисунке 1.

визуализация по умолчанию
Рисунок 1. Визуализация по умолчанию слоя данных о наличии поверхностных вод в мире.

В большинстве регионов набор данных GSW выглядит прозрачным, поскольку места, где изображения Landsat не собирались (например, океаны) или где вода не была обнаружена ни в одном из наблюдений за 32 года, скрыты.

Проверка значений

Чтобы изучить значения слоя наличия воды, мы воспользуемся вкладкой Inspector (Инспектор) в редакторе кода. Сначала нажмите на вкладку инспектора, а затем выберите местоположение на карте. На вкладке инспектора появится информация о каждом слое, который присутствует в месте нажатия.

вкладка инспектора
Рисунок 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
});

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