Skip to main content

Processing satellite imagery

Prerequisite

Familiarity with front-end development concepts. Some advanced JavaScript required.

In this tutorial, you will compare historical and present-day scenes of Dubai in the United Arab Emirates that show the landscape before and after Dubai's period of economic growth in the early 2000s.

To do this, you will download satellite imagery, use command line tools to process it, and use Mapbox GL JS with the Mapbox GL Compare plugin to create an interactive map with a 'swipe to compare' control.

You will use imagery from the USGS Landsat program to create georeferenced composite images that prioritize the natural look of land and water.

Landsat imagery is particularly appropriate for this use case because the program has been continually acquiring images of the Earth's surface for nearly 50 years, at a high enough spatial resolution to capture significant changes at the landscape scale.

Finding other Landsat scenes
This tutorial uses Landsat scenes covering Dubai, but you may also try out the process using other locations. A free NASA Earthdata account will let you use EarthExplorer, where the data for this tutorial comes from, and where you can get other Landsat scenes.

Getting started

If you are new to working with satellite imagery, or are unfamiliar with bands or the raster data type, read the How satellite imagery works guide before getting started.

There are a few tools you will need to complete this tutorial:

  • GDAL GDAL is a low-level GIS toolkit that Rasterio depends on. Install GDAL using the method recommended for your operating system.
  • Rasterio Rasterio is a tool for reading and writing geospatial raster data. You can install Rasterio on the command line with the command pip install rasterio.
  • rio-color rio-color is a Rasterio plugin for applying basic color-oriented image operations to geospatial rasters. You can install rio-color by following these instructions.
  • Your Mapbox access token You can find your access token on your Mapbox Account page.
  • A text editor. Use the text editor of your choice for writing HTML, CSS, and JavaScript.
  • Mapbox GL Compare A freely available Mapbox GL JS plugin that adds an interactive 'swipe to compare' control to a Mapbox GL JS web map.
  • Landsat scenes Download these two scenes from two different satellites in the Landsat series:
arrow-downDownload Landsat 5 scene (2001) arrow-downDownload Landsat 8 scene (2018)
  • Command line. You will also need to use your computer's command line to complete this tutorial.

Understanding Landsat scenes

Landsat image data is cut into scenes, which are roughly square images, for distribution. You can think of a scene as a single frame from a camera. A Landsat scene covers about 170 × 185 kilometers (105 × 115 miles).

The two scenes in this tutorial come from two different satellites in the Landsat series:

  • The before image is from Landsat 5, which was decommissioned in 2013.
  • The after image is from Landsat 8, the latest satellite.

Some features change between these satellites, but in general the Landsat program maintains as much consistency as possible, which makes this kind of comparison possible.

Landsat's imaging process
For a more detailed understanding of Landsat's imaging process, see the Landsat Data Continuity Mission documentation.

Examine the bundle contents

  1. Create a new folder for your project files, and move the two Landsat files you downloaded in Getting started into the folder.

  2. The Landsat Level 1 products that you downloaded are compressed .tar.gz files called bundles. Unpack both bundles. The method you use to unpack them will vary depending your computer's operating system, or your web browser may unzip or fully unpack them automatically. As long as the unpacked bundles are directories in your project folder, you will be able to follow the processing instructions exactly.

Each bundle will unpack into a directory that contains 14 items, mostly TIFF images. Each item's name starts with the Landsat product ID and ends with the band number. For example, LT05_L1TP_160043_20011208_20180930_01_T1_B1.TIF is the Band 1 readout for the Landsat 5 LT05_L1TP_160043_20011208_20180930_01_T1 scene.

Open LT05_L1TP_160043_20011208_20180930_01_T1_B1.TIF to see what Band 1 for the Landsat 5 scene looks like.

Process Landsat 5 imagery

Now that you have the images you want, you will process them so that you can use them in a live map. In this section, you will work entirely from the command line, starting with the Landsat 5 bundle you downloaded earlier.

In the following steps, you will composite the bands into a single image, reproject these bands into the Web Mercator (EPSG:3857) projection, then color-correct the image.

Composite the bands

The aim of this tutorial is to make a visible image, and the natural choice would be to use the red, green, and blue bands to make a red, green, blue image. But Landsat 5 doesn’t have a blue band, so instead you will make a slightly false-color image with green for blue, red for green, and near-infrared for red. This wouldn’t work for scientific analysis, but it’s fine for visualization purposes.

The numbers of the Landsat 5 bands you’ll use, which will map respectively to red, green, and blue, are 3, 2, and 1.

To stack those bands into an RGB image, you will use the Rasterio command rio stack to composite the TIFF files for Bands 1-3 and export them as a new file.

  1. In your command line, navigate to the folder you created for the two Landsat scenes you downloaded.

  2. Copy the following command and paste it into your command line:

The --rgb option tells viewing software (for example Photoshop) that the bands should be interpreted as red, green, and blue.

The last argument in this command is the new output file (landsat5_stack.tif). The LT05_L1TP_160043_20011208_20180930_01_T1_B{3,2,1}.TIF argument specifies the files that get combined. This command uses a shell expansion to specify bands 3, 2, and 1 instead of separately naming each band file.

After the command runs, check your project folder. You will see the new landsat5_stack.tif file. Open this file to see what the new composite image looks like.

Reproject the image

Next, you will reproject the composite image into the Web Mercator (EPSG:3857) projection with rio warp. You will tell rio warp to reproject with bilinear sampling, a method that does not leave pixelation.

  1. Copy the following command and paste it into your command line:

The --dst-crs EPSG:3857 option sets the projection to Web Mercator. The last argument in this command is the new output file (landsat5_mercator.tif).

After the command runs, open the new file with the reprojected image, landsat5_mercator.tif. It will look like the image in landsat5_stack.tif because the original projection is fairly close to Web Mercator.

Color-correct the image

Next, you will change the color, saturation, and contrast of the image using rio color, a color-correction plugin for Rasterio. It is important to note that rio color will create a useful visualization, but not one that is suitable for analysis like land cover classification or change detection. For such analyses, you would need a separate workflow that included top-of-atmospheric calibration and atmospheric correction.

  1. Copy the following command and paste it into your command line:

This command applies a gamma of 1.7 to the green band and a gamma of 1.4 to the red band, as well as sigmoidal contrast to all bands. The effect provides a visual "punch up" for easier image interpretation. (If you’re curious, you can change the numbers (and operations) in the rio color command to see if you can make the image clearer or more attractive.)

Open the newly created landsat5_color.tif file. You have successfully processed the Landsat 5 image.

Process Landsat 8 imagery

Next, you will process the Landsat 8 image.

The processing steps are much the same as the ones that you performed for the Landsat 5 image, with one important addition. Landsat 8 data is collected by a sensor that has a higher radiometric resolution than the sensor on Landsat 5. This means that Landsat 8 data comes in a 16 bit format, while Landsat 5 comes as 8 bit. Because Mapbox only accepts 8 bit resolution images, you need to convert your 16 bit Landsat 8 bands into 8 bit.

  1. Run the following commands in the command line:

Composite the bands:

Reproject the image:

Next, you will use rio color to convert the image to 8 bit format. You will also color-correct the image in the same step.

  1. Copy and paste the following command into the command line:

Open the newly created landsat8_color.tif file. You have successfully processed the Landsat 8 image.

Build a map using Mapbox GL JS

Now that your images are processed and ready to upload, you will upload them to your Mapbox account as tilesets so you can use them in your project.

Upload to Mapbox Studio

The following steps show how to upload your GeoTIFFs to Mapbox using your Mapbox Tilesets page. You can also upload using the Mapbox Uploads API if you prefer.

  1. Navigate to the Tilesets page.
  2. Click the New tileset button.
  3. A new window will open. Select the final Landsat 5 file (landsat5_color.tif), then click Confirm. The page will let you know when the file has been uploaded successfully.
  4. Repeat these steps with the final Landsat 8 file (landsat8_color.tif).

Your uploaded tilesets are listed on your Tilesets page. Each tileset has its own tileset ID, which you can find by clicking the Menu option to the right of the listed tileset. The tileset ID allows you to reference a tileset when you use developer tools, such as Mapbox GL JS or the Mapbox iOS or Android SDKs.

Compare tilesets with Mapbox GL JS

Next, you will use the tileset IDs from your Landsat 5 and Landsat 8 tilesets to build a map with Mapbox GL JS. This project uses the Mapbox GL Compare plugin to compare the Landsat 5 and Landsat 8 images.

  1. Open your text editor and create a new file named index.html.
  2. Copy and paste the code block from the bottom of this page into your text editor to initialize a Mapbox GL JS map.
  3. Replace the BEFORE_STYLE placeholder with the tileset ID of your Landsat 5 tileset, which you can find on the Tilesets page by clicking the Menu option to the right of the tileset.
  4. Replace the AFTER_STYLE placeholder with the tileset ID of your Landsat 8 tileset, which you can also find on the Tilesets page.

Open the file in your browser. You will see your initialized Mapbox GL JS map displayed in the browser window. Drag the slider left and right to compare the difference in Dubai's landscape.

Finished product

Congratulations! You sourced original satellite imagery, processed it for the best visual impact, and created a display to visualize landscape change over time. You also learned how to use command-line analysis tools to process any kind of raster imagery you might want to use with Mapbox.

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Demo: Processing satellite imagery</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v3.1.0/mapbox-gl.js"></script>
<link
href="https://api.tiles.mapbox.com/mapbox-gl-js/v3.1.0/mapbox-gl.css"
rel="stylesheet"
/>
<style>
body {
margin: 0;
padding: 0;
}

#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
</head>
<body>
<style>
body {
overflow: hidden;
}

body * {
-webkit-touch-callout: none;
user-select: none;
}

.map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
<script src="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-compare/v0.4.0/mapbox-gl-compare.js"></script>
<link
rel="stylesheet"
href="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-compare/v0.4.0/mapbox-gl-compare.css"
type="text/css"
/>
<div id="comparison-container">
<div id="before" class="map"></div>
<div id="after" class="map"></div>
</div>
<script>
mapboxgl.accessToken = '<your access token here>';

const beforeTileset = 'examples.8o2p7j57';
const afterTileset = 'examples.6y2ya602';

const beforeMap = new mapboxgl.Map({
container: 'before',
style: {
'version': 8,
'sources': {
'raster-tiles': {
'type': 'raster',
'url': `mapbox://${beforeTileset}`,
'tileSize': 256
}
},
'layers': [
{
'id': 'simple-tiles',
'type': 'raster',
'source': 'raster-tiles',
'minzoom': 0,
'maxzoom': 22
}
]
},
center: [55.102, 25.0859],
zoom: 11
});

const afterMap = new mapboxgl.Map({
container: 'after',
style: {
'version': 8,
'sources': {
'raster-tiles': {
'type': 'raster',
'url': `mapbox://${afterTileset}`,
'tileSize': 256
}
},
'layers': [
{
'id': 'simple-tiles',
'type': 'raster',
'source': 'raster-tiles',
'minzoom': 0,
'maxzoom': 22
}
]
},
center: [55.102, 25.0859],
zoom: 11
});

// A selector or reference to HTML element
const container = '#comparison-container';

const map = new mapboxgl.Compare(beforeMap, afterMap, container, {});
</script>
</body>
</html>

Next steps

You can georeference imagery or raster data that doesn't already come with a geospatial reference system using free software like QGIS. To learn more, see the QGIS georeferencing tutorial. To explore using a georeferenced raster image in a Mapbox map, see the following examples:

Was this page helpful?