14

Given two input layers

  1. The clip layer - an arbitrary layer (though in my case it's a float 1 band geotiff)
  2. The mask layer - a paletted raster in which every pixel is either NO DATA or a single "color" value, same for every pixel.

I want to create an output raster whose overall extent matches the extent of the mask layer and each pixel is either NO DATA if the corresponding pixel of the mask layer is NO DATA or the value of the corresponding pixel from the clip layer if the corresponding pixel of the mask layer is not NO DATA.

I know I can mask the clip layer with a polygon, but the mask layer is a raster. Polygonizing the raster layer is possible in principle, but would result in a polygon with a lot of very short edges.

Is there a direct way to do this in QGIS?

I suppose there's probably a path that involves creating a new layer and using the raster calculator, but I'm hoping there's something more direct. Further complicating the matter is that the two rasters might not have the same resolution and origin.

I believe this is equivalent to Extract by Mask in ArcMap.

4 Answers 4

16

The simple way to do this in QGIS is to use the Raster Calculator (Raster->Raster Calculator). You have a couple of options. The easiest to explain/understand is to make a unitary raster from your mask (all data set to either 1 or NoData) and then multiply your clip layer by the unitary mask layer.

To ensure the extents match the mask layer, in the raster calculator window select the mask layer in the 'Raster bands' list on the left and then click the 'Current layer extent' button on the right.

You can create a unitary mask on the fly by using a conditional statement (see the link) something like this:

(maskLayer@1 >= 0) * clipLayer@1

This statement basically says: treat everything in my mask layer that is not NoData as being equal to 1 (NoData stays as NoData). Just be sure to remember to set the extent (see above)!


Raster Calculator and paletted data:

Any output from the raster calculator will be just values and not carry over any information contained within a colour pallet. You have a couple of options to 'get your palette back':

  1. Go to the style tab of the original layer's properties and (making sure it is paletted), click on Save Style button at the bottom. You can then apply this same style to your new layer and if you have only clipped it as per the above instructions, it will appear the same as before. This is easy but your raster is not paletted in a persistent way outside of the QGIS project.
  2. To make the presentation persistent, you can right-click the layer and 'Save As'. Check the 'Rendered Image' radio button at the top of the save-dialog box. This will make a new raster with the exact colour scheme as your palatted layer BUT it will no longer be a single band raster but a four band RGBA raster.
  3. If you MUST have an actual stand-alone single-band raster with a persistent palette (and not RGBA), then I don't know of a way of doing this in QGIS but you could take the output of step 2 above and open it in GIMP (or Photoshop) and change the mode from RGB to Indexed Colour. But you will need to create a world file as saving the image in GIMP/Photoshop will destroy the georeferencing.
8
  • This is what I'm looking for. I had some problems at first when I omitted the parens around the first term, which ended up giving me nonsense. This works exactly as expected when the clip layer is a float32 layer. However, I get unexpected results when the clip layer is another paletted tif. The resulting clip is a float32 grayscale layer, which perhaps isn't surprising after a little thought. Is there a way to get a paletted layer back out again?
    – Llaves
    Feb 19, 2014 at 17:26
  • See my edits to my post. I don't think there is a way of preserving a palette from within Raster Calculatior. However, you can style the clipped output identically to your palatted original, make an analogous RGBA raster or create an actual palatted layer but the process gets successively more involved at each step on the way. Feb 19, 2014 at 17:53
  • thanks for the added info. I guess it would be too hard to enable the Raster Calculator to output a paletted image, since too often it would have no meaning. It's really the domain of a special case tool if I needed it often enough.
    – Llaves
    Feb 19, 2014 at 18:05
  • I finally looked at the clipped raster and the resolution has changed from the input layer. The input raster has pixel size (1, -1), the output raster has pixel size (3, -3), which is the raster size of the mask raster. Is there any way to coerce the output raster to match the size of the input? Is there a way to resample the mask layer on-the-fly?
    – Llaves
    Feb 20, 2014 at 15:42
  • Set the mask to the same resolution as the image or set the cell size in the raster environment settings Feb 20, 2014 at 15:51
3

I don't have enough rep to comment, but I would like to share what worked with me after spending quite some time! After following @MappaGnosis advice, I used raster calculator 4 times (because I had a 4-band image) and following the exact same process, changing the bands used in the raster calculator, ended up with 4 images whose extent were equal to the raster we wanted to clip by and (as each resulting raster has only 1 band) the value of those bands were from the raster we wanted to clip.

To sum it up, all I did was:

(maskLayer@1 >= 0) * clipLayer@1
(maskLayer@2 >= 0) * clipLayer@2
(maskLayer@3 >= 0) * clipLayer@3
(maskLayer@4 >= 0) * clipLayer@4

Then, we can build a virtual raster with those 4 files (don't forget to tick the "place each file in separate band") and voilá! Export the virtual raster and it's done.

1
0

I find the easiest way to be the following - without using the raster calculator:

To obtain mask from raster:

Vector -> Research Tools -> Extract Layer Extent

To extract by mask:

Raster -> Extraction -> Clip raster by extent
0

A way around.

Mask raster layer > Processing > Raster values to points (Saga)

Creates a shapefile with a mosaic of polygons (usually squares), one for each pixel of the mask layer.

Edit mode >> select all polygons in the shapefile >> Advanced digitizing toolbar >> Merge selected features

A single polygon is created that mimics exactly the outline of the mask raster layer. Now you can use the standard "Clip raster by mask layer" command.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.