Skip to main content
 logo

Main navigation

  • About Us
    • Overview
      • Spatial and Temporal Design
      • History
    • Vision and Management
    • Diversity, Equity, Inclusion, and Accessibility (DEIA)
      • Code of Conduct
    • Advisory Groups
      • Science, Technology & Education Advisory Committee
      • Technical Working Groups (TWGs)
    • FAQ
    • Contact Us
      • Field Offices
    • User Accounts
    • Staff

    About Us

  • Data & Samples
    • Data Portal
      • Explore Data Products
      • Data Availability Charts
      • Spatial Data & Maps
      • Document Library
      • API & GraphQL
      • Prototype Data
      • External Lab Data Ingest (restricted)
    • Data Themes
      • Atmosphere
      • Biogeochemistry
      • Ecohydrology
      • Land Cover and Processes
      • Organisms, Populations, and Communities
    • Samples & Specimens
      • Discover and Use NEON Samples
        • Sample Types
        • Sample Repositories
        • Sample Explorer
        • Megapit and Distributed Initial Characterization Soil Archives
        • Excess Samples
      • Sample Processing
      • Sample Quality
      • Taxonomic Lists
    • Collection Methods
      • Protocols & Standardized Methods
      • Airborne Remote Sensing
        • Flight Box Design
        • Flight Schedules and Coverage
        • Daily Flight Reports
          • AOP Flight Report Sign Up
        • Camera
        • Imaging Spectrometer
        • Lidar
      • Automated Instruments
        • Site Level Sampling Design
        • Sensor Collection Frequency
        • Instrumented Collection Types
          • Meteorology
          • Phenocams
          • Soil Sensors
          • Ground Water
          • Surface Water
      • Observational Sampling
        • Site Level Sampling Design
        • Sampling Schedules
        • Observation Types
          • Aquatic Organisms
            • Aquatic Microbes
            • Fish
            • Macroinvertebrates & Zooplankton
            • Periphyton, Phytoplankton, and Aquatic Plants
          • Terrestrial Organisms
            • Birds
            • Ground Beetles
            • Mosquitoes
            • Small Mammals
            • Soil Microbes
            • Terrestrial Plants
            • Ticks
          • Hydrology & Geomorphology
            • Discharge
            • Geomorphology
          • Biogeochemistry
          • DNA Sequences
          • Pathogens
          • Sediments
          • Soils
            • Soil Descriptions
    • Data Notifications
    • Data Guidelines and Policies
      • Acknowledging and Citing NEON
      • Publishing Research Outputs
      • Usage Policies
    • Data Management
      • Data Availability
      • Data Formats and Conventions
      • Data Processing
      • Data Quality
      • Data Product Bundles
      • Data Product Revisions and Releases
        • Release 2021
        • Release 2022
        • Release 2023
      • NEON and Google
      • Externally Hosted Data

    Data & Samples

  • Field Sites
    • About Field Sites and Domains
    • Explore Field Sites
    • Site Management Data Product

    Field Sites

  • Impact
    • Observatory Blog
    • Case Studies
    • Spotlights
    • Papers & Publications
    • Newsroom
      • NEON in the News
      • Newsletter Archive
      • Newsletter Sign Up

    Impact

  • Resources
    • Getting Started with NEON Data & Resources
    • Documents and Communication Resources
      • Papers & Publications
      • Document Library
      • Outreach Materials
    • Code Hub
      • Code Resources Guidelines
      • Code Resources Submission
      • NEON's GitHub Organization Homepage
    • Learning Hub
      • Science Videos
      • Tutorials
      • Workshops & Courses
      • Teaching Modules
      • Faculty Mentoring Networks
      • Data Education Fellows
    • Research Support and Assignable Assets
      • Field Site Coordination
      • Letters of Support
      • Mobile Deployment Platforms
      • Permits and Permissions
      • AOP Flight Campaigns
      • Excess Samples
      • Assignable Assets FAQs
    • Funding Opportunities

    Resources

  • Get Involved
    • Advisory Groups
      • Science, Technology & Education Advisory Committee
      • Technical Working Groups
    • Upcoming Events
    • Past Events
    • NEON Ambassador Program
      • Exploring NEON-Derived Data Products Workshop Series
    • Collaborative Works
      • EFI-NEON Ecological Forecasting Challenge
      • NCAR-NEON-Community Collaborations
      • NEON Science Summit
      • NEON Great Lakes User Group
    • Community Engagement
    • Science Seminars and Data Skills Webinars
      • Past Years
    • Work Opportunities
      • Careers
      • Seasonal Fieldwork
      • Internships
        • Intern Alumni
    • Partners

    Get Involved

  • My Account
  • Search

Search

Learning Hub

  • Science Videos
  • Tutorials
  • Workshops & Courses
  • Teaching Modules
  • Faculty Mentoring Networks
  • Data Education Fellows

Breadcrumb

  1. Resources
  2. Learning Hub
  3. Tutorials
  4. Functions in Google Earth Engine (GEE)

Tutorial

Functions in Google Earth Engine (GEE)

Authors: Bridget M. Hass, John Musinsky

Last Updated: Jul 29, 2023

Writing a Function to Visualize AOP SDR Image Collections

In the earlier Reflectance preprocessing tutorial, we showed how to read in a band of data containing weather quality information and apply cloud-masking using that band. In this tutorial, we will show you a more simplified way of doing this, using functions so we can more easily apply that operation to an Image Collection. This is called "refactoring". In any coding language, if you notice you are writing very similar lines of code repeatedly, it may be an opportunity to create a function. For example, in the previous tutorial, we repeated lines of code to pull in different years of data at SRER, the only difference being the year and the variable names for each year. As you become more proficient with GEE coding, it is good practice to start writing functions to make your scripts more readable and reproducible.

Objectives

After completing this activity, you will be able to:

  • Understand the basic structure of functions in GEE (JavaScript API)
  • Write and call a function to read in and display images from each year in an AOP SDR Image Collection
  • Write a function to add the weather quality layer to the map, and mask out cloudy data from an SDR Image Collection

Requirements

  • A gmail (@gmail.com) account
  • An Earth Engine account. You can sign up for an Earth Engine account here: https://earthengine.google.com/new_signup/
  • A basic understanding of the GEE code editor and the GEE JavaScript API. These are introduced in the tutorials:
    • Intro to AOP Data in GEE
    • Introduction to AOP Hyperspectral Data in GEE
  • A basic understanding of hyperspectral data and the AOP spectral data products. If this is your first time working with AOP hyperspectral data, we encourage you to start with the Intro to Working with Hyperspectral Remote Sensing Data in R tutorial. You do not need to follow along with the code in those lessons, but at least read through to gain a better understanding NEON's spectral data products.

Additional Resources

If this is your first time using GEE, we recommend starting on the Google Developers website, and working through some of the introductory tutorials. The links below are good places to start.

  • Get Started with Earth-Engine
  • GEE JavaScript Tutorial
  • Functional Programming in GEE
  • EE Guides Best Practices

Let's get started! First let's take a look at the syntax for writing user-defined functions in GEE. If you are familiar with other programming languages, this should look somewhat familiar. The function requires input argument(s) args and returns an output.

var functionName = function(args) {
  // do something with input args
  return output;
};

To call the function for a full image collection, you can use a map to apply the function to all items in a collection. This is shown in the script below.

// Map the function over the collection.
var newVariable = collection.map(myFunction);

First, we'll read in the AOP SDR Image Collection at Soaproot Saddle (SOAP).

// specify center location of SOAP
var site_center = ee.Geometry.Point([-119.262, 37.033])

// read in the AOP SDR Image Collection
var sdr_col = ee.ImageCollection('projects/neon-prod-earthengine/assets/DP3-30006-001')
  .filterBounds(site_center)

print('NEON AOP SDR Image Collection',sdr_col)

Building off the example from the previous tutorial, we can write a simple function to apply cloud-masking to an Image Collection:

// Function to mask out poor-weather data, keeping only the <10% cloud cover weather data
function clearSDR(image) { 
  // create a single band Weather Quality QA layer 
  var weather_qa = image.select(['Weather_Quality_Indicator']);
  // WEATHER QUALITY INDICATOR = 1 is < 10% CLOUD COVER
  var clear_qa = weather_qa.eq(1);
  // mask out all cloudy pixels from the SDR image
  return image.updateMask(clear_qa);
}

Then we can use .map() to apply this as follows:

// Use map to apply this function on all the NISImages and return a clear-weather collection
var sdr_cloudfree = sdr_col.map(clearSDR)

For the next example, we will write a function to add a Map Layer for each Image in an Image collection. We'll provide the full script below, including the function addNISImage, with comments explaining what each part of the function does. Note that a helpful troubleshooting technique is to add in print statements if you are unsure what the code is returning. We have included some commented-out print statements in the function, which show the outputs (which would show up in the console tab).

For a little more detail on how this function was applied, refer to this GIS Stack Exchange Post: Add/display all images of my collection in google earth engine. When writing your own GEE code, the Google earth-engine developers pages may not always have an example of what you are trying to do, so stack overflow can be a valuable resource.

// Define visualization parameters for the reflectance data, showing a true-color image
// B053 ~ 642 nm, B035 ~ 552 nm , B019 ~ 472nm 
var sdr_vis_params = {'min':0, 'max':1200, 'gamma':0.9, 'bands':['B053','B035','B019']};

// Function to display each NIS Image in the NEON AOP Image Collection
function addNISImage(image) { 
  // get the system:id and convert to string
  var imageId = ee.Image(image.id);
  // get the system:id - this is an object on the server
  var sysID_serverObj = ee.String(imageId.get("system:id"));
  // getInfo() converts to string on the server
  var sysID_serverStr = sysID_serverObj.getInfo()
  // truncate the string to show only the fileName (NEON domain + site code + product code + year)
  var fileName = sysID_serverStr.slice(52,100); 
  // print("fileName: "+fileName) // optionally print the file name, can uncomment

  // add this layer to the map using the true-color (RGB) visualization parameters
  Map.addLayer(imageId, sdr_vis_params, fileName)
}

// call the addNISimages function
// see this link for an explanation of what is occurring:
// https://gis.stackexchange.com/questions/284610/add-display-all-images-of-mycollection-in-google-earth-engine
sdr_col.evaluate(function(sdr_col) {
  sdr_col.features.map(addNISImage);
})

// Center the map on site and set zoom level (11)
Map.centerObject(site_center, 11);

Note that the first half of this function is just pulling out relevant information about the site in order to properly label the layer on the Map display.

SOAP visualization function output

Function including cloud-masking

Next we can build upon this function to include some small pre-processing steps, such as selecting the Weather_Quality_Indicator band, plotting it, and masking the SDR data to include only the clear-weather (<10% cloud cover) data and add that masked dataset to the Map.

// Define a palette for the weather - to match NEON AOP's weather color conventions
// This will be used in the visualization parameters for the Weather QA layer
var gyr_palette = [
  '00ff00',  // green (<10% cloud cover)
  'ffff00',  // yellow (10-50% cloud cover)
  'ff0000']; // red (>50% cloud cover)

// Build upon the function to add a layer of the weather band, and 
// mask out poor-weather data (>10% cloud cover), keeping only the clear weather (<10% cloud cover)
function addClearNISImages(image) { 
  // get the system:id and convert to string
  var imageId = ee.Image(image.id);
  // get the system:id - this is an object on the server
  var sysID_serverObj = ee.String(imageId.get("system:id"));
  // getInfo() converts to string on the server
  var sysID_serverStr = sysID_serverObj.getInfo()
  // truncate the string to show only the fileName (NEON domain + site code + product code + year)
  var fileName = sysID_serverStr.slice(52,100); // optionally print, can uncomment
  
  // create a single band Weather Quality QA layer for 2016
  var weather_qa = imageId.select(['Weather_Quality_Indicator']);

  // apply the function from the beginning of this script to generate a cloud-free image
  // you can apply a function directly on a single image in this way
  var sdr_cloudfree = clearSDR(imageId)

  // add the weather QA bands to the map with the green-yellow-red palette
  Map.addLayer(weather_qa, {min: 1, max: 3, palette: gyr_palette, opacity: 0.3}, fileName + ' Weather QA Band')

  // add the clear weather reflectance layer to the map - the 0 means the layer won't be turned on by default
  Map.addLayer(sdr_cloudfree, sdr_vis_params, fileName + ' Clear',0)
}

//call the clearNISImages function
sdr_col.evaluate(function(sdr_col) {
  sdr_col.features.map(addClearNISImages);
})
SOAP clear qa function output

This figure shows the weather quality information at SOAP in 2019, where the data were collected in mixed cloud conditions. Flight operators prioritize flying the area over NEON plots in the best weather conditions when possible. As explained in the previous lesson, when working with AOP reflectance data, the weather conditions during the flights are one of the most important quality considerations.

Recap

This lesson showed examples of two functions that demonstrate how to use functional programming to add layers to a Map. As explained in introduction-to-functional-programming, "Earth Engine uses a parallel processing system to carry out computation across a large number of machines...The use of for-loops is discouraged in Earth Engine. The same results can be achieved using a map() operation where you specify a function that can be independently applied to each element. This allows the system to distribute the processing to different machines." The examples presented in this lesson show some examples of how to make use of that map operation in lieu of a for loop.

Get Lesson Code

Functions to display AOP SDR Image Collections in GEE

Questions?

If you have questions or comments on this content, please contact us.

Contact Us
NEON Logo

Follow Us:

Join Our Newsletter

Get updates on events, opportunities, and how NEON is being used today.

Subscribe Now

Footer

  • My Account
  • About Us
  • Newsroom
  • Contact Us
  • Terms & Conditions
  • Careers
  • Code of Conduct

Copyright © Battelle, 2023

The National Ecological Observatory Network is a major facility fully funded by the National Science Foundation.

Any opinions, findings and conclusions or recommendations expressed in this material do not necessarily reflect the views of the National Science Foundation.