Les images qui composent une ImageCollection
peuvent être visualisées sous forme d'animation ou de série de miniatures appelées "filmstrip". Ces méthodes permettent d'évaluer rapidement le contenu d'une ImageCollection
et constituent un moyen efficace de constater les changements spatiotemporels (figure 1).
getVideoThumbURL()
produit une série d'images animées.getFilmstripThumbURL()
produit une série d'images miniatures
Les sections suivantes décrivent comment préparer une ImageCollection
pour la visualisation, fournissent un exemple de code pour chaque méthode de visualisation de la collection et couvrent plusieurs techniques d'animation avancées.
Figure 1. Animation montrant l'évolution des ouragans de l'Atlantique sur trois jours en septembre 2017.
Préparation de la collecte
Filtrez, composez, triez et stylisez les images d'une collection pour n'afficher que celles qui vous intéressent ou pour mettre en avant un phénomène. Vous pouvez fournir n'importe quel ImageCollection
comme entrée aux fonctions de visualisation, mais une collection sélectionnée en tenant compte des plages de dates inter- et intra-annuelles, de l'intervalle d'observation, de l'étendue régionale, de la qualité et de la représentation peut donner de meilleurs résultats.
Filtrage
Filtrez une collection d'images pour n'inclure que les données pertinentes qui servent l'objectif de la visualisation. Tenez compte des dates, de l'étendue spatiale, de la qualité et d'autres propriétés spécifiques à un ensemble de données donné.
Par exemple, filtrez une collection de réflectance de surface Sentinel-2 par:
une seule période,
Éditeur de code (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filterDate('2018-01-01', '2019-01-01');
une plage de jours de l'année,
Éditeur de code (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filter(ee.Filter.calendarRange(171, 242, 'day_of_year'));
une région d'intérêt,
Éditeur de code (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filterBounds(ee.Geometry.Point(-122.1, 37.2));
ou une propriété d'image.
Éditeur de code (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 50));
Enchaîner plusieurs filtres.
Éditeur de code (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');
Composition
Combinez des plages de dates intra- et interannuelles pour réduire le nombre d'images dans une collection et améliorer la qualité. Par exemple, imaginons que vous souhaitiez créer une visualisation du NDVI annuel pour l'Afrique. Vous pouvez simplement filtrer une collection NDVI MODIS de 16 jours pour inclure toutes les observations de 2018.
Éditeur de code (JavaScript)
var ndviCol = ee.ImageCollection('MODIS/006/MOD13A2') .filterDate('2018-01-01', '2019-01-01') .select('NDVI');
Composite interannuel par filtre et réduction
La visualisation de la collection ci-dessus montre un bruit considérable dans les régions boisées où la couverture nuageuse est importante (figure 2a). Une meilleure représentation peut être obtenue en réduisant les plages de dates séquentielles en fonction de la médiane pour toutes les années de la collection MODIS.
Éditeur de code (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);
L'animation issue de cette collection est moins bruyante, car chaque image représente la médiane d'un composite NDVI sur 16 jours pour plus de 20 ans de données (figure 1b). Pour en savoir plus sur cette animation, consultez ce tutoriel.
![]() |
![]() |
---|---|
Figure 2a. NDVI annuel sans composition interannuelle. | Figure 2b. NDVI annuel avec composition interannuelle. |
Composite intra-annuel par filtre et réduction
L'exemple précédent applique une composition interannuelle. Il peut également être utile de composer une série d'observations intra-annuelles. Par exemple, les données Landsat sont collectées tous les 16 jours pour une scène donnée par capteur, mais une partie des images est souvent masquée par des nuages. Masquer les nuages et composer plusieurs images de la même saison peut produire une représentation plus claire. Prenons l'exemple suivant, où les images Landsat 5 de juillet et d'août sont composées à l'aide de la médiane pour chaque année de 1985 à 2011.
Éditeur de code (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);
Composite intra-annuel par jointure et réduction
Notez que les deux méthodes de composition précédentes mappent sur une List
de jours et d'années pour définir progressivement de nouvelles dates à filtrer et à composer.
Vous pouvez également effectuer cette opération en appliquant une jointure. Dans l'extrait de code suivant, une collection d'année unique est définie, puis une jointure saveAll
est appliquée pour identifier toutes les images correspondant à une année donnée.
Les images appartenant à une année donnée sont regroupées dans un objet List
, qui est stocké en tant que propriété du représentant de l'année respective dans la collection d'années distinctes. Les composites annuels sont générés à partir de ces listes en réduisant les ImageCollections
définies par elles dans une fonction mappée sur la collection d'années distinctes.
Éditeur de code (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);
Composite du même jour par association et réduction
Un autre cas de composition consiste à créer des mosaïques d'images contiguës spatialement. Supposons que votre région d'intérêt s'étende sur deux lignes Landsat dans le même chemin, et que votre objectif soit d'afficher une mosaïque d'images des deux images pour chaque orbite Landsat 8 en 2017 et 2018. Ici, après avoir filtré la collection par chemin et ligne, une opération de jointure est utilisée pour créer une mosaïque d'images Landsat de la même orbite, définie par la date d'acquisition.
Éditeur de code (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(); }));
Tri
Triez une collection par date pour assurer une séquence chronologique correcte ou triez-la par propriété de votre choix. Par défaut, la série de cadres de visualisation est triée dans l'ordre naturel de la collection. La disposition de la série peut être modifiée à l'aide de la méthode de collection sort
, dans laquelle une propriété Image
est sélectionnée pour le tri par ordre croissant ou décroissant. Par exemple, pour trier par heure d'observation, utilisez la propriété system:time_start
omniprésente.
Éditeur de code (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filterBounds(ee.Geometry.Point(-122.1, 37.2)) .sort('system:time_start');
L'ordre pourrait également être défini en fonction de l'augmentation de l'opacité des nuages, comme dans le cas des images Sentinel-2.
Éditeur de code (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filterBounds(ee.Geometry.Point(-122.1, 37.2)) .sort('CLOUDY_PIXEL_PERCENTAGE');
L'ordre peut également être défini par une propriété dérivée, telle que l'indice NDVI régional moyen. Ici, l'indice NDVI régional est ajouté en tant que propriété à chaque image dans une fonction mappée, suivie d'un tri sur la nouvelle propriété.
Éditeur de code (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);
Visualisation des images
La visualisation d'images transforme les chiffres en couleurs. Il existe trois façons de contrôler la représentation des données d'image sous forme de couleur dans les méthodes de visualisation de la collection:
- Fournissez des arguments de visualisation directement à
getVideoThumbURL
etgetFilmstripThumbURL
. - Mappez la méthode d'image
visualize
sur la collection d'images avant d'appliquergetVideoThumbURL
etgetFilmstripThumbURL
. - Mappez la méthode d'image
sldStyle
sur la collection d'images avant d'appliquergetVideoThumbURL
etgetFilmstripThumbURL
. Pour en savoir plus, consultez la section Styled Layer Descriptor.
Les exemples de ce guide utilisent les options 1 et 2, où la visualisation est obtenue en mappant trois bandes d'image d'une image multibande sur les canaux de couleur rouge, vert et bleu, ou en graduant les valeurs d'une seule bande de manière linéaire le long d'une palette de couleurs. Les paramètres de visualisation incluent les suivants:
Paramètre | Description | Type |
---|---|---|
bandes | Liste des trois noms de bandes à mapper sur RGB, séparés par une virgule | list |
min | Valeur(s) à mapper sur 0 | nombre ou liste de trois nombres, un pour chaque bande |
max | Valeur(s) à mapper sur 255 | nombre ou liste de trois nombres, un pour chaque bande |
gain | Valeur(s) à multiplier par chaque valeur de pixel | nombre ou liste de trois nombres, un pour chaque bande |
biais | Valeur(s) à ajouter à chaque DN | nombre ou liste de trois nombres, un pour chaque bande |
gamma | Facteur(s) de correction de gamma | nombre ou liste de trois nombres, un pour chaque bande |
palette | Liste des chaînes de couleur de style CSS (images à bande unique uniquement) | Liste de chaînes hexadécimales séparées par une virgule |
opacité | Opacité du calque (0,0 correspond à une transparence totale et 1,0 à une opacité totale) | Total |
Utilisez l'argument bands
pour sélectionner la ou les bandes que vous souhaitez visualiser. Fournissez une liste d'un à trois noms de groupes. Pour les images multibandes, les trois premières bandes sont sélectionnées par défaut. L'ordre des noms de bande détermine l'attribution des couleurs. Les bandes 1, 2 et 3 sont mappées respectivement sur le rouge, le vert et le bleu.
La mise à l'échelle de la plage de données est un élément important à prendre en compte lors de la visualisation d'images. Par défaut, les valeurs de données à virgule flottante comprises entre 0 et 1 (inclus) sont mises à l'échelle entre 0 et 255 (inclus). Les valeurs en dehors de cette plage sont forcées sur 0 et 255, selon qu'elles sont inférieures à 0 ou supérieures à 1, respectivement. En ce qui concerne les données entières, la capacité totale définie par son type est mise à l'échelle entre 0 et 255 (par exemple, les données signées 16 bits ont une plage allant de −32 768 à 32 767, qui est mise à l'échelle sur [0, 255] par défaut). Accepter les valeurs par défaut peut souvent entraîner des visualisations avec peu ou pas de contraste entre les éléments de l'image. Utilisez min
et max
pour améliorer le contraste et mettre en avant une plage de données spécifique. En règle générale, définissez min
et max
sur des valeurs qui représentent les 2e et 98e centiles des données dans votre domaine d'intérêt. Consultez l'exemple suivant pour calculer ces valeurs pour un modèle numérique d'élévation.
Éditeur de code (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());
Le paramètre palette
définit les couleurs à utiliser pour représenter l'image d'affichage 8 bits. Il ne s'applique qu'aux représentations monobandes. Si vous le spécifiez avec une image multibande, vous recevrez une erreur.
Si les données sont monobandes ou si vous souhaitez visualiser une seule bande à partir d'une image multibande, définissez le paramètre forceRgbOutput
sur true
(inutile si l'argument palette
est fourni). Utilisez les paramètres min
et max
pour définir la plage de valeurs à mettre à l'échelle linéaire entre 0 et 255.
Vous trouverez ci-dessous un exemple de mappage d'une fonction de visualisation sur une collection d'images monobandes. Une collection NDVI MODIS est importée, les arguments de visualisation de la méthode visualization
sont définis et une fonction qui transforme les valeurs en représentations d'images RVB est mappée sur la collection NDVI.
Éditeur de code (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);
Voici un exemple de mappage d'une fonction de visualisation sur une collection d'images multibandes:
Éditeur de code (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);
Dans ce cas, aucun argument de palette n'est fourni, car trois bandes sont fournies, qui définissent l'intensité pour chaque calque RVB. Notez que les deux exemples utilisent les paramètres min
et max
pour contrôler les valeurs étirées jusqu'aux limites des données RVB 8 bits.
Miniature vidéo
La fonction getVideoThumbURL()
génère une animation à partir de toutes les images d'un ImageCollection
, où chaque image représente un frame. Le workflow général pour créer une animation est le suivant:
- Définissez une
Geometry
dont les limites déterminent l'étendue régionale de l'animation. - Définissez un
ImageCollection
. - Envisagez la visualisation d'images: mappez une fonction de visualisation d'images sur la collection ou ajoutez des arguments de visualisation d'images à l'ensemble d'arguments d'animation.
- Définissez les arguments d'animation et appelez la méthode
getVideoThumbURL
.
Le résultat de getVideoThumbURL
est une URL. Imprimez l'URL dans la console, puis cliquez dessus pour démarrer les serveurs Earth Engine qui génèrent l'animation instantanément dans un nouvel onglet du navigateur. Vous pouvez également afficher l'animation dans la console de l'éditeur de code en appelant la fonction ui.Thumbnail
sur la collection et ses arguments d'animation correspondants. Une fois l'animation générée, vous pouvez la télécharger en effectuant un clic droit dessus et en sélectionnant les options appropriées dans le menu contextuel.
L'exemple suivant illustre la génération d'une animation représentant les températures mondiales sur 24 heures. Notez que cet exemple inclut des arguments de visualisation ainsi que des arguments d'animation, au lieu de mapper d'abord une fonction de visualisation sur ImageCollection
. Lorsque vous exécutez ce script, une animation semblable à la figure 3 doit s'afficher dans la console de l'éditeur de code.
Éditeur de code (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));
Figure 3. Température de surface horaire pour le solstice d'hiver dans l'hémisphère nord représentée sous forme d'image GIF animée.
Pellicule
La fonction getFilmstripThumbUrl
génère une seule image statique représentant la concaténation de toutes les images d'un ImageCollection
dans une série nord-sud. La séquence des images de la pellicule suit l'ordre naturel de la collection.
Le résultat de getFilmstripThumbUrl
est une URL. Imprimez l'URL dans la console, puis cliquez dessus pour démarrer les serveurs Earth Engine qui génèrent l'image instantanément dans un nouvel onglet du navigateur. Une fois l'image affichée, vous pouvez la télécharger en effectuant un clic droit dessus et en sélectionnant les options appropriées dans son menu contextuel.
L'extrait de code suivant utilise la même collection que l'exemple d'aperçu vidéo ci-dessus. Lorsque vous exécutez ce script, une pellicule semblable à la figure 4 doit s'afficher dans la console de l'éditeur de code.
Éditeur de code (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));
Figure 4. Température de surface horaire pour le solstice d'hiver dans l'hémisphère nord représentée sous forme d'image PNG de pellicule. Notez que la pellicule a été divisée en quatre sections à des fins d'affichage. Le résultat de getFilmstripThumbURL
est une seule série d'images de collection jointes du nord au sud.
Techniques avancées
Les sections suivantes décrivent comment utiliser le masquage, l'opacité et la composition de calques pour améliorer les visualisations en ajoutant des bordures de polygone, en mettant en avant des régions d'intérêt et en comparant des images dans une collection.
Notez que tous les exemples suivants de cette section utilisent la même ImageCollection
de base définie ici:
Éditeur de code (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});
Superpositions
Vous pouvez superposer plusieurs images à l'aide de la méthode Image
blend
, où les pixels qui se chevauchent de deux images sont mélangés en fonction de leurs masques (opacité).
Superposition vectorielle
Ajouter des polygones de limites administratives et d'autres géométries à une image peut fournir un contexte spatial précieux. Considérons l'animation de la température de surface quotidienne mondiale ci-dessus (figure 3). Les limites entre la terre et l'océan sont quelque peu discernables, mais elles peuvent être explicitées en ajoutant un calque de polygone des pays.
Les données vectorielles (Features
) sont dessinées sur les images en appliquant la méthode paint
.
Vous pouvez peindre des éléments sur une image existante, mais il est préférable de les peindre sur une image vierge, de leur appliquer un style, puis de mélanger le résultat avec d'autres calques d'images stylisés. Traiter chaque couche d'une pile de visualisation indépendamment permet de mieux contrôler le style.
L'exemple suivant montre comment peindre les frontières des pays d'Amérique du Sud sur une Image
vierge et mélanger le résultat avec chaque Image
de la collection de températures quotidiennes mondiales (figure 5). Les frontières des pays superposées permettent de distinguer les terres de l'eau et de mettre en contexte les tendances de température.
Éditeur de code (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));
Figure 5. Ajoutez des superpositions vectorielles aux images d'une collection pour fournir un contexte spatial.
Images superposées
Vous pouvez superposer plusieurs images pour obtenir le style souhaité. Supposons que vous souhaitiez mettre en avant une zone d'intérêt. Vous pouvez créer une copie atténuée d'une visualisation d'image en tant que calque de base, puis superposer une version tronquée de la visualisation d'origine. S'appuyant sur l'exemple précédent, le script suivant génère la figure 6.
Éditeur de code (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));
Figure 6. Mettez en avant une zone d'intérêt en coupant l'image et en la superposant à une copie en demi-teinte.
Vous pouvez également mélanger des données d'image avec un calque de base en ombres portées pour indiquer le relief et donner de la profondeur à la visualisation (figure 7).
Éditeur de code (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));
Figure 7. Afficher le relief en superposant des données d'image partiellement transparentes sur un calque d'ombres portées
Transitions
Personnalisez une collection d'images pour produire des animations qui révèlent les différences entre deux images d'une collection à l'aide de transitions de fondu, de clignotement et de diapositive. Chacun des exemples suivants utilise la même visualisation de base générée par le script suivant:
Éditeur de code (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
S'il n'y a que deux images dans une collection, comme c'est le cas ici, le scintillement est la représentation par défaut lors de l'animation de la collection. Ajustez l'argument d'animation framesPerSecond
pour accélérer ou ralentir la fréquence de clignotement. Les arguments de visualisation suivants appliqués à la collection ci-dessus génèrent la figure 8.
Éditeur de code (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));
Figure 8. Exemple de clignotement entre 12h GMT et la température de surface pour le solstice d'hiver et le solstice d'été.
Fondu
Une transition de fondu entre deux calques est obtenue en diminuant simultanément l'opacité de l'un tout en augmentant l'opacité de l'autre sur une séquence d'incréments d'opacité allant de près de 0 à 1 (figure 9).
Éditeur de code (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));
Figure 9. Exemple de fondu entre la température de surface à midi (GMT) pour l'été et le solstice d'hiver.
Curseur
Une transition de curseur affiche et masque progressivement la couche d'image sous-jacente. Pour ce faire, il suffit d'ajuster de manière itérée l'opacité de l'image superposée sur une plage de longitudes (figure 10).
Éditeur de code (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));
Figure 10. Exemple de transition glissante entre la température de surface à midi (GMT) pour le solstice d'été et d'hiver.