Skip to content

PATTERNS

local overlay operations

These methods compare values at corresponding pixels in two or more rasters.

local-overlay-operations


masks

Masks act like masking tape when you paint. When you mask pixels in a raster before displaying the raster as a map layer, all the pixels with the mask will remain transparent (they will not be displayed with a color). Similarly, when you mask pixels of an input raster in an operation, the masked pixels will be excluded from the computation.

Typically, workflows with masks involve three steps.

graph LR
  step01("Make mask")
  step02("Apply mask") ;
  step03("Paint (display as layer)") ;
  step04("Transform (input in operation)") ;


  step01 --> step02
  step02 --> step03
  step02 --> step04


  classDef steps fill:#C9C3E6,stroke-width:1px,stroke: #00000000, color:#000000; 



  class step01 steps; 
  class step02 steps;
  class step03 steps;
  class step04 steps; 

mask pixels

This pattern uses another raster, typically a Boolean raster as a mask on another raster.

Any pixel with the value 0 in the mask acts like masking tape and prevents numbers in the output raster from being painted at that location. Masked values will not be displayed with colors when you place the raster layer on a Map. Masked values in an input raster will also be ignored in any subsequent operation.

mask


graph LR
  input[image]
  method(".updateMask()") ;
  output[/"image_with_mask"/]  ;
  arg01["mask<br>boolean_raster"] ;

  input --> method
  method --> output
  arg01 --o method


  classDef in-out fill:#FFFFFF,stroke-width:1px,stroke: #000000, color:#000000; 
  classDef op fill:#000000,stroke-width:0px,color:#FFFFFF;
  classDef arg fill:#CCCCCC,stroke-width:0px,color:#000000;


  class input in-out; 
  class method op;
  class output in-out;
  class arg01 arg; 


var image_with_mask = image.updateMask(boolean_image);

self mask pixels

If you want to ignore pixels that store the value 0 in an raster, you can self-mask. This is not technically a local operation because it only involves one raster, but I wanted to keep the mask operations together.

self mask


graph LR
  input[image]
  method(".selfMask()") ;
  output[/"image_with_mask"/]  ;

  input --> method
  method --> output


  classDef in-out fill:#FFFFFF,stroke-width:1px,stroke: #000000, color:#000000; 
  classDef op fill:#000000,stroke-width:0px,color:#FFFFFF;
  classDef arg fill:#CCCCCC,stroke-width:0px,color:#000000;


  class input in-out; 
  class method op;
  class output in-out;


var image_with_mask = image.selfMask();

unmask

If you are working with a masked image, you can remove the mask and populate all the masked locations with a constant. Again, this is not technically a local operation because it only involves one raster, but I wanted to keep the mask operations together.

self mask



graph LR
  input["image_with_mask"]
  method(".unmask()") ;
  output[/"image_without_mask"/]  ;
  arg["constant"]

  input --> method
  method --> output
  arg --o method  

  classDef in-out fill:#FFFFFF,stroke-width:1px,stroke: #000000, color:#000000; 
  classDef op fill:#000000,stroke-width:0px,color:#FFFFFF;
  classDef arg fill:#CCCCCC,stroke-width:0px,color:#000000;

  class input in-out; 
  class method op;
  class output in-out;
  class arg arg


var image_without_mask = image_with_mask.unmask();

In Earth Engine, unmask() will replace masked values with 0 by default (This makes the method the inverse of selfMask(). You can include an argument (a number in the parantheses) to specify a different constant.


logical comparisons

The diagram below illustrates three common logical comparisons between two regions: A, B. Going from left to right, the first picture shows the two regions. The second picture shows where either region A or region B are present (or true), called the union of the two. The third picture shows where both region A and region B are present, called the intersection of the two. The fourth and final picture shows where region A is present but not region B. In this last case, region B acts like an eraser or knife that cuts out the portion of region A that it touches. Sometimes this last case is called the difference or subtraction of two sets.

Logical comparisons


The patterns below describe how each logical comparison shown above can be implemented with raster data models.


union

The .or() method takes two rasters as inputs and kicks out a boolean raster that represents their union: pixels in the output raster are true if they are true (not 0) in either raster A or raster B.

OR union


The inputs are commonly boolean rasters, as illustrated in the above diagram, but the method will work with nominal (class) data, returning a boolean raster.

OR union nominal case


The order of the inputs (which raster is image_A versus image_B) does not really matter. The main thing to remember here is that any masked pixels will be excluded from this operation. So it is good practice to triple-check your inputs to see if you are using a mask on pixels that should be zeros so that you do not inadvertently erase locations that are true in one layer but masked in another.

var image_union = image_A.or(image_B);

intersection

The and() method takes two rasters as inputs and kicks out a boolean raster that represents their intersection: pixels in the output raster are true (not 0) if they are true (not zero) in both raster A and raster B.

AND intersection


Like the or operation, the inputs are commonly boolean rasters, but the method will work with nominal (class) data, returning a boolean raster as shown below.

AND nominal case


The order of inputs again does not really matter here. And because this operation is like a knife that cuts and alters the shapes of inputs, this method is less sensitive to masks, unlike the or() method.

var image_intersection = image_A.and(image_B);

not

In Earth Engine, finding locations that are in raster A but not in raster B is a little tricky. The workflow involves inverting the binary of raster_B and then multiplying it against raster_A.

NOT


var image_A_not_B = image_A.multiply(image_B_inverted_binary);

map arithmetic

As the diagram at the top of this page illustrates, a common type of local overlay operation performs arithmetic operations (addition, subtraction, multiplication, and division) with two rasters.


addition

The .add() method performs addition between values in corresponding pixels of two rasters. The order (which raster is A versus B) does not matter. The main thing to remember is that any pixel that is masked will be excluded from the operation (so that output pixel will remain masked).

local-overlay-operations


var image_A_add_B = image_A.add(image_B);

subtraction

The .subtract() method performs subtraction between values in corresponding pixels of two rasters. The order matters here: you subtract image_B from image_A. Masked pixels in either raster will remain masked in the output.

local-overlay-operations

var image_A_subtract_B = image_A.subtract(image_B);

multiplication

The .multiply() method performs multiplication between values in corresponding pixels of two rasters. The order does not matter here. Masked pixels do matter and will remain masked.

Multiplication is often used with a boolean raster as a method to erase values in another image, because 0 will convert to 0 and 1 will retain the original value.

local-overlay-operations

var image_A_subtract_B = image_A.multiply(image_B);

division

The .divide() method performs division between values in corresponding pixels of the two rasters. The order does matter here because you divide the values in image_A by the values in image_B. Masked pixels in either image again remain masked in the output.

local-overlay-operations

var image_A_divide_B = image_A.divide(image_B);

This work is licensed under CC BY-NC-SA 4.0