Os algoritmos criados no Earth Engine são executados na nuvem do Google, distribuídos em muitos computadores. A depuração pode ser desafiadora porque os erros podem ocorrer no código do lado do cliente ou na execução do lado do servidor das instruções codificadas e resultar de problemas de escalonamento, bem como de erros sintáticos ou lógicos. Os bits do programa que estão sendo executados em algum lugar na nuvem não estão disponíveis para inspeção, a menos que você solicite. Este documento apresenta estratégias, ferramentas e soluções de depuração para ajudar a resolver erros comuns e depurar scripts do Earth Engine.
Erros de sintaxe
Erros de sintaxe ocorrem quando o código viola as regras da linguagem de programação (JavaScript ou Python no Earth Engine). Esses erros impedem a execução do código e geralmente são detectados antes da execução. Se você encontrar um erro de sintaxe, analise cuidadosamente a linha destacada ou a mensagem de erro e consulte recursos como a Referência da linguagem Python ou o Guia de estilo do JavaScript do Google. Um lintificador de código também pode ajudar a identificar e corrigir esses problemas.
Erros do lado do cliente
Apesar do código estar sintaticamente correto, pode haver erros associados à consistência ou lógica do script. Os exemplos a seguir demonstram erros ao usar uma variável e um método que não existem.
Erro: este código não funciona.
Editor de código (JavaScript)
// Load a Sentinel-2 image. var image = ee.Image('USGS/SRTMGL1_003'); // Error: "bandNames" is not defined in this scope. var display = image.visualize({bands: bandNames, min: 0, max: 9000}); // Error: image.selfAnalyze is not a function var silly = image.selfAnalyze();
import ee import geemap.core as geemap
Colab (Python)
# Load a Sentinel-2 image. image = ee.Image('USGS/SRTMGL1_003') # NameError: name 'band_names' is not defined. display = image.visualize(bands=band_names, min=0, max=9000) # AttributeError: 'Image' object has no attribute 'selfAnalyze'. silly = image.selfAnalyze()
O primeiro erro informa que a variável bandNames não está definida
      no escopo em que é referenciada. Como solução, defina a variável ou forneça um
       argumento de lista para o parâmetro bands. O segundo erro demonstra o que
      acontece quando a função selfAnalyze() inexistente é chamada. Como
      esse não é um método real em imagens, o erro informa que não é uma função. Em ambos
      os casos, o erro é descritivo do problema.
Atribuição de tipo de objeto desconhecida
O erro "...is not a function" pode ocorrer porque o Earth Engine não
      conhece o tipo de uma variável. As manifestações comuns desse problema são resultado de:
- Fazer algo com um objeto retornado por 
first()(o tipo dos elementos em uma coleção é desconhecido). - Fazer algo com um objeto retornado por 
get()(o tipo de elemento armazenado em uma propriedade é desconhecido). - Fazer algo com um argumento de função (na função) quando o tipo do argumento é desconhecido.
 
Como exemplo do primeiro:
Erro: este código não funciona.
Editor de código (JavaScript)
var collection = ee.FeatureCollection('USDOS/LSIB_SIMPLE/2017'); // Error: collection.first(...).area is not a function var area = collection.first().area();
import ee import geemap.core as geemap
Colab (Python)
collection = ee.FeatureCollection('USDOS/LSIB_SIMPLE/2017') # AttributeError: 'Element' object has no attribute 'area'. area = collection.first().area()
A solução em todos os casos é converter o objeto de tipo desconhecido com o construtor
      do tipo conhecido. Continuando o exemplo anterior, a solução é converter para
      ee.Feature:
Solução: use uma transmissão.
Editor de código (JavaScript)
var area = ee.Feature(collection.first()).area();
import ee import geemap.core as geemap
Colab (Python)
area = ee.Feature(collection.first()).area()
É possível chamar qualquer método em Element aqui com segurança, porque é isso que o Earth Engine considera.
Evitar misturar funções de cliente e servidor
O exemplo a seguir é menos óbvio:
Erro: o código não faz o que você quer.
Editor de código (JavaScript)
// Don't mix EE objects and JavaScript objects. var image = ee.Image('USGS/SRTMGL1_003'); var nonsense = image + 2; // You can print this, but it's not what you were hoping for. print(nonsense); // Error: g.eeObject.name is not a function Map.addLayer(nonsense);
import ee import geemap.core as geemap
Colab (Python)
# Don't mix EE objects and Python objects. image = ee.Image('USGS/SRTMGL1_003') nonsense = image + 2 # TypeError: unsupported operand type(s) for +: 'Image' and 'int'. display(nonsense) # TypeError: unsupported operand type(s) for +: 'Image' and 'int'. m = geemap.Map() m.add_layer(nonsense) m
Supondo que o autor desse código pretendia adicionar 2 a cada pixel da
      imagem, essa não é a maneira certa de fazer isso. Especificamente, esse código mistura incorretamente um objeto do lado do servidor (image) com um operador do lado do cliente (+). Os resultados podem ser surpreendentes. No primeiro caso, a impressão de
      nonsense no editor de código JavaScript vai realizar a operação solicitada
      (+) convertendo image e 2 em strings e
      concatenando-as. A string resultante é involuntária (no Python, uma TypeError é gerada).
      No segundo caso, ao adicionar nonsense ao mapa, o erro g.eeObject.name is not a function
      criptográfico é exibido no editor de código JavaScript
      porque o objeto adicionado ao mapa, nonsense, é uma string, não um
      objeto EE (no Python, um TypeError é gerado). Para evitar resultados não intencionais e
      erros não informativos, não misture objetos e funções do servidor com objetos, primitivos
      ou funções do cliente. A solução neste exemplo é usar uma função do servidor.
Solução: use uma função do servidor.
Editor de código (JavaScript)
Map.addLayer(image.add(2));
import ee import geemap.core as geemap
Colab (Python)
m = geemap.Map() m.add_layer(image.add(2)) m
Consulte a página Cliente x servidor para mais detalhes.
Bloqueio do navegador do editor de código JavaScript
O congelamento ou travamento do navegador pode ocorrer quando a execução do JavaScript no cliente leva muito tempo ou
      quando há uma espera por algo do Earth Engine. Duas fontes comuns desse erro são
      loops for e/ou getInfo() no código do editor de código JavaScript, com o
      pior cenário de getInfo() dentro de um loop for. Os loops For podem fazer com que o
      navegador trave porque o código é executado na sua máquina. Por outro lado,
      getInfo() solicita de forma síncrona o resultado de uma computação do Earth Engine,
      bloqueando até que o resultado seja recebido. Se a computação demorar muito, o bloqueio
      poderá fazer com que o navegador trave. Evite loops for e getInfo() ao
      trabalhar no editor de código. Consulte a página
      Cliente x servidor para mais
      detalhes.
Erros do lado do servidor
Apesar da consistência lógica no código do cliente, podem haver bugs que só se tornam aparentes no tempo de execução no servidor. O exemplo a seguir demonstra o que acontece ao tentar acessar uma banda que não existe.
Erro: este código não funciona.
Editor de código (JavaScript)
// Load a Sentinel-2 image. var s2image = ee.Image( 'COPERNICUS/S2_HARMONIZED/20160625T100617_20160625T170310_T33UVR'); // Error: Image.select: Pattern 'nonBand' did not match any bands. print(s2image.select(['nonBand']));
import ee import geemap.core as geemap
Colab (Python)
# Load a Sentinel-2 image. s2image = ee.Image( 'COPERNICUS/S2_HARMONIZED/20160625T100617_20160625T170310_T33UVR' ) # EEException: Image.select: Band pattern 'non_band' did not match any bands. print(s2image.select(['non_band']).getInfo())
Neste exemplo, o erro informa que não há uma banda chamada
      nonBand. A solução mais óbvia é especificar um nome de banda que
      exista. É possível descobrir os nomes das bandas imprimindo a imagem e
      inspecionando-a no console ou imprimindo a lista de nomes de bandas retornada por
      image.bandNames().
Imutabilidade
Os objetos criados no lado do servidor no Earth Engine são immutable. (Qualquer
      ee.Object é um Object do lado do servidor). Isso significa que, se você
      quiser fazer uma alteração no objeto, salve o estado alterado em uma nova
      variável. Por exemplo, esta abordagem não vai funcionar para definir uma propriedade na imagem Sentinel-2:
Erro: esse código não faz o que você quer.
Editor de código (JavaScript)
var s2image = ee.Image( 'COPERNICUS/S2_HARMONIZED/20160625T100617_20160625T170310_T33UVR'); s2image.set('myProperty', 'This image is not assigned to a variable'); // This will not result in an error, but will not find 'myProperty'. print(s2image.get('myProperty')); // null
import ee import geemap.core as geemap
Colab (Python)
s2image = ee.Image( 'COPERNICUS/S2_HARMONIZED/20160625T100617_20160625T170310_T33UVR' ) s2image.set('my_property', 'This image is not assigned to a variable') # This will not result in an error, but will not find 'my_property'. display(s2image.get('my_property')) # None
Neste exemplo, s2image.set() retorna uma cópia da imagem com a nova
      propriedade, mas a imagem armazenada na variável s2image não é alterada. É necessário
      salvar a imagem retornada por s2image.set() em uma nova variável. Exemplo:
Solução: capture o resultado em uma variável.
Editor de código (JavaScript)
s2image = s2image.set('myProperty', 'OK'); print(s2image.get('myProperty')); // OK
import ee import geemap.core as geemap
Colab (Python)
s2image = s2image.set('my_property', 'OK') display(s2image.get('my_property')) # OK
Funções mapeadas
Outro contexto em que as funções do cliente e do servidor não se misturam é nas funções
      mapeadas. Especificamente, as operações especificadas pela função mapeada são executadas na nuvem,
      portanto, funções do cliente, como getInfo e Export,
      além de print e método em Map e Chart no
      editor de código JavaScript, não funcionam em funções mapeadas. Exemplo:
Erro: este código não funciona.
Editor de código (JavaScript)
var collection = ee.ImageCollection('MODIS/006/MOD44B'); // Error: A mapped function's arguments cannot be used in client-side operations var badMap3 = collection.map(function(image) { print(image); return image; });
import ee import geemap.core as geemap
Colab (Python)
collection = ee.ImageCollection('MODIS/006/MOD44B') # Error: A mapped function's arguments cannot be used in client-side operations. bad_map_3 = collection.map(lambda image: print(image.getInfo()))
Esse erro um tanto misterioso é resultado do processo que o Earth Engine usa para transformar esse código em um conjunto de instruções que podem ser executadas nos servidores do Google. As funções do lado do cliente e as estruturas de controle não podem ser usadas para operar na imagem do argumento transmitida para a função mapeada. Para evitar esse erro, não use funções do lado do cliente em funções mapeadas. Consulte a página Cliente x servidor para saber mais sobre a distinção entre as funções do cliente e do servidor.
As funções mapeadas têm requisitos adicionais. Por exemplo, as funções mapeadas precisam retornar algo:
Erro: este código não funciona.
Editor de código (JavaScript)
var collection = ee.ImageCollection('MODIS/006/MOD44B'); // Error: User-defined methods must return a value. var badMap1 = collection.map(function(image) { // Do nothing. });
import ee import geemap.core as geemap
Colab (Python)
collection = ee.ImageCollection('MODIS/006/MOD44B') # Error: User-defined methods must return a value. bad_map_1 = collection.map(lambda image: None)
A solução mais óbvia é devolver o produto. Mas ele não pode retornar qualquer tipo
      de coisa. Especificamente, as funções mapeadas em um ImageCollection ou
      FeatureCollection precisam retornar um Image ou
      Feature. Por exemplo, não é possível retornar uma data de uma função mapeada em
      um ImageCollection:
Erro: este código não funciona.
Editor de código (JavaScript)
var collection = ee.ImageCollection('MODIS/006/MOD44B'); var badMap2 = collection.map(function(image) { return image.date(); }); // Error: Collection.map: A mapped algorithm must return a Feature or Image. print(badMap2);
import ee import geemap.core as geemap
Colab (Python)
collection = ee.ImageCollection('MODIS/006/MOD44B') bad_map_2 = collection.map(lambda image: image.date()) # EEException: Collection.map: # A mapped algorithm must return a Feature or Image. print(bad_map_2.getInfo())
Para evitar isso, retorne a imagem de entrada com um novo conjunto de propriedades. Em seguida, se você precisar de uma lista
      das datas das imagens na coleção, use aggregate_array():
Solução: defina uma propriedade.
Editor de código (JavaScript)
var collection = ee.ImageCollection('MODIS/006/MOD44B'); var okMap2 = collection.map(function(image) { return image.set('date', image.date()); }); print(okMap2); // Get a list of the dates. var datesList = okMap2.aggregate_array('date'); print(datesList);
import ee import geemap.core as geemap
Colab (Python)
collection = ee.ImageCollection('MODIS/006/MOD44B') ok_map_2 = collection.map(lambda image: image.set('date', image.date())) print(ok_map_2.getInfo()) # Get a list of the dates. dates_list = ok_map_2.aggregate_array('date') print(dates_list.getInfo())
Erros procedimentais
O padrão foi aplicado a uma imagem sem faixas
O erro "Pattern 'my_band' was applied to an Image with no bands"
      significa que há uma chamada ee.Image.select() para uma imagem
      com uma lista de faixas vazia. Confira o que você pode fazer para resolver esse problema:
- Se a imagem for produzida a partir de uma ImageCollection com um redutor ou
        usando as chamadas 
first()outoBands(), verifique se a coleção de origem não está vazia. - Se a imagem for produzida a partir de um dicionário usando
        
ee.Dictionary().toImage(), verifique se o dicionário não está vazio. - Se a imagem for independente, verifique se ela tem dados (e não apenas
        
ee.Image(0)). 
Erros de escalonamento
Embora um script possa estar sintaticamente correto, sem erros lógicos, e representar um conjunto válido de instruções para o servidor, ao paralelizar e executar a computação, os objetos resultantes podem ser muito grandes, muito numerosos ou levar muito tempo para serem computados. Nesse caso, você vai receber um erro indicando que o algoritmo não pode ser escalonado. Esses erros geralmente são os mais difíceis de diagnosticar e resolver. Exemplos desse tipo de erro incluem:
- O tempo de computação expirou
 - Muitas agregações simultâneas
 - Limite de memória do usuário excedido
 - Ocorreu um erro interno
 
Melhorar a escalabilidade do código permite que você obtenha resultados mais rapidamente e também melhora a
      disponibilidade de recursos de computação para todos os usuários. Cada tipo de erro é discutido nas
      seções a seguir, após uma breve observação sobre reduceRegion(), uma função usada com frequência
      que é conhecida por causar todos os tipos de erro de dimensionamento.
reduceRegion()
    Embora reduceRegion() consuma muitos pixels para acionar uma
      variedade de erros, também há parâmetros destinados a controlar a
      computação, para que você possa superar os erros. Por exemplo, considere a redução
      inadequada a seguir:
Erro: este código não funciona.
Editor de código (JavaScript)
var absurdComputation = ee.Image(1).reduceRegion({ reducer: 'count', geometry: ee.Geometry.Rectangle([-180, -90, 180, 90], null, false), scale: 100, }); // Error: Image.reduceRegion: Too many pixels in the region. // Found 80300348117, but only 10000000 allowed. print(absurdComputation);
import ee import geemap.core as geemap
Colab (Python)
absurd_computation = ee.Image(1).reduceRegion( reducer='count', geometry=ee.Geometry.Rectangle([-180, -90, 180, 90], None, False), scale=100, ) # EEException: Image.reduceRegion: Too many pixels in the region. # Found 80300348117, but only 10000000 allowed. print(absurd_computation.getInfo())
Este exemplo é apenas para demonstração. O objetivo desse erro é perguntar
      se você realmente quer reduzir 80300348117 (80 bilhões)
      de pixels. Caso contrário, aumente o scale (tamanho do pixel em metros) de acordo ou
      defina bestEffort como verdadeiro para recalcular automaticamente uma escala maior. Consulte a página
      reduceRegion() para
      mais detalhes sobre esses parâmetros.
O tempo de computação expirou
Suponha que você precise de todos esses pixels na computação. Nesse caso, aumente o
      parâmetro maxPixels para permitir que a computação seja concluída. No entanto, o Earth Engine vai levar algum tempo para concluir a computação. Como resultado, um
      erro de "tempo limite de computação" pode ser gerado:
Ruim: não faça isso.
Editor de código (JavaScript)
var ridiculousComputation = ee.Image(1).reduceRegion({ reducer: 'count', geometry: ee.Geometry.Rectangle([-180, -90, 180, 90], null, false), scale: 100, maxPixels: 1e11 }); // Error: Computation timed out. print(ridiculousComputation);
import ee import geemap.core as geemap
Colab (Python)
ridiculous_computation = ee.Image(1).reduceRegion( reducer='count', geometry=ee.Geometry.Rectangle([-180, -90, 180, 90], None, False), scale=100, maxPixels=int(1e11), ) # Error: Computation timed out. print(ridiculous_computation.getInfo())
Esse erro significa que o Earth Engine esperou cerca de cinco minutos antes de interromper a
      computação. A exportação permite que o Earth Engine realize a computação em um ambiente
      com tempos de execução mais longos (mas não mais memória). Como o valor de retorno de reduceRegion() é um dicionário, é possível usar o dicionário para definir as propriedades de um elemento com geometria nula:
Bom: use Export.
Editor de código (JavaScript)
Export.table.toDrive({ collection: ee.FeatureCollection([ ee.Feature(null, ridiculousComputation) ]), description: 'ridiculousComputation', fileFormat: 'CSV' });
import ee import geemap.core as geemap
Colab (Python)
task = ee.batch.Export.table.toDrive( collection=ee.FeatureCollection([ee.Feature(None, ridiculous_computation)]), description='ridiculous_computation', fileFormat='CSV', ) # task.start()
Muitas agregações simultâneas
A parte "agregações" desse erro se refere a operações distribuídas em várias máquinas (como reduções que abrangem mais de um bloco). O Earth Engine tem limites para evitar que muitas agregações sejam executadas simultaneamente. Neste exemplo, o erro "Muitas agregações simultâneas" é acionado por uma redução em um mapa:
Ruim: não faça isso.
Editor de código (JavaScript)
var collection = ee.ImageCollection('LANDSAT/LT05/C02/T1') .filterBounds(ee.Geometry.Point([-123, 43])); var terribleAggregations = collection.map(function(image) { return image.set(image.reduceRegion({ reducer: 'mean', geometry: image.geometry(), scale: 30, maxPixels: 1e9 })); }); // Error: Quota exceeded: Too many concurrent aggregations. print(terribleAggregations);
import ee import geemap.core as geemap
Colab (Python)
collection = ee.ImageCollection('LANDSAT/LT05/C02/T1').filterBounds( ee.Geometry.Point([-123, 43]) ) def apply_mean_aggregation(image): return image.set( image.reduceRegion( reducer='mean', geometry=image.geometry(), scale=30, maxPixels=int(1e9), ) ) terrible_aggregations = collection.map(apply_mean_aggregation) # EEException: Computation timed out. print(terrible_aggregations.getInfo())
Supondo que o objetivo desse código seja receber estatísticas de imagem para cada imagem, uma
      solução possível é Export o resultado. Por exemplo, usando o fato
      de que um ImageCollection também é um FeatureCollection, os
      metadados associados às imagens podem ser exportados como uma tabela:
Bom: use Export.
Editor de código (JavaScript)
Export.table.toDrive({ collection: terribleAggregations, description: 'terribleAggregations', fileFormat: 'CSV' });
import ee import geemap.core as geemap
Colab (Python)
task = ee.batch.Export.table.toDrive( collection=terrible_aggregations, description='terrible_aggregations', fileFormat='CSV', ) # task.start()
Limite de memória do usuário excedido
Uma maneira de paralelizar seus algoritmos no Earth Engine é dividindo as entradas em blocos, executando a mesma computação separadamente em cada bloco e combinando os resultados. Como consequência, todas as entradas necessárias para calcular um Bloco de saída precisam caber na memória. Por exemplo, quando a entrada é uma imagem com muitas bandas, ela pode acabar consumindo muita memória se todas as bandas forem usadas na computação. Para demonstrar, este exemplo usa muita memória forçando (desnecessariamente) uma coleção de imagens inteira em um bloco:
Ruim: não faça isso.
Editor de código (JavaScript)
var bands = ['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7']; var memoryHog = ee.ImageCollection('LANDSAT/LT05/C02/T1').select(bands) .toArray() .arrayReduce(ee.Reducer.mean(), [0]) .arrayProject([1]) .arrayFlatten([bands]) .reduceRegion({ reducer: 'mean', geometry: ee.Geometry.Point([-122.27, 37.87]).buffer(1000), scale: 1, bestEffort: true, }); // Error: User memory limit exceeded. print(memoryHog);
import ee import geemap.core as geemap
Colab (Python)
bands = ['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7'] memory_hog = ( ee.ImageCollection('LANDSAT/LT05/C02/T1') .select(bands) .toArray() .arrayReduce(ee.Reducer.mean(), [0]) .arrayProject([1]) .arrayFlatten([bands]) .reduceRegion( reducer=ee.Reducer.mean(), geometry=ee.Geometry.Point([-122.27, 37.87]).buffer(1000), scale=1, bestEffort=True, ) ) # EEException: User memory limit exceeded. print(memory_hog.getInfo())
Esse código muito ruim demonstra um motivo para não usar matrizes, a menos que seja realmente necessário. Consulte também a seção "Evitar a conversão desnecessária de tipos". Quando essa coleção é convertida em uma matriz gigante, ela precisa ser carregada na memória de uma só vez. Como é uma série temporal longa de imagens, a matriz é grande e não cabe na memória.
Uma solução possível é definir o parâmetro tileScale como um valor
      maior. Valores mais altos de tileScale resultam em blocos menores por um fator de
      tileScale^2. Por exemplo, o exemplo a seguir permite que o cálculo
      seja concluído:
Editor de código (JavaScript)
var bands = ['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7']; var smallerHog = ee.ImageCollection('LANDSAT/LT05/C02/T1').select(bands) .toArray() .arrayReduce(ee.Reducer.mean(), [0]) .arrayProject([1]) .arrayFlatten([bands]) .reduceRegion({ reducer: 'mean', geometry: ee.Geometry.Point([-122.27, 37.87]).buffer(1000), scale: 1, bestEffort: true, tileScale: 16 }); print(smallerHog);
import ee import geemap.core as geemap
Colab (Python)
bands = ['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7'] smaller_hog = ( ee.ImageCollection('LANDSAT/LT05/C02/T1') .select(bands) .toArray() .arrayReduce(ee.Reducer.mean(), [0]) .arrayProject([1]) .arrayFlatten([bands]) .reduceRegion( reducer=ee.Reducer.mean(), geometry=ee.Geometry.Point([-122.27, 37.87]).buffer(1000), scale=1, bestEffort=True, tileScale=16, ) ) print(smaller_hog.getInfo())
No entanto, a solução mais recomendada é não usar matrizes desnecessariamente, para que você não
      precise mexer com tileScale:
Bom: evite matrizes.
Editor de código (JavaScript)
var bands = ['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7']; var okMemory = ee.ImageCollection('LANDSAT/LT05/C02/T1').select(bands) .mean() .reduceRegion({ reducer: 'mean', geometry: ee.Geometry.Point([-122.27, 37.87]).buffer(1000), scale: 1, bestEffort: true, }); print(okMemory);
import ee import geemap.core as geemap
Colab (Python)
bands = ['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7'] ok_memory = ( ee.ImageCollection('LANDSAT/LT05/C02/T1') .select(bands) .mean() .reduceRegion( reducer=ee.Reducer.mean(), geometry=ee.Geometry.Point([-122.27, 37.87]).buffer(1000), scale=1, bestEffort=True, ) ) print(ok_memory.getInfo())
A menos que seja necessário resolver um erro de memória, não defina tileScale,
      porque blocos menores também resultam em uma sobrecarga maior de paralelização.
Erros internos
Talvez você encontre um erro parecido com este:
Se esse erro aparecer, clique no link "Report error" (Informar erro) que aparece no console do editor de código JavaScript. Você também pode enviar feedback pelo botão Help. Esse erro pode ser resultado de erros lógicos no script que só se tornam óbvios no momento da execução ou um problema com o funcionamento interno do Earth Engine. Em qualquer caso, o erro não é informativo e precisa ser informado para que possa ser corrigido.
Erros internos incluem um ID request, como este:
Essas strings funcionam como identificadores exclusivos para ajudar a equipe do Earth Engine a identificar problemas específicos. Inclua essa string nos relatórios de bugs.
Métodos de depuração
Você programou sua análise, a executou e recebeu um erro. E agora? Esta seção descreve técnicas gerais de depuração para isolar e corrigir o problema.
Inspecionar variáveis e camadas do mapa
Digamos que você tenha uma análise muito complexa que produz um erro. Se não for óbvio onde o erro se origina, uma boa estratégia inicial é imprimir ou visualizar objetos intermediários e inspecioná-los para garantir que a estrutura do objeto seja consistente com a lógica do script. Especificamente, é possível inspecionar os valores de pixel das camadas adicionadas ao mapa com as ferramentas do editor de código ou do inspetor do geemap. Se você imprimir algo, abra as propriedades com os zippies (▶). Confira alguns itens:
- Nomes de bandas. Os nomes das faixas de imagem correspondem ao seu código?
 - Valores de pixel. Seus dados têm o intervalo certo? Ele está mascarado adequadamente?
 - Nulo. Há algum valor nulo que não deveria existir?
 - Tamanhos. O tamanho é zero quando não deveria ser?
 
aside()
    Pode ser trabalhoso colocar cada etapa intermediária de uma análise em uma variável para que
      ela possa ser impressa e inspecionada. Para imprimir valores intermediários de uma longa cadeia de
      chamadas de função, use o método aside(). Exemplo:
Editor de código (JavaScript)
var image = ee.Image(ee.ImageCollection('COPERNICUS/S2') .filterBounds(ee.Geometry.Point([-12.29, 168.83])) .aside(print) .filterDate('2011-01-01', '2016-12-31') .first());
import ee import geemap.core as geemap
Colab (Python)
image = ee.Image( ee.ImageCollection('COPERNICUS/S2_HARMONIZED') .filterBounds(ee.Geometry.Point([-12.29, 168.83])) .aside(display) .filterDate('2011-01-01', '2016-12-31') .first() )
Lembre-se de que aside(print) (editor de código JavaScript) e aside(display) (geemap do Python) estão chamando funções do lado do cliente e ainda falham em funções mapeadas. Também é possível usar o aside
      com funções definidas pelo usuário. Exemplo:
Editor de código (JavaScript)
var composite = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA') .filterBounds(ee.Geometry.Point([106.91, 47.91])) .map(function(image) { return image.addBands(image.normalizedDifference(['B5', 'B4'])); }) .aside(Map.addLayer, {bands: ['B4', 'B3', 'B2'], max: 0.3}, 'collection') .qualityMosaic('nd'); Map.setCenter(106.91, 47.91, 11); Map.addLayer(composite, {bands: ['B4', 'B3', 'B2'], max: 0.3}, 'composite');
import ee import geemap.core as geemap
Colab (Python)
m = geemap.Map() m.set_center(106.91, 47.91, 11) composite = ( ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA') .filterBounds(ee.Geometry.Point([106.91, 47.91])) .map(lambda image: image.addBands(image.normalizedDifference(['B5', 'B4']))) .aside(m.add_layer, {'bands': ['B4', 'B3', 'B2'], 'max': 0.3}, 'collection') .qualityMosaic('nd') ) m.add_layer(composite, {'bands': ['B4', 'B3', 'B2'], 'max': 0.3}, 'composite') m
Como executar uma função em first()
    A impressão e a visualização são úteis para depuração quando disponíveis, mas, ao depurar uma função mapeada em uma coleção, não é possível imprimir na função, conforme descrito na seção de funções mapeadas. Nesse caso, é útil isolar elementos problemáticos na coleção e testar a função mapeada em um elemento individual. Ao testar a função sem mapeá-la, use instruções de impressão para entender o problema. Veja o exemplo a seguir.
Erro: este código não funciona.
Editor de código (JavaScript)
var image = ee.Image( 'COPERNICUS/S2_HARMONIZED/20150821T111616_20160314T094808_T30UWU'); var someFeatures = ee.FeatureCollection([ ee.Feature(ee.Geometry.Point([-2.02, 48.43])), ee.Feature(ee.Geometry.Point([-2.80, 48.37])), ee.Feature(ee.Geometry.Point([-1.22, 48.29])), ee.Feature(ee.Geometry.Point([-1.73, 48.65])), ]); var problem = someFeatures.map(function(feature) { var dictionary = image.reduceRegion({ reducer: 'first', geometry: feature.geometry(), scale: 10, }); return feature.set({ result: ee.Number(dictionary.get('B5')) .divide(dictionary.get('B4')) }); }); // Error in map(ID=2): // Number.divide: Parameter 'left' is required. print(problem);
import ee import geemap.core as geemap
Colab (Python)
image = ee.Image( 'COPERNICUS/S2_HARMONIZED/20150821T111616_20160314T094808_T30UWU' ) some_features = ee.FeatureCollection([ ee.Feature(ee.Geometry.Point([-2.02, 48.43])), ee.Feature(ee.Geometry.Point([-2.80, 48.37])), ee.Feature(ee.Geometry.Point([-1.22, 48.29])), ee.Feature(ee.Geometry.Point([-1.73, 48.65])), ]) # Define a function to be mapped over the collection. def function_to_map(feature): dictionary = image.reduceRegion( reducer=ee.Reducer.first(), geometry=feature.geometry(), scale=10 ) return feature.set( {'result': ee.Number(dictionary.get('B5')).divide(dictionary.get('B4'))} ) problem = some_features.map(function_to_map) # EEException: Error in map(ID=2): # Number.divide: Parameter 'left' is required. print(problem.getInfo())
Para depurar isso, é instrutivo examinar o erro. Felizmente, esse erro útil
      informa que há um problema com o recurso ID=2. Para
      investigar mais, é útil refatorar um pouco o código. Especificamente, não é possível
      ter instruções de impressão na função quando ela é mapeada em uma coleção, conforme descrito
      nesta seção. O objetivo da depuração é isolar o recurso problemático e executar a
      função com algumas instruções de impressão. Com a mesma imagem e recursos usados
      anteriormente:
Editor de código (JavaScript)
// Define a function to be mapped over the collection. var functionToMap = function(feature) { var dictionary = image.reduceRegion({ reducer: 'first', geometry: feature.geometry(), scale: 10, }); // Debug: print(dictionary); return feature.set({ result: ee.Number(dictionary.get('B5')) .divide(dictionary.get('B4')) }); }; // Isolate the feature that's creating problems. var badFeature = ee.Feature(someFeatures .filter(ee.Filter.eq('system:index', '2')) .first()); // Test the function with print statements added. functionToMap(badFeature); // Inspect the bad feature in relation to the image. Map.centerObject(badFeature, 11); Map.addLayer(badFeature, {}, 'bad feature'); Map.addLayer(image, {bands: ['B4', 'B3', 'B2'], max: 3000}, 'image');
import ee import geemap.core as geemap
Colab (Python)
# Define a function to be mapped over the collection. def function_to_map(feature): dictionary = image.reduceRegion( reducer=ee.Reducer.first(), geometry=feature.geometry(), scale=10 ) # Debug: display(dictionary) return feature.set( {'result': ee.Number(dictionary.get('B5')).divide(dictionary.get('B4'))} ) # Isolate the feature that's creating problems. bad_feature = ee.Feature( some_features.filter(ee.Filter.eq('system:index', '2')).first() ) # Test the function with print statements added. function_to_map(bad_feature) # Inspect the bad feature in relation to the image. m = geemap.Map() m.center_object(bad_feature, 11) m.add_layer(bad_feature, {}, 'bad feature') m.add_layer(image, {'bands': ['B4', 'B3', 'B2'], 'max': 3000}, 'image') m
Agora, como a função é executada apenas em um recurso, você pode colocar uma chamada de impressão ("display" para o geemap do Python) dentro dela. Inspecione o objeto impresso para descobrir (ah ha!) que o objeto
      retornado por reduceRegion() tem valores nulos para cada faixa. Isso explica por que a
      divisão está falhando: porque não é possível dividir nulos por nulos. Por que ele é nulo?
      Para investigar, adicione a imagem de entrada e o elemento incorreto ao mapa e centralize o elemento incorreto. Ao fazer isso, você descobre que o problema é devido ao ponto estar fora
      dos limites da imagem. Com base nessa descoberta, o código de depuração é:
Editor de código (JavaScript)
var functionToMap = function(feature) { var dictionary = image.reduceRegion({ reducer: 'first', geometry: feature.geometry(), scale: 10, }); return feature.set({ result: ee.Number(dictionary.get('B5')) .divide(dictionary.get('B4')) }); }; var noProblem = someFeatures .filterBounds(image.geometry()) .map(functionToMap); print(noProblem);
import ee import geemap.core as geemap
Colab (Python)
def function_to_map(feature): dictionary = image.reduceRegion( reducer=ee.Reducer.first(), geometry=feature.geometry(), scale=10 ) return feature.set( {'result': ee.Number(dictionary.get('B5')).divide(dictionary.get('B4'))} ) no_problem = some_features.filterBounds(image.geometry()).map(function_to_map) display(no_problem)
Profiler
O Profiler fornece informações sobre o tempo de EECU e o uso de memória (por algoritmo e recurso) resultante da computação realizada enquanto ele está ativado. Procure as entradas na parte de cima do perfil para informações sobre as operações que consomem mais recursos. Para scripts de execução longa ou ineficientes, as entradas na parte de cima do Profiler fornecem pistas sobre onde concentrar os esforços para otimizar o script. Observação importante: o próprio perfilador influencia a performance do script. Portanto, execute-o apenas quando necessário.