Berlin and Venice are exactly 786 kilometres apart. It turns out, the Sentinel-2 satellites are just as far from the Earth, 786 km! It’s incredible when you consider that, despite the distance, the sensors take very detailed pictures of the Earth.

Scientists like Sentinel-2. Maybe it’s the high spatial and spectral resolution or the short revisiting cycle (5 days), or maybe the 290 km field of view. Whatever it is, everyone has his personal reasons to use Sentinel-2, but we all love it especially because of its free and open data policy. Landsat-8 images are also free, and also very popular for similar reasons (maybe even more popular than Sentinel).

Whenever I refer to the Sentinels I mean SENTINEL-2A (launched 23 June 2015) and SENTINEL-2B (launched 7 March 2017) which occupy the same orbit, but separated by 180 degrees.

In fact many remote sensing scientist or practisioners combine, merge or fuse Sentinel-2 images with Landsat-8 scenes to get a more precise and dense data cube for their analysis.

So it’s not surprising that, the number of scientific publications covering Landsat-8 and Sentinel-2 increase annually.



So when people do their satellite data munging they look particularly for dates when Landsat and Sentinel have overflown (or will overfly) the area of interest at the very same day. They get excited and move with their expensive instruments outdoors at the same day to record validation and calibration values. Thats very exciting and good science.


Websites, such as n2yo.com are very helpful for satellite overpass predictions (i.e. n2yo.com provides 10-day predictions with alert functionality for many sensors).

n2yo screenshot of Landsat-8 & Sentinel-2A with orbits (5th of July at 21:30:13) n2yo screenshot of Landsat-8 & Sentinel-2A with orbits (5th of July at 21:30:13)

Motivation

At this point I wondered, How often does Landsat and Sentinel actually appear at the same location at the same time?!?! Do both satellites really fly over the same spot somewhere at the same time, sometime? If so, Sentinel should incidentally take photos of the Landsat satellite itself.

In theory, that would be possible. Sentinel orbits the Earth at a high altitude (786 km; remember Berlin - Venice ?!) and takes a picture of the Landsat-8 satellite orbiting the Earth at a lower altitude (705 km).

The quest for an unlikely image

Well let’s find out. For this task, I used the Google Earth Engine again because all Landsat-8 and Sentinel-2 images are available as ImageCollection in the cloud based data catalog. Naive as I am, I search first over Berlin (Germany) for the pictures of all pictures.

Parameter Setup

At first I dropped a point marker over Berlin (or any other place, as you wish). Than, I set up some parameter (i.e. terrain background basemap) and get the date of today.

// Javascript

var Berlin = ee.Geometry.Point([13.40619231451105, 52.51970379595016]);

// add Landsat footprint for point marker
var wrs2_descending = ee.FeatureCollection('users/gaertnerp/Blog/WRS2_descending');
var wrs2_filtered = wrs2_descending.filterBounds(Berlin); // filter footprint to aoi

Map.addLayer(wrs2_filtered, {},'Landsat footprint', true, 0.3);  // add layer to map


Map.setOptions('TERRAIN');      // change basemap
Map.centerObject(Berlin, 7);    // center map to Berlin

var now = Date.now();
var eeNow = ee.Date(now);

Get all Landsat-8 and Sentinel-2 images

Result for Berlin: At the selected location are 125 Landsat and 546 Sentinel images available.

Now, we are particularly interested in the spacecraft name, the date/time & location of the observations and the product identifier.

// Javascript

// #### Landsat 8 ####

var L8 = ee.ImageCollection('LANDSAT/LC08/C01/T1_SR')
.filterBounds(Berlin)
.filterDate('2015-06-23', eeNow)
.map(function(image) {
  var date = ee.Date(image.get('system:time_start')).format("YYYY-MM-dd");
  date = ee.Date(date);
    return image.set('date', date);
  })
  .map(function(image) {
  var ID = ee.String(image.get('system:index'));
    return image.set('ID', ID);
  })
  .map(function(image) {
  var date = ee.Date(image.get('system:time_start'));
    return image.set('date_time', date);
  });


// ### Sentinel 2 ####

var S2 = ee.ImageCollection('COPERNICUS/S2')
.filterBounds(Berlin)
.map(function(image) {
  var date = ee.Date(image.get('system:time_start')).format("YYYY-MM-dd");
    return image.set('date', ee.Date(date));
  })
  .map(function(image) {
  var ID = ee.String(image.get('system:index'));
    return image.set('ID', ID);
  })
  .map(function(image) {
  var date = ee.Date(image.get('system:time_start'));
    return image.set('date_time', date);
  });
  

Join Sentinel-2 and Landsat-8 by Date

We are only interested in images with the same date at the same location.

Result for Berlin: For the selected location where 20 distinct dates recorded.

Wow. So at least 20 times where Landsat-8 and Sentinel-2 at the same day over Berlin. But they weren’t over Berlin at the same time, or were they?

// Javascript

// Get FeatureCollection from ImageCollection
var L8_FC = ee.FeatureCollection(L8).select([
  'ID','date','date_time','CLOUD_COVER','SATELLITE','system:index'
]);

var S2_FC = ee.FeatureCollection(S2).select([
  'ID','date','date_time','CLOUDY_PIXEL_PERCENTAGE','SPACECRAFT_NAME','system:index'],
 ['ID','date','date_time','CLOUD_COVER'            ,'SATELLITE'      ,'system:index']);

// Get all matches between the 'date' 
// elements of two collections

// the equals filter specifies how the collections match ('date')
var toyFilter = ee.Filter.equals({ leftField: 'date', rightField: 'date'});

// define the join.
var innerJoin = ee.Join.inner('primary', 'secondary');

// apply the join.
var joined = innerJoin.apply(L8_FC, S2_FC, toyFilter);


// #### Select Matches for 

var flattener = function(feat){
  return ee.Feature(ee.Feature(feat).get('primary'));
};
var sel_primary = joined.map(flattener);


var flattener = function(feat){
  return ee.Feature(ee.Feature(feat).get('secondary'));
};
var sel_secondary = joined.map(flattener);


// Merge & Sort by Date
var merged_selection = sel_secondary.merge(sel_primary).sort('date');

// get unique matching dates
var distinct_dates = sel_primary.select('date').distinct(['date']).sort('date');

ScatterChart - When Landsat-8 (almost) meets the Sentinels

The following scatterplot shows the days (y-axis) and the times (x-axis) on which both satellites, Landsat-8 and Sentinel-2, were flying over Berlin.

When Landsat-8 (almost) meets the SentinelsWhen Landsat-8 (almost) meets the Sentinels

Landsat-8 orbits the Earth sun-synchronous. Meaning Landsat-8 visits Berlin shortly before or shortly after 10:00 am. The images shortly before 10:00 am are scenes of the PATH 193, ROW 23. Shortly after 10:00 am are pictures of the other PATH: 192 and ROW: 24.

Sun-synchronous orbits are used to ensure the angle of sunlight upon the Earth’s surface is consistently maintained. Apart from small seasonal variations, anchoring of the satellites orbit to the angle of the sun minimises the potential impact of shadows and levels of illumination on the ground. This ensures consistency over time and is critical in assessing time-series data (source: sentinel.esa.int).

The Sentinels (A & B) always comes in a time window of 10:10 am to 10:25 am, depending on the season and the PATH /ROW (as with Landsat-8).

// Javascript


// Create a new property with default dates but original times for the x-axis.
var all_dates_to_default_date = function(feature) {
  
  var xx         = feature.get('date_time');
  var equal_time = ee.Date(xx).update({year: 2000, month: 1, day:1});
  var add_3h     = ee.Date(equal_time).advance({delta:3,unit:'hour'}); // add 3 hours
  
  return feature.set({time_default: add_3h});
  
};

merged_selection = merged_selection.map(all_dates_to_default_date);

// Create a ScatterChart witch all dates when L8 & S2 where at the same location

var chart_date = ui.Chart.feature.groups(merged_selection, 'time_default', 'date', 'SATELLITE')
    .setChartType('ScatterChart')
    .setOptions({
      width: 600,
      height: 400,
      crosshair: { 
        trigger: 'both' ,
        opacity: 0.5 ,
        orientation: 'both'
      },
      title: 'When Landsat-8 (almost) meets the Sentinels',
      hAxis: {title: 'Time',
        gridlines: {
            count: -1,
            units: {
              hours: {format: ['HH:mm']}
            }
          }
      },
      vAxis: {title: 'Date'},
      tooltip: {isHtml: true},
    });

print(chart_date);

But how close (in time) were Landsat-8 and Sentinel-2?

To answer this question I selected the top 5 dates with the smallest time difference. The Barchart is shown below. Images with the same time come from different overlapping tiles (Grid Reference System).

That means for Berlin, Landsat-8 missed Sentinel-2B on the 4th of May 2018 by

522 Seconds difference!!!! What does it actually mean?

8.69816 minutes, or 522.0 seconds.

At a flight speed of about 7.5 km per second, Landsat-8 continued already roughly 3915 km when Sentinel arrived over Berlin!

Top 5: Days with the smallest time difference between Landsat-8 and Sentinel-2 scenesTop 5: Days with the smallest time difference between Landsat-8 and Sentinel-2 scenes

// Javascript


var flattener_get_diff = function(feat){
  
  feat             = ee.Feature(feat);
  var primary_f    = ee.Feature(feat.get('primary')); // primary is L8
  var L8_date_time = primary_f.get('date_time');

  var secondary_f  = ee.Feature(feat.get('secondary')); // primary is S2
  var S2_ID        = secondary_f.get('ID');             // image ID
  var S2_date_time = secondary_f.get('date_time');
  var date_str     = secondary_f.get('date');
  date_str         = ee.Date(date_str).format("YYYY-MM-dd");
  
  // absolute difference between the S2 & L8 sensing times in minutes
  var time_diff    = ee.Date(S2_date_time).difference(L8_date_time, 'minute').abs(); 
  
  return primary_f.set('date_str', date_str).set('S2/L8', time_diff).set('S2_ID', S2_ID);

};

var primary_f = joined.map(flattener_get_diff)
primary_f = primary_f.sort('S2/L8').limit(5) // Select the Top 5 with the smallest difference

// Make BarChart with the Top 5.
var chart1 = ui.Chart.feature.byProperty({features: primary_f,xProperties: ['S2/L8'], seriesProperty: 'date_str'})
    .setChartType('BarChart')
    .setOptions({
      title: 'Top 5: Days with the smallest time difference between Landsat and Sentinel scenes',
      hAxis: { title: 'Time difference between Landsat 8 and Sentinel (Minutes)',
               minValue: 0},
      vAxis: { title: 'Top 5 Days' }
});
print(chart1);

We can also look directly at the two pictures. Here are the images and the Javascript code.

Landsat-8 at the 4th of May 2018 over Berlin (Germany) Landsat-8 at the 4th of May 2018 over Berlin (Germany)
Sentinel-2B at the 4th of May 2018 over Berlin (Germany) Sentinel-2B at the 4th of May 2018 over Berlin (Germany)

//Javascript

// #### Load Images with the smallest difference to the Map. ####

// #LANDSAT-8

var L8_ID = primary_f.first().get('ID'); // get the L8 image ID

var srCollection = ee.ImageCollection('LANDSAT/LC08/C01/T1_SR')
  .filterBounds(Berlin) 
  .filterMetadata('system:index','equals' ,L8_ID);

var L8_vizParams = {
  bands: ['B5', 'B4', 'B3'],
  min: 0,
  max: 4000,
  gamma: [0.95, 1.1, 1]
};

var L8_img = ee.Image(srCollection.first());
Map.addLayer(L8_img, L8_vizParams, 'Landsat8');

// Sentinel 2

var S2_ID = primary_f.first().get('S2_ID'); // get the S2 image ID

var srCollection_S2 = ee.ImageCollection('COPERNICUS/S2')
  .filterBounds(Berlin) 
  .filterMetadata('system:index','equals' ,S2_ID);

var S2_vizParams = {
  bands: ['B8', 'B4', 'B3'],
  min: 0,
  max: 4000,
  gamma: [0.95, 1.1, 1]
};

var S2_img = ee.Image(srCollection_S2.first());
Map.addLayer(S2_img, S2_vizParams, 'Sentinel', 0.7, true);

Well that’s a bit disappointing. Lets have a look more north to a Sentinel ground station - what about Svalbard, Norway, this station is responsible for data acquisition and near real-time processing.

Svalbard, Norway

At the selected location are 90 Landsat-8 and 396 Sentinel-2 images available and 37 distinct dates were recorded. It turns out Landsat-8 missed Sentinel by 1.9975 minutes (or 120.0 seconds). That would be a difference of 900 km.

Top 5: Days with the smallest time difference between Landsat and Sentinel scenes over Svalbard, Norway Top 5: Days with the smallest time difference between Landsat and Sentinel scenes over Svalbard, Norway
Landsat-8 and Sentinel-2B over Svalbard, Norway Landsat-8 and Sentinel-2B over Svalbard, Norway

Greenland, Denmark

At the selected location are 137 Landsat-8 and 310 Sentinel images available and 37 distinct dates were recorded. It turns out Landsat-8 missed Sentinel by 1.815 minutes (or 109.0 seconds) or 817 km.

Top 5: Days with the smallest time difference between Landsat and Sentinel scenes over Greenland, Denmark Top 5: Days with the smallest time difference between Landsat and Sentinel scenes over Greenland, Denmark
Landsat-8 and Sentinel-2B over Greenland, Denmark Landsat-8 and Sentinel-2B over Greenland, Denmark

Bottom line

This blogpost shows you how to filter days when Landsat-8 and Sentinel-2 were in one place at (almost) the same time using the Google Earth Engine.

Unfortunately, I did not find a Sentinel-2 image were the actual Landsat-8 satellite 🛰️ is visible. Have you had any luck? Why don’t you go and find one by yourself?

One last note, I have always worked with point markers. You should do this too. Good luck with the search.

Complete Script

The following link opens a copy of the explained script in the Javascript Code Editor.


You can cite this blogpost using: Gärtner, Philipp (2018/07/06) “When Landsat-8 (almost) meets Sentinel-2”, https://philippgaertner.github.io/2018/07/landsat-meets-sentinels/

If you have any questions, suggestions or spotted a mistake, please use the comment function at the bottom of this page.

Previous blog posts are available within the blog archive. Feel free to connect or follow me on Twitter - @Mixed_Pixels.