Warstwa przejściowa wody rejestruje zmiany między 3 klasami występowania wody (brak wody, woda sezonowa i woda stała) oraz 2 dodatkowymi klasami wody efemerycznej (efemeryczna stała i efemeryczna sezonowa).
W tej części samouczka:
- dodać warstwę mapy do wizualizacji zmian w zasobach wodnych;
- utwórz zgrupowany reduktor, który sumuje obszar każdej klasy przejścia w określonym regionie zainteresowania,
- utworzyć wykres podsumowujący obszar według klasy przejścia.
Podstawowa wizualizacja
W sekcji listy komponentów skryptu dodaj to stwierdzenie, które tworzy obiekt obrazu z 1 zakresem o nazwie transition
:
Edytor kodu (JavaScript)
var transition = gsw.select('transition');
Obrazy GSW zawierają metadane dotyczące numerów i nazw klas przejść oraz domyślną paletę do stylizowania klas przejść. Gdy warstwa przejściowa zostanie dodana do mapy, te parametry wizualizacji będą używane automatycznie.
U dołu sekcji Warstwy mapy w skrypcie dodaj to polecenie, które dodaje nową warstwę mapy wyświetlającą klasy przejść:
Edytor kodu (JavaScript)
Map.setCenter(105.26, 11.2134, 9); // Mekong River Basin, SouthEast Asia Map.addLayer({ eeObject: transition, name: 'Transition classes (1984-2015)', });
Po uruchomieniu skryptu wyświetli się warstwa przejścia.

Klucz mapy dla klas przejść to:
Wartość | Symbol | Etykieta |
---|---|---|
0 | Nie woda | |
1 | Trwałe | |
2 | Nowe stałe | |
3 | Utracono na stałe | |
4 | Sezonowe | |
5 | Nowe sezonowe | |
6 | Utracone treści sezonowe | |
7 | Przejście z umowy sezonowej na umowę na czas nieokreślony | |
8 | Stałe na sezonowe | |
9 | Efemeryczny stały | |
10 | Efemeryczne sezonowe |
Podsumowanie obszaru według klasy przejścia
W tej sekcji ponownie użyjemy narzędzia do tworzenia wielokątów, aby zdefiniować obszar zainteresowania. Jeśli chcesz przeanalizować nową lokalizację, najpierw wybierz i usuń pierwotny narysowany wielokąt, aby nie otrzymywać wyników z połączonych obszarów. Informacje o modyfikowaniu geometrii znajdziesz w sekcji Narzędzia do geometrii w dokumentacji Edytora kodu.
W tym przykładzie narysujemy nowy wielokąt w delcie Mekongu.

Aby obliczyć obszar pokryty przez części obrazu, dodamy do obiektu obrazu przejścia dodatkowe pasmo, które określa rozmiar każdego piksela w metrach kwadratowych za pomocą metody ee.Image.pixelArea.
Edytor kodu (JavaScript)
var area_image_with_transition_class = ee.Image.pixelArea().addBands(transition);
Obiekt obrazu wynikowego (area_image_with_transition_class
) to obraz dwupasmowy, w którym pierwsze pasmo zawiera informacje o obszarze w metrach kwadratowych (uzyskane za pomocą metody
ee.Image.pixelArea
code>
), a drugie pasmo zawiera informacje o klasie przejścia.
Następnie podsumowujemy przejścia między klasami w wybranym regionie (roi
) za pomocą metody
ee.Image.reduceRegion
i
reduktora grupującego, który sumuje obszar w każdej klasie przejścia:
Edytor kodu (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);
Dane wyjściowe na karcie konsoli będą teraz zawierać znak reduction_results
. Pamiętaj, że aby zobaczyć dane podsumowujące obszar, musisz rozwinąć drzewo o kilka poziomów.

Obiekt reduction_results
zawiera informacje o obszarze objętym każdą klasą przejścia, ale nie są one zbyt czytelne. W następnej sekcji ułatwimy wyświetlanie wyników.
Tworzenie wykresu podsumowującego
W tej sekcji utworzymy wykres, aby lepiej podsumować wyniki. Na początek wyodrębniamy listę klas przejścia z obszarami w ten sposób:
Edytor kodu (JavaScript)
var roi_stats = ee.List(reduction_results.get('groups'));
Wynikiem zgrupowanego reduktora (reduction_results
) jest słownik zawierający listę słowników.
Na liście znajduje się jeden słownik dla każdej klasy przejścia.
Te instrukcje używają metody
ee.Dictionary.get
, aby wyodrębnić z tego słownika zgrupowane wyniki reduktora, i rzutują wyniki na typ danych ee.List
, abyśmy mogli uzyskać dostęp do poszczególnych słowników.
Aby korzystać z funkcji tworzenia wykresów w edytorze kodu, utworzymy obiekt FeatureCollection zawierający niezbędne informacje. W tym celu najpierw tworzymy 2 słowniki wyszukiwania i 2 funkcje pomocnicze. Kod tworzący słowniki wyszukiwania można umieścić u góry sekcji „Obliczenia” w ten sposób:
Edytor kodu (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') );
Słownik lookup_names
przypisuje wartości klasy przejścia do ich nazw, a słownik lookup_palette
przypisuje wartości klasy przejścia do definicji kolorów.
Te 2 funkcje pomocnicze można umieścić w nowej sekcji kodu o nazwie „Funkcje pomocnicze”.
Edytor kodu (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(); }
Funkcja createFeature
przyjmuje słownik (zawierający obszar i klasę przejścia wody) i zwraca obiekt Feature odpowiedni do tworzenia wykresów.
Funkcja createPieChartSliceDictionary
tworzy listę kolorów, które odpowiadają klasom przejść, w formacie oczekiwanym przez wykres kołowy.
Następnie zastosujemy funkcję createFeature
do każdego słownika na liście roi_stats
, używając funkcji ee.List.map, aby zastosować funkcję pomocniczą do każdego elementu listy.
Edytor kodu (JavaScript)
var transition_fc = ee.FeatureCollection(roi_stats.map(createFeature)); print('transition_fc', transition_fc);
Mamy już obiekt FeatureCollection zawierający atrybuty, które chcemy wyświetlić na wykresie. Możemy teraz utworzyć obiekt wykresu i wydrukować go w konsoli.
Edytor kodu (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);
Opcja slices
powoduje pokolorowanie wycinków wykresu kołowego za pomocą domyślnej palety zdefiniowanej dla klas przejść (pokazanej wcześniej w tabeli legendy mapy).
Opcja sliceVisibilityThreshold
zapobiega grupowaniu małych wycinków w kategorii „Inne”.
Wynikowy wykres powinien być podobny do tego na rysunku 13.

Skrypt końcowy
Cały skrypt tej sekcji to:
Edytor kodu (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)', });
To koniec samouczka dotyczącego zbioru danych Global Surface Water. Pamiętaj, że w tym samouczku pokazaliśmy, jak pracować tylko z 3 warstwami danych (występowanie, intensywność zmian i przejście) dostępnymi w zbiorze danych Global Surface Water. Więcej informacji o innych warstwach danych dostępnych w Przewodniku dla użytkowników danych (wersja 2) znajdziesz w tym dokumencie.
Życzymy owocnych analiz.