google-earth-enginesatellite-image

How do I solve the 0 element problem in Google Earth Engine?


I used the .combine command to convert two image collections into a two-band image collection (in the last line) to use in a function in the next step. This command is executed but writes 0 elements in the console. Where does this problem come from?

code link: https://code.earthengine.google.com/ed0992093ff830d926c7dd14403477c6

Code:

           var ndvi = function(img){
           var bands = img.select(['B2','B3','B4','B8']).multiply(0.0001)
           .clip(geometry);
           var index = bands.normalizedDifference(['B8','B4']).rename('NDVI_S2');
           return index
           .copyProperties(img,['system:time_start','system:time_end','system:index']);
           };

           var S2 = ee.ImageCollection('COPERNICUS/S2_SR')
           .filterBounds(geometry)
           .filterDate('2018-10-24','2019-06-30')
          //.filter(ee.Filter.lte('CLOUDY_PIXEL_PERCENTAGE',20))
          .map(ndvi);

          print(S2);



          var START = '2018-10-24';
          var END = '2019-06-30';

          var DATES = [ '2018-12-19', '2018-12-29', '2019-01-23', '2019-02-12', '2019-03-04',
          '2019-03-19', '2019-04-08', '2019-04-13', '2019-05-13', '2019-05-18', '2019-05-23',
          '2019-05-28', '2019-06-02', '2019-06-07', '2019-06-12', '2019-06-17', '2019-06-22',
          '2019-06-27'];

          var addTime = function(x) {
            return x.set('Date', ee.Date(x.get('system:time_start')).format("YYYY-MM-dd"))};

          var Sentinel = ee.ImageCollection(S2)
             .filter(ee.Filter.date(START, END))
             .map(addTime)
             .filter(ee.Filter.inList('Date',ee.List(DATES)));
          print(Sentinel);

          var PMODIS = 
          ee.Image('MODIS/006/MCD43A4/2018_12_19').select('Nadir_Reflectance_Band4');

          var MODProjection = PMODIS.projection();
          print('MODIS projection:', MODProjection);

          var Viz = {min: 0, max: 1, palette: ['be6c44','ca3a3a','e4ae0c','565c04','819536']};


          var S2_resampled = Sentinel.map(function(img){
          var S2Mean = img
          // Force the next reprojection to aggregate instead of resampling.
          .reduceResolution({
          reducer: ee.Reducer.mean(),
          maxPixels: 2146
          })
         // Request the data at the scale and projection of the Sentinel image.
         .reproject({
         crs: MODProjection
          });

          return S2Mean
        .copyProperties(img,['system:time_start','system:time_end','system:index']);
        });

        Map.addLayer(S2_resampled)

        var M_ndvi = function(img){
        var bands = 
        img.select(['Nadir_Reflectance_Band1','Nadir_Reflectance_Band5']).multiply(0.0001)
        .clip(geometry);
        
         var index=bands
         .normalizedDifference(['Nadir_Reflectance_Band1','Nadir_Reflectance_Band5'])
         .rename( 
        'NDVI_MOD');
         return index
        .copyProperties(img,['system:time_start','system:time_end','system:index']);
         };

        var MOD = ee.ImageCollection('MODIS/006/MCD43A4')
        .filterBounds(geometry)
        .filterDate('2018-10-24','2019-06-30')
        .map(M_ndvi);


        var MODIS = ee.ImageCollection(MOD)
            .filter(ee.Filter.date(START, END))
            .map(addTime)
            .filter(ee.Filter.inList('Date',ee.List(DATES)));
        print(MODIS);

        var S2_and_MOD = S2_resampled.combine(MODIS, false);
        print(S2_and_MOD);

        var Diff = S2_and_MOD.map(function(img){
        var clip = img.clip(geometry);
        var Diffe = clip.expression('NDVI_S2 - NDVI_MOD',
        {'NDVI_S2':clip.select('NDVI_S2') , 
        'NDVI_MOD':clip.select('NDVI_MOD')}).rename('Diff');

        return Diffe
        .copyProperties(img,['system:time_start','system:time_end']); });

        print(Diff);

Solution

  • ee.Image.combine() uses the system:ID property to join the 2 images. See the documentation here. Since your images do not match, the resulting collection has no images.

    A solution that should fit your needs utilizes the ee.Join.inner() to take advantage of the Date property that you have created to join the 2 image collections. A similar question was answered here.

    Using inner join, I was able to accomplish what appeared to be your goal of finding the difference in NDVI between the S2 and MODIS collections. The full working script can be found here: https://code.earthengine.google.com/dc45df1b7cf83723d53e9f7917975e2d

    Code:

    // Function - Calculate S2 NDVI
    var ndvi = function(img){
      var bands = img.select(['B2','B3','B4','B8']).multiply(0.0001)
      .clip(geometry);
      var index = bands.normalizedDifference(['B8','B4']).rename('NDVI_S2');
      return index
      .copyProperties(img,['system:time_start','system:time_end','system:index']);
    };
    
    // Get S2 NDVI images
    var S2 = ee.ImageCollection('COPERNICUS/S2_SR')
    .filterBounds(geometry)
    .filterDate('2018-10-24','2019-06-30')
    //.filter(ee.Filter.lte('CLOUDY_PIXEL_PERCENTAGE',20))
    .map(ndvi);
    
    print('S2 NDVI ImageCollection',S2);
    
    // Set Date Parameters
    var START = '2018-10-24';
    var END = '2019-06-30';
    
    // Create Date List
    var DATES = [ '2018-12-19', '2018-12-29', '2019-01-23', '2019-02-12', '2019-03-04',
    '2019-03-19', '2019-04-08', '2019-04-13', '2019-05-13', '2019-05-18', '2019-05-23',
    '2019-05-28', '2019-06-02', '2019-06-07', '2019-06-12', '2019-06-17', '2019-06-22',
    '2019-06-27'];
    
    // Function - Add 'Date' field to image
    var addTime = function(x) {
      return x.set('Date', ee.Date(x.get('system:time_start')).format("YYYY-MM-dd"))};
    
    // Run addTime on S2 ImageCollection
    var Sentinel = ee.ImageCollection(S2)
                .filter(ee.Filter.date(START, END))
                .map(addTime)
                .filter(ee.Filter.inList('Date',ee.List(DATES)));
    print('Date Added S2', Sentinel);
    
    // Get MODIS Projection
    var PMODIS = ee.Image('MODIS/006/MCD43A4/2018_12_19').select('Nadir_Reflectance_Band4');
    
    var MODProjection = PMODIS.projection();
    print('MODIS projection:', MODProjection);
    
    // Set Visualization Parameters
    var Viz = {min: 0, max: 1, palette: ['be6c44','ca3a3a','e4ae0c','565c04','819536']};
    
    
    // Reproject S2 images to MODIS projection
    var S2_resampled = Sentinel.map(function(img){
      var S2Mean = img
          // Force the next reprojection to aggregate instead of resampling.
          .reduceResolution({
            reducer: ee.Reducer.mean(),
            maxPixels: 2146
          })
          // Request the data at the scale and projection of the Sentinel image.
          .reproject({
            crs: MODProjection
          });
      
      return S2Mean
      .copyProperties(img,['system:time_start','system:time_end','system:index']);
    });
    
    print('S2_resampled',S2_resampled);
    Map.addLayer(S2_resampled);
    
    // Function - Calculate MODIS NDVI
    var M_ndvi = function(img){
      var bands = img.select(['Nadir_Reflectance_Band1','Nadir_Reflectance_Band5']).multiply(0.0001)
      .clip(geometry);
      var index = bands.normalizedDifference(['Nadir_Reflectance_Band1','Nadir_Reflectance_Band5']).rename('NDVI_MOD');
      return index
      .copyProperties(img,['system:time_start','system:time_end','system:index']);
    };
    
    // Get MODIS NDVI Images
    var MOD = ee.ImageCollection('MODIS/006/MCD43A4')
    .filterBounds(geometry)
    .filterDate('2018-10-24','2019-06-30')
    .map(M_ndvi);
    
    // Run addTime on MODIS ImageCollection
    var MODIS = ee.ImageCollection(MOD)
                .filter(ee.Filter.date(START, END))
                .map(addTime)
                .filter(ee.Filter.inList('Date',ee.List(DATES)));
    print('MODIS',MODIS);
    
    // Combine MODIS and S2 Image Collections using Date
    // Specify the join type
    var join_type = ee.Join.inner();
    
    // Set the join parameter
    var filter = ee.Filter.equals({
      leftField: 'Date',
      rightField: 'Date'
    });
    
    // Execute the join
    var inner_join = ee.ImageCollection(join_type.apply(MODIS,S2_resampled,filter));
    
    // Flatten joined images into a single image with 2 bands
    var S2_and_MOD = inner_join.map(function(feature) {
      return ee.Image.cat(feature.get('primary'), feature.get('secondary'));
    });
    
    print('Combined S2 and MODIS Collection:',S2_and_MOD);
    
    // Calculate the difference between S2 and MODIS NDVI values
    var Diff = S2_and_MOD.map(function(img){
      var clip = img.clip(geometry);
      var Diffe = clip.expression('NDVI_S2 - NDVI_MOD',
      {'NDVI_S2':clip.select('NDVI_S2') , 'NDVI_MOD':clip.select('NDVI_MOD')}).rename('Diff');
    
      return Diffe
      .copyProperties(img,['system:time_start','system:time_end']); });
    
    print('NDVI Difference Collection',Diff);