Clipping rasters with GDAL using polygons

If you are a keen GDAL user, you have probably noticed by now that you can extract a rectangular portion of an image into a new image. Sometimes you want to go a little further and actually extract only the cells within a polygonal area from a shapefile or similar vector file. In this article I will show you how.

Overview

There are basically four steps to follow:

- create a shpfile containing only the features you wish to use as your clip mask
- determine the extent of your clipmask
- perform a rectangular clip on the image
- perform a polygonal clip on the image

Heres a little preview of what we will be able to produce:

Hillshade clipped to a shapefile

A quick diversion to add support for MrSid

If my previous article on mosaicking I illustrated how GDAL can can be built with ECW support. Before I get started with my clipping, I am going to add MrSid support since some of the rasters I plan to clip are in MrSid format. To do this you need to download the MrSid geo express sdk from their website (requires registration). Once you have it downloaded, unpack it into /usr/local/GeoExpressSDK and then follow the gdal build guide from my mosaicking article while adding a couple of options to the configure line:

./configure --with-libtiff=internal --with-geotiff=internal \
--with-ecw=/usr/local --with-mrsid=/usr/local/GeoExpressSDK --without-jp2mrsid
make
sudo make install

Once installed, you can check if your gdal supports MrSid by doing:

/usr/local/bin/gdalinfo --formats | grep SID

Which should result in a line like this being displayed:

  MrSID (ro): Multi-resolution Seamless Image Database (MrSID)

Create your mask shapefile

For my purposes, I want to clip data out for the Eastern Cape Province of South Africa. So I loaded a national dataset of SA Provinces in QGIS, selected the Eastern Cape province and the exported that to its own shapefile by right clicking on its legend entry and choosing the ‘Save selection as shapefile’ option. It is important that your shapefile contain only the features needed for clipping as we will be using its bounding box as part of the clip process.

Determine the extent of your clip mask

With a few lines of bash and the ogrinfo programme we can determine the bounding box of a shapefile e.g.:

#!/bin/bash
SHPFILE=$1
BASE=`basename $SHPFILE .shp`
EXTENT=`ogrinfo -so $SHPFILE $BASE | grep Extent \
| sed 's/Extent: //g' | sed 's/(//g' | sed 's/)//g' \
| sed 's/ - /, /g'`
EXTENT=`echo $EXTENT | awk -F ',' '{print $1 " " $4 " " $3 " " $2}'`
echo $EXTENT

If we run the script it produces output like this:

22.735740 -30.001800 30.194720 -34.213860

This gives you the extents in the order and format expected by gdal_translate which we need for our clip operation.

Clip the raster to the bounding box of your shapefile

To do the clip to bounding box, we can simply add a few more lines to our script:

RASTERFILE=$2
gdal_translate -projwin $EXTENT -of GTiff $RASTERFILE /tmp/`basename $RASTERFILE .sid`_bbclip.tif

Ok so that should have clipped out your raster to the bounding box of your shapefile.

Perform a polygonal clip on the image

Last on our list is to clip out just the polygonal area from the clipped-to-bounding-box version of our image. To do this we use gdalwarp e.g.:

gdalwarp -co COMPRESS=DEFLATE -co TILED=YES -of GTiff \
-r lanczos -cutline $SHPFILE \
/tmp/`basename $RASTERFILE .sid`_bbclip.tif /tmp/`basename $RASTERFILE .sid`_shpclip.tif

Tying it all together

Lets see what our final script looks like then:

#!/bin/bash
SHPFILE=$1
BASE=`basename $SHPFILE .shp`
EXTENT=`ogrinfo -so $SHPFILE $BASE | grep Extent \
| sed 's/Extent: //g' | sed 's/(//g' | sed 's/)//g' \
| sed 's/ - /, /g'`
EXTENT=`echo $EXTENT | awk -F ',' '{print $1 " " $4 " " $3 " " $2}'`
echo "Clipping to $EXTENT"
RASTERFILE=$2
gdal_translate -projwin $EXTENT -of GTiff $RASTERFILE /tmp/`basename $RASTERFILE .sid`_bbclip.tif
gdalwarp -co COMPRESS=DEFLATE -co TILED=YES -of GTiff \
-r lanczos -cutline $SHPFILE \
/tmp/`basename $RASTERFILE .sid`_bbclip.tif /tmp/`basename $RASTERFILE .sid`_shpclip.tif

Save the script and make it executable. I saved mine to mine as ~/bin/clip.sh and then made it executable using

chmod +x ~/bin/clip.sh

To invoke the script you would do something like:

~/bin/clip myshapefile.shp mybigraster.sid

Of course there are some things that can be improved in the script – for example its hard coded to assume that you are working with MrSid data. However the script should provide you with a starting point to clipping out your own raster data using arbitary polygons.

pixelstats trackingpixel

Comments

  1. makhan says:

    Hi Tim,
    I was going through your tutorial on Clipping a rater file using gdal, iam also doing some thing simillar, i have clipped a raster image using gdal_translate command and now i want to mask this clipped raster image to a polygon shape. I found your tutorial very helpful and tried to use the code what you have shown to mask a raster file,but it does nothing.

    code am trying
    gdalwarp -co COMPRESS=DEFLATE -co TILED=YES -of GTiff
    -r lanczos -cutline shapefile.shp sourcefile.tif destfile.tif
    and am trying this in osgeo4W command prompt, and the whole code is in one single line

    anykind of help would be much appriciated, please help me

    looking forward to hear from you
    Thanks Heaps
    Cheers

  2. admin says:

    Does it give you any error message? I don’t really use windows so this is something better take up on the gdal mailing list where the experts on using it in windows can help you.

    Regards

    Tim

  3. Digger says:

    Hi,
    Is this clip method based on center point of the raster cell? I’m looking for ways to clip the EXACT polygon boundary of a raster (not just pick up cells whose centers are inside the polygon.

    Thanks.

Submit a Comment

You must be logged in to post a comment.