Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Working with HLS Data in QGIS: Access, Visualization, and Analysis

NASA’s Harmonized Landsat Sentinel-2 (HLS) project combines Landsat 8 and 9 with Sentinel-2 A, 2B, and 2C into a single, consistent 30 m global surface reflectance product, giving you a sub-two-day revisit at most locations on Earth. I recently presented at a NASA HLS workshop on how to work with the data inside QGIS, and several attendees asked for the recording. While we wait for the official workshop video to be released, this companion tutorial walks through the same workflow end to end: streaming HLS scenes from NASA, building monthly cloud-free composites from Google Earth Engine, extracting pixel values for points and polygons, and driving the whole thing from natural language or voice with OpenGeoAgent.

Video tutorial: Working with HLS Data in QGIS

What You Will Need

What Is HLS?

HLS is a NASA initiative that takes Landsat 8/9 and Sentinel-2 A/B/C surface reflectance, harmonizes their geometry, atmospheric correction, and spectral response, and reprojects everything onto the Sentinel-2 Military Grid Reference System (MGRS) tile system. The result is a single, analysis-ready collection that you can use as if it came from one sensor.

Two collections matter for this tutorial:

Both have 30 m spatial resolution. Cloud cover is still a factor, but combining the two sensors gives you a much higher temporal frequency than either alone, which is why HLS has become a workhorse for environmental monitoring, crop yield estimation, water mapping, and many other downstream applications. The two product versions in the catalog are V1.5 and v2.0. Pick v2.0 whenever it is available.

Install the Plugins

Open Plugins > Manage and Install Plugins in QGIS, switch to the All tab, and install each of the four plugins by name: NASA Earthdata, GEE Data Catalogs, OpenGeoAgent, and leafmap. Restart QGIS so they load cleanly. The first time you open each plugin, accept the prompt to install its Python dependencies.

If you want full setup walkthroughs for any of these plugins, see the companion posts: Access 120 Petabytes of NASA Data Directly in QGIS, Browse and Visualize Google Earth Engine Datasets in QGIS, and OpenGeoAgent: An Open-Source Multimodal AI Agent for Geospatial Analysis in QGIS.

Stream HLS Imagery with the NASA Earthdata Plugin

Open the NASA Earthdata panel from the toolbar or from the NASA Earthdata top menu. The output box at the bottom shows the catalog has loaded over fifty thousand datasets, so the fastest way to find HLS is the keyword filter.

  1. Type HLS into the keyword box and pick HLSL30 v2.0 from the Dataset dropdown. (Use HLSS30 v2.0 if you want the Sentinel-2 derived product instead.)

  2. Set the area of interest. Click Use Map Extent to use the current canvas, Use Layer Extent to use a vector layer, or Draw Bounding Box to draw a rectangle directly on the map. For this example, draw a small box over the San Francisco Bay Area.

  3. Set the Date Range. The default is one year ending today.

  4. Click Advanced Options and set Max Cloud Cover to 10 percent so noisy scenes are excluded.

  5. Click Collection Info to read the dataset’s summary, temporal extent, and whether it is cloud hosted. HLS is distributed as Cloud Optimized GeoTIFFs, so you can stream it without downloading anything.

  6. Click Search.

The plugin returns the matching footprints on the map and lists them in the results table on the right. Double-click the Date column header to sort by date. Some footprints look like diagonal slivers rather than full rectangles. That is not an artifact: each granule is a single MGRS tile clipped to a satellite orbit, and the diagonal edges are where adjacent orbits meet.

Three tabs sit beneath the results table:

Single Band, RGB, and False Color Composites

Select a granule in the results table and look at the display options at the top of the panel.

For a single band, choose Single Band, pick a band such as B5 (near infrared), and click Display Granule. The plugin streams the GeoTIFF directly from NASA and adds it to the map as a grayscale image. Zoom in and watch the progress bar at the bottom of QGIS load higher-resolution tiles on the fly.

For an RGB composite, choose RGB Composite and pick three bands:

Click Display Granule. The plugin writes a virtual raster (.vrt) in the temporary directory and adds it to the map. Double-click the layer in the Layers panel and look at the source: it ends in .vrt, and inside that file are three HTTPS URLs, one per band. GDAL is mosaicking those URLs on the fly, which is why you never have to download the full scene.

Calculate NDVI on HLS

The same panel exposes analysis-ready indices:

  1. Switch to the Indices section.

  2. Pick NDVI.

  3. Set the near-infrared band to B5 and the red band to B4 (for HLSL30).

  4. Click Create Index VRT.

The plugin builds another virtual raster, this time computing the index on the fly from the streaming bands. To save a permanent copy, right-click the NDVI layer in the Layers panel and pick Export > Save As, then choose a destination GeoTIFF.

Export Granule Footprints

If you want to share or reproduce a search, the Export menu writes the results table to CSV, GeoJSON, or STAC. The Export Bundle option packs both the search criteria and the results into a single file that anyone can reload to reproduce the exact query.

Build Monthly Time Series with the GEE Data Catalogs Plugin

The NASA Earthdata plugin is ideal for individual granules. When you want a year of cloud-free monthly composites, switch to GEE Data Catalogs > Data Catalog and search for HLS. The catalog includes both the official Google Earth Engine data catalog and the awesome-gee-community-catalog, so over 5,000 datasets are available. Click the Favorite star to bookmark HLSL30 and HLSS30 so you can jump to them from the Favorites tab next time.

Select HLSL30 and click the Time Series tab at the bottom (not Config). Then:

  1. Set Start Date to 2025-01-01 and End Date to 2026-01-01. The end date is exclusive, so this gives you all of 2025.

  2. Check Apply Cloud Filter and set Max Cloud Cover to 20 percent.

  3. Click the bounding box tool and draw a rectangle over your area of interest.

  4. Set Frequency to month. (day and week are also available; day returns one composite per acquisition day, so days without imagery are skipped.)

  5. Set Reducer to median. The median reducer is the simplest way to get a cloud-free composite from the available scenes.

  6. Set the visualization to bands B5, B4, B3 with min 0 and max 0.3 for a false color composite.

  7. Click Preview Info to see how many input scenes meet your criteria. Expect a few dozen scenes for a year over the Bay Area with a 20 percent cloud-cover threshold.

  8. Click Create Time Series.

The plugin builds twelve monthly composites and exposes them through a slider at the top of the map. Drag the slider to step through the year, or use the arrow buttons to move one month at a time. Each frame is computed on demand from Earth Engine, so expect a brief delay when you jump to a new month.

Single-Date HLS Composites in GEE

When you only need a composite for one date range, use the Config tab instead of Time Series. Set a start and end date, draw a bounding box, set the cloud-cover threshold, pick a reducer (median is again a good default), and click Load Dataset.

Two extras on the Config tab are worth knowing about:

Extract Pixel Values for Points or Polygons

The Extract Pixel Values tab lets you sample a time series at any set of points or polygons. The easiest way to create sample sites is a scratch layer.

  1. Go to Layer > Create Layer > New Temporary Scratch Layer.

  2. Set Geometry Type to Point.

  3. Add at least one attribute field (for example, id as an integer). The extraction tool fails on a layer with no fields, so do not skip this step.

  4. Click OK. The scratch layer appears in the Layers panel.

  5. Toggle editing on the layer, click Add Point Feature, and drop a few points on the map: one on vegetation, one on water, one on a built-up area.

  6. Save your edits and toggle editing off.

Back in the GEE plugin’s Extract Pixel Values tab, click the refresh button next to the vector layer dropdown and pick your scratch layer. Set the Scale to 30, the Reducer to median (or mean or first), and optionally restrict the extraction to specific bands by entering a comma-separated list such as B2, B3, B4, B5. Click Extract and choose an output GeoJSON path.

The result is a GeoJSON in which each input point is duplicated once per time step. The attribute table includes the original geometry, a date column, and per-band columns named after the reducer, such as B5_median, B4_median, and so on. Twelve monthly composites with four points gives forty-eight rows, ready to load into any analysis tool. Polygons work the same way: the reducer aggregates all pixels inside the polygon.

Plot Spectral Signatures with the Pixel Inspector

If you only need to eyeball the spectral signature at a location, the Pixel Inspector is faster. Open it, click anywhere on the map, and a small plot appears showing reflectance per band at that pixel. You can restrict the plotted bands to B2, B3, B4, B5 to focus on the visible and near-infrared range. Comparing a vegetation pixel with a water pixel makes the difference in spectral shape obvious without saving any samples to disk. Click Clear Markers when you are finished.

Export a Year of HLS Composites

When you want the monthly composites as local files for offline analysis, open the Export Time Series tab.

  1. Pick an output folder.

  2. Set Scale to 90 if you want to download a coarser, faster version of the data. Leave it at 30 for native HLS resolution.

  3. Choose whether to export only the visualization bands or all bands. For this example, exporting B5, B4, B3 keeps the downloads small.

  4. Click Export All Images.

Each month is exported to a separate GeoTIFF in your chosen folder. Months with no qualifying imagery are skipped, and the export log reports how many of the twelve months succeeded. Drop the resulting files back into QGIS to confirm everything looks right.

Drive the Workflow with OpenGeoAgent

Everything above is reachable through the GUI, but OpenGeoAgent lets you do the same things with plain English or your voice. Open the OpenGeoAgent panel, open Settings, and on the Models tab pick the OpenAI Codex provider (a flat-rate ChatGPT subscription is the simplest option). Enable auto-approval for the GEE Data Catalogs plugin so the agent can add layers without confirmation prompts.

Press Ctrl+Alt+Space to start voice dictation, speak your prompt, press Ctrl+Alt+Space again to stop, and Ctrl+Enter to submit:

HLS imagery over San Francisco for summer 2025.

The agent picks the right collection, converts “summer 2025” into a date range, draws a sensible bounding box, and loads the composite onto the map. Follow up with:

Use a false color composite.

The agent swaps the band combination to B5, B4, B3 without you opening any dialog. Then:

Calculate NDVI.

The agent writes the index on the fly. And then:

Extract vegetation using an NDVI threshold of 0.2.

The agent generates PyQGIS or Earth Engine code to threshold the NDVI raster and adds the resulting vegetation layer. You can open the leafmap plugin and use its swipe widget to compare the false color composite against the NDVI or the vegetation mask side by side.

For a deeper agent walkthrough, see the companion post Search and Visualize NASA Earth Data in QGIS with OpenGeoAgent.

Create a Landsat Timelapse with One Sentence

Switch OpenGeoAgent to time-series mode and try:

Create a Landsat timelapse of Las Vegas from 1986 to the present.

The agent infers the bounding box for Las Vegas, sets the date range, calls the Timelapse plugin under the hood, and produces an animated GIF after a minute or two of processing. Click the resulting image in the chat to open the full view, then use the Save button to write the GIF to disk. The agent can also copy the underlying Python script if you want to reproduce or tweak the call later.

For more time-lapse examples, see Create Satellite Timelapse Animations in QGIS with OpenGeoAgent.

Resources

Try this on a place you care about: a hometown, a farm field, a wildfire scar, or a recent flood event. The combination of streaming Cloud Optimized GeoTIFFs from NASA, monthly cloud-free composites from Earth Engine, and an AI agent that turns sentences into maps makes it trivial to go from a question in plain English to a quantitative answer about the land surface. If you run into issues or have feature requests, please open an issue on the NASA Earthdata plugin, GEE Data Catalogs plugin, or OpenGeoAgent repositories, and subscribe on YouTube or follow the RSS feed to catch the next post when it lands.