As imagens que compõem um ImageCollection
podem ser visualizadas como uma
animação ou uma série de miniaturas, também chamada de "tira de filme". Esses
métodos fornecem uma avaliação rápida do conteúdo de um ImageCollection
e um meio eficaz para testemunhar mudanças espaciais e temporais (Figura 1).
getVideoThumbURL()
produz uma série de imagens animadasgetFilmstripThumbURL()
produz uma série de imagens em miniatura
As seções a seguir descrevem como preparar um ImageCollection
para
visualização, fornecem um exemplo de código para cada método de visualização de coleção
e abordam várias técnicas de animação avançadas.
Figura 1. Animação mostrando a progressão de três dias de furacões no Atlântico em
setembro de 2017.
Preparação para a coleta
Filtrar, compor, classificar e estilizar imagens em uma coleção para mostrar apenas
aquelas de interesse ou enfatizar um fenômeno. Qualquer ImageCollection
pode ser
fornecido como entrada para as funções de visualização, mas uma coleção selecionada
com consideração de intervalos de datas inter e intra-anuais, intervalo de observação, extensão regional, qualidade e representação pode alcançar melhores resultados.
Filtragem
Filtre uma coleção de imagens para incluir apenas dados relevantes que apoiem o objetivo da visualização. Considere datas, extensão espacial, qualidade e outras propriedades específicas de um determinado conjunto de dados.
Por exemplo, filtre uma coleção de refletância de superfície do Sentinel-2:
um único período
Editor de código (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filterDate('2018-01-01', '2019-01-01');
um intervalo de dias do ano em série,
Editor de código (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filter(ee.Filter.calendarRange(171, 242, 'day_of_year'));
uma região de interesse,
Editor de código (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filterBounds(ee.Geometry.Point(-122.1, 37.2));
ou uma propriedade de imagem.
Editor de código (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 50));
Encadear vários filtros.
Editor de código (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');
Composição
Composto de períodos de datas intra e interanuais para reduzir o número de imagens em uma coleção e melhorar a qualidade. Por exemplo, suponha que você criou uma visualização do NDVI anual para a África. Uma opção é simplesmente filtrar uma coleção NDVI de 16 dias do MODIS para incluir todas as observações de 2018.
Editor de código (JavaScript)
var ndviCol = ee.ImageCollection('MODIS/006/MOD13A2') .filterDate('2018-01-01', '2019-01-01') .select('NDVI');
Composto inter-anual por filtro e redução
A visualização da coleção acima mostra ruído considerável nas regiões florestais em que a cobertura de nuvens é intensa (Figura 2a). É possível conseguir uma representação melhor reduzindo os intervalos de datas seriais pela mediana em todos os anos na coleção MODIS.
Editor de código (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);
A animação resultante dessa coleção é menos ruidosa, já que cada imagem representa a mediana de um composto de NDVI de 16 dias para mais de 20 anos de dados (Figura 1b). Consulte este tutorial para mais informações sobre essa animação.
![]() |
![]() |
---|---|
Figura 2a. NDVI anual sem composição inter-anual. | Figura 2b. NDVI anual com composição inter-anual. |
Composto intra-anual por filtro e redução
O exemplo anterior aplica a composição inter-anual. Também pode ser útil compor uma série de observações intra-anuais. Por exemplo, os dados da Landsat são coletados a cada 16 dias para uma determinada cena por sensor, mas, muitas vezes, parte das imagens fica obscurecida por nuvens. O mascaramento das nuvens e a composição de várias imagens da mesma estação podem produzir uma representação mais livre de nuvens. Considere o exemplo a seguir em que as imagens do Landsat 5 de julho e agosto são compostas usando a mediana para cada ano de 1985 a 2011.
Editor de código (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);
Composto intra-anual por união e redução
Os dois métodos de composição anteriores mapeiam um List
de dias e anos para definir de forma incremental novas datas a serem filtradas e compostas.
Aplicar uma mesclagem é outro método para realizar essa operação. No snippet abaixo, uma coleção de anos exclusiva é definida e uma mesclagem saveAll
é aplicada para identificar todas as imagens que correspondem a um determinado ano.
As imagens pertencentes a um determinado ano são agrupadas em um objeto List
, que é
armazenado como uma propriedade do representante do ano na coleção de anos
diferentes. Os compostos anuais são gerados a partir dessas listas, reduzindo
ImageCollections
definido por elas em uma função mapeada sobre a coleção de anos
diferentes.
Editor de código (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);
Composição no mesmo dia por mesclagem e redução
Outro caso de composição é criar mosaicos de imagens espacialmente contíguos. Suponha que sua região de interesse abranja duas linhas do Landsat no mesmo caminho e que seu objetivo seja mostrar um mosaico de imagens das duas imagens para cada órbita do Landsat 8 em 2017 e 2018. Aqui, depois de filtrar a coleção por caminho e linha, uma operação de mesclagem é usada para mesclar imagens do Landsat do mesmo período, definido pela data de aquisição.
Editor de código (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(); }));
Classificação
Classifique uma coleção por tempo para garantir a sequência cronológica adequada ou ordene
por uma propriedade de sua escolha. Por padrão, a série de visualização é classificada na ordem natural da coleção. A disposição da série pode
ser alterada usando o método de coleta sort
, em que uma propriedade Image
é
selecionada para classificação em ordem crescente ou decrescente. Por exemplo, para
ordenar por tempo de observação, use a propriedade system:time_start
onipresente.
Editor de código (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filterBounds(ee.Geometry.Point(-122.1, 37.2)) .sort('system:time_start');
Ou talvez a ordem seja definida por aumento da cobertura de nuvens, como neste caso das imagens do Sentinel-2.
Editor de código (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filterBounds(ee.Geometry.Point(-122.1, 37.2)) .sort('CLOUDY_PIXEL_PERCENTAGE');
A ordem também pode ser definida por uma propriedade derivada, como a NDVI regional média. Aqui, o NDVI regional é adicionado como uma propriedade a cada imagem em uma função mapeada, seguida por uma classificação na nova propriedade.
Editor de código (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);
Visualização de imagens
A visualização de imagens transforma números em cores. Há três maneiras de controlar como os dados de imagem são representados como cores nos métodos de visualização de coletâneas:
- Forneça argumentos de visualização diretamente para
getVideoThumbURL
egetFilmstripThumbURL
. - Mapeie o método de imagem
visualize
sobre a coleção de imagens antes da aplicação degetVideoThumbURL
egetFilmstripThumbURL
. - Mapeie o método de imagem
sldStyle
sobre a coleção de imagens antes da aplicação degetVideoThumbURL
egetFilmstripThumbURL
. Consulte Descritor de camada estilizada para mais informações.
Os exemplos neste guia usam as opções 1 e 2, em que a visualização é feita mapeando três bandas de uma imagem multibanda para canais de cores vermelho, verde e azul ou valores de gradação de uma única banda linearmente em uma paleta de cores. Os parâmetros de visualização incluem:
Parâmetro | Descrição | Tipo |
---|---|---|
bandas | Lista delimitada por vírgulas de três nomes de faixas a serem mapeadas para RGB | list |
min | Valores a serem mapeados para 0 | número ou lista de três números, um para cada faixa |
max | Valores a serem mapeados para 255 | número ou lista de três números, um para cada faixa |
ganho | Valores para multiplicar cada valor de pixel | número ou lista de três números, um para cada faixa |
viés | Valores a serem adicionados a cada DN | número ou lista de três números, um para cada faixa |
gama | Fatores de correção de gama | número ou lista de três números, um para cada faixa |
palette | Lista de strings de cores no estilo CSS (somente imagens de banda única) | lista separada por vírgulas de strings hexadecimais |
opacidade | A opacidade da camada (0,0 é totalmente transparente e 1,0 é totalmente opaco) | número |
Use o argumento bands
para selecionar as faixas que você quer visualizar. Forneça
uma lista de um ou três nomes de bandas. Em relação a imagens de várias bandas,
as três primeiras bandas são selecionadas por padrão. A ordem do nome da faixa determina
a atribuição de cores. As faixas 1, 2 e 3 listadas são mapeadas para
vermelho, verde e azul, respectivamente.
A escala de intervalo de dados é uma consideração importante ao visualizar imagens. Por
padrão, os valores de dados de ponto flutuante entre 0 e 1 (inclusive) são dimensionados
entre 0 e 255 (inclusive). Os valores fora desse intervalo são forçados a 0 e
255, dependendo se são menores que 0 ou maiores que 1,
respectivamente. Em relação aos dados inteiros, a capacidade total definida pelo tipo
é dimensionada entre 0 e 255. Por exemplo, dados assinados de 16 bits têm um intervalo de
−32.768 a 32.767, que é dimensionado para [0, 255] por padrão. Aceitar os
padrões muitas vezes pode resultar em visualizações com pouco ou nenhum contraste
entre os recursos da imagem. Use min
e max
para melhorar o contraste e enfatizar
um intervalo de dados específico. Uma boa regra é definir min
e max
como valores que representam o segundo e o 98º percentil dos dados na sua área de interesse. Confira o exemplo a seguir de cálculo desses valores para um modelo de elevação digital.
Editor de código (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());
O parâmetro palette
define as cores para representar a imagem de visualização de 8 bits. Ele se aplica apenas a representações de banda única.
Especificá-lo com uma imagem de várias bandas resulta em um erro.
Se os dados forem de banda única ou se você quiser visualizar uma única banda de
uma imagem de várias bandas, defina o parâmetro forceRgbOutput
como true
(não é necessário
se o argumento palette
for fornecido). Use os parâmetros min
e max
para
definir o intervalo de valores para dimensionar linearmente entre 0 e 255.
Confira a seguir um exemplo de mapeamento de uma função de visualização em uma coleção de imagens de uma única banda. Uma coleção NDVI do MODIS é importada, os argumentos de visualização
para o método visualization
são definidos e uma função que
transforma valores em representações de imagens RGB é mapeada sobre a coleção
NDVI.
Editor de código (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);
Confira um exemplo de mapeamento de uma função de visualização em uma coleção de imagens multibanda:
Editor de código (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);
Nesse caso, nenhum argumento de paleta é fornecido porque três bandas são fornecidas,
que definem a intensidade de cada camada RGB. Ambos os exemplos usam os parâmetros
min
e max
para controlar quais valores são esticados até os limites
dos dados RGB de 8 bits.
Miniatura do vídeo
A função getVideoThumbURL()
gera uma animação de todas as imagens em
um ImageCollection
, em que cada imagem representa um frame. O fluxo de trabalho
geral para produzir uma animação é o seguinte:
- Defina um
Geometry
cujos limites determinam a extensão regional da animação. - Defina um
ImageCollection
. - Considere a visualização de imagens: mapeie uma função de visualização de imagens sobre a coleção ou adicione argumentos de visualização de imagens ao conjunto de argumentos de animação.
- Defina argumentos de animação e chame o método
getVideoThumbURL
.
O resultado de getVideoThumbURL
é um URL. Imprima o URL no console e
clique nele para iniciar os servidores do Earth Engine que geram a animação em tempo real em
uma nova guia do navegador. Como alternativa, para conferir a animação no console do Editor de código,
chame a função ui.Thumbnail
na coleção e nos
argumentos de animação correspondentes. Após a renderização, a animação fica disponível
para download. Para fazer isso, clique com o botão direito do mouse nela e selecione as opções
adequadas no menu de contexto.
O exemplo a seguir ilustra a geração de uma animação que mostra as temperaturas globais ao longo de 24 horas. Observe que este exemplo inclui
argumentos de visualização e de animação, em vez de mapear primeiro
uma função de visualização no ImageCollection
. Ao executar
esse script, uma animação semelhante à Figura 3 vai aparecer no console do
editor de código.
Editor de código (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));
Figura 3. Temperatura da superfície por hora para o solstício de inverno do hemisfério norte, representada como uma imagem GIF animada.
Trecho
A função getFilmstripThumbUrl
gera uma única imagem estática
que representa a concatenação de todas as imagens em um ImageCollection
em uma
série norte-sul. A sequência de frames da tira de filme segue a ordem natural
da coleção.
O resultado de getFilmstripThumbUrl
é um URL. Mostre o URL no console
e clique nele para iniciar os servidores do Earth Engine que geram a imagem em tempo real em
uma nova guia do navegador. Após a renderização, a imagem fica disponível para download.
Clique com o botão direito do mouse nela e selecione as opções adequadas no menu de contexto.
O snippet de código abaixo usa a mesma coleção do exemplo de miniatura de vídeo acima. Ao executar esse script, uma tira de filme semelhante à Figura 4 vai aparecer no console do editor de código.
Editor de código (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));
Figura 4. Temperatura da superfície por hora para o solstício de inverno do hemisfério norte,
representada como uma imagem PNG de filme. A tira de filme foi
dividida em quatro seções para exibição. O resultado de getFilmstripThumbURL
é uma única série de imagens da coleção unidas de norte a sul.
Técnicas avançadas
As seções a seguir descrevem como usar recorte, opacidade e composição de camadas para melhorar as visualizações adicionando bordas de polígono, enfatizando regiões de interesse e comparando imagens em uma coleção.
Todos os exemplos a seguir nesta seção usam a mesma base
ImageCollection
definida aqui:
Editor de código (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});
Sobreposições
Várias imagens podem ser sobrepostas usando o método blend
Image
, em que
os pixels sobrepostos de duas imagens são mesclados com base nas máscaras (opacidade).
Sobreposição de vetor
Adicionar polígonos de limite administrativo e outras geometrias a uma imagem pode fornecer um contexto espacial valioso. Considere a animação da temperatura da superfície diária global acima (Figura 3). Os limites entre terra e oceano são um pouco discerníveis, mas podem ser explicitados adicionando uma sobreposição de polígonos de países.
Os dados vetoriais (Features
) são desenhados em imagens aplicando o método paint
.
Os recursos podem ser pintados em uma imagem existente, mas a melhor prática é
pintar em uma imagem em branco, estilizar e mesclar o resultado com outras
camadas de imagem estilizadas. O tratamento de cada camada de uma pilha de visualização
de forma independente permite mais controle sobre o estilo.
O exemplo a seguir demonstra como pintar as fronteiras dos países da América do Sul em uma Image
em branco e mesclar o resultado com cada Image
da coleção de temperatura diária global (Figura 5). Os limites dos países sobrepostos
diferenciam a terra da água e fornecem contexto para os padrões de temperatura.
Editor de código (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));
Figura 5. Adicione sobreposições de vetor a imagens em uma coleção para fornecer contexto espacial.
Imagem sobreposta
Várias imagens podem ser sobrepostas para alcançar o estilo desejado. Suponha que você queira destacar uma região de interesse. Você pode criar uma cópia silenciada de uma visualização de imagem como uma camada de base e, em seguida, sobrepor uma versão cortada da visualização original. Com base no exemplo anterior, o script a seguir produz a Figura 6.
Editor de código (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));
Figura 6. Destaque uma área de interesse recortando a imagem e sobrepondo-a
em uma cópia sem som.
Também é possível mesclar dados de imagem com uma camada de base de sombreamento de colinas para indicar o terreno e dar profundidade à visualização (Figura 7).
Editor de código (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));
Figura 7. Mostre o terreno sobrepondo dados de imagem parcialmente transparentes em uma camada de sombreamento de terreno.
Transições
Personalize uma coleção de imagens para produzir animações que revelem diferenças entre duas imagens em uma coleção usando transições de desbotamento, cintilação e deslize. Cada um dos exemplos a seguir usa a mesma visualização de base gerada pelo seguinte script:
Editor de código (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
Com apenas duas imagens em uma coleção, como é o caso aqui, o flicker é a
representação padrão na animação da coleção. Ajuste o
argumento de animação framesPerSecond
para acelerar ou desacelerar a taxa
de oscilação. Os argumentos de visualização a seguir aplicados à coleção acima
produzem a Figura 8.
Editor de código (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));
Figura 8. Exemplo de oscilação entre a temperatura da superfície às 12h GMT para o solstício de inverno e de verão.
Esmaecer
Uma transição de desbotamento entre duas camadas é alcançada diminuindo simultaneamente a opacidade de uma camada e aumentando a opacidade da outra em uma sequência de incrementos de opacidade de quase 0 a 1 (Figura 9).
Editor de código (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));
Figura 9. Exemplo de desvanecimento entre a temperatura da superfície às 12h GMT no verão
e no solstício de inverno.
Controle deslizante
Uma transição de controle deslizante mostra e oculta progressivamente a camada de imagem. Isso é feito ajustando iterativamente a opacidade da imagem sobreposta em uma faixa de longitudes (Figura 10).
Editor de código (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));
Figura 10. Exemplo de transição deslizante entre a temperatura da superfície às 12h GMT
para o solstício de verão e de inverno.