0

This is the GEE script I used to show a cassification product. https://code.earthengine.google.com/21603a6e19f76d8c121a4dd9000ebee4

The resulting map in GEE is clipped correctly to the border that I imported as an asset:

enter image description here

var table = ee.FeatureCollection("users/parivash89/Canopy_Height_Product/pnp_perimeter_Basilicata");

//Import the boundaries of the Park
var Park_Border = ee.FeatureCollection(table);

var Park_Border_Vis = Park_Border.style({
  color: 'ff2525', 
  width: 3,
  lineType: 'solid',
  fillColor: '00000000',
});

Map.addLayer(Park_Border_Vis, null, 'Park Area');
Map.centerObject(Park_Border, 11);

////Earth Engine Snippet
//var canopy_ht = ee.ImageCollection("projects/meta-forest-monitoring-okw37/assets/CanopyHeight");

////How many frames are available in the canopy worldwide
//print(canopy_ht);

//If we want a single mosaic for all worldwide connecting all frames together into a single image
var canopy_ht_mosaic = ee.ImageCollection("projects/meta-forest-monitoring-okw37/assets/CanopyHeight").mosaic();
//print(canopy_ht_mosaic);
Map.addLayer(canopy_ht_mosaic.clip(Park_Border),[], 'canopy_ht_mosaic');

//Histogram of Canopy height frequency
print(
  ui.Chart.image.histogram(canopy_ht_mosaic,Park_Border,11)
  );
  
//Non-forest pixels Removal (pixels with value=0)  
var canopy_threshold = canopy_ht_mosaic.gt(0);
var forest = canopy_ht_mosaic.updateMask(canopy_threshold);
Map.addLayer(forest.clip(Park_Border),[],'Forest');

print(
  ui.Chart.image.histogram(forest,Park_Border,20)
  );
  
//Avg, Max, Min Value of canopy height
var canopy_mean = forest.reduceRegion({
  reducer: ee.Reducer.mean(), geometry:Park_Border, scale: 11
  }).values().get(0);
  
print(canopy_mean, 'Canopy_MEAN');

var canopy_max = forest.reduceRegion({
  reducer: ee.Reducer.max(), geometry:Park_Border, scale: 11
  }).values().get(0);
  
print(canopy_max, 'Canopy_MAX');  

var canopy_min = forest.reduceRegion({
  reducer: ee.Reducer.min(), geometry:Park_Border, scale: 11
  }).values().get(0);
  
print(canopy_min, 'Canopy_MIN');    


//By downloading the CSV of the 'Canopy_MAX' histogram, we see that there are only two pixels related to the maximum values of 31 meteres. For a more realistic solution to get the max value according to the frequency:
var canopy_percentile99 = forest.reduceRegion({
  reducer: ee.Reducer.percentile([99]), geometry:Park_Border, scale: 11
  }).values().get(0);

print(canopy_percentile99, 'Canopy_Percentile99');
//99% of the Max canopy height according to the frequency is 20 meters.

//Classification by the thresholding technqiue
var cons = ee.Image.constant(0);
var class1 = cons.where(forest.lt(5), 1);
var class2 = class1.where(forest.gte(5).and(forest.lt(10)), 2);
var class3 = class2.where(forest.gte(10).and(forest.lt(15)), 3);
var class4 = class3.where(forest.gte(15).and(forest.lt(20)), 4);
var class5 = class4.where(forest.gte(20).and(forest.lt(25)), 5);
var class6 = class5.where(forest.gte(25).and(forest.lt(30)), 6);
var class7 = class6.where(forest.gte(30), 7);

Map.addLayer(class7.clip(Park_Border),{min:0, max:7, palette:['#64481a','#e8a73c','#c1ffb8','#87ff93','#00fb30','#00b92c','#009323','#006e1a']},'Class7'); //All the pixel where canopy height is 0 < x < 5 are shown in white

//Add a legend

// set position of panel
var legend = ui.Panel({
  style: {
    position: 'bottom-left',
    padding: '8px 15px'
  }
});

// Create legend title
var legendTitle = ui.Label({
  value: 'Canopy Height Classified',
  style: {
    fontWeight: 'bold',
    fontSize: '18px',
    margin: '0 0 4px 0',
    padding: '0'
    }
});

// Add the title to the panel
legend.add(legendTitle);
    
// Creates and styles 1 row of the legend.
var makeRow = function(color, name) {
      
      // Create the label that is actually the colored box.
      var colorBox = ui.Label({
        style: {
          backgroundColor: '#' + color,
          // Use padding to give the box height and width.
          padding: '10px',
          margin: '0 0 4px 0'
        }
      });
      
      // Create the label filled with the description text.
      var description = ui.Label({
        value: name,
        style: {margin: '0 0 4px 6px'}
      });
      
      // return the panel
      return ui.Panel({
        widgets: [colorBox, description],
        layout: ui.Panel.Layout.Flow('horizontal')
      });
};


//  Identify Palette with the legend colors
var palette =[
  '64481a',
  'e8a73c',
  'c1ffb8',
  '87ff93',
  '00fb30',
  '00b92c',
  '009323',
  '006e1a'
];

// Identify names with the legend
var names = ['H<5','5<H<10','10<H<15','15<H<20','20<H<25','25<H<30','H>30'];

// Add color and and names
for (var i = 0; i < 7; i++) {
  legend.add(makeRow(palette[i], names[i]));
  }  

// add legend to map (alternatively you can also print the legend to the console)  
Map.add(legend);  
  

Export.image.toDrive({
  image: forest,
  description: 'Canopy_Height_PollinoPark_Basilicata',
  scale: 1,
  maxPixels: 1e13,
  region: Park_Border.geometry(),
  crs: 'EPSG:32633',
  folder: 'Pollino_Park'
});

/*
var visualization = class7.visualize({
        min:0, 
        max:7, 
        palette:['#64481a','#e8a73c','#c1ffb8','#87ff93','#00fb30','#00b92c','#009323','#006e1a']
      });*/
      
      
Export.image.toDrive({
  image: class7,
  description: 'Canopy_Height_Classified_PollinoPark_Basilicata',
  scale: 1,
  maxPixels: 1e13,
  region: Park_Border,
  crs: 'EPSG:32633',
  folder: 'Pollino_Park'
});


  
  

When I export this map to QGIS 3.26.1, it is not clipped to the area (shown in red):

enter image description here

In the Symbology tab, if I remove class 0, the area outside of the border gets deleted, but also some values inside the map. I tried adding .clip() to the image: class7 and also adding .geometry() to the region: Park_Border part of the script because I found these solutions in another post but it did not work.

1 Answer 1

0

When exporting, the image is only clipped to the bounding box of the region property. You can manually clip the image, just like you did when you added it to the EE Code Editor map. This code highlights how it works:

var geometry = ee.Geometry.Polygon([[
      [16.14844468273243, 40.09264295378325],
      [16.127845317498053, 40.076882530508264],
      [16.15943101085743, 40.08371249523182]
]])
var image = ee.Image(1)

Map.addLayer(image, {}, 'unclipped')
Map.addLayer(image.clip(geometry), {palette: 'red'}, 'clipped')
Map.centerObject(geometry)

Export.image.toDrive({
  image: image, 
  description: 'unclipped', 
  region: geometry, 
  scale: 10,
})

Export.image.toDrive({
  image: image.clip(geometry), 
  description: 'clipped', 
  region: geometry, 
  scale: 10,
})

https://code.earthengine.google.com/91b86661364195fae7d934e4c9644eba

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