Creating a mosaic of images by date is a common step in remote sensing workflows: joining up images taken at a similar enough time to make a single image.
Google Earth Engine makes this easy, but there are a few gotchas that, if you don’t take into account, could ruin your downstream workflow.
For the boilerplate, see my shared notebook demonstrating how to fix Earth Engine mosaic projections for sampleRectangle() and geoTIFF downloads.
Starting with a typical image collection
imcol = ee.ImageCollection(‘COPERNICUS/S2_SR_HARMONIZED’).filterBounds(ROI_POLY).filterDate(START_DATE, END_DATE)
We might create a mosaic
mosaic = ee.ImageCollection(imcol.filterDate(‘2022–01–01’, ‘2022–01–04’)).mosaic()
However if we try to sample the pixels of this image
my_array = np.array(img.sampleRectangle(region=ROI_POLY_SMALL, defaultValue=0).get(‘B2’).getInfo())
plt.imshow(my_array)
we will get the dreaded purple square — indicating an array of NaNs or zeros.
Why? Take a look at the projection of the original image
print(imcol.projection().getInfo())
and of the mosaic
print(mosaic.projection().getInfo())
They are not the same. This doesn’t cause a problem for displaying the data in folium, which can lead you to think that everything is ok. However it will cause your saved GeoTIFFs to be empty of data.
Here’s the fix.
default_projection = imcol.first().select([‘B2’]).projection()
img = ee.Image(ee.ImageCollection(imcol.filterDate(‘2022–01–01’, ‘2022–01–04’)).mosaic().setDefaultProjection(default_projection))
Explicitly set the projection of the mosaic to the source image. This will work for multiple bands. You may run into trouble with image collections consisting of different resolution images (e.g. the QA60 band in Sentinel), so my advice is to split them up before mosaicing.
For more details, see my shared notebook where I demonstrate how to create this problem, and how to solve it: https://colab.research.google.com/drive/1ifUfQs3kXtiQHnXgLHwKnKIV5U8KbBsj?usp=sharing