Übergang der Wasserklasse

Die Ebene für den Wasserübergang erfasst Änderungen zwischen drei Klassen von Wasservorkommen (kein Wasser, saisonales Wasser und permanentes Wasser) sowie zwei zusätzlichen Klassen für ephemeres Wasser (ephemeres permanentes und ephemeres saisonales Wasser).

In diesem Abschnitt der Anleitung wird Folgendes beschrieben:

  1. eine Kartenebene zur Visualisierung des Wasserübergangs hinzufügen,
  2. Erstellen Sie einen gruppierten Reducer, um die Fläche jeder Übergangsklasse innerhalb einer bestimmten Region zu summieren.
  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, um ein Bildobjekt mit einem einzelnen Band namens transition zu erstellen:

Code-Editor (JavaScript)

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

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

Fügen Sie am Ende des Abschnitts „Map Layers“ Ihres Skripts die folgende Anweisung hinzu, um eine neue Kartenebene mit den Übergangsklassen hinzuzufügen:

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 Script 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 bis dauerhaft
8 Dauerhaft bis saisonal
9 Sitzungsspezifisch permanent
10 Sitzungsspezifisch saisonal

Zusammenfassung der Fläche nach Übergangsklasse

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

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

Übergangsklassen mit ROI
Abbildung 11. Das Mekong-Delta in Vietnam mit einem Interessenbereich, der mit dem Polygon-Zeichentool des Code-Editors 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 mit 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 (erzeugt durch die Methode ee.Image.pixelArea ) und das zweite Band die Informationen zur Übergangsklasse.

Anschließend fassen wir die Klassenübergänge innerhalb eines Interessenbereichs (roi) mit der Methode ee.Image.reduceRegion und einem gruppierten Reducer zusammen, um die Fläche innerhalb jeder Übergangsklasse zu addieren:

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);

Auf dem Tab „Console“ wird jetzt reduction_results angezeigt. Beachten Sie, dass Sie die Baumstruktur um einige Ebenen erweitern müssen, um die Zusammenfassungsdaten für den Bereich zu sehen.

Gruppierte Reduktionsergebnisse
Abbildung 12. Ausgabe auf dem Tab „Console“ mit den Ergebnissen der gruppierten Reduzierung.

Das Objekt reduction_results enthält zwar Informationen zu dem Bereich, der von den einzelnen Übergangsklassen abgedeckt wird, ist aber nicht besonders leicht zu lesen. Im nächsten Abschnitt machen wir es einfacher, die Ergebnisse anzusehen.

Zusammenfassungsdiagramm erstellen

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

Code-Editor (JavaScript)

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

Das Ergebnis des gruppierten Reducers (reduction_results) ist ein Dictionary, das eine Liste von Dictionaries enthält. Die Liste enthält ein Wörterbuch für jede Übergangsklasse. In diesen Anweisungen wird die Methode ee.Dictionary.get verwendet, um die gruppierten Reduzierer-Ergebnisse aus diesem Wörterbuch zu extrahieren und die Ergebnisse in den Datentyp ee.List umzuwandeln, damit wir auf die einzelnen Wörterbücher zugreifen können.

Um die Diagrammfunktionen des Code-Editors zu nutzen, erstellen wir eine FeatureCollection, die die erforderlichen Informationen enthält. Dazu erstellen wir zuerst zwei Suchwörterbücher und zwei Hilfsfunktionen. Der Code, mit dem die Suchwörterbücher erstellt werden, kann am Anfang des Abschnitts „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')
);

Das lookup_names-Wörterbuch verknüpft die Werte der Übergangsklassen mit ihren Namen, während das lookup_palette-Wörterbuch die Werte der Übergangsklassen mit Farbdefinitionen verknüpft.

Die beiden Hilfsfunktionen können in einem neuen Codeabschnitt namens „Hilfsfunktionen“ platziert 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 Wörterbuch (mit der Fläche und der Wasserübergangsklasse) und gibt ein Feature zurück, das für die Diagrammerstellung geeignet ist. Die Funktion createPieChartSliceDictionary erstellt eine Liste von Farben, die den Übergangsklassen entsprechen, im vom Kreisdiagramm erwarteten Format.

Als Nächstes wenden wir die Funktion createFeature auf jedes Wörterbuch 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);

Da wir jetzt eine FeatureCollection mit den Attributen haben, die wir im Diagramm darstellen möchten, können wir ein Diagrammobjekt erstellen und 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 Segmente des Kreisdiagramms so eingefärbt, dass die Standardpalette verwendet wird, die für die Übergangsklassen definiert ist (siehe Tabelle mit der Legende oben). Mit der Option sliceVisibilityThreshold wird verhindert, dass kleine Segmente in einer Kategorie „Sonstige“ zusammengefasst werden. Das resultierende Diagramm sollte in etwa so aussehen wie in Abbildung 13.

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

Final 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 Global Surface Water-Dataset abgeschlossen. In dieser Anleitung wurde gezeigt, wie Sie mit nur drei der Datenebenen (Vorkommen, Änderungsintensität und Übergang) arbeiten, die im Global Surface Water-Dataset verfügbar sind. Informationen zu den anderen verfügbaren Datenebenen finden Sie im Data Users Guide (v2).

Viel Erfolg mit Ihren Analysen!