Übergang der Wasserklasse

Die Wassergrenzschicht erfasst Änderungen zwischen drei Klassen des Wasservorkommens (kein Wasser, saisonales Wasser und dauerhaftes Wasser) sowie zwei zusätzlichen Klassen für ephemeres Wasser (ephemeres dauerhaftes und ephemeres saisonales Wasser).

In diesem Abschnitt der Anleitung wird Folgendes behandelt:

  1. eine Kartebene zum Visualisieren von Wasserübergängen hinzuzufügen,
  2. einen gruppierten Reducer zum Summieren der Fläche jeder Übergangsklasse in einer angegebenen Region of Interest erstellen und
  3. Erstellen Sie ein Diagramm, in dem die Fläche nach Übergangsklasse zusammengefasst wird.

Einfache Visualisierung

Fügen Sie im Abschnitt „Asset List“ des Skripts die folgende Anweisung hinzu, mit der ein Einzelbandbildobjekt mit dem Namen transition erstellt wird:

Code-Editor (JavaScript)

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

Die GSW-Bilder enthalten Metadaten zu den Übergangsklassennummern und -namen sowie eine Standardpalette für die Formatierung der Übergangsklassen. Wenn die Übergangsebene der Karte hinzugefügt wird, werden diese Visualisierungsparameter automatisch verwendet.

Fügen Sie unten im Abschnitt „Kartenebenen“ Ihres Skripts die folgende Anweisung ein, um eine neue Kartenebene hinzuzufügen, auf der die Übergangsklassen angezeigt werden:

Code-Editor (JavaScript)

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

Wenn Sie das Skript ausführen, wird die Übergangsebene angezeigt.

Übergangsklassen für Oberflächenwasser
Abbildung 10. Screenshot des Mekong-Deltas, der eine große Vielfalt an Übergängen zwischen Oberflächenwasserklassen zeigt.

Der Kartenschlüssel für die Übergangsklassen lautet:

Wert Symbol Label
0 Kein Wasser
1 Dauerhaft
2 Neue permanente Nummer
3 Dauerhaft verloren
4 Saisonal
5 Neue saisonale
6 Saisonal verloren
7 Saisonal zu dauerhaft
8 Von dauerhaft zu saisonal
9 Sitzungsspezifisch dauerhaft
10 Sitzungsspezifisch und saisonal

Zusammenfassung der Fläche nach Übergangsklasse

In diesem Abschnitt verwenden wir noch einmal das Tool für Geometrie-Polygone, um eine Region von Interesse zu definieren. Wenn Sie einen neuen Standort analysieren möchten, müssen Sie zuerst das ursprüngliche Polygon auswählen und löschen, damit Sie keine Ergebnisse aus den kombinierten Bereichen erhalten. Informationen zum Ändern von Geometrien finden Sie im Abschnitt Geometrie-Tools der Code Editor-Dokumentation.

In diesem Beispiel zeichnen wir ein neues Polygon im Mekong-Delta.

Übergangsklassen mit ROI
Abbildung 11. Das Mekongdelta in Vietnam mit einer Region of Interest, die mit dem Polygon-Zeichentool des Codeeditors erstellt wurde.

Um die von Teilen eines Bildes abgedeckte Fläche zu berechnen, fügen wir dem Übergangsbildobjekt ein zusätzliches Band hinzu, das die Größe jedes Pixels in Quadratmetern mithilfe der Methode ee.Image.pixelArea angibt.

Code-Editor (JavaScript)

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

Das resultierende Bildobjekt (area_image_with_transition_class) ist ein Bild mit zwei Bändern. Das erste Band enthält die Flächeninformationen in Quadratmetern (erstellt mit der Methode ee.Image.pixelAreacode> ) und das zweite Band die Informationen zur Übergangsklasse.

Anschließend fassen wir die Klassenübergänge in einer Region von Interesse (roi) mit der Methode ee.Image.reduceRegion und einem gruppierten Reducer zusammen, der die Fläche innerhalb jeder Übergangsklasse summiert:

Code-Editor (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);

In der Konsolenausgabe wird jetzt reduction_results angezeigt. Sie müssen den Baum einige Ebenen erweitern, um die Daten zur Bereichsübersicht zu sehen.

Gruppierte Ergebnisse zur Reduzierung
Abbildung 12. Konsolenausgabe mit den Ergebnissen der gruppierten Reduzierung.

Das reduction_results-Objekt enthält zwar Informationen zum Bereich, der von jeder Übergangsklasse abgedeckt wird, aber es ist nicht besonders leicht zu lesen. Im nächsten Abschnitt wird es einfacher, die Ergebnisse anzusehen.

Übersichtsdiagramm erstellen

In diesem Abschnitt erstellen wir ein Diagramm, um die Ergebnisse besser zusammenzufassen. Zuerst extrahieren wir die Liste der Übergangsklassen mit Bereichen:

Code-Editor (JavaScript)

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

Das Ergebnis des gruppierten Reducer (reduction_results) ist ein Dictionary mit einer Liste von Dictionaries. Für jede Übergangsklasse ist ein Wörterbuch in der Liste vorhanden. In diesen Anweisungen wird die Methode ee.Dictionary.get verwendet, um die gruppierten Reducer-Ergebnisse aus diesem Dictionary zu extrahieren und die Ergebnisse in den Datentyp ee.List umzuwandeln, damit wir auf die einzelnen Dictionaries zugreifen können.

Um die Diagrammfunktionen des Code-Editors nutzen zu können, erstellen wir eine FeatureCollection, die die erforderlichen Informationen enthält. Dazu erstellen wir zuerst zwei Nachschlagewerte und zwei Hilfsfunktionen. Der Code, mit dem die Nachschlagewerte erstellt werden, kann wie folgt oben im Abschnitt „Berechnungen“ platziert werden:

Code-Editor (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')
);

Im lookup_names-Dictionary werden Übergangsklassenwerte ihren Namen zugeordnet, während im lookup_palette-Dictionary die Übergangsklassenwerte Farbdefinitionen zugeordnet werden.

Die beiden Hilfsfunktionen können in einen neuen Codeabschnitt mit dem Namen „Helper functions“ (Hilfsfunktionen) eingefügt werden.

Code-Editor (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();
}

Die Funktion createFeature verwendet ein Dictionary (mit der Fläche und der Wasserübergangsklasse) und gibt ein Feature zurück, das sich für die Darstellung in einem Diagramm eignet. Mit der Funktion createPieChartSliceDictionary wird eine Liste von Farben erstellt, die den Übergangsklassen entsprechen. Dabei wird das Format verwendet, das für das Kreisdiagramm erwartet wird.

Als Nächstes wenden wir die Funktion createFeature auf jedes Dictionary in der Liste (roi_stats) an. Dazu verwenden wir ee.List.map, um die Hilfsfunktion auf jedes Element der Liste anzuwenden.

Code-Editor (JavaScript)

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

Nachdem wir eine FeatureCollection mit den Attributen haben, die wir im Diagramm darstellen möchten, können wir ein Diagrammobjekt erstellen und es in der Konsole ausgeben.

Code-Editor (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);

Mit der Option slices werden die Kreissegmente so eingefärbt, dass sie die Standardpalette verwenden, die für die Übergangsklassen definiert ist (siehe oben in der Tabelle mit der Kartenlegende). Mit der Option sliceVisibilityThreshold wird verhindert, dass kleine Segmente in der Kategorie „Sonstiges“ zusammengefasst werden. Das resultierende Diagramm sollte in etwa so aussehen wie in Abbildung 13.

Übersichtsdiagramm für Wasserübergangsklassen
Abbildung 13. Diagramm, in dem die relative Größe der Wasserübergangsklassen zusammengefasst ist.

Endgültiges Script

Das gesamte Skript für diesen Abschnitt lautet:

Code-Editor (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)',
});

Damit ist die Anleitung zum Dataset „Global Surface Water“ abgeschlossen. In dieser Anleitung wurde gezeigt, wie Sie mit nur drei der Datenschichten (Vorkommen, Änderungsintensität und Übergang) arbeiten, die im Dataset „Global Surface Water“ verfügbar sind. Informationen zu den anderen verfügbaren Datenschichten finden Sie im Data Users Guide (v2).

Viel Erfolg mit Ihren Analysen!