Geographic Information Systems Asked on April 12, 2021
I’m using the GEE Python API. The Hansen & Al. glad alert dataset is currently broken and the 20 last images are missing the ‘conf19’ band. In my process I need to use it whatever the image so I’d like to add a dummy 0 value band to each image that do not contains the ‘conf19’ band.
I tried the following :
all_alerts = ee.ImageCollection('projects/glad/alert/UpdResult')
# add the missing conf2019 to all images
def addConf2019(image):
#retreive bands name
names = image.bandNames()
#add conf19 if missing
if not names.contains('conf19'):
conf19 = image.expression(
'conf19 = 0 * A',
{'A' : image.select('conf20')}
)
image = image.addBands(conf19)
return image
alerts_cor = all_alerts.map(addConf2019)
but when I display the bands names of the imageCollection :
band_names = alerts_cor.map(lambda image:
image.set('bandNames', image.bandNames())
).aggregate_array('bandNames').getInfo()
band_names
not a single one changed. Do you see what I am doing wrong ?
This is a client vs. server issue. names.contains('conf19')
is an Earth Engine "computed object" which does not represent any individual image, and a Python if
will always consider it to be true. You need to use the server-side conditional ee.Algorithms.If
:
# add the missing conf2019 to all images
def addConf2019(image):
#retreive bands name
names = image.bandNames()
#add conf19 if missing
image = ee.Algorithms.If(
names.contains('conf19'),
image, # true branch
image.expression( # false branch
'conf19 = 0 * A',
{'A' : image.select('conf20')}))
return image
Note that it is in general best to avoid using ee.Algorithms.If
whenever possible, as it often has poor performance such as evaluating both branches even though only one is needed, due to the nature of Earth Engine's computation framework.
In this case, we can use addBands
to implement a conditional replacement of bands:
def addConf2019(image):
fake19 = ee.Image.constant(0).rename('conf19')
return fake19.addBands(srcImg=image, overwrite=true).copyProperties(image)
fake19
always has a conf19
band, and addBands
will here replace that band with the one from image
only if image
has one.
There's a slight difference here: fake19
will have the pixel type "all values are 0" whereas the real dataset has a different type, and some operations will fail when there is a type mismatch. Your strategy of multiplying by 0 instead handles matching the type automatically, or you could also write ee.Image.constant(0).toByte()
to set the type explicitly.
Correct answer by Kevin Reid on April 12, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP