Transition de la classe d'eau

La couche de transition de l'eau capture les changements entre trois classes d'occurrence d'eau (pas d'eau, eau saisonnière et eau permanente) ainsi que deux classes supplémentaires pour l'eau éphémère (permanente éphémère et saisonnière éphémère).

Dans cette section du tutoriel, vous allez :

  1. ajouter un calque de carte pour visualiser la transition de l'eau,
  2. Créer un réducteur groupé pour additionner la superficie de chaque classe de transition dans une zone d'intérêt spécifiée
  3. créer un graphique qui résume la zone par classe de transition.

Visualisation de base

Dans la section "Asset List" (Liste des éléments) du script, ajoutez l'instruction suivante, qui crée un objet d'image à bande unique appelé transition :

Éditeur de code (JavaScript)

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

Les images GSW contiennent des métadonnées sur les numéros et les noms des classes de transition, ainsi qu'une palette par défaut pour styliser les classes de transition. Lorsque la couche de transition est ajoutée à la carte, ces paramètres de visualisation sont utilisés automatiquement.

Au bas de la section "Map Layers" (Calques de carte) de votre script, ajoutez l'instruction suivante, qui ajoute un calque de carte affichant les classes de transition :

Éditeur de code (JavaScript)

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

Lorsque vous exécutez le script, la couche de transition s'affiche.

Classes de transition des eaux de surface
Figure 10. Capture d'écran du delta du Mékong, montrant une grande variation dans les transitions de classe des eaux de surface.

La clé de carte pour les classes de transition est :

Valeur Symbole Libellé
0 Pas de l'eau
1 Permanente
2 Nouveau permanent
3 Perte définitive
4 Saisonnier
5 Nouveau contenu saisonnier
6 Saisonnier perdu
7 Saisonnier à permanent
8 Permanent à saisonnier
9 Éphémère permanent
10 Saisonnier éphémère

Résumer la zone par classe de transition

Dans cette section, nous allons à nouveau utiliser l'outil de polygone géométrique pour définir une région d'intérêt. Si vous souhaitez analyser un nouvel emplacement, vous devez d'abord sélectionner et supprimer le polygone d'origine que vous avez dessiné afin de ne pas obtenir de résultats pour les zones combinées. Pour savoir comment modifier des géométries, consultez la section Outils de géométrie de la documentation de l'éditeur de code.

Pour cet exemple, nous allons dessiner un nouveau polygone dans le delta du Mékong.

Classes de transition avec ROI
Figure 11. Delta du Mékong au Vietnam, avec une région d'intérêt créée à l'aide de l'outil de dessin de polygones de l'éditeur de code.

Pour calculer la superficie couverte par des parties d'une image, nous allons ajouter une bande supplémentaire à l'objet image de transition qui identifie la taille de chaque pixel en mètres carrés à l'aide de la méthode ee.Image.pixelArea.

Éditeur de code (JavaScript)

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

L'objet d'image obtenu (area_image_with_transition_class) est une image à deux bandes, où la première bande contient les informations de zone en mètres carrés (produites par la méthode ee.Image.pixelArea ) et la deuxième bande contient les informations de classe de transition.

Nous résumons ensuite les transitions de classe dans une région d'intérêt (roi) à l'aide de la méthode ee.Image.reduceRegion et d'un réducteur groupé qui permet de résumer la zone dans chaque classe de transition :

Éditeur de code (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);

Le résultat de l'onglet de la console affiche désormais reduction_results. Notez que vous devrez développer l'arborescence de quelques niveaux pour afficher les données récapitulatives de la zone.

Résultats de réduction groupés
Figure 12. Résultat de l'onglet "Console", affichant les résultats de la réduction groupée.

Bien que l'objet reduction_results contienne des informations sur la zone couverte par chaque classe de transition, il n'est pas particulièrement facile à lire. Dans la section suivante, nous allons faciliter l'affichage des résultats.

Créer un graphique récapitulatif

Dans cette section, nous allons créer un graphique pour mieux résumer les résultats. Pour commencer, nous extrayons d'abord la liste des classes de transition avec les zones comme suit :

Éditeur de code (JavaScript)

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

Le résultat du réducteur groupé (reduction_results) est un dictionnaire contenant une liste de dictionnaires. La liste contient un dictionnaire pour chaque classe de transition. Ces instructions utilisent la méthode ee.Dictionary.get pour extraire les résultats du réducteur groupé de ce dictionnaire et les convertit en un type de données ee.List, afin que nous puissions accéder aux dictionnaires individuels.

Pour utiliser les fonctions de création de graphiques de l'éditeur de code, nous allons créer une FeatureCollection contenant les informations nécessaires. Pour ce faire, nous créons d'abord deux dictionnaires de recherche et deux fonctions d'assistance. Le code qui crée les dictionnaires de recherche peut être placé en haut de la section "Calculations" (Calculs) comme suit :

Éditeur de code (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')
);

Le dictionnaire lookup_names associe les valeurs de classe de transition à leurs noms, tandis que le dictionnaire lookup_palette associe les valeurs de classe de transition aux définitions de couleur.

Les deux fonctions d'assistance peuvent être placées dans une nouvelle section de code appelée "Fonctions d'assistance".

Éditeur de code (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();
}

La fonction createFeature utilise un dictionnaire (contenant la zone et la classe de transition de l'eau) et renvoie un élément géographique adapté à la création de graphiques. La fonction createPieChartSliceDictionary crée une liste de couleurs correspondant aux classes de transition, au format attendu par le graphique à secteurs.

Ensuite, nous appliquerons la fonction createFeature à chaque dictionnaire de la liste (roi_stats) à l'aide de ee.List.map pour appliquer la fonction d'assistance à chaque élément de la liste.

Éditeur de code (JavaScript)

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

Maintenant que nous disposons d'une FeatureCollection contenant les attributs que nous voulons afficher sur le graphique, nous pouvons créer un objet graphique et l'imprimer dans la console.

Éditeur de code (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'option slices colore les secteurs du graphique à secteurs de sorte qu'ils utilisent la palette par défaut définie pour les classes de transition (présentées précédemment dans le tableau des clés de la carte). L'option sliceVisibilityThreshold empêche les petits secteurs d'être regroupés dans une catégorie "autre". Le graphique obtenu doit ressembler à celui de la figure 13.

Graphique récapitulatif des classes de transition de l'eau
Figure 13. Graphique résumant la taille relative des classes de transition de l'eau.

Script final

Voici le script complet de cette section :

Éditeur de code (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)',
});

Ce tutoriel sur l'ensemble de données Global Surface Water est maintenant terminé. Notez que ce tutoriel n'a montré comment utiliser que trois des couches de données (occurrence, intensité du changement et transition) disponibles dans l'ensemble de données Global Surface Water. Pour en savoir plus sur les autres calques de données disponibles, consultez le guide de l'utilisateur des données (v2).

Bonne analyse !