Introduction

Google Satellite Embedding Dataset is a global dataset of pre-computed, analysis-ready geospatial embeddings for each year from 2017 onwards. This dataset was produced by Google DeepMind’s AlphaEarth Foundations model and presents a big leap in making remote sensing and climate datasets useful. Along with making existing remote sensing workflows more efficient, this dataset unlocks a range of new use cases. This workshop is designed to help you get started with the dataset in GEE and use it for a variety of applications.

Watch the video

Watch the Video ↗

Access the Presentation ↗

Setting up the Environment

Sign-up for Google Earth Engine

If you already have a Google Earth Engine account, you can skip this step.

Visit our GEE Sign-Up Guide for step-by-step instructions.

Get the Workshop Materials

The workshop material and exercises are in the form of Earth Engine scripts shared via a code repository.

  1. Click this link to open Google Earth Engine code editor and add the repository to your account.
  2. If successful, you will have a new repository named users/ujavalgandhi/GEE-Satellite-Embedding in the Scripts tab in the Reader section.

If you do not see the repository in the Reader section, click Refresh repository cache button in your Scripts tab and it will show up.

Workshop Repository

Workshop Repository

Get the Workshop Video

The course is accompanied by a video covering the all the sections This video is recorded from our live webinar class and is edited to make them easier to consume for self-study. We have 2 versions of the videos:

YouTube

The video on YouTube is ideal for online learning and sharing. You may also turn on Subtitles/closed-captions and adjust the playback speed to suit your preference. Access the YouTube Video ↗

Vimeo

We have also made full-length video available on Vimeo. This video can be downloaded for offline learning. Access the Vimeo Video ↗

Hands-on With Satellite Embedding Dataset

01. Visualizing Embeddings

Open in Code Editor ↗

// Visualizing the Satellite Embedding Dataset
// ****************************************************

// Select a region
// ****************************************************
var geometry = ee.Geometry.Polygon([[
  [76.39785, 12.5521],
  [76.39785, 12.3550],
  [76.65191, 12.3550],
  [76.65191, 12.5521]
]]);

// Use the satellite basemap
Map.setOptions('SATELLITE');

// Draw a polygon to define the region
// Save it as the variable 'geometry'
Map.centerObject(geometry, 12);

// Prepare the Satellite Embedding dataset
// ****************************************************

var embeddings = ee.ImageCollection('GOOGLE/SATELLITE_EMBEDDING/V1/ANNUAL');
var year = 2024;
var startDate = ee.Date.fromYMD(year, 1, 1);
var endDate = startDate.advance(1, 'year');

var filteredEmbeddings = embeddings
  .filter(ee.Filter.date(startDate, endDate))
  .filter(ee.Filter.bounds(geometry));

var embeddingsImage = filteredEmbeddings.mosaic();

print('Satellite Embeddings Image', embeddingsImage);

// Visualize the Satellite Embedding Dataset
// *********************************************************

// Visualize three axes of the embedding space as an RGB.
var visParams = {min: -0.3, max: 0.3, bands: ['A01', 'A16', 'A09']};
Map.addLayer(embeddingsImage.clip(geometry), visParams, 'Embeddings Image');

// Make the training dataset for unsupervised clustering
var nSamples = 1000;
var training = embeddingsImage.sample({
  region: geometry,
  scale: 10,
  numPixels: nSamples,
  seed: 100
});
print(training.first());

// Function to train a model for desired number of clusters
var getClusters = function(nClusters) {
  var clusterer = ee.Clusterer.wekaKMeans({nClusters: nClusters})
    .train(training);
  
  // Cluster the image
  var clustered = embeddingsImage.cluster(clusterer);
  return clustered;
};

var cluster3 = getClusters(3);
Map.addLayer(cluster3.randomVisualizer().clip(geometry), {}, ' 3 clusters');

var cluster5 = getClusters(5);
Map.addLayer(cluster5.randomVisualizer().clip(geometry), {}, ' 5 clusters');

var cluster10 = getClusters(10);
Map.addLayer(cluster10.randomVisualizer().clip(geometry), {}, ' 10 clusters');

Exercise

Open in Code Editor ↗

// Exercise

// Delete the geometry
// Draw a geometry for your region of interest
// Try visualizing the embeddings with different bands (A01, A02, A03...)
// Try changing the number of clusters to see different levels of detail

02. Crop Type Mapping

Open in Code Editor ↗

// Unsupervised Clustering with Satellite Embeddings
// Crop Type Mapping
// ****************************************************

// Select the region
// ****************************************************

// Cerro Gordo County, Iowa
var counties = ee.FeatureCollection('TIGER/2018/Counties');

var selected = counties
  .filter(ee.Filter.eq('GEOID', '19033'));
var geometry = selected.geometry();
Map.centerObject(geometry, 12);
Map.setOptions('SATELLITE');

Map.addLayer(geometry, {color: 'red'}, 'Selected Region', false);

// Prepare the Satellite Embedding dataset
// ****************************************************

var embeddings = ee.ImageCollection('GOOGLE/SATELLITE_EMBEDDING/V1/ANNUAL');

var year = 2022;
var startDate = ee.Date.fromYMD(year, 1, 1);
var endDate = startDate.advance(1, 'year');

var filteredembeddings = embeddings
  .filter(ee.Filter.date(startDate, endDate))
  .filter(ee.Filter.bounds(geometry));

var embeddingsImage = filteredembeddings.mosaic();


// Visualize three axes of the embedding space as an RGB.
var visParams = {min: -0.3, max: 0.3, bands: ['A01', 'A16', 'A09']};
Map.addLayer(embeddingsImage.clip(geometry), visParams, 'Embeddings Image');

// Create a Cropland Mask
// ****************************************************

// Use Cropland Data Layers (CDL) to obtain cultivated cropland
var cdl = ee.ImageCollection('USDA/NASS/CDL')
  .filter(ee.Filter.date(startDate, endDate))
  .first();
var cropLandcover = cdl.select('cropland');
var croplandMask = cdl.select('cultivated').eq(2).rename('cropmask');

// Visualize the crop mask
var croplandMaskVis = {min:0, max:1, palette: ['white', 'green']};
Map.addLayer(croplandMask.clip(geometry), croplandMaskVis, 'Crop Mask', false);

// Extract Training Samples
// ****************************************************

// Mask all non-cropland pixels
var clusterImage = embeddingsImage.updateMask(croplandMask);
Map.addLayer(clusterImage.clip(geometry), visParams,
  'Embeddings Image (with Crop Mask)', false);

// We need to extract well distributed training samples
// for all target crops in the county

// Stratified random sampling to ensure we get desired
// number of samples exluding the masked pixels
var training = clusterImage.addBands(croplandMask).stratifiedSample({
  numPoints: 1000,
  classBand: 'cropmask',
  region: geometry,
  scale: 10, 
  tileScale: 16,
  seed: 100,
  dropNulls: true,
  geometries: true
});

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Export samples to an asset (optional)
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// Replace this with your asset folder
// The folder must exist before exporting
var exportFolder = 'projects/spatialthoughts/assets/satellite_embedding/';

var samplesExportFc = 'cluster_training_samples';
var samplesExportFcPath = exportFolder + samplesExportFc;

Export.table.toAsset({
  collection: training, 
  description: 'Cluster_Training_Samples',
  assetId: samplesExportFcPath
});

// Wait for the export to complete and continue with
// the exported asset from here onwards.

// Use the exported asset
var training = ee.FeatureCollection(samplesExportFcPath);

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// End optional export section
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// Visualize the samples
// ****************************************************
print('Extracted sample', training.first());
Map.addLayer(training, {color: 'blue'}, 'Extracted Samples', false);

// Perform Unsupervised Clustering
// ****************************************************

var minClusters = 4;
var maxClusters = 5;

var clusterer = ee.Clusterer.wekaCascadeKMeans({
  minClusters:minClusters, maxClusters: maxClusters}).train({
  features: training,
  inputProperties: clusterImage.bandNames()
});

var clustered = clusterImage.cluster(clusterer);
Map.addLayer(clustered.randomVisualizer().clip(geometry), {}, 'Clusters', false);

// Assign Labels to Clusters
// ****************************************************

// Calculate Cluster Areas
// 1 Acre = 4046.86 Sq. Meters
var areaImage = ee.Image.pixelArea().divide(4046.86).addBands(clustered);

var areas = areaImage.reduceRegion({
      reducer: ee.Reducer.sum().group({
      groupField: 1,
      groupName: 'cluster',
    }),
    geometry: geometry,
    scale: 10,
    maxPixels: 1e10
    }); 
 
var clusterAreas = ee.List(areas.get('groups'));

// Process results to extract the areas and create a FeatureCollection

var clusterAreas = clusterAreas.map(function(item) {
  var areaDict = ee.Dictionary(item);
  var clusterNumber = areaDict.getNumber('cluster').format();
  var area = areaDict.getNumber('sum');
  return ee.Feature(null, {cluster: clusterNumber, area: area});
});

var clusterAreaFc = ee.FeatureCollection(clusterAreas);
print('Cluster Areas', clusterAreaFc);

// This region has 2 primary crops - corn and soybean
// Pick the 2 clusters with the highest area
var selectedFc = clusterAreaFc.sort('area', false).limit(2);
print('Top 2 Clusters by Area', selectedFc);


// We do not know which is what crops
// Use the crop statistics and match those areas
// Cerro Gordo County, Iowa
// Corn statistics https://www.nass.usda.gov/Statistics_by_State/Iowa/Publications/County_Estimates/2023/IA-CtyEst-Corn-02-23.pdf
// Soybean statistics https://www.nass.usda.gov/Statistics_by_State/Iowa/Publications/County_Estimates/2023/IA-CtyEst-Soybeans-02-23.pdf
// Corn Area: 163,500 Acres
// Soybean Area: 110,500 Acres

// From the 2 clusters, the one with the highest area is 'Corn'
// Other is Soybean
var cornFeature = selectedFc.sort('area', false).first();
var soybeanFeature = selectedFc.sort('area').first();
var cornCluster = cornFeature.get('cluster');
var soybeanCluster = soybeanFeature.get('cluster');

print('Corn Area (Detected)', cornFeature.getNumber('area').round());
print('Corn Area (From Crop Statistics)', 163500);

print('Soybean Area (Detected)', soybeanFeature.getNumber('area').round());
print('Soybean Area (From Crop Statistics)', 110500);

// Create a Crop Map
// ****************************************************

// Select the clusters to create the crop map
var corn = clustered.eq(ee.Number.parse(cornCluster));
var soybean = clustered.eq(ee.Number.parse(soybeanCluster));

// Visualize the final output
var merged = corn.add(soybean.multiply(2));
var cropVis = {min:0, max:2, palette: ['#bdbdbd', '#ffd400', '#267300']};

Map.addLayer(merged.clip(geometry), cropVis, 'Crop Map (Detected)');

// Add a Legend
var legend = ui.Panel({
  layout: ui.Panel.Layout.Flow('horizontal'),
  style: {position: 'bottom-center', padding: '8px 15px'}});

var addItem = function(color, name) {
  var colorBox = ui.Label({
    style: {color: '#ffffff',
      backgroundColor: color,
      padding: '10px',
      margin: '0 4px 4px 0',
    }
  });
  var description = ui.Label({
    value: name,
    style: {
      margin: '0px 10px 0px 2px',
    }
  }); 
  return ui.Panel({
    widgets: [colorBox, description],
    layout: ui.Panel.Layout.Flow('horizontal')}
)};

var title = ui.Label({
  value: 'Legend',
  style: {fontWeight: 'bold',
    fontSize: '16px',
    margin: '0px 10px 0px 4px'}});

legend.add(title);
legend.add(addItem('#ffd400', 'Corn'));
legend.add(addItem('#267300', 'Soybean'));
legend.add(addItem('#bdbdbd', 'Other Crops'));

Map.add(legend);

// Validate the results
// ****************************************************

// Compare our results with the crop type map from CDL
var cdl = ee.ImageCollection('USDA/NASS/CDL')
  .filter(ee.Filter.date(startDate, endDate))
  .first();
var cropLandcover = cdl.select('cropland');
var cropMap = cropLandcover.updateMask(croplandMask).rename('crops');

// Original data has unique values for each crop ranging from 0 to 254 
var cropClasses = ee.List.sequence(0, 254);
// We remap all values as following
// Crop     | Source Value | Target Value
// Corn     | 1            | 1
// Soybean  | 5            | 2
// All other| 0-255        | 0
var targetClasses = ee.List.repeat(0, 255).set(1, 1).set(5, 2);
var cropMapReclass = cropMap.remap(cropClasses, targetClasses).rename('crops'); 

var cropVis = {min: 0, max: 2, palette: ['#bdbdbd', '#ffd400', '#267300']};
Map.addLayer(cropMapReclass.clip(geometry), cropVis, 'Crop Landcover (CDL)');

 

Exercise

Open in Code Editor ↗

// Exercise: Crop Type Mapping
// ****************************************************

// Select the region
// ****************************************************
var geometry = ee.Geometry.Polygon([[
  [83.6180, 21.43577],
  [83.6180, 21.26181],
  [83.8391, 21.26181],
  [83.8391, 21.43577]
]]);
          
Map.centerObject(geometry, 12);
Map.setOptions('SATELLITE');

Map.addLayer(geometry, {color: 'red'}, 'Selected Region', false);

// Prepare the Satellite Embedding dataset
// ****************************************************

var embeddings = ee.ImageCollection('GOOGLE/SATELLITE_EMBEDDING/V1/ANNUAL');

var year = 2024;
var startDate = ee.Date.fromYMD(year, 1, 1);
var endDate = startDate.advance(1, 'year');

var filteredembeddings = embeddings
  .filter(ee.Filter.date(startDate, endDate))
  .filter(ee.Filter.bounds(geometry));

var embeddingsImage = filteredembeddings.mosaic();

// Visualize three axes of the embedding space as an RGB.
var visParams = {min: -0.3, max: 0.3, bands: ['A01', 'A16', 'A09']};
Map.addLayer(embeddingsImage.clip(geometry), visParams, 'Embeddings Image', false);

// Create a Cropland Mask
// ****************************************************

// Use ESA Worldcover cropland
// This dataset is from 2021 so there maybe a mismatch
// in cropland extent in recent years
var worldcover = ee.ImageCollection('ESA/WorldCover/v200');
var classification = worldcover.first();
var cropLandcover = classification.eq(40);
var croplandMask = cropLandcover.rename('cropmask');

// Visualize the crop mask
var croplandMaskVis = {min:0, max:1, palette: ['white', 'green']};
Map.addLayer(croplandMask.clip(geometry), croplandMaskVis, 'Crop Mask', false);

// Extract Training Samples
// ****************************************************

// Mask all non-cropland pixels
var clusterImage = embeddingsImage.updateMask(croplandMask);
Map.addLayer(clusterImage.clip(geometry), visParams,
  'Embeddings Image (with Crop Mask)', false);

// We need to extract well distributed training samples
// for all target crops in the county

// Stratified random sampling to ensure we get desired
// number of samples exluding the masked pixels
var training = clusterImage.addBands(croplandMask).stratifiedSample({
  numPoints: 1000,
  classBand: 'cropmask',
  region: geometry,
  scale: 10, 
  tileScale: 16,
  seed: 100,
  dropNulls: true,
  geometries: true
});


// Perform Unsupervised Clustering
// ****************************************************

var minClusters = 2;
var maxClusters = 5;

var clusterer = ee.Clusterer.wekaCascadeKMeans({
  minClusters:minClusters, maxClusters: maxClusters}).train({
  features: training,
  inputProperties: clusterImage.bandNames()
});

var clustered = clusterImage.cluster(clusterer);
Map.addLayer(clustered.randomVisualizer().clip(geometry), {}, 'Clusters');

// Add Sentinel-2 NDVI Time-Series
// ****************************************************
var s2 = ee.ImageCollection('COPERNICUS/S2_HARMONIZED');

// Load the Cloud Score+ collection
var csPlus = ee.ImageCollection('GOOGLE/CLOUD_SCORE_PLUS/V1/S2_HARMONIZED');
var csPlusBands = csPlus.first().bandNames();

// We need to add Cloud Score + bands to each Sentinel-2
// image in the collection
// This is done using the linkCollection() function
var s2WithCs = s2.linkCollection(csPlus, csPlusBands);

// Function to mask pixels with low CS+ QA scores.
function maskLowQA(image) {
  var qaBand = 'cs';
  var clearThreshold = 0.5;
  var mask = image.select(qaBand).gte(clearThreshold);
  return image.updateMask(mask);
}

function addNDVI(image) {
  var ndvi = image.normalizedDifference(['B8', 'B4']).rename('ndvi');
  return image.addBands(ndvi);
}
// Function to create and display NDVI time-series chart
// when a point is clicked
function displayChart(point) {
  chartPanel.clear();
 
  var pointGeom = ee.Geometry.Point(point.lon, point.lat);
  
  var filtered = s2WithCs
    .filter(ee.Filter.date(startDate, endDate))
    .map(maskLowQA)
    .map(addNDVI)
    .filter(ee.Filter.bounds(pointGeom));
  
  var chart = ui.Chart.image.series({
    imageCollection: filtered.select('ndvi'),
    region: pointGeom,
    reducer: ee.Reducer.mean(),
    scale: 20}).setOptions({
      title: 'NDVI Time Series',
      vAxis: {title: 'NDVI', viewWindow: {min:0, max:1}},
      hAxis: {title: 'Date', gridlines: {count: 12}},
      interpolateNulls: true,
      pointSize: 2,
      lineWidth: 1
    });
      
  chartPanel.add(chart);
}
var chartPanel = ui.Panel({
  style: {width: '400px', position: 'bottom-right'}
});
Map.add(chartPanel);
Map.onClick(displayChart);
  
// Exercise
// Delete the geometry
// Draw a geometry for your region of interest
// Adjust the minClusters and maxClusters based on your knowledge
// Click on any location to see the NDVI Time-Series
// Use your local knowledge to identify the crop(s)

// Note: Interactive visualization of clusters will only work for
//      small regions. Export your training samples as Asset first
//      if classifying large regions.

// The region selected here is in the Bargarh distrct, Odisha, India
// with the primary crop being Rice.
// Data from https://upag.gov.in/

03. Mapping Mangroves

Open in Code Editor ↗

/**** Start of imports. If edited, may not auto-convert in the playground. ****/
var geometry = 
    /* color: #98ff00 */
    /* shown: false */
    ee.Geometry.Polygon(
        [[[39.4926, -4.39833],
          [39.4926, -4.47394],
          [39.5491, -4.47394],
          [39.5491, -4.39833]]]),
    mangroves = 
    /* color: #6bd651 */
    /* shown: false */
    ee.FeatureCollection(
        [ee.Feature(
            ee.Geometry.Point([39.53332459156346, -4.424306862786138]),
            {
              "landcover": 1,
              "system:index": "0"
            }),
        ee.Feature(
            ee.Geometry.Point([39.515674132076356, -4.417484208564611]),
            {
              "landcover": 1,
              "system:index": "1"
            }),
        ee.Feature(
            ee.Geometry.Point([39.521682280269715, -4.414916932798933]),
            {
              "landcover": 1,
              "system:index": "2"
            }),
        ee.Feature(
            ee.Geometry.Point([39.53301193114862, -4.412092919198809]),
            {
              "landcover": 1,
              "system:index": "3"
            }),
        ee.Feature(
            ee.Geometry.Point([39.52305557128534, -4.41904596364173]),
            {
              "landcover": 1,
              "system:index": "4"
            }),
        ee.Feature(
            ee.Geometry.Point([39.52751876708612, -4.418767843115292]),
            {
              "landcover": 1,
              "system:index": "5"
            }),
        ee.Feature(
            ee.Geometry.Point([39.512952520329506, -4.42470302325086]),
            {
              "landcover": 1,
              "system:index": "6"
            }),
        ee.Feature(
            ee.Geometry.Point([39.51191450544074, -4.425050671107723]),
            {
              "landcover": 1,
              "system:index": "7"
            }),
        ee.Feature(
            ee.Geometry.Point([39.51075895498842, -4.429791895347292]),
            {
              "landcover": 1,
              "system:index": "8"
            }),
        ee.Feature(
            ee.Geometry.Point([39.51114519308656, -4.429235662261579]),
            {
              "landcover": 1,
              "system:index": "9"
            })]),
    water = 
    /* color: #0b4a8b */
    /* shown: false */
    ee.FeatureCollection(
        [ee.Feature(
            ee.Geometry.Point([39.51274523032135, -4.4343394780686385]),
            {
              "landcover": 2,
              "system:index": "0"
            }),
        ee.Feature(
            ee.Geometry.Point([39.51441892874664, -4.429162247319931]),
            {
              "landcover": 2,
              "system:index": "1"
            }),
        ee.Feature(
            ee.Geometry.Point([39.52403196585602, -4.429418970360026]),
            {
              "landcover": 2,
              "system:index": "2"
            }),
        ee.Feature(
            ee.Geometry.Point([39.52016958487457, -4.425782052317534]),
            {
              "landcover": 2,
              "system:index": "3"
            }),
        ee.Feature(
            ee.Geometry.Point([39.50879701865143, -4.443581386549747]),
            {
              "landcover": 2,
              "system:index": "4"
            }),
        ee.Feature(
            ee.Geometry.Point([39.50553545248932, -4.447860008667267]),
            {
              "landcover": 2,
              "system:index": "5"
            }),
        ee.Feature(
            ee.Geometry.Point([39.50399050009674, -4.449913738457232]),
            {
              "landcover": 2,
              "system:index": "6"
            }),
        ee.Feature(
            ee.Geometry.Point([39.51965460074371, -4.445635128266346]),
            {
              "landcover": 2,
              "system:index": "7"
            }),
        ee.Feature(
            ee.Geometry.Point([39.51171526205963, -4.469081606555194]),
            {
              "landcover": 2,
              "system:index": "8"
            }),
        ee.Feature(
            ee.Geometry.Point([39.50347551596588, -4.469680594368735]),
            {
              "landcover": 2,
              "system:index": "9"
            }),
        ee.Feature(
            ee.Geometry.Point([39.525425885851405, -4.417474500749167]),
            {
              "landcover": 2,
              "system:index": "10"
            })]),
    other = 
    /* color: #79776d */
    /* shown: false */
    ee.FeatureCollection(
        [ee.Feature(
            ee.Geometry.Point([39.50560992076606, -4.4242595999510455]),
            {
              "landcover": 3,
              "system:index": "0"
            }),
        ee.Feature(
            ee.Geometry.Point([39.50620000674934, -4.423307578260568]),
            {
              "landcover": 3,
              "system:index": "1"
            }),
        ee.Feature(
            ee.Geometry.Point([39.50448339297981, -4.423799634568]),
            {
              "landcover": 3,
              "system:index": "2"
            }),
        ee.Feature(
            ee.Geometry.Point([39.50197284534187, -4.423649878335117]),
            {
              "landcover": 3,
              "system:index": "3"
            }),
        ee.Feature(
            ee.Geometry.Point([39.503313949849314, -4.4228369153997535]),
            {
              "landcover": 3,
              "system:index": "4"
            }),
        ee.Feature(
            ee.Geometry.Point([39.497137934254695, -4.416632173880207]),
            {
              "landcover": 3,
              "system:index": "5"
            }),
        ee.Feature(
            ee.Geometry.Point([39.49610796599298, -4.418386475891598]),
            {
              "landcover": 3,
              "system:index": "6"
            }),
        ee.Feature(
            ee.Geometry.Point([39.504884153889705, -4.415434111585769]),
            {
              "landcover": 3,
              "system:index": "7"
            }),
        ee.Feature(
            ee.Geometry.Point([39.540219677644, -4.402738757778825]),
            {
              "landcover": 3,
              "system:index": "8"
            }),
        ee.Feature(
            ee.Geometry.Point([39.537083376051925, -4.414620272781714]),
            {
              "landcover": 3,
              "system:index": "9"
            }),
        ee.Feature(
            ee.Geometry.Point([39.54329128212492, -4.400688640340887]),
            {
              "landcover": 3,
              "system:index": "10"
            }),
        ee.Feature(
            ee.Geometry.Point([39.543870639272136, -4.399725891211968]),
            {
              "landcover": 3,
              "system:index": "11"
            }),
        ee.Feature(
            ee.Geometry.Point([39.50106019752159, -4.41120573786903]),
            {
              "landcover": 3,
              "system:index": "12"
            }),
        ee.Feature(
            ee.Geometry.Point([39.50085098521843, -4.411943834251456]),
            {
              "landcover": 3,
              "system:index": "13"
            })]);
/***** End of imports. If edited, may not auto-convert in the playground. *****/
// Supervised Classification with Satellite Embeddings
// Mapping Mangroves
// ****************************************************

// Select a region
// ****************************************************

// Draw a polygon to define the region
// Save it as the variable 'geometry'
Map.centerObject(geometry);

// Collect Training Samples
// ****************************************************

// Pick a year for classification
var year = 2020;
var startDate = ee.Date.fromYMD(year, 1, 1);
var endDate = startDate.advance(1, 'year');

// Create a Sentinel-2 Compsite for the selected year
// for selecting training samples
var s2 = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED');
var filteredS2 = s2
  .filter(ee.Filter.date(startDate, endDate))
  .filter(ee.Filter.bounds(geometry));

// Use the Cloud Score+ collection for cloud masking
var csPlus = ee.ImageCollection('GOOGLE/CLOUD_SCORE_PLUS/V1/S2_HARMONIZED');
var csPlusBands = csPlus.first().bandNames();
var filteredS2WithCs = filteredS2.linkCollection(csPlus, csPlusBands);

function maskLowQA(image) {
  var qaBand = 'cs';
  var clearThreshold = 0.6;
  var mask = image.select(qaBand).gte(clearThreshold);
  return image.updateMask(mask);
}

var filteredS2Masked = filteredS2WithCs
  .map(maskLowQA)
  .select('B.*');  
  
// Create a median composite of cloud-masked images
var composite = filteredS2Masked.median();

// Display the input composite in false color
// that helps distinguish between
// water, vegetation and built surfaces
var swirVis = {min: 300, max: 4000, bands: ['B11', 'B8', 'B4']};

Map.centerObject(geometry);
Map.addLayer(composite.clip(geometry), swirVis, 'S2 Composite (False Color)');

// Merge the collected training samples
var gcps = mangroves.merge(water).merge(other);

// Train a Classifier
// ****************************************************

// Sample Embedding Vectors
var embeddings = ee.ImageCollection('GOOGLE/SATELLITE_EMBEDDING/V1/ANNUAL'); 

var embeddingsFiltered = embeddings
  .filter(ee.Filter.date(startDate, endDate))
  .filter(ee.Filter.bounds(geometry));

var embeddingsImage = embeddingsFiltered.mosaic();

// Overlay the samples on the image to get training data.
var training = embeddingsImage.sampleRegions({
  collection: gcps, 
  properties: ['landcover'], 
  scale: 10
});


// Train a classifier.
var classifier = ee.Classifier.smileKNN().train({
  features: training,  
  classProperty: 'landcover', 
  inputProperties: embeddingsImage.bandNames()
});

// Classify the Satellite Embedding Mosaic
// ****************************************************

var classified = embeddingsImage.classify(classifier);


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Export classified image to an asset (optional)
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// Replace this with your asset folder
// The folder must exist before exporting
var exportFolder = 'projects/spatialthoughts/assets/satellite_embedding/';

var classifiedExportImage = 'mangrove_classification';
var classifiedExportImagePath = exportFolder + classifiedExportImage;

Export.image.toAsset({
  image: classified.clip(geometry),
  description: 'Classified_Image_Export',
  assetId: classifiedExportImagePath,
  region: geometry,
  scale: 10,
  pyramidingPolicy: 'MODE',
  maxPixels: 1e10
});

// Wait for the export to complete and continue with
// the exported asset from here onwards.

// Use the exported asset
var classified = ee.Image(classifiedExportImagePath);

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// End optional export section
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// Visualize the classification
// ****************************************************

// Choose a 3-color palette
// Assign a color for each class in the following order
// Mangrove, Water, Other
var palette = ['green', 'blue', 'gray'];

Map.addLayer(
  classified.clip(geometry),
  {min: 1, max: 3, palette: palette}, 
  'Classified Satellite Embeddings Image');

// Extract mangroves class
var mangrovesImage = classified.eq(1).selfMask();

var mangroveVis = {min:0, max:1, palette: ['green']};

Map.addLayer(mangrovesImage.clip(geometry),
  mangroveVis, 'Mangroves (Satellite Embedding Classification)');

Exercise

Open in Code Editor ↗

// Exercise: Mapping Mangroves
// ****************************************************

// Select the region
// ****************************************************
var geometry = ee.Geometry.Polygon([[
  [39.4926, -4.39833],
  [39.4926, -4.47394],
  [39.5491, -4.47394],
  [39.5491, -4.39833]
]]);
          
Map.centerObject(geometry);

// Pick a year for classification
var year = 2020;
var startDate = ee.Date.fromYMD(year, 1, 1);
var endDate = startDate.advance(1, 'year');

// Create a Sentinel-2 Compsite for the selected year
// for selecting training samples
var s2 = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED');
var filteredS2 = s2
  .filter(ee.Filter.date(startDate, endDate))
  .filter(ee.Filter.bounds(geometry));

// Use the Cloud Score+ collection for cloud masking
var csPlus = ee.ImageCollection('GOOGLE/CLOUD_SCORE_PLUS/V1/S2_HARMONIZED');
var csPlusBands = csPlus.first().bandNames();
var filteredS2WithCs = filteredS2.linkCollection(csPlus, csPlusBands);

function maskLowQA(image) {
  var qaBand = 'cs';
  var clearThreshold = 0.6;
  var mask = image.select(qaBand).gte(clearThreshold);
  return image.updateMask(mask);
}

var filteredS2Masked = filteredS2WithCs
  .map(maskLowQA)
  .select('B.*');  
  
// Create a median composite of cloud-masked images
var composite = filteredS2Masked.median();

// Display the input composite in false color
// that helps distinguish between
// water, vegetation and built surfaces
var swirVis = {min: 300, max: 4000, bands: ['B11', 'B8', 'B4']};

Map.centerObject(geometry);
Map.addLayer(composite.clip(geometry), swirVis, 'S2 Composite (False Color)');

//  Global Mangrove Watch reference layer
var gmw = ee.ImageCollection('projects/earthengine-legacy/assets/projects/sat-io/open-datasets/GMW/extent/GMW_V3');
var gmwFiltered = gmw
  .filter(ee.Filter.date(startDate, endDate));
var gmwImage = gmwFiltered.mosaic();

Map.addLayer(gmwImage,
  {min:0, max:1, palette: ['purple']}, 
  'Reference Mangrove Layer', false); 
  
// Exercise
// Delete the geometry and draw a polygon for your region of interest
//   Tip: Turn on Reference Mangrove Layer to previously mapped
//        locations of mangroves.
// Add training samples for 3 classes
// Create FeatureCollections and the 
// 'landcover' property as follows

// mangroves: 1
// water: 2
// other: 3

// After adding samples, uncomments lines below
// Use Ctrl + / keyboard shortcut for uncommenting selection

// // ****************************************************

// // Merge the collected training samples
// var gcps = mangroves.merge(water).merge(other);

// // Train a Classifier
// // ****************************************************

// // Sample Embedding Vectors
// var embeddings = ee.ImageCollection('GOOGLE/SATELLITE_EMBEDDING/V1/ANNUAL'); 

// var embeddingsFiltered = embeddings
//   .filter(ee.Filter.date(startDate, endDate))
//   .filter(ee.Filter.bounds(geometry));

// var embeddingsImage = embeddingsFiltered.mosaic();

// // Overlay the samples on the image to get training data.
// var training = embeddingsImage.sampleRegions({
//   collection: gcps, 
//   properties: ['landcover'], 
//   scale: 10
// });


// // Train a classifier.
// var classifier = ee.Classifier.smileKNN().train({
//   features: training,  
//   classProperty: 'landcover', 
//   inputProperties: embeddingsImage.bandNames()
// });

// // Classify the Satellite Embedding Mosaic
// // ****************************************************

// var classified = embeddingsImage.classify(classifier);

// // Visualize the classification
// // ****************************************************

// // Choose a 3-color palette
// // Assign a color for each class in the following order
// // Mangrove, Water, Other
// var palette = ['green', 'blue', 'gray'];

// Map.addLayer(
//   classified.clip(geometry),
//   {min: 1, max: 3, palette: palette}, 
//   'Classified Satellite Embeddings Image');

// // Extract mangroves class
// var mangrovesImage = classified.eq(1).selfMask();

// var mangroveVis = {min:0, max:1, palette: ['green']};

// Map.addLayer(mangrovesImage.clip(geometry),
//   mangroveVis, 'Mangroves (Satellite Embedding Classification)');

Supplement

Mapping Surface Water with Unsupervised Classification

Open in Code Editor ↗

// Unsupervised Clustering with Satellite Embeddings

// Adaptation of the 'waterdetect' algorithm using
// Satellite Embedding dataset

// Reference: https://github.com/cordmaur/WaterDetect
// Cordeiro, M. C. R.; Martinez, J.-M.; Peña-Luque, S. 
// Automatic Water Detection from Multidimensional Hierarchical Clustering for Sentinel-2 Images
// and a Comparison with Level 2A Processors. 
// Remote Sensing of Environment 2021, 253, 112209. https://doi.org/10.1016/j.rse.2020.112209.

// Use the satellite basemap
Map.setOptions('SATELLITE');

// Draw a polygon to define the region
var geometry = ee.Geometry.Polygon([[
  [77.48932, 13.0311],
  [77.48932, 12.8130],
  [77.72828, 12.8130],
  [77.72828, 13.0311]
]]);
          

Map.centerObject(geometry, 12);


// Prepare the Satellite Embedding dataset
// ****************************************************
var embeddings = ee.ImageCollection('GOOGLE/SATELLITE_EMBEDDING/V1/ANNUAL');

var year = 2024;
var startDate = ee.Date.fromYMD(year, 1, 1);
var endDate = startDate.advance(1, 'year');

var filteredEmbeddings = embeddings
  .filter(ee.Filter.date(startDate, endDate))
  .filter(ee.Filter.bounds(geometry));

var embeddingsImage = filteredEmbeddings.mosaic();

print('Satellite Embeddings Image', embeddingsImage);

// Perform Unsupervised Clustering
// ****************************************************

// Make the training dataset for unsupervised clustering
var training = embeddingsImage.sample({
  region: geometry,
  scale: 10,
  numPixels: 1000
});
print(training.first());

// Instantiate the clusterer and train it.
var clusterer = ee.Clusterer.wekaCascadeKMeans({
  minClusters: 10,
  maxClusters: 12
}).train(training);

// Cluster the stacked image
var clustered = embeddingsImage.cluster(clusterer);

// Automatic Detection of Water Cluster
// ****************************************************

// We need to identify which of the clusters represent water
// Use Sentinel-2 MNDWI to find the 'water' cluster automaticallly
// Prepare a Sentinel-2 composite for the selected region
var s2 = ee.ImageCollection("COPERNICUS/S2_SR_HARMONIZED");

var filtered = s2.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 30))
  .filter(ee.Filter.date(startDate, endDate))
  .filter(ee.Filter.bounds(geometry));

// Load the Cloud Score+ collection
var csPlus = ee.ImageCollection('GOOGLE/CLOUD_SCORE_PLUS/V1/S2_HARMONIZED');
var csPlusBands = csPlus.first().bandNames();

// We need to add Cloud Score + bands to each Sentinel-2
// image in the collection
// This is done using the linkCollection() function
var filteredS2WithCs = filtered.linkCollection(csPlus, csPlusBands);

// Function to mask pixels with low CS+ QA scores.
function maskLowQA(image) {
  var qaBand = 'cs';
  var clearThreshold = 0.5;
  var mask = image.select(qaBand).gte(clearThreshold);
  return image.updateMask(mask);
}

var filteredMasked = filteredS2WithCs
  .map(maskLowQA)
  .select('B.*');

var image = filteredMasked.median(); 
 
// Calculate Modified Normalized Difference Water Index (MNDWI)
// 'GREEN' (B3) and 'SWIR1' (B11)
var mndwi = image.normalizedDifference(['B3', 'B11']).rename(['mndwi']); 

// We use the MNDWI band and select the cluster with the 
// highest average MNDWI values of all pixels within the cluster

// Calculate the stats on MNDWI band, grouped by clusters
// Copmpute at lower resolution as accuracy is not
// important. We just need to find the cluster with 
// highest MNDWI
var stats = mndwi.addBands(clustered).reduceRegion({
  reducer: ee.Reducer.mean().group({
    groupField: 1,
    groupName: 'cluster',
  }),
  geometry: geometry,
  scale: 100,
  maxPixels: 1e8
});
print(stats);

// Extract the cluster-wise stats as a list of lists
// We get a list in the following format
// [[avg_mndwi, cluster_number], [avg_mndwi, cluster_number] ...]]
var groupStats = ee.List(stats.get('groups'));

var groupStatsLists = groupStats.map(function(item) {
      var areaDict = ee.Dictionary(item);
      var clusterNumber = ee.Number(
        areaDict.get('cluster'));
      var mndwi = ee.Number(
        areaDict.get('mean'));
      return ee.List([mndwi, clusterNumber]);
    });
    
// Use the ee.Reducer.max() on the list of lists
// It will pick the list with the highest MNDWI
var waterClusterList = ee.Dictionary(ee.List(groupStatsLists)
  .reduce(ee.Reducer.max(2)));

// Extract the cluster number
var waterCluster = ee.Number(waterClusterList.get('max1'));

// Select all pixels from the water cluster and mask everything else
var water = clustered.eq(waterCluster).selfMask();

// The original waterdetect algorithm has an additional step
// to train a supervised classifier using the water vs. non-water
// samples detected from the procedure above.
// In our testing, there was no significant improvement to the
// output, so we have not added that step.

// Visualize the results
// ****************************************************
var waterVis = {min:0, max:1, palette: ['white', 'blue']};

Map.setCenter(77.61, 13.08, 14);

Map.centerObject(geometry, 10);
Map.addLayer(clustered.clip(geometry).randomVisualizer(), {}, 'clusters');
Map.addLayer(water.clip(geometry), waterVis, 'water');

// Interactive visualization may time-out for large images
// Export the image to use the batch processing mode
Export.image.toDrive({
  image: water,
  description: 'Water_Cluster',
  folder: 'earthengine',
  fileNamePrefix: 'water_cluster',
  region: geometry,
  scale: 10,
  maxPixels: 1e10});

Mapping Urban Tree Cover with Supervised Classification

Open in Code Editor ↗

/**** Start of imports. If edited, may not auto-convert in the playground. ****/
var geometry = 
    /* color: #d63000 */
    /* shown: false */
    /* displayProperties: [
      {
        "type": "rectangle"
      }
    ] */
    ee.Geometry.Polygon(
        [[[77.45008052370622, 13.099222201663046],
          [77.45008052370622, 12.81148072984957],
          [77.74739802858903, 12.81148072984957],
          [77.74739802858903, 13.099222201663046]]], null, false),
    built = /* color: #ff0400 */ee.FeatureCollection(
        [ee.Feature(
            ee.Geometry.Polygon(
                [[[77.55746624775949, 12.935821122826876],
                  [77.55747697659555, 12.935429001761442],
                  [77.55777738400522, 12.935193728826327],
                  [77.55752062496639, 12.935648232422064],
                  [77.55799269375301, 12.935836450444983],
                  [77.55782103237605, 12.936249483941939],
                  [77.55753135380245, 12.936228570869929]]]),
            {
              "landcover": 1,
              "system:index": "0"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.56818411665238, 12.93297109349934],
                  [77.56808755712784, 12.932829928374142],
                  [77.56798026876724, 12.932767188292866],
                  [77.5675940306691, 12.9324744010383],
                  [77.56758866625107, 12.93219729849878],
                  [77.56778178530014, 12.93198293594578],
                  [77.56807682829178, 12.931805171737762],
                  [77.56834504919327, 12.931894053857597],
                  [77.56850598173416, 12.93213455825844],
                  [77.56860790567673, 12.932254810371916],
                  [77.56883857565201, 12.932087503067805],
                  [77.56881711797989, 12.932312322231782],
                  [77.5688922198323, 12.932411660867626],
                  [77.56909606771744, 12.9324744010383],
                  [77.56909606771744, 12.932741046587681],
                  [77.56893513517655, 12.932892668439655]]]),
            {
              "landcover": 1,
              "system:index": "1"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.55966542082108, 12.92704470371513],
                  [77.55993364172257, 12.926971505255315],
                  [77.55999801473892, 12.927159729822899],
                  [77.56005434112824, 12.927525721631364],
                  [77.55993095951355, 12.927606762602116],
                  [77.55952326374329, 12.92761460527531]]]),
            {
              "landcover": 1,
              "system:index": "2"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.58913514122024, 12.908931210607625],
                  [77.58953210815444, 12.908910295247637],
                  [77.58983251556411, 12.908878922204362],
                  [77.59030458435073, 12.909004414353815],
                  [77.59054061874404, 12.908638395408474],
                  [77.59106633171096, 12.908648853100065],
                  [77.59147402748123, 12.909067160404927],
                  [77.5910019586946, 12.909443636380821],
                  [77.59061572059646, 12.909276313794859],
                  [77.58974668487564, 12.909224025463784],
                  [77.58923170074478, 12.909725992990666]]]),
            {
              "landcover": 1,
              "system:index": "3"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.61573227314476, 12.921415857429206],
                  [77.61545332340721, 12.920662940987198],
                  [77.61613996891502, 12.921196257034753],
                  [77.61602195171837, 12.921363571638516],
                  [77.61619361309532, 12.921792314799008],
                  [77.61573227314476, 12.921666829072132]]]),
            {
              "landcover": 1,
              "system:index": "4"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.62816320274716, 12.882943381724802],
                  [77.62788425300961, 12.882880629123182],
                  [77.62794862602597, 12.882587783441089],
                  [77.62773404930478, 12.882368148954866],
                  [77.62801299904233, 12.881949797019837],
                  [77.62857089851742, 12.881562820857978],
                  [77.63010456075271, 12.883191640487594],
                  [77.62838794698318, 12.883024300347486]]]),
            {
              "landcover": 1,
              "system:index": "5"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.61221335121711, 12.9521074223386],
                  [77.61397288033088, 12.951396422136343],
                  [77.61474535652717, 12.952379274820865],
                  [77.61435911842902, 12.954094029794597],
                  [77.61392996498664, 12.954094029794597],
                  [77.6133291501673, 12.954554083998717],
                  [77.6129858274134, 12.953968560318724]]]),
            {
              "landcover": 1,
              "system:index": "6"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.59805128761847, 12.95846451042281],
                  [77.5994245786341, 12.958307676320405],
                  [77.59967134186347, 12.959102301421517],
                  [77.59932801910956, 12.959583257487568],
                  [77.59893105217536, 12.960053757087966],
                  [77.59813711830695, 12.959896923986635]]]),
            {
              "landcover": 1,
              "system:index": "7"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.63455221948686, 13.010374248303735],
                  [77.63442347345415, 13.009370717999056],
                  [77.6357109337813, 13.008743509496409],
                  [77.63618300256792, 13.009098927842672],
                  [77.63607847733172, 13.00986916075317],
                  [77.63577806992205, 13.010193217206663],
                  [77.63577806992205, 13.010465006163697],
                  [77.63474810166034, 13.010590447120325]]]),
            {
              "landcover": 1,
              "system:index": "8"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.67136979766062, 13.015590361873178],
                  [77.6714556283491, 13.015355164770845],
                  [77.67200279898813, 13.015480603253204],
                  [77.67196524806192, 13.015809878967339],
                  [77.67188478179148, 13.015971903364512],
                  [77.67164874739817, 13.016008489504053],
                  [77.67131615348032, 13.015956223588763]]]),
            {
              "landcover": 1,
              "system:index": "9"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.60055607512109, 12.937216602088446],
                  [77.60086721136682, 12.937132950114206],
                  [77.60142511084192, 12.937028385106942],
                  [77.60136073782556, 12.936359168022458],
                  [77.60157531454675, 12.936254602690832],
                  [77.60167187407129, 12.936526472461921],
                  [77.60184353544824, 12.937112037116247],
                  [77.60250872328393, 12.936965646081536],
                  [77.60322755529992, 12.936777428910661],
                  [77.60324901297204, 12.93708066761605],
                  [77.6023048753988, 12.937143406612513],
                  [77.60206884100549, 12.937310710525937],
                  [77.60194009497278, 12.937572122665994],
                  [77.60224050238244, 12.938889635681452],
                  [77.60199373915307, 12.938973287066492],
                  [77.60184353544824, 12.938241336496006],
                  [77.60156458571069, 12.937342079997205],
                  [77.60078138067834, 12.937436188387357]]]),
            {
              "landcover": 1,
              "system:index": "10"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.66150849386902, 12.94914575556225],
                  [77.67097132727356, 12.949961321813811],
                  [77.67094986960144, 12.950525943039601],
                  [77.6614870361969, 12.949689466693222]]]),
            {
              "landcover": 1,
              "system:index": "11"
            })]),
    largePark = 
    /* color: #0b4a8b */
    /* shown: false */
    ee.FeatureCollection(
        [ee.Feature(
            ee.Geometry.Polygon(
                [[[77.57171894317565, 13.00974571743543],
                  [77.57220174079833, 13.009421660397162],
                  [77.57245923286376, 13.009191684177605],
                  [77.5727167249292, 13.009557555335734],
                  [77.57275964027343, 13.010048867184636],
                  [77.57264162307678, 13.010634258755037],
                  [77.57257725006042, 13.011052394744919],
                  [77.57242704635559, 13.011125568470652],
                  [77.57201935058532, 13.01079105983387],
                  [77.57148290878234, 13.010498364406496]]]),
            {
              "landcover": 2,
              "system:index": "0"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.57116564512269, 13.013013671615555],
                  [77.5708974242212, 13.012313298973975],
                  [77.57144459486024, 13.012114685476725],
                  [77.57174655647032, 13.012832946597658],
                  [77.5716714546179, 13.013679663736696],
                  [77.57112428397886, 13.013679663736696]]]),
            {
              "landcover": 2,
              "system:index": "1"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.58499108728763, 12.949247564868747],
                  [77.58530222353336, 12.94904890097151],
                  [77.58524857935306, 12.948662028717099],
                  [77.5853987830579, 12.948170595527872],
                  [77.58580647882816, 12.94804512306893],
                  [77.58636437830326, 12.9488816049352],
                  [77.58607469972965, 12.949027988973114],
                  [77.58563481745121, 12.94949850851256]]]),
            {
              "landcover": 2,
              "system:index": "2"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.52127227201635, 12.881502572157066],
                  [77.52011355772191, 12.87924345560438],
                  [77.52277430906469, 12.876775138310093],
                  [77.5245767535227, 12.877528186841339],
                  [77.5240188540476, 12.883426988708969],
                  [77.52187308683568, 12.883217813712905]]]),
            {
              "landcover": 2,
              "system:index": "3"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.5910989048272, 12.973849327897769],
                  [77.59060537836847, 12.972448359695232],
                  [77.59021914027032, 12.97177923776914],
                  [77.58953249476251, 12.969646399617162],
                  [77.58923208735284, 12.9687681668278],
                  [77.59107744715509, 12.970022784149249],
                  [77.59116327784356, 12.971151934328653],
                  [77.59217178843316, 12.971193754607238],
                  [77.59281551859674, 12.97175832767994],
                  [77.59318029902276, 12.972343809512944],
                  [77.59223616144952, 12.972992019934718]]]),
            {
              "landcover": 2,
              "system:index": "4"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.6027780366433, 12.977741635500964],
                  [77.60281022315148, 12.976978434405225],
                  [77.60407622580651, 12.976549786187062],
                  [77.60455902342919, 12.977908912140418],
                  [77.60427391550836, 12.978271735441785],
                  [77.60305082819757, 12.9786376521642]]]),
            {
              "landcover": 2,
              "system:index": "5"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.53948055718051, 13.060069056320518],
                  [77.54076801750766, 13.058396839354431],
                  [77.54205547783481, 13.05929565738082],
                  [77.54291378471957, 13.06080064768324],
                  [77.54115426366407, 13.063026769886232],
                  [77.53853641960727, 13.062619165396288]]]),
            {
              "landcover": 2,
              "system:index": "6"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.59158319925616, 12.895966653150252],
                  [77.59147591089557, 12.893644917177667],
                  [77.59269899820636, 12.893456667371083],
                  [77.59269899820636, 12.89577840509002]]]),
            {
              "landcover": 2,
              "system:index": "7"
            })]),
    garden = /* color: #ffc82d */ee.FeatureCollection(
        [ee.Feature(
            ee.Geometry.Polygon(
                [[[77.58051928977152, 12.921638012882644],
                  [77.58051928977152, 12.921638012882644],
                  [77.58051928977152, 12.921638012882644],
                  [77.58051928977152, 12.921638012882644]]], null, false),
            {
              "landcover": 3,
              "system:index": "0"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.58496639231821, 12.91928514355793],
                  [77.58513268927713, 12.919034169521753],
                  [77.58549210528513, 12.919295600803975],
                  [77.58540627459665, 12.919478602538726],
                  [77.58515951136728, 12.919713890286383],
                  [77.58493420581003, 12.919630232445938]]]),
            {
              "landcover": 3,
              "system:index": "1"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.59550341650595, 12.92529082586494],
                  [77.59546586557974, 12.924935287789802],
                  [77.59614714666952, 12.924945744799238],
                  [77.59613641783346, 12.925322196847263]]]),
            {
              "landcover": 3,
              "system:index": "2"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.59431788012137, 12.92495620180823],
                  [77.59510644957174, 12.924914373769615],
                  [77.59514400049795, 12.92530128285948],
                  [77.59436615988363, 12.92534833932951]]]),
            {
              "landcover": 3,
              "system:index": "3"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.58106893991778, 12.915020807178204],
                  [77.58195943331073, 12.914958062621785],
                  [77.58203453516315, 12.91569008146616],
                  [77.58114710419804, 12.915747072340457]]]),
            {
              "landcover": 3,
              "system:index": "4"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.58189215023758, 12.925264271803345],
                  [77.58189751465561, 12.92447476736639],
                  [77.58269681294205, 12.924453853307629],
                  [77.58268608410599, 12.925353156252465],
                  [77.5820584471965, 12.925311328280348]]]),
            {
              "landcover": 3,
              "system:index": "5"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.56846373124301, 12.913512524240808],
                  [77.5687855963248, 12.913282459401634],
                  [77.56951515717685, 12.91307330936403],
                  [77.56950442834079, 12.913303374395756],
                  [77.56964390320957, 12.913721673910816],
                  [77.56910746140659, 12.913617099097701],
                  [77.5688392405051, 12.913993568220112],
                  [77.56890361352146, 12.914767419635023],
                  [77.56829206986606, 12.914223632404603]]]),
            {
              "landcover": 3,
              "system:index": "6"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.5766396110571, 12.95210406839103],
                  [77.57675226383573, 12.951962914098635],
                  [77.5769078319586, 12.951926318528294],
                  [77.57703121357328, 12.952009965538327],
                  [77.57709558658964, 12.952153032144517],
                  [77.57709558658964, 12.952524215199473],
                  [77.57659133129484, 12.95259740615912]]]),
            {
              "landcover": 3,
              "system:index": "7"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.56584841450672, 12.925263166983274],
                  [77.56563383778553, 12.92441614887677],
                  [77.56615955075245, 12.92430112150488],
                  [77.56631511887531, 12.925163825502247]]]),
            {
              "landcover": 3,
              "system:index": "8"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.57480676422192, 12.941854345206552],
                  [77.57474239120556, 12.940798256612911],
                  [77.57671649704052, 12.940714605840054],
                  [77.57667358169628, 12.942338160476737],
                  [77.57476384887768, 12.942484548357596]]]),
            {
              "landcover": 3,
              "system:index": "9"
            })]),
    isolatedGreen = /* color: #00ffff */ee.FeatureCollection(
        [ee.Feature(
            ee.Geometry.Polygon(
                [[[77.60793656057083, 12.939272671495173],
                  [77.60765224641526, 12.938326364701208],
                  [77.60823160356247, 12.938221800194288],
                  [77.6084890956279, 12.939042630394946],
                  [77.60844618028366, 12.939220389445568]]]),
            {
              "landcover": 4,
              "system:index": "0"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.56368912846887, 12.957003080995905],
                  [77.56478883416497, 12.957065814977387],
                  [77.56514825017297, 12.957118093283214],
                  [77.56517507226312, 12.95723310551739],
                  [77.56489612252557, 12.957206966377932],
                  [77.56476737649285, 12.95718082723571],
                  [77.56363548428857, 12.95718082723571]]]),
            {
              "landcover": 4,
              "system:index": "1"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.56614762047808, 12.958907604405269],
                  [77.56607373386241, 12.958714176008982],
                  [77.5664867940507, 12.958724631601802],
                  [77.56747384696818, 12.958766453968751],
                  [77.56793518691875, 12.958803048534051],
                  [77.5684126201234, 12.95878736514958],
                  [77.5684501710496, 12.958944198949833],
                  [77.56737192302562, 12.958912832197685],
                  [77.56666918426372, 12.958965110115738]]]),
            {
              "landcover": 4,
              "system:index": "2"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.56851088472689, 12.962117252093533],
                  [77.56853770681704, 12.96190291527356],
                  [77.56853770681704, 12.96138014176794],
                  [77.5684035963663, 12.961181487547947],
                  [77.56838213869418, 12.960972377671425],
                  [77.56858062216128, 12.9607946341383],
                  [77.56829094358767, 12.960710990078788],
                  [77.56826412149752, 12.960836456157512],
                  [77.56805284969072, 12.961259903706358],
                  [77.5678704594777, 12.961348775322676],
                  [77.56767734042863, 12.96126513144937],
                  [77.56800993434648, 12.961056021643113],
                  [77.5680850361989, 12.960559385149299],
                  [77.56849273196916, 12.960564612907033],
                  [77.56864830009202, 12.96062211823478],
                  [77.56888433448533, 12.960616890478253],
                  [77.56897552959184, 12.960810317396321],
                  [77.56881996146898, 12.960862594915943],
                  [77.56896480075578, 12.96126513144937],
                  [77.56912573329667, 12.961834954779917],
                  [77.56897552959184, 12.961981331204726],
                  [77.56871267310838, 12.962357727330419],
                  [77.5684820031331, 12.962326361008344]]]),
            {
              "landcover": 4,
              "system:index": "3"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.58580109726185, 12.90900320022248],
                  [77.58615514885182, 12.90908686162086],
                  [77.58623219979488, 12.909280328497383],
                  [77.58618392003261, 12.909526083503001],
                  [77.58595861447536, 12.909510397020505],
                  [77.58577622426235, 12.909494710537018]]]),
            {
              "landcover": 4,
              "system:index": "4"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.5790603355235, 12.90459440164502],
                  [77.57903887785137, 12.904510738743422],
                  [77.57924540794552, 12.904461063882374],
                  [77.57926686561764, 12.904560413594627]]]),
            {
              "landcover": 4,
              "system:index": "5"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.57874919927777, 12.904591787179776],
                  [77.57874383485974, 12.90440354560986],
                  [77.57878406799496, 12.904372172001098],
                  [77.57882966554821, 12.904515967675595],
                  [77.57878675020397, 12.90453688340318],
                  [77.57879479683102, 12.904591787179776],
                  [77.57881357229412, 12.904659763267412],
                  [77.57878675020397, 12.904696365768501],
                  [77.57870896614254, 12.904712052553036]]]),
            {
              "landcover": 4,
              "system:index": "6"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.57269545353115, 12.905980064381774],
                  [77.57309242046536, 12.905964377676778],
                  [77.57305486953915, 12.906089871289156],
                  [77.57274909771145, 12.906152618071733],
                  [77.57244869030178, 12.90628334048485],
                  [77.57246478355587, 12.906126473580901]]]),
            {
              "landcover": 4,
              "system:index": "7"
            })]),
    waterbody = 
    /* color: #d63000 */
    /* shown: false */
    ee.FeatureCollection(
        [ee.Feature(
            ee.Geometry.Polygon(
                [[[77.61944514570256, 12.985154431540222],
                  [77.61768561658879, 12.983774436127218],
                  [77.61614066419621, 12.982603524918357],
                  [77.61614066419621, 12.981767156391507],
                  [77.61678439435978, 12.981432608192684],
                  [77.61794310865422, 12.980888966409168],
                  [77.61858683881779, 12.980428960894367],
                  [77.61905890760441, 12.97938349064927],
                  [77.61957389173527, 12.978965301320063],
                  [77.6203892832758, 12.97988531691568],
                  [77.62068969068547, 12.98047077961271],
                  [77.61957389173527, 12.980888966409168],
                  [77.6187155848505, 12.98118169674804],
                  [77.6172564631464, 12.981808974884697],
                  [77.61699897108097, 12.982478069818768],
                  [77.61811477003117, 12.982478069818768],
                  [77.61957389173527, 12.982143522576896],
                  [77.62068969068547, 12.981307152502035],
                  [77.62163382825871, 12.981767156391507],
                  [77.62017470655461, 12.982812616610275]]]),
            {
              "landcover": 5,
              "system:index": "0"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.61705279323951, 12.913604751308693],
                  [77.61610865566627, 12.909338061409425],
                  [77.61520743343726, 12.90766482980356],
                  [77.61829733822242, 12.907204689148696],
                  [77.61975645992652, 12.908585108572662],
                  [77.62035727474586, 12.911680566841879],
                  [77.61808276150123, 12.911513245753333]]]),
            {
              "landcover": 5,
              "system:index": "1"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.57954478237525, 12.901180951571499],
                  [77.57864356014625, 12.899967820203194],
                  [77.57804274532691, 12.899173006806603],
                  [77.57902979824439, 12.89904750972368],
                  [77.57945895168677, 12.898169028380611],
                  [77.58031725857154, 12.898252693403306],
                  [77.58126139614478, 12.898880180181855],
                  [77.58104681942359, 12.901264615586943]]]),
            {
              "landcover": 5,
              "system:index": "2"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.52197671633247, 12.940890936500946],
                  [77.52076435785774, 12.940368118904518],
                  [77.52090383272652, 12.939709367172293],
                  [77.521172053628, 12.939500239274341],
                  [77.52134371500496, 12.939918494894872],
                  [77.52155829172615, 12.939918494894872],
                  [77.52168703775887, 12.939677997998777],
                  [77.52201963167671, 12.939542064867965],
                  [77.5223414967585, 12.940420400713496],
                  [77.52243805628304, 12.940681809593913]]]),
            {
              "landcover": 5,
              "system:index": "3"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.56002218990443, 12.952976210240205],
                  [77.55957157878993, 12.952286124244173],
                  [77.5592067983639, 12.951784242319086],
                  [77.55905659465907, 12.951177800310667],
                  [77.55978615551112, 12.951470565602486],
                  [77.56034405498622, 12.951470565602486],
                  [77.56098778514979, 12.951094153021254],
                  [77.56128819255946, 12.951073241194504],
                  [77.56120236187098, 12.951386918411366],
                  [77.56120236187098, 12.951888801136858],
                  [77.56081612377284, 12.95211883038148],
                  [77.5607732084286, 12.952620711632493],
                  [77.5607732084286, 12.9528507402013]]]),
            {
              "landcover": 5,
              "system:index": "4"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.57648022441981, 12.934489610227581],
                  [77.57602961330531, 12.934217738236644],
                  [77.57594378261683, 12.933830842969495],
                  [77.57621200351832, 12.933297553915116],
                  [77.5764051225674, 12.93355897026068],
                  [77.57675917415736, 12.933736733219199],
                  [77.57697375087855, 12.933297553915116],
                  [77.57757456569789, 12.933768103139917],
                  [77.57716686992762, 12.934123628632285],
                  [77.57694156437037, 12.934416413951483]]]),
            {
              "landcover": 5,
              "system:index": "5"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.67427425528479, 12.938407462236507],
                  [77.67119310727965, 12.936608947194635],
                  [77.6713647686566, 12.9337229308417],
                  [77.67406843534361, 12.933597451112467],
                  [77.67518423429381, 12.93619068602391]]]),
            {
              "landcover": 5,
              "system:index": "6"
            })]),
    openarea = 
    /* color: #98ff00 */
    /* shown: false */
    ee.FeatureCollection(
        [ee.Feature(
            ee.Geometry.Polygon(
                [[[77.73264788022887, 12.900468596814665],
                  [77.73093126645934, 12.897707660746448],
                  [77.73350618711363, 12.896034351332165],
                  [77.73556612363707, 12.899380958970472]]]),
            {
              "landcover": 6,
              "system:index": "0"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.66170496421522, 12.882563666756962],
                  [77.66091103034681, 12.88112035075511],
                  [77.66170496421522, 12.880095382168715],
                  [77.66247744041151, 12.880764749883824],
                  [77.66365761237806, 12.881475951121704],
                  [77.66479486900037, 12.882354491040031],
                  [77.66569609122938, 12.883023852719427],
                  [77.66417259650892, 12.882710089654891],
                  [77.66367907005018, 12.882249903116058],
                  [77.66247744041151, 12.882166232745451],
                  [77.66211265998548, 12.882647336994827],
                  [77.66217703300184, 12.883233027877445]]]),
            {
              "landcover": 6,
              "system:index": "1"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.6221119302609, 12.873985908882297],
                  [77.6222192186215, 12.873839480886895],
                  [77.62215484560514, 12.873536165481486],
                  [77.62255181253934, 12.873504788004801],
                  [77.62271274508024, 12.87336881889381],
                  [77.62284149111295, 12.873536165481486],
                  [77.62251962603116, 12.873870858321686],
                  [77.62275566042447, 12.874236928104006],
                  [77.62271274508024, 12.874393814989942],
                  [77.62235869349027, 12.874111418524581]]]),
            {
              "landcover": 6,
              "system:index": "2"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.61023930358279, 12.872511695027958],
                  [77.61100105094302, 12.87229205171123],
                  [77.61121562766421, 12.873139246301209],
                  [77.61040023612368, 12.873400725534772]]]),
            {
              "landcover": 6,
              "system:index": "3"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.60768523145241, 12.871591723168615],
                  [77.60928382802528, 12.871246568032364],
                  [77.60929455686134, 12.871999633171612],
                  [77.60892977643532, 12.872334328063065],
                  [77.60818948674721, 12.872428460920776]]]),
            {
              "landcover": 6,
              "system:index": "4"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.61582841802162, 12.88325350376569],
                  [77.61574258733314, 12.882981576048445],
                  [77.6160215370707, 12.882741024360186],
                  [77.61745920110268, 12.882019367909525],
                  [77.61758794713539, 12.882636436597595],
                  [77.61707296300453, 12.882772400680446],
                  [77.61690130162758, 12.882992034812252],
                  [77.61690130162758, 12.883232586259464],
                  [77.61610736775917, 12.88325350376569]]]),
            {
              "landcover": 6,
              "system:index": "5"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.62236659510695, 12.889833138178536],
                  [77.62222175582015, 12.88934158923451],
                  [77.62270455344283, 12.889289296736871],
                  [77.6227903841313, 12.889686719445061],
                  [77.622554349738, 12.889723324136458],
                  [77.62261872275435, 12.890146892319073],
                  [77.62241487486922, 12.890173038479695]]]),
            {
              "landcover": 6,
              "system:index": "6"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.62784366591536, 12.889618739289698],
                  [77.62814943774306, 12.889597822315109],
                  [77.62848203166091, 12.889691948687021],
                  [77.62850348933303, 12.889854055133474],
                  [77.62826745493972, 12.88997955682638],
                  [77.62794558985793, 12.889922035224945]]]),
            {
              "landcover": 6,
              "system:index": "7"
            })]),
    golfCourse = 
    /* color: #546346 */
    /* shown: false */
    ee.FeatureCollection(
        [ee.Feature(
            ee.Geometry.Polygon(
                [[[77.5838022436437, 12.988757253656859],
                  [77.58417775290579, 12.988851342609596],
                  [77.58414556639761, 12.988924522881524],
                  [77.58373787062735, 12.988924522881524]]]),
            {
              "landcover": 7,
              "system:index": "0"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.58739640372366, 12.98718909919782],
                  [77.58762170928091, 12.986959102378103],
                  [77.58767535346121, 12.987126372813568],
                  [77.5873320307073, 12.987325006309396]]]),
            {
              "landcover": 7,
              "system:index": "1"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.64769243139946, 12.950758866624172],
                  [77.64769243139946, 12.9509993528292],
                  [77.64741348166191, 12.951229382895052],
                  [77.64748858351433, 12.950821602178308]]]),
            {
              "landcover": 7,
              "system:index": "2"
            })]),
    wetland = /* color: #49ffb8 */ee.FeatureCollection(
        [ee.Feature(
            ee.Geometry.Polygon(
                [[[77.70036294170843, 13.01687860196935],
                  [77.69993378826605, 13.015456970137205],
                  [77.70168258854376, 13.016408209986377]]]),
            {
              "landcover": 8,
              "system:index": "0"
            }),
        ee.Feature(
            ee.Geometry.Polygon(
                [[[77.70662271981143, 13.047484527460087],
                  [77.70747566227817, 13.047437494117524],
                  [77.70758295063877, 13.04788692346974],
                  [77.70671391491794, 13.04793395672681]]]),
            {
              "landcover": 8,
              "system:index": "1"
            })]);
/***** End of imports. If edited, may not auto-convert in the playground. *****/
// Supervised Classification with Satellite Embeddings
// Classifying Urban Tree Cover

// Credit: Training samples are adapted from original work by
// Nishalini, Shweta, Raj Bhagat P, Janhavi Mane, Jyoti
// for the 'Urban True Tree Cover Project'
// ****************************************************

// Select a region
// ****************************************************

// Draw a polygon to define the region
// Save it as the variable 'geometry'
Map.centerObject(geometry, 12);

// Collect Training Samples
// ****************************************************

// Pick a year for classification
var year = 2024;
var startDate = ee.Date.fromYMD(year, 1, 1);
var endDate = startDate.advance(1, 'year');

// Create a Sentinel-2 Compsite for the selected year
// for selecting training samples
var s2 = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED');
var filteredS2 = s2
  .filter(ee.Filter.date(startDate, endDate))
  .filter(ee.Filter.bounds(geometry));

// Use the Cloud Score+ collection for cloud masking
var csPlus = ee.ImageCollection('GOOGLE/CLOUD_SCORE_PLUS/V1/S2_HARMONIZED');
var csPlusBands = csPlus.first().bandNames();
var filteredS2WithCs = filteredS2.linkCollection(csPlus, csPlusBands);

function maskLowQA(image) {
  var qaBand = 'cs';
  var clearThreshold = 0.6;
  var mask = image.select(qaBand).gte(clearThreshold);
  return image.updateMask(mask);
}

var filteredS2Masked = filteredS2WithCs
  .map(maskLowQA)
  .select('B.*');  
  
// Create a median composite of cloud-masked images
var composite = filteredS2Masked.median();

// Display the input composite in false color
// that helps distinguish between
// water, vegetation and built surfaces
var rgbVis = {min: 300, max: 4000, bands: ['B4', 'B3', 'B2']};

Map.addLayer(composite.clip(geometry), rgbVis, 'S2 Composite (RGB)', false);

// Merge the collected training samples
var gcps = built.merge(largePark).merge(garden)
  .merge(isolatedGreen).merge(waterbody)
  .merge(openarea).merge(golfCourse).merge(wetland);

// Train a Classifier
// ****************************************************

// Sample Embedding Vectors
var embeddings = ee.ImageCollection('GOOGLE/SATELLITE_EMBEDDING/V1/ANNUAL'); 

var embeddingsFiltered = embeddings
  .filter(ee.Filter.date(startDate, endDate))
  .filter(ee.Filter.bounds(geometry));

var embeddingsImage = embeddingsFiltered.mosaic();

// Take mean values for each polygon
var training = embeddingsImage.reduceRegions({
  collection: gcps,
  reducer: ee.Reducer.mean(),
  scale: 10,
  tileScale: 16
});

// Some small polygons end up with null values
training = training.filter(ee.Filter.notNull(['A00']));

// Train a classifier.
var classifier = ee.Classifier.smileKNN().train({
  features: training,  
  classProperty: 'landcover', 
  inputProperties: embeddingsImage.bandNames()
});

// Classify the Satellite Embedding Mosaic
// ****************************************************

var classified = embeddingsImage.classify(classifier);

// Visualize the classification
// ****************************************************

var palette = ['ff0000','129b0a','b9ff14','f7ae08','21e0ff','faff08', '546346', '#49ffb8'];
var viz_class = {
  'min':1,
  'max':8,
  'palette': palette
};
Map.addLayer(classified.clip(geometry), viz_class, 'Classified');

// Add a Legend
var legend = ui.Panel({style: {position: 'middle-right', padding: '8px 15px'}});

var makeRow = function(color, name) {
  var colorBox = ui.Label({
    style: {color: '#ffffff',
      backgroundColor: color,
      padding: '10px',
      margin: '0 0 4px 0',
    }
  });
  var description = ui.Label({
    value: name,
    style: {
      margin: '0px 0 4px 6px',
    }
  }); 
  return ui.Panel({
    widgets: [colorBox, description],
    layout: ui.Panel.Layout.Flow('horizontal')}
)};

var title = ui.Label({
  value: 'Legend',
  style: {fontWeight: 'bold',
    fontSize: '16px',
    margin: '0px 0 4px 0px'}});

legend.add(title);

var palette = ['ff0000','129b0a','b9ff14','f7ae08','21e0ff','faff08'];
var classes = ['Built', 'National Parks', 'Garden', 'Isolated Green',  
  'Water', 'Open Area', 'Golf Course', 'Wetland'];


legend.add(makeRow('#ff0000','Built'));
legend.add(makeRow('#129b0a','Large Park'));
legend.add(makeRow('#b9ff14','Garden'));
legend.add(makeRow('#f7ae08','Isolated Green'));
legend.add(makeRow('#546346','Golf Course'));
legend.add(makeRow('#21e0ff','Water'));
legend.add(makeRow('#49ffb8','Wetland'));
legend.add(makeRow('#faff08','Open Area'));

Map.add(legend);

Learning Resources

Data Credits

References

License

The course material (text, images, presentation, videos) is licensed under a Creative Commons Attribution 4.0 International License.

The code (scripts, Jupyter notebooks etc.) is licensed under the MIT License. For a copy, see https://opensource.org/licenses/MIT

Kindly give appropriate credit to the original author as below:

Copyright © 2025 Ujaval Gandhi www.spatialthoughts.com

Citing and Referencing

You can cite the course materials as follows



If you want to report any issues with this page, please comment below.