Transição de classe de água

A camada de transição de água captura mudanças entre três classes de ocorrência de água (não água, água sazonal e água permanente), além de duas classes adicionais para água efêmera (efêmera permanente e efêmera sazonal).

Esta seção do tutorial vai:

  1. adicionar uma camada de mapa para visualizar a transição da água;
  2. criar um redutor agrupado para somar a área de cada classe de transição em uma região de interesse especificada;
  3. Crie um gráfico que resuma a área por classe de transição.

Visualização básica

Na seção "Lista de recursos" do script, adicione a seguinte instrução, que cria um objeto de imagem de banda única chamado transition:

Editor de código (JavaScript)

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

As imagens do GSW contêm metadados sobre os números e nomes das classes de transição, além de uma paleta padrão para estilizar essas classes. Quando a camada de transição é adicionada ao mapa, esses parâmetros de visualização são usados automaticamente.

Na parte de baixo da seção "Camadas do mapa" do script, adicione a seguinte instrução, que adiciona uma nova camada do mapa que mostra as classes de transição:

Editor de código (JavaScript)

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

Quando você executa o script, a camada de transição é exibida.

Classes de transição de água da superfície
Figura 10. Captura de tela do delta do rio Mekong, mostrando uma grande variação nas transições de classe de água superficial.

A chave do mapa para as classes de transição é:

Valor Símbolo Rótulo
0 Não é água
1 Permanente
2 Novo permanente
3 Perda permanente
4 Trilha da temporada
5 Nova temporada
6 Perda sazonal
7 De sazonal para permanente
8 De permanente para sazonal
9 Temporário permanente
10 Sazonal efêmero

Resumo da área por classe de transição

Nesta seção, vamos usar novamente a ferramenta de polígono de geometria para definir uma região de interesse. Se quiser analisar um novo local, primeiro selecione e exclua o polígono original que você desenhou para não receber resultados das áreas combinadas. Consulte a seção Ferramentas de geometria da documentação do Editor de código para saber como modificar geometrias.

Neste exemplo, vamos desenhar um novo polígono no delta do rio Mekong.

Classes de transição com ROI
Figura 11. O delta do rio Mekong no Vietnã, com uma região de interesse criada usando a ferramenta de desenho de polígonos do editor de código.

Para calcular a área coberta por partes de uma imagem, vamos adicionar uma banda extra ao objeto de imagem de transição que identifica o tamanho de cada pixel em metros quadrados usando o método ee.Image.pixelArea.

Editor de código (JavaScript)

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

O objeto de imagem resultante (area_image_with_transition_class) é uma imagem de duas bandas em que a primeira banda contém as informações de área em unidades de metros quadrados (produzidas pelo método ee.Image.pixelAreacode> ) e a segunda banda contém as informações de classe de transição.

Em seguida, resumimos as transições de classe em uma região de interesse (roi) usando o método ee.Image.reduceRegion e um reducer agrupado , que soma a área em cada classe de transição:

Editor de código (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);

A saída da guia do console agora mostra o reduction_results. É necessário expandir a árvore alguns níveis para ver os dados do resumo da área.

Resultados de redução agrupados
Figura 12. Saída da guia "Console", mostrando os resultados da redução agrupada.

Embora o objeto reduction_results contenha informações sobre a área coberta por cada classe de transição, não é muito fácil de ler. Na próxima seção, vamos facilitar a visualização dos resultados.

Como criar um gráfico de resumo

Nesta seção, vamos criar um gráfico para resumir melhor os resultados. Para começar, extraímos a lista de classes de transição com áreas da seguinte forma:

Editor de código (JavaScript)

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

O resultado do redutor agrupado (reduction_results) é um dicionário que contém uma lista de dicionários. Há um dicionário na lista para cada classe de transição. Essas instruções usam o método ee.Dictionary.get para extrair os resultados do redutor agrupado desse dicionário e convertem os resultados em um tipo de dados ee.List para que possamos acessar os dicionários individuais.

Para usar as funções de criação de gráficos do Editor de código, vamos criar um FeatureCollection que contenha as informações necessárias. Para isso, primeiro criamos dois dicionários de pesquisa e duas funções auxiliares. O código que cria os dicionários de pesquisa pode ser colocado na parte de cima da seção "Cálculos", da seguinte forma:

Editor de código (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')
);

O dicionário lookup_names associa valores de classe de transição aos respectivos nomes, enquanto o dicionário lookup_palette associa os valores de classe de transição às definições de cores.

As duas funções auxiliares podem ser colocadas em uma nova seção de código chamada "Funções auxiliares".

Editor de código (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();
}

A função createFeature usa um dicionário (com a área e a classe de transição de água) e retorna um recurso adequado para criação de gráficos. A função createPieChartSliceDictionary cria uma lista de cores que correspondem às classes de transição, usando o formato esperado pelo gráfico de pizza.

Em seguida, vamos aplicar a função createFeature a cada dicionário na lista (roi_stats) usando ee.List.map para aplicar a função auxiliar a cada elemento da lista.

Editor de código (JavaScript)

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

Agora que temos um FeatureCollection com os atributos que queremos mostrar no gráfico, podemos criar um objeto de gráfico e imprimir no console.

Editor de código (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);

A opção slices colore as fatias do gráfico de pizza para que elas usem a paleta padrão definida para as classes de transição (mostradas anteriormente na tabela de legenda do mapa). A opção sliceVisibilityThreshold evita que pequenas fatias sejam agrupadas em uma categoria "Outros". O gráfico resultante será semelhante ao mostrado na Figura 13.

Gráfico de resumo da classe de transição de água
Figura 13. Gráfico que resume o tamanho relativo das classes de transição de água.

Script final

O script completo desta seção é:

Editor de código (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)',
});

Isso conclui o tutorial sobre o conjunto de dados de água superficial global. Este tutorial mostrou como trabalhar com apenas três das camadas de dados (ocorrência, intensidade de mudança e transição) disponíveis no conjunto de dados de água superficial global. Leia sobre as outras camadas de dados disponíveis no Guia para usuários de dados (v2).

Boa sorte com as análises!