0

The Problem:

Two identical Landsat scenes were downloaded from two different sources. USGS Earth Explorer and Google Earth Engine. Although both of the scenes are in the exact same coordinate system (EPSG:32638), their pixels do not align correctly. They are shifted 15 meters both horizontally and vertically as shown Below:

enter image description here I believe that the USGS raster is the correct one, while GEE one has some issues when exporting it.

Data:

To generate the GEE raster please see the following GEE code:

var image = ee.Image('LANDSAT/LC08/C02/T1_L2/LC08_168037_20210918').select('SR_B2')
Map.centerObject(image,8);
Map.addLayer(image , null,'Band 2');

Export.image.toDrive({
    image: image,
    description: 'testImage',
    fileNamePrefix: 'testImage',
    scale: 30,
    // region: aoi,
    maxPixels: 1e10,
    crs:'EPSG:32638',
    folder: 'Image Production'
    })
  • USGS raster can be downloaded here
  • GEE raster can be downloaded here

Non-Working solutions:

My request:

  • To be able to export Landsat8 rasters perfectly aligned with their corresponding ones in USGS Earth explorer.
  • To be able to export Sentinel2 rasters perfectly aligned with their corresponding ones in Scihub.
2
  • 1
    But what is your question? Bug reports should go to vendors.
    – Vince
    Oct 20, 2021 at 12:35
  • My question was: How can I download Landsat 8 images perfectly aligned with corresponding ones downloaded from USGS Earth Explorer?... I have reported this issue in GEE Issue tracker... However, I have found the solution and posted it below. Oct 22, 2021 at 15:14

2 Answers 2

2

If you additionally pass in the crs transform to the export call and remove the scale parameter everything should line up perfectly. You can access the transform like this: image.projection().getInfo().transform.

Then you can export like this:

Export.image.toDrive({
    image: image,
    description: 'testImage',
    fileNamePrefix: 'testImage',
    // region: aoi,
    maxPixels: 1e10,
    crs:'EPSG:32638',
    crsTransform: image.projection().getInfo().transform,
    folder: 'Image Production'
})
6
  • JonasV's answer do the trick indeed. It works quite well if I'm exporting raw Landsat8 scenes. However, If I do some analysis (e.g. clip, mosaic ... etc) then, the resulting image's crsTransform defaults to zeroes and ones as shown in this code, and the resulting image will not align correctly with the one undergone same analysis in ArcGIS. Can you help me with this part @JonasV? Oct 20, 2021 at 20:31
  • If you do some analysis, you still need to use the original transform from the unaltered image. However if you clip the image or alter the extent of it some other way you won't be able to use the original transform. But with mosaicing and other operations you won't be easily able to keep the same alignment anyway.
    – JonasV
    Oct 21, 2021 at 6:27
  • Thanks for clarifying. In conclusion, this is a big drawback in Earth Engine. Since software like ArcGIS and QGIS can handle image alignement easily during different processes, Earth Engine should be able to do that natively. Oct 21, 2021 at 6:40
  • I would argue that it's a big advantage of Earth Engine, that you don't have to worry about Projections in your day to day analysis. But this definitely leads to some unexpected behaviour in some cases
    – JonasV
    Oct 21, 2021 at 7:47
  • In my field of work; I need to supply my work team with tailor-made Landsat8/Sentinel2 images. These are, clipped and mosaiced images. My team on their side need to process them based on their demand and produce professional maps using ArcGIS. That being said, Eearth engine is hindering me from achieving this goal because of image misalignment. Oct 21, 2021 at 8:00
-1

After hours of work and a fruitful discussion with JonasV, I came up with a solution.
We simply need to shift back the image by modifying the factors in crsTransform as shown below:

var aoi = /* color: #0b4a8b */ee.Geometry.Polygon(
    [[[44.1374165309615, 32.51214068906346],
      [44.000087429399, 32.20124427322498],
      [44.7636372340865, 32.06169106082084],
      [45.087733913774, 32.19659594016746],
      [45.153651882524, 32.30809035172925],
      [44.4230610622115, 32.52140473578572],
      [44.373622585649, 32.627872600190045]]]);

var image1 = ee.Image('LANDSAT/LC08/C02/T1_L2/LC08_168037_20210918').select('SR_B2')
var image2 = ee.Image('LANDSAT/LC08/C02/T1_L2/LC08_168038_20210918').select('SR_B2')
var mosaic = ee.ImageCollection.fromImages([image2,image1]).mosaic()
var final = mosaic.clip(aoi)
var crst = [30,0,15,0,-30,-15]

Export.image.toDrive({
    image: final,
    description: 'testImage',
    fileNamePrefix: 'testImage',
    // scale: 30, // No need
    // region: aoi, // No need
    maxPixels: 1e10,
    crs:'EPSG:32638',
    crsTransform: crst,
    folder: 'Image Production'
    })

Note that in crst variable there is a 15 which tells GEE to shift the raster to the east 15 meters and -15 which tells GEE to shift the raster to the south 15 meters in order to compensate the offset in the new processed image. For Sentinel 2, I believe the crst should be [10,0,5,0,-10,-5] for bands with 10m resolution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.