Creating Heightmaps of Large Regions

An open question from Josh Ajima about making 3D printable models of Virginia prompted me to consider the general problem of finding a suitable elevation dataset for a large region like a state.

In this post I will explain how I made the image I posted in reply, using free tools and data.


I use QGIS, a free cross-platform GIS. I also use the GdalTools plugin. It is distributed with QGIS, but you may need to install or activate it via the Plugins > Manage and Install Plugins dialog:

Screenshot-Plugins | All (331)

An image editor like GIMP capable of manipulating and converting TIFF images is also useful.


For many of my terrain models, I use SRTM data retrieved from EarthExplorer. However, that data is published in 1° tiles that are tedious to mosaic and unnecessarily detailed for some purposes. So, rather than patch together many small images, I clip the desired area from one big image.


  1. Start a new QGIS project and click Add Raster Layer in the toolbar. Load the big elevation dataset (elev48i0100a.tif):

    Screenshot-QGIS 2.8.1-Wien

  2. Go to Project > Project Properties > CRS (Coordinate Reference System) and check Enable 'on the fly' CRS transformation. Keep the “Generated CRS” selection – it is based on the layer you just loaded.

    Screenshot-Project Properties | CRS

    Don’t sweat the sight of all the codes and numbers. This step just ensures that different layers will appear aligned even if their files use different coordinate systems.

  3. Click Add Vector Layer in the toolbar and load the boundary layer (ne_50m_admin_1_states_provinces_lakes.shp). It will appear on top of the elevation image.

    Screenshot-QGIS 2.8.1-Wien - demo

  4. Right click the boundaries layer and select Filter. Type or use the provided interface to enter a query like "name" = 'Virginia'.

    Screenshot-Query Builder

    This hides everything except the desired feature, making the layer useful as a selection tool. Right click the layer again and select Zoom to layer for a closer look.

    Screenshot-QGIS 2.8.1-Wien - demo-1

  5. Next, right click the boundary layer once more and select Save As. Select the same CRS you previously selected in Project Properties and set an output filename like virginia. The other default options should suffice.

    Screenshot-Save vector layer as...

    The result is a new layer consisting only of the selected state. Furthermore, it is saved using the same coordinate system as the elevation layer. This is important because the plugin tool we’re about to use doesn’t know about “on the fly” display translations.

  6. Everything so far has been setup. Now, open the Raster > Extraction > Clipper plugin and ensure elev48i0100a is selected as the Input file. Set an output filename like va-elev.tif, select virginia as the Mask Layer, and consider setting a No data value of -1 to help distinguish transparent areas from sea-level regions.


    The result is a new raster elevation layer cut to the state boundary:

    Screenshot-QGIS 2.8.1-Wien - demo-2

  7. Lastly, you can re-export the clipped layer at a suitable resolution and format. Right click the va-elev layer and select Save As and set a file name.

    Note the Resolution section lists the layer’s pixel resolution in real-world units (initially about 100 x 100 meters) as well as the overall dimensions in pixels (7017 x 3880). Adjust these to suit; I used 400 x 400 resolution.

    Also note the Output mode. A TIFF image is output in both cases. With Raw data, the pixel values encode real-world units (elevation in meters), appropriate for continued GIS or calibrated 3D work. The Rendered image mode scales the data to 8-bit range, losing some fidelity, but making it easier to work with in most image editors.

    Screenshot-Save raster layer as...


Related topics not (yet?) covered in this tutorial:

Posted on Tuesday, September 29th, 2015. Tags: , .