Die Bilder eines ImageCollection
können entweder als Animation oder als Reihe von Thumbnails dargestellt werden, die als „Filmstreifen“ bezeichnet werden. Diese Methoden ermöglichen eine schnelle Beurteilung des Inhalts eines ImageCollection
und sind ein effektives Medium, um raumzeitliche Veränderungen zu beobachten (Abbildung 1).
getVideoThumbURL()
erstellt eine animierte BildreihegetFilmstripThumbURL()
erzeugt eine Reihe von Miniaturansichten.
In den folgenden Abschnitten wird beschrieben, wie Sie eine ImageCollection
für die Visualisierung vorbereiten. Außerdem finden Sie Beispielcode für jede Sammlungsvisualisierungsmethode und Informationen zu verschiedenen erweiterten Animationstechniken.
Abbildung 1. Animation, die die Entwicklung von Atlantik-Hurrikanen im September 2017 über drei Tage hinweg zeigt
Vorbereitung der Datenerhebung
Sie können Bilder in einer Sammlung filtern, zusammenstellen, sortieren und stilisieren, um nur die gewünschten Bilder anzuzeigen oder ein Phänomen hervorzuheben. Jede ImageCollection
kann als Eingabe für die Visualisierungsfunktionen verwendet werden. Bessere Ergebnisse lassen sich jedoch mit einer ausgewählten Sammlung erzielen, bei der jahresübergreifende und jahresinterne Datumsbereiche, Beobachtungsintervalle, regionale Ausdehnung, Qualität und Darstellung berücksichtigt werden.
Filtern
Filtern Sie eine Bildsammlung, damit nur relevante Daten enthalten sind, die dem Zweck der Visualisierung entsprechen. Berücksichtigen Sie Datumsangaben, räumliche Ausdehnung, Qualität und andere Eigenschaften, die für einen bestimmten Datensatz spezifisch sind.
Sie können beispielsweise eine Sentinel-2-Sammlung mit Oberflächenreflexionen nach folgenden Kriterien filtern:
einen einzelnen Zeitraum
Code-Editor (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filterDate('2018-01-01', '2019-01-01');
einen fortlaufenden Zeitraum für den Tag des Jahres,
Code-Editor (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filter(ee.Filter.calendarRange(171, 242, 'day_of_year'));
einen Bereich von Interesse,
Code-Editor (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filterBounds(ee.Geometry.Point(-122.1, 37.2));
oder eine Bildeigenschaft.
Code-Editor (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 50));
Mehrere Filter verketten
Code-Editor (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filterDate('2018-01-01', '2019-01-01') .filterBounds(ee.Geometry.Point(-122.1, 37.2)) .filter('CLOUDY_PIXEL_PERCENTAGE < 50');
Compositing
Kombinieren Sie innerhalb eines Jahres und zwischen verschiedenen Jahren liegende Zeiträume, um die Anzahl der Bilder in einer Sammlung zu reduzieren und die Qualität zu verbessern. Angenommen, Sie möchten eine Visualisierung des jährlichen NDVI für Afrika erstellen. Eine Möglichkeit besteht darin, eine 16-tägige MODIS-NDVI-Sammlung einfach so zu filtern, dass alle Beobachtungen aus dem Jahr 2018 enthalten sind.
Code-Editor (JavaScript)
var ndviCol = ee.ImageCollection('MODIS/006/MOD13A2') .filterDate('2018-01-01', '2019-01-01') .select('NDVI');
Mehrjährige zusammengesetzte Daten nach Filter und Reduzierung
Die Visualisierung der obigen Sammlung zeigt erhebliches Rauschen in den bewaldeten Gebieten mit hoher Wolkenbedeckung (Abbildung 2a). Eine bessere Darstellung kann durch die Reduzierung der seriellen Zeiträume auf den Median für alle Jahre in der MODIS-Sammlung erreicht werden.
Code-Editor (JavaScript)
// Make a day-of-year sequence from 1 to 365 with a 16-day step. var doyList = ee.List.sequence(1, 365, 16); // Import a MODIS NDVI collection. var ndviCol = ee.ImageCollection('MODIS/006/MOD13A2').select('NDVI'); // Map over the list of days to build a list of image composites. var ndviCompList = doyList.map(function(startDoy) { // Ensure that startDoy is a number. startDoy = ee.Number(startDoy); // Filter images by date range; starting with the current startDate and // ending 15 days later. Reduce the resulting image collection by median. return ndviCol .filter(ee.Filter.calendarRange(startDoy, startDoy.add(15), 'day_of_year')) .reduce(ee.Reducer.median()); }); // Convert the image List to an ImageCollection. var ndviCompCol = ee.ImageCollection.fromImages(ndviCompList);
Die Animation aus dieser Sammlung ist weniger verrauscht, da jedes Bild den Median eines 16-tägigen NDVI-Composites aus mehr als 20 Jahren Daten darstellt (Abbildung 1b). Weitere Informationen zu dieser Animation finden Sie in dieser Anleitung.
Abbildung 2a. Jährlicher NDVI ohne mehrjährige Komposition. | Abbildung 2b. Jährlicher NDVI mit mehrjährigem Compositing. |
Innerhalb des Jahres zusammengesetzte Daten nach Filter und Reduzierung
Im vorherigen Beispiel wird eine mehrjährige Komposition angewendet. Es kann auch hilfreich sein, eine Reihe von Beobachtungen innerhalb eines Jahres zusammenzuführen. So werden beispielsweise Landsat-Daten alle 16 Tage für eine bestimmte Szene pro Sensor erfasst. Oft sind jedoch Teile der Bilder von Wolken verdeckt. Wenn Sie die Wolken ausblenden und mehrere Bilder aus derselben Jahreszeit zusammensetzen, können Sie eine wolkenlosere Darstellung erzielen. Im folgenden Beispiel werden Landsat 5-Bilder aus Juli und August mit dem Median für jedes Jahr von 1985 bis 2011 kombiniert.
Code-Editor (JavaScript)
// Assemble a collection of Landsat surface reflectance images for a given // region and day-of-year range. var lsCol = ee.ImageCollection('LANDSAT/LT05/C02/T1_L2') .filterBounds(ee.Geometry.Point(-122.9, 43.6)) .filter(ee.Filter.dayOfYear(182, 243)) // Add the observation year as a property to each image. .map(function(img) { return img.set('year', ee.Image(img).date().get('year')); }); // Define a function to scale the data and mask unwanted pixels. function maskL457sr(image) { // Bit 0 - Fill // Bit 1 - Dilated Cloud // Bit 2 - Unused // Bit 3 - Cloud // Bit 4 - Cloud Shadow var qaMask = image.select('QA_PIXEL').bitwiseAnd(parseInt('11111', 2)).eq(0); var saturationMask = image.select('QA_RADSAT').eq(0); // Apply the scaling factors to the appropriate bands. var opticalBands = image.select('SR_B.').multiply(0.0000275).add(-0.2); var thermalBand = image.select('ST_B6').multiply(0.00341802).add(149.0); // Replace the original bands with the scaled ones and apply the masks. return image.addBands(opticalBands, null, true) .addBands(thermalBand, null, true) .updateMask(qaMask) .updateMask(saturationMask); } // Define a list of unique observation years from the image collection. var years = ee.List(lsCol.aggregate_array('year')).distinct().sort(); // Map over the list of years to build a list of annual image composites. var lsCompList = years.map(function(year) { return lsCol // Filter image collection by year. .filterMetadata('year', 'equals', year) // Apply cloud mask. .map(maskL457sr) // Reduce image collection by median. .reduce(ee.Reducer.median()) // Set composite year as an image property. .set('year', year); }); // Convert the image List to an ImageCollection. var lsCompCol = ee.ImageCollection.fromImages(lsCompList);
Zusammengesetztes Jahr innerhalb des Jahres durch Zusammenführen und Reduzieren
Beachten Sie, dass die beiden vorherigen Kompositionsmethoden über einen Zeitraum von List
Tagen und Jahren hinweg ablaufen, um inkrementell neue Datumsangaben für die Filterung und Komposition zu definieren.
Eine weitere Methode ist die Anwendung eines Joins. Im folgenden Snippet wird eine eindeutige Jahressammlung definiert und dann ein saveAll
-Join angewendet, um alle Bilder zu ermitteln, die einem bestimmten Jahr entsprechen.
Bilder, die zu einem bestimmten Jahr gehören, werden in einem List
-Objekt gruppiert, das als Property des jeweiligen Jahresvertreters in der Sammlung „Distinct Year“ gespeichert wird. Jährliche Zusammenstellungen werden aus diesen Listen generiert, indem die darin definierte ImageCollections
in einer Funktion reduziert wird, die auf die Sammlung der einzelnen Jahre angewendet wird.
Code-Editor (JavaScript)
// Assemble a collection of Landsat surface reflectance images for a given // region and day-of-year range. var lsCol = ee.ImageCollection('LANDSAT/LT05/C02/T1_L2') .filterBounds(ee.Geometry.Point(-122.9, 43.6)) .filter(ee.Filter.dayOfYear(182, 243)) // Add the observation year as a property to each image. .map(function(img) { return img.set('year', ee.Image(img).date().get('year')); }); // Make a distinct year collection; one image representative per year. var distinctYears = lsCol.distinct('year').sort('year'); // Define a join filter; one-to-many join on ‘year’ property. var filter = ee.Filter.equals({leftField: 'year', rightField: 'year'}); // Define a join. var join = ee.Join.saveAll('year_match'); // Apply the join; results in 'year_match' property being added to each distinct // year representative image. The list includes all images in the collection // belonging to the respective year. var joinCol = join.apply(distinctYears, lsCol, filter); // Define a function to scale the data and mask unwanted pixels. function maskL457sr(image) { // Bit 0 - Fill // Bit 1 - Dilated Cloud // Bit 2 - Unused // Bit 3 - Cloud // Bit 4 - Cloud Shadow var qaMask = image.select('QA_PIXEL').bitwiseAnd(parseInt('11111', 2)).eq(0); var saturationMask = image.select('QA_RADSAT').eq(0); // Apply the scaling factors to the appropriate bands. var opticalBands = image.select('SR_B.').multiply(0.0000275).add(-0.2); var thermalBand = image.select('ST_B6').multiply(0.00341802).add(149.0); // Replace the original bands with the scaled ones and apply the masks. return image.addBands(opticalBands, null, true) .addBands(thermalBand, null, true) .updateMask(qaMask) .updateMask(saturationMask); } // Map over the distinct years collection to build a list of annual image // composites. var lsCompList = joinCol.map(function(img) { // Get the list of images belonging to the given year. return ee.ImageCollection.fromImages(img.get('year_match')) // Apply cloud mask. .map(maskL457sr) // Reduce image collection by median. .reduce(ee.Reducer.median()) // Set composite year as an image property. .copyProperties(img, ['year']); }); // Convert the image List to an ImageCollection. var lsCompCol = ee.ImageCollection(lsCompList);
Zusammengesetzte Daten für denselben Tag durch Zusammenführen und Reduzieren
Ein weiterer Anwendungsfall für das Compositing ist die Erstellung räumlich zusammenhängender Bildmosaike. Angenommen, Ihr Interessensgebiet umfasst zwei Landsat-Zeilen im selben Pfad und Sie möchten für jeden Landsat 8-Orbit in den Jahren 2017 und 2018 ein Bildmosaik aus den beiden Bildern anzeigen. Hier werden die Daten nach Pfad und Zeile gefiltert und dann mithilfe eines Join-Vorgangs Landsat-Bilder aus demselben Orbit zusammengesetzt, definiert durch das Aufnahmedatum.
Code-Editor (JavaScript)
var lsCol = ee.ImageCollection('LANDSAT/LC08/C02/T1_L2') .filterDate('2017-01-01', '2019-01-01') .filter('WRS_PATH == 38 && (WRS_ROW == 28 || WRS_ROW == 29)') .map(function(img) { var date = img.date().format('YYYY-MM-dd'); return img.set('date', date); }); var distinctDates = lsCol.distinct('date').sort('date'); var filter = ee.Filter.equals({leftField: 'date', rightField: 'date'}); var join = ee.Join.saveAll('date_match'); var joinCol = join.apply(distinctDates, lsCol, filter); var lsColMos = ee.ImageCollection(joinCol.map(function(col) { return ee.ImageCollection.fromImages(col.get('date_match')).mosaic(); }));
Sortieren
Sie können eine Sammlung nach Zeit sortieren, um eine korrekte chronologische Reihenfolge zu erhalten, oder nach einem beliebigen Attribut. Standardmäßig werden die Visualisierungsframes in der natürlichen Reihenfolge der Sammlung sortiert. Die Anordnung der Reihe kann mit der Sammlungsmethode sort
geändert werden, wobei eine Image
-Eigenschaft für die Sortierung in aufsteigender oder absteigender Reihenfolge ausgewählt wird. Wenn Sie beispielsweise nach dem Zeitpunkt der Beobachtung sortieren möchten, verwenden Sie das Attribut system:time_start
.
Code-Editor (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filterBounds(ee.Geometry.Point(-122.1, 37.2)) .sort('system:time_start');
Vielleicht sollte die Reihenfolge auch nach zunehmender Bewölkung definiert werden, wie in diesem Fall bei Sentinel-2-Bildern.
Code-Editor (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filterBounds(ee.Geometry.Point(-122.1, 37.2)) .sort('CLOUDY_PIXEL_PERCENTAGE');
Die Reihenfolge kann auch durch ein abgeleitetes Attribut wie den durchschnittlichen regionalen NDVI definiert werden. Hier wird der regionale NDVI jedem Bild in einer zugeordneten Funktion als Attribut hinzugefügt, gefolgt von einer Sortierung nach dem neuen Attribut.
Code-Editor (JavaScript)
// Define an area of interest geometry. var aoi = ee.Geometry.Point(-122.1, 37.2).buffer(1e4); // Filter MODIS NDVI image collection by a date range. var ndviCol = ee.ImageCollection('MODIS/061/MOD13A1') .filterDate('2018-01-01', '2019-01-01') .select('NDVI') // Map over the image collection to calculate regional mean NDVI and add // the result to each image as a property. .map(function(img) { var meanNdvi = img.reduceRegion({ reducer: ee.Reducer.mean(), geometry: aoi, scale: 500}); return img.set('meanNdvi', meanNdvi.get('NDVI')); }) // Sort the collection by descending regional mean NDVI. .sort('meanNdvi', false);
Bildvisualisierung
Bei der Bildvisualisierung werden Zahlen in Farben umgewandelt. Es gibt drei Möglichkeiten, festzulegen, wie Bilddaten in Sammlungsvisualisierungsmethoden als Farbe dargestellt werden:
- Geben Sie Visualisierungsargumente direkt an
getVideoThumbURL
undgetFilmstripThumbURL
weiter. - Ordnen Sie die Bildmethode
visualize
der Bildsammlung zu, bevor SiegetVideoThumbURL
undgetFilmstripThumbURL
anwenden. - Ordnen Sie die Bildmethode
sldStyle
der Bildsammlung zu, bevor SiegetVideoThumbURL
undgetFilmstripThumbURL
anwenden. Weitere Informationen finden Sie unter Styled Layer Descriptor.
In den Beispielen in diesem Leitfaden werden die Optionen 1 und 2 verwendet. Dabei werden drei Bildbänder eines mehrbändigen Bilds den Farbkanälen Rot, Grün und Blau zugeordnet oder die Werte eines einzelnen Bandes werden linear entlang einer Farbpalette abgestuft. Zu den Visualisierungsparametern gehören:
Parameter | Beschreibung | Typ |
---|---|---|
Bänder | Durch Kommas getrennte Liste mit drei Bandnamen, die RGB zugeordnet werden sollen | list |
Min. | Werte, die dem Wert „0“ zugeordnet werden sollen | Eine Zahl oder eine Liste mit drei Zahlen, eine für jede Band |
Max | Wert(e), die 255 zugeordnet werden sollen | Eine Zahl oder eine Liste mit drei Zahlen, eine für jede Band |
gewinnen | Wert(e), mit dem bzw. denen jeder Pixelwert multipliziert wird | Eine Zahl oder eine Liste mit drei Zahlen, eine für jede Band |
Voreingenommenheit | Werte, die jeder DN hinzugefügt werden sollen | Eine Zahl oder eine Liste mit drei Zahlen, eine für jede Band |
Gamma | Gammakorrekturfaktor(en) | Eine Zahl oder eine Liste mit drei Zahlen, eine für jede Band |
palette | Liste der CSS-Farbstrings (nur einfarbige Bilder) | durch Kommas getrennte Liste von Hexadezimalstrings |
opacity | Die Deckkraft der Ebene (0,0 = vollständig transparent, 1,0 = vollständig undurchsichtig) | Zahl |
Verwenden Sie das Argument bands
, um die Bänder auszuwählen, die Sie visualisieren möchten. Gib eine Liste mit einem oder drei Bandnamen an. Bei Multibandbildern sind standardmäßig die ersten drei Bänder ausgewählt. Die Reihenfolge der Bandnamen bestimmt die Farbzuordnung. Die erste, zweite und dritte aufgeführte Band wird jeweils rot, grün und blau zugeordnet.
Die Skalierung des Datenbereichs ist ein wichtiger Faktor bei der Visualisierung von Bildern. Standardmäßig werden Gleitkommadatenwerte zwischen 0 und 1 (einschließlich) zwischen 0 und 255 (einschließlich) skaliert. Werte außerhalb dieses Bereichs werden auf 0 oder 255 gesetzt, je nachdem, ob sie kleiner als 0 oder größer als 1 sind. Bei Ganzzahldaten wird die durch den Typ definierte volle Kapazität zwischen 0 und 255 skaliert. Beispiel: Signierte 16-Bit-Daten haben einen Bereich von −32.768 bis 32.767, der standardmäßig auf [0, 255] skaliert wird. Wenn Sie die Standardeinstellungen akzeptieren, kann das oft zu Visualisierungen mit wenig bis gar keinem Kontrast zwischen Bildelementen führen. Mit min
und max
können Sie den Kontrast verbessern und einen bestimmten Datenbereich hervorheben. Als Faustregel gilt: Legen Sie für min
und max
Werte fest, die dem 2. und 98. Perzentil der Daten in Ihrem Interessenbereich entsprechen. Im folgenden Beispiel wird die Berechnung dieser Werte für ein digitales Höhenmodell veranschaulicht.
Code-Editor (JavaScript)
// Import SRTM global elevation model. var demImg = ee.Image('USGS/SRTMGL1_003'); // Define a rectangular area of interest. var aoi = ee.Geometry.Polygon( [[ [-103.84153083119054, 49.083004219142886], [-103.84153083119054, 25.06838270664608], [-85.64817145619054, 25.06838270664608], [-85.64817145619054, 49.083004219142886] ]], null, false); // Calculate the 2nd and 98th percentile elevation values from rescaled (to // 500m) pixels intersecting the area of interest. A Dictionary is returned. var percentClip = demImg.reduceRegion({ reducer: ee.Reducer.percentile([2, 98]), geometry: aoi, scale: 500, maxPixels: 3e7 }); // Print the regional 2nd and 98th percentile elevation values. Get the // dictionary keys and use them to get the values for each percentile summary. var keys = percentClip.keys(); print('Set vis min to:', ee.Number(percentClip.get(keys.get(0))).round()); print('Set vis max to:', ee.Number(percentClip.get(keys.get(1))).round());
Der Parameter palette
definiert die Farben für das 8‑Bit-Visualisierungsbild. Sie gilt nur für Einbanddarstellungen. Wenn Sie sie für ein Multibandbild angeben, tritt ein Fehler auf.
Wenn die Daten nur ein Band haben oder Sie ein einzelnes Band aus einem mehrbändigen Bild visualisieren möchten, legen Sie den Parameter forceRgbOutput
auf true
fest. Dies ist nicht erforderlich, wenn das Argument palette
angegeben ist. Mit den Parametern min
und max
können Sie den Wertebereich definieren, der linear zwischen 0 und 255 skaliert werden soll.
Im Folgenden finden Sie ein Beispiel für die Zuordnung einer Visualisierungsfunktion auf eine einfarbige Bildsammlung. Eine MODIS-NDVI-Sammlung wird importiert, Visualisierungsargumente für die visualization
-Methode werden festgelegt und eine Funktion, die Werte in RGB-Bilddarstellungen umwandelt, wird auf die NDVI-Sammlung angewendet.
Code-Editor (JavaScript)
// Filter MODIS NDVI image collection by a date range. var ndviCol = ee.ImageCollection('MODIS/061/MOD13A1') .filterDate('2018-01-01', '2019-01-01') .select('NDVI'); // Define visualization arguments. var visArgs = { min: 0, max: 9000, palette: [ 'FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718', '74A901', '66A000', '529400', '3E8601', '207401', '056201', '004C00', '023B01', '012E01', '011D01', '011301' ] }; // Define a function to convert an image to an RGB visualization image and copy // properties from the original image to the RGB image. var visFun = function(img) { return img.visualize(visArgs).copyProperties(img, img.propertyNames()); }; // Map over the image collection to convert each image to an RGB visualization // using the previously defined visualization function. var ndviColVis = ndviCol.map(visFun);
Hier ein Beispiel für die Zuordnung einer Visualisierungsfunktion auf eine mehrbandige Bildsammlung:
Code-Editor (JavaScript)
// Assemble a collection of Sentinel-2 surface reflectance images for a given // region and date range. var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filterBounds(ee.Geometry.Point(-96.9037, 48.0395)) .filterDate('2019-06-01', '2019-10-01'); // Define visualization arguments. var visArgs = {bands: ['B11', 'B8', 'B3'], min: 300, max: 3500}; // Define a function to convert an image to an RGB visualization image and copy // properties from the original image to the RGB image. var visFun = function(img) { return img.visualize(visArgs).copyProperties(img, img.propertyNames()); }; // Map over the image collection to convert each image to an RGB visualization // using the previously defined visualization function. var s2colVis = s2col.map(visFun);
In diesem Fall wird kein Palettenargument angegeben, da drei Bänder angegeben sind, die die Intensität für jede RGB-Ebene definieren. In beiden Beispielen werden die Parameter min
und max
verwendet, um zu steuern, welche Werte bis an die Grenzen der 8‑Bit-RGB-Daten gedehnt werden.
Video-Thumbnail
Die Funktion getVideoThumbURL()
generiert eine Animation aus allen Bildern in einem ImageCollection
, wobei jedes Bild einen Frame darstellt. Der allgemeine Workflow für die Erstellung einer Animation sieht so aus:
- Definieren Sie eine
Geometry
, deren Grenzen den regionalen Umfang der Animation bestimmen. - Definieren Sie eine
ImageCollection
. - Bildvisualisierung: Ordnen Sie entweder eine Bildvisualisierungsfunktion der Sammlung zu oder fügen Sie den Animationen Argumente für die Bildvisualisierung hinzu.
- Definieren Sie die Animationsargumente und rufen Sie die Methode
getVideoThumbURL
auf.
Das Ergebnis von getVideoThumbURL
ist eine URL. Geben Sie die URL in die Konsole ein und klicken Sie darauf, um Earth Engine-Server zu starten, die die Animation direkt in einem neuen Browsertab generieren. Alternativ können Sie die Animation in der Code-Editor-Konsole aufrufen, indem Sie die Funktion ui.Thumbnail
auf die Sammlung und die entsprechenden Animationsargumente anwenden. Nach dem Rendern kann die Animation heruntergeladen werden. Klicken Sie dazu mit der rechten Maustaste darauf und wählen Sie die entsprechenden Optionen aus dem Kontextmenü aus.
Im folgenden Beispiel wird die Erstellung einer Animation veranschaulicht, die die globalen Temperaturen im Verlauf von 24 Stunden darstellt. Beachten Sie, dass dieses Beispiel Visualisierungs- und Animationsargumente enthält, anstatt zuerst eine Visualisierungsfunktion auf die ImageCollection
zuzuordnen. Wenn Sie dieses Script ausführen, sollte in der Code-Editor-Konsole eine Animation ähnlich wie in Abbildung 3 angezeigt werden.
Code-Editor (JavaScript)
// Define an area of interest geometry with a global non-polar extent. var aoi = ee.Geometry.Polygon( [[[-179.0, 78.0], [-179.0, -58.0], [179.0, -58.0], [179.0, 78.0]]], null, false); // Import hourly predicted temperature image collection for northern winter // solstice. Note that predictions extend for 384 hours; limit the collection // to the first 24 hours. var tempCol = ee.ImageCollection('NOAA/GFS0P25') .filterDate('2018-12-22', '2018-12-23') .limit(24) .select('temperature_2m_above_ground'); // Define arguments for animation function parameters. var videoArgs = { dimensions: 768, region: aoi, framesPerSecond: 7, crs: 'EPSG:3857', min: -40.0, max: 35.0, palette: ['blue', 'purple', 'cyan', 'green', 'yellow', 'red'] }; // Print the animation to the console as a ui.Thumbnail using the above defined // arguments. Note that ui.Thumbnail produces an animation when the first input // is an ee.ImageCollection instead of an ee.Image. print(ui.Thumbnail(tempCol, videoArgs)); // Alternatively, print a URL that will produce the animation when accessed. print(tempCol.getVideoThumbURL(videoArgs));
Abbildung 3. Stündliche Oberflächentemperatur für die Wintersonnenwende im Norden als animiertes GIF-Bild.
Filmstreifen
Die Funktion getFilmstripThumbUrl
generiert ein einzelnes statisches Bild, das die Konkatenierung aller Bilder in einem ImageCollection
in einer Nord-Süd-Reihe darstellt. Die Reihenfolge der Filmstreifenbilder folgt der natürlichen Reihenfolge der Sammlung.
Das Ergebnis von getFilmstripThumbUrl
ist eine URL. Geben Sie die URL in die Konsole ein und klicken Sie darauf, um Earth Engine-Server zu starten, die das Bild in einem neuen Browsertab in Echtzeit generieren. Nach dem Rendern kann das Bild heruntergeladen werden. Klicken Sie dazu mit der rechten Maustaste darauf und wählen Sie die entsprechenden Optionen aus dem Kontextmenü aus.
Im folgenden Code-Snippet wird dieselbe Sammlung verwendet wie im Beispiel für Video-Thumbnails oben. Wenn Sie dieses Script ausführen, sollte in der Code-Editor-Konsole ein Filmstreifen ähnlich wie in Abbildung 4 angezeigt werden.
Code-Editor (JavaScript)
// Define an area of interest geometry with a global non-polar extent. var aoi = ee.Geometry.Polygon( [[[-179.0, 78.0], [-179.0, -58.0], [179.0, -58.0], [179.0, 78.0]]], null, false); // Import hourly predicted temperature image collection for northern winter // solstice. Note that predictions extend for 384 hours; limit the collection // to the first 24 hours. var tempCol = ee.ImageCollection('NOAA/GFS0P25') .filterDate('2018-12-22', '2018-12-23') .limit(24) .select('temperature_2m_above_ground'); // Define arguments for the getFilmstripThumbURL function parameters. var filmArgs = { dimensions: 128, region: aoi, crs: 'EPSG:3857', min: -40.0, max: 35.0, palette: ['blue', 'purple', 'cyan', 'green', 'yellow', 'red'] }; // Print a URL that will produce the filmstrip when accessed. print(tempCol.getFilmstripThumbURL(filmArgs));
Abbildung 4. Stündliche Oberflächentemperatur für die Wintersonnenwende im Norden als PNG-Filmstreifenbild. Der Filmstreifen wurde zur Anzeige in vier Abschnitte unterteilt. Das Ergebnis von getFilmstripThumbURL
ist eine einzelne Reihe von Sammlungsbildern, die von Norden nach Süden verbunden sind.
Fortgeschrittene Techniken
In den folgenden Abschnitten wird beschrieben, wie Sie mithilfe von Clipping, Deckkraft und Ebenenkompositionen Visualisierungen verbessern können, indem Sie Polygonränder hinzufügen, interessante Regionen hervorheben und Bilder innerhalb einer Sammlung vergleichen.
Beachten Sie, dass in allen folgenden Beispielen in diesem Abschnitt dieselbe BasisImageCollection
verwendet wird:
Code-Editor (JavaScript)
// Import hourly predicted temperature image collection for northern winter // solstice. Note that predictions extend for 384 hours; limit the collection // to the first 24 hours. var tempCol = ee.ImageCollection('NOAA/GFS0P25') .filterDate('2018-12-22', '2018-12-23') .limit(24) .select('temperature_2m_above_ground'); // Define visualization arguments to control the stretch and color gradient // of the data. var visArgs = { min: -40.0, max: 35.0, palette: ['blue', 'purple', 'cyan', 'green', 'yellow', 'red'] }; // Convert each image to an RGB visualization image by mapping the visualize // function over the image collection using the arguments defined previously. var tempColVis = tempCol.map(function(img) { return img.visualize(visArgs); }); // Import country features and filter to South American countries. var southAmCol = ee.FeatureCollection('USDOS/LSIB_SIMPLE/2017') .filterMetadata('wld_rgn', 'equals', 'South America'); // Define animation region (South America with buffer). var southAmAoi = ee.Geometry.Rectangle({ coords: [-103.6, -58.8, -18.4, 17.4], geodesic: false});
Overlays
Mit der Methode blend
Image
können mehrere Bilder überlagert werden. Dabei werden überlappende Pixel aus zwei Bildern basierend auf ihren Masken (Deckkraft) zusammengeführt.
Vektor-Overlay
Wenn Sie einem Bild Verwaltungsgrenzen und andere Geometrien hinzufügen, können Sie einen wertvollen räumlichen Kontext schaffen. Sehen Sie sich die Animation der globalen täglichen Oberflächentemperatur oben an (Abbildung 3). Die Grenzen zwischen Land und Ozean sind zwar etwas zu erkennen, können aber durch ein Polygon-Overlay von Ländern deutlicher gemacht werden.
Vektordaten (Features
) werden mithilfe der Methode paint
in Bildern dargestellt.
Elemente können auf ein vorhandenes Bild gemalt werden. Es ist jedoch besser, sie auf ein leeres Bild zu malen, zu stilisieren und das Ergebnis dann mit anderen stilisierten Bildebenen zu überblenden. Wenn Sie jede Ebene eines Visualisierungsstapels unabhängig voneinander behandeln, haben Sie mehr Kontrolle über das Styling.
Im folgenden Beispiel wird gezeigt, wie die Landesgrenzen Südamerikas in eine leere Image
-Datei eingezeichnet und das Ergebnis mit jeder Image
der globalen täglichen Temperaturdatensammlung vermischt wird (Abbildung 5). Die eingeblendeten Ländergrenzen unterscheiden Land von Wasser und geben einen Kontext zu den Temperaturmustern.
Code-Editor (JavaScript)
// Define an empty image to paint features to. var empty = ee.Image().byte(); // Paint country feature edges to the empty image. var southAmOutline = empty .paint({featureCollection: southAmCol, color: 1, width: 1}) // Convert to an RGB visualization image; set line color to black. .visualize({palette: '000000'}); // Map a blend operation over the temperature collection to overlay the country // border outline image on all collection images. var tempColOutline = tempColVis.map(function(img) { return img.blend(southAmOutline); }); // Define animation arguments. var videoArgs = { dimensions: 768, region: southAmAoi, framesPerSecond: 7, crs: 'EPSG:3857' }; // Display the animation. print(ui.Thumbnail(tempColOutline, videoArgs));
Abbildung 5. Fügen Sie Bildern in einer Sammlung Vektor-Overlays hinzu, um einen räumlichen Kontext zu schaffen.
Bild-Overlay
Es können mehrere Bilder überlagert werden, um einen gewünschten Stil zu erzielen. Angenommen, Sie möchten einen Bereich hervorheben. Sie können eine gedämpfte Kopie einer Bildvisualisierung als Basisebene erstellen und dann eine zugeschnittene Version der ursprünglichen Visualisierung darüberlegen. Das folgende Script baut auf dem vorherigen Beispiel auf und führt zu Abbildung 6.
Code-Editor (JavaScript)
// Define an empty image to paint features to. var empty = ee.Image().byte(); // Paint country feature edges to the empty image. var southAmOutline = empty .paint({featureCollection: southAmCol, color: 1, width: 1}) // Convert to an RGB visualization image; set line color to black. .visualize({palette: '000000'}); // Map a blend operation over the temperature collection to overlay the country // border outline image on all collection images. var tempColOutline = tempColVis.map(function(img) { return img.blend(southAmOutline); }); // Define a partially opaque grey RGB image to dull the underlying image when // blended as an overlay. var dullLayer = ee.Image.constant(175).visualize({ opacity: 0.6, min: 0, max: 255, forceRgbOutput: true}); // Map a two-part blending operation over the country outline temperature // collection for final styling. var finalVisCol = tempColOutline.map(function(img) { return img // Blend the dulling layer with the given country outline temperature image. .blend(dullLayer) // Blend a clipped copy of the country outline temperature image with the // dulled background image. .blend(img.clipToCollection(southAmCol)); }); // Define animation arguments. var videoArgs = { dimensions: 768, region: southAmAoi, framesPerSecond: 7, crs: 'EPSG:3857' }; // Display the animation. print(ui.Thumbnail(finalVisCol, videoArgs));
Abbildung 6. Betonen Sie einen Bereich, indem Sie das Bild zuschneiden und es auf einer gedimmten Kopie überlagern.
Sie können Bilddaten auch mit einer Basisebene mit Reliefschattierung kombinieren, um das Gelände anzuzeigen und der Visualisierung mehr Tiefe zu verleihen (Abbildung 7).
Code-Editor (JavaScript)
// Define a hillshade layer from SRTM digital elevation model. var hillshade = ee.Terrain.hillshade(ee.Image('USGS/SRTMGL1_003') // Exaggerate the elevation to increase contrast in hillshade. .multiply(100)) // Clip the DEM by South American boundary to clean boundary between // land and ocean. .clipToCollection(southAmCol); // Map a blend operation over the temperature collection to overlay a partially // opaque temperature layer on the hillshade layer. var finalVisCol = tempColVis.map(function(img) { return hillshade .blend(img.clipToCollection(southAmCol).visualize({opacity: 0.6})); }); // Define animation arguments. var videoArgs = { dimensions: 768, region: southAmAoi, framesPerSecond: 7, crs: 'EPSG:3857' }; // Display the animation. print(ui.Thumbnail(finalVisCol, videoArgs));
Abbildung 7. Gelände darstellen, indem teilweise transparente Bilddaten auf einer Reliefschattierungsebene überlagert werden
Übergänge
Sie können eine Bildsammlung anpassen, um mithilfe von Übergängen wie „Weichzeichnen“, „Flimmern“ und „Darstellen“ Animationen zu erstellen, die Unterschiede zwischen zwei Bildern in einer Sammlung aufzeigen. In den folgenden Beispielen wird dieselbe Basisvisualisierung verwendet, die mit dem folgenden Script generiert wurde:
Code-Editor (JavaScript)
// Define an area of interest geometry with a global non-polar extent. var aoi = ee.Geometry.Polygon( [[[-179.0, 78.0], [-179.0, -58.0], [179.0, -58.0], [179.0, 78.0]]], null, false); // Import hourly predicted temperature image collection. var temp = ee.ImageCollection('NOAA/GFS0P25') // Define a northern summer solstice temperature image. var summerSolTemp = temp .filterDate('2018-06-21', '2018-06-22') .filterMetadata('forecast_hours', 'equals', 12) .first() .select('temperature_2m_above_ground'); // Define a northern winter solstice temperature image. var winterSolTemp = temp .filterDate('2018-12-22', '2018-12-23') .filterMetadata('forecast_hours', 'equals', 12) .first() .select('temperature_2m_above_ground'); // Combine the solstice images into a collection. var tempCol = ee.ImageCollection([ summerSolTemp.set('season', 'summer'), winterSolTemp.set('season', 'winter') ]); // Import international boundaries feature collection. var countries = ee.FeatureCollection('USDOS/LSIB_SIMPLE/2017'); // Define visualization arguments. var visArgs = { min: -40.0, max: 35.0, palette: ['blue', 'purple', 'cyan', 'green', 'yellow', 'red'] }; // Convert the image data to RGB visualization images. // The clip and unmask combination sets ocean pixels to black. var tempColVis = tempCol.map(function(img) { return img .visualize(visArgs) .clipToCollection(countries) .unmask(0) .copyProperties(img, img.propertyNames()); });
Flicker
Wenn eine Sammlung nur zwei Bilder enthält, wie hier, ist das Flackern die Standarddarstellung bei der Sammlungsanimation. Passen Sie das framesPerSecond
-Animationsargument an, um die Blinkrate zu beschleunigen oder zu verlangsamen. Mit den folgenden Visualisierungsargumenten, die auf die Sammlung oben angewendet werden, entsteht Abbildung 8.
Code-Editor (JavaScript)
// Define arguments for animation function parameters. var videoArgs = { dimensions: 768, region: aoi, framesPerSecond: 2, crs: 'EPSG:3857' }; // Display animation to the Code Editor console. print(ui.Thumbnail(tempColVis, videoArgs));
Abbildung 8. Beispiel für Flackern zwischen 12:00 Uhr GMT bei der Oberflächentemperatur für die Sommer- und die Wintersonnenwende.
Ausblenden
Ein Ausblendungsübergang zwischen zwei Ebenen wird durch gleichzeitiges Verringern der Deckkraft einer Ebene und gleichzeitiges Erhöhen der Deckkraft der anderen Ebene über eine Abfolge von Deckkraftschritten von fast 0 auf 1 erreicht (Abbildung 9).
Code-Editor (JavaScript)
// Define a sequence of decreasing opacity increments. Note that opacity cannot // be 0, so near 1 and 0 are used. Near 1 is needed because a compliment is // calculated in a following step that can result in 0 if 1 is an element of the // list. var opacityList = ee.List.sequence({start: 0.99999, end: 0.00001, count: 20}); // Filter the summer and winter solstice images from the collection and set as // image objects. var summerImg = tempColVis.filter(ee.Filter.eq('season', 'summer')).first(); var winterImg = tempColVis.filter(ee.Filter.eq('season', 'winter')).first(); // Map over the list of opacity increments to iteratively adjust the opacity of // the two solstice images. Returns a list of images. var imgList = opacityList.map(function(opacity) { var opacityCompliment = ee.Number(1).subtract(ee.Number(opacity)); var winterImgFade = winterImg.visualize({opacity: opacity}); var summerImgFade = summerImg.visualize({opacity: opacityCompliment}); return summerImgFade.blend(winterImgFade).set('opacity', opacity); }); // Convert the image list to an image collection; the forward phase. var fadeForward = ee.ImageCollection.fromImages(imgList); // Make a copy of the collection that is sorted by ascending opacity to // represent the reverse phase. var fadeBackward = fadeForward.sort({property: 'opacity'}); // Merge the forward and reverse phase frame collections. var fadeCol = fadeForward.merge(fadeBackward); // Define animation arguments. var videoArgs = { dimensions: 768, region: aoi, framesPerSecond: 25, crs: 'EPSG:3857' }; // Display the animation. print(ui.Thumbnail(fadeCol, videoArgs));
Abbildung 9. Beispiel für das Ausblenden der Oberflächentemperatur zwischen 12:00 Uhr GMT an der Sommer- und Wintersonnwende.
Schieberegler
Bei einem Schiebereglerübergang wird die darunter liegende Bildebene nach und nach eingeblendet und ausgeblendet. Dazu wird die Deckkraft des überlagernden Bilds iterativ über einen Bereich von Längengraden angepasst (Abbildung 10).
Code-Editor (JavaScript)
// Define a sequence of longitude increments. Start and end are defined by the // min and max longitude of the feature to be provided to the region parameter // of the animation arguments dictionary. var lonSeq = ee.List.sequence({start: -179, end: 179, count: 20}); // Define a longitude image. var longitude = ee.Image.pixelLonLat().select('longitude'); // Filter the summer and winter solstice images from the collection and set as // image objects. var summerImg = tempColVis.filter(ee.Filter.eq('season', 'summer')).first(); var winterImg = tempColVis.filter(ee.Filter.eq('season', 'winter')).first(); // Map over the list of longitude increments to iteratively adjust the mask // (opacity) of the overlying image layer. Returns a list of images. var imgList = lonSeq.map(function(lon) { lon = ee.Number(lon); var mask = longitude.gt(lon); return summerImg.blend(winterImg.updateMask(mask)).set('lon', lon); }); // Convert the image list to an image collection; concealing phase. var sliderColForward = ee.ImageCollection.fromImages(imgList); // Make a copy of the collection that is sorted by descending longitude to // represent the revealing phase. var sliderColbackward = sliderColForward .sort({property: 'lon', ascending: false}); // Merge the forward and backward phase frame collections. var sliderCol = sliderColForward.merge(sliderColbackward); // Define animation arguments. var videoArgs = { dimensions: 768, region: aoi, framesPerSecond: 25, crs: 'EPSG:3857' }; // Display the animation. print(ui.Thumbnail(sliderCol, videoArgs));
Abbildung 10. Beispiel für einen gleitenden Übergang zwischen der Oberflächentemperatur um 12 Uhr GMT für die Sommer- und die Wintersonnenwende.