ronnyhdez / blog

A site for my blog posts
https://blog.ronnyale.com/
Creative Commons Zero v1.0 Universal
0 stars 0 forks source link

Getting areas per each land cover category in polygons #63

Open ronnyhdez opened 1 month ago

ronnyhdez commented 1 month ago

I had two assets: one with many polygons and one image with a land cover classification. I needed to get per each of the polygons the area per category in the land cover classfication. So, here is the code:

// With knowledge gain in the individual mapping, let's do the simplification
// var image = ee.Image('projects/ee-eoagsaer/assets/LULC_2022_EE');
var image = ee.Image('projects/ee-ronnyale/assets/aer_lulc')

var originalClasses = ee.List([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]);
var simplifiedValues = ee.List([
  0,  // 0 - Unclassified -> Unclassified
  2,  // 1 - Water -> Other
  4,  // 2 - Bryoids -> Other
  2,  // 3 - Wetland – Treed -> Wetland/Marsh/Swamp
  3,  // 4 - Herbs -> Crop/Herbaceous
  4,  // 5 - Exposed/Barren Land -> Other
  4,  // 6 - Shrubland -> Other
  2,  // 7 - Wetland -> Wetland/Marsh/Swamp
  3,  // 8 - Grassland -> Crop/Herbaceous
  1,  // 9 - Coniferous -> Forest
  1,  // 10 - Broadleaf -> Forest
  1,  // 11 - Mixedwood -> Forest
  3,  // 12 - Agriculture -> Crop/Herbaceous
  4,  // 13 - Developed -> Other
]);

// Reclassify the image
var reclassifiedImage = image.remap(originalClasses, simplifiedValues);

// Define a color palette for the simplified categories
var simplifiedPalette = [
  'black',    // 0 - Unclassified
  'green',   // 1 - Forest
  'blue',    // 2 - Water/Wetland/Marsh/Swamp
  'yellow',  // 3 - Crop/Herbaceous
  'grey'     // 4 - Other
];

// Define visualization parameters for the simplified categories
var simplifiedVizParams = {
  min: 0,
  max: 4,
  palette: simplifiedPalette
};

// Add the reclassified image to the map
Map.addLayer(reclassifiedImage, simplifiedVizParams, 'Again Simplified LULC 2022');

// Reference buffers land cover use
var reference = ee.FeatureCollection('projects/ee-ronnyale/assets/reference_buffers');
Map.addLayer(reference, {}, 'Reference polygons');

// Function to calculate area for each land cover type within a polygon
var calculateLandCoverArea = function(feature) {
  // Get the area of each land cover class within the polygon
  var stats = reclassifiedImage.reduceRegion({
    reducer: ee.Reducer.frequencyHistogram(),
    geometry: feature.geometry(),
    scale: 10,
    maxPixels: 1e13
  });

  // Convert the results to a dictionary and set as properties of the feature
  return feature.set(stats);
};

// Apply the function to each feature in the collection
var landCoverAreas = reference.map(calculateLandCoverArea);

// Print the results
print('with histogram', landCoverAreas.limit(6));

var areaImage = ee.Image.pixelArea().addBands(reclassifiedImage);
// print(areaImage)

var calculateClassArea = function(feature) {
  // Calculate the area of each land cover class within the polygon
  var areas = ee.Image.pixelArea().addBands(reclassifiedImage)
    .reduceRegion({
      reducer: ee.Reducer.sum().group({
        groupField: 1,
        groupName: 'class',
      }),
      geometry: feature.geometry(),
      scale: 10,  
      maxPixels: 1e13
    });

  // Extract the grouped dictionary
  var grouped = ee.List(areas.get('groups'));

  // Convert the list to a dictionary for easier handling
  var areasDict = ee.Dictionary(
    grouped.map(function(item) {
      item = ee.Dictionary(item);
      var key = ee.String(item.get('class'));
      var value = ee.Number(item.get('sum'));
      return ee.List([key, value]);
    }).flatten());

  // Set the areas as properties of the feature
  return feature.set(areasDict);
};

// Apply the function to each feature in the collection
var landCoverAreas2 = reference.map(calculateClassArea);

// Print the results
print(landCoverAreas2.limit(6));

// Check total area
var first = landCoverAreas2.first();
print(first);

var firstArea = first.geometry().area();
print(firstArea);

// var second = landCoverAreas2.toList(3).get(2);
var second = ee.Feature(landCoverAreas2.toList(3).get(2));
print(second);

var secondArea = second.geometry().area();
print(secondArea);

The last steps are to validate that the sum of the areas categories are equal to the total area of the polygon.