1

I'm seeing a very strange result using .pixelArea() on two different layers that should yield identical results. Code within GEE is here, also reproduced below:

var states = ee.FeatureCollection("ft:1KU0yvyS5glqa5NmHHl9j9_v-12s_b5YA90qUn9Y");

var test1 = ee.Image("users/test1");
var test2 = ee.Image("users/test2");
test1 = test1.updateMask(test1.gt(0));
test1 = test1.updateMask(test1.lt(999));

var maskedArea = ee.Image.pixelArea().mask(test1);
var maskedArea2 = ee.Image.pixelArea().mask(test2);

print(maskedArea.reduceRegion({
  reducer: ee.Reducer.sum(),
  geometry: states.filterMetadata('name','equals', 'California'), //geographic area you want summary stats for -- comment the whole line out if you want CONUS
  maxPixels: 10e13,
  scale: 30
}).get("area"));

print(maskedArea2.reduceRegion({
  reducer: ee.Reducer.sum(),
  geometry: states.filterMetadata('name','equals', 'California'), //geographic area you want summary stats for -- comment the whole line out if you want CONUS
  maxPixels: 10e13,
  scale: 30
}).get("area"));

In test1, I uploaded an asset that included cells I didn't want to consider -- hence my use of .updateMask() to remove those cells (any cells with values >0 and <999)

In test2, I uploaded the same asset, except the removal of cells with values >0 and <999 had been done in ArcGIS beforehand (using the "Con" tool). This dataset was in USA Contiguous Albers Equal Area Conic (ESRI: 102003) projection, with a cell size of 30m.

I then calculate the area and get 127,179 for test1 and 145,685 for test2, as you'll see from running the code. What I would like to see is two identical numbers. I am not sure which one of these numbers is "correct", but strongly suspect it is the latter, since it is close to the ArcGIS zonal statistics result and previous findings by others, which I trust.

You can also see from the code link to GEE above that test1 & test2, if added to the map, are completely identical, so the removals of unwanted cells in both cases appear to have worked identically.

How is it possible that these area numbers are so different? (I looked at some other places around the country using similar data snippets & the difference is sometimes not so big, often as much as a factor of 2, on average about ~1.6x bigger -- always bigger in test2, the case where I removed unwanted cells within ArcGIS before uploading the asset).

Hard to imagine simplifying the problem any further, so I'm pretty stumped. I think it has something to do with test1 cells having floating-point values and test2 cells having only 1s and 0s. But, all non-zero cells in both tests are the same, so when used as a mask on ee.Image.pixelArea(), I would think it shouldn't make a difference -- the same parts of the .pixelArea() image should get pulled out.

1 Answer 1

1

The problem in your script is that you provide floating point values in your mask.

https://code.earthengine.google.com/09affa96a7baaf93f4a2b87df3edb910

5
  • Thank you, I see ... but why is providing floating-point values in my mask a problem? Shouldn't .mask() use any floating-point values >0 in the same way as it would use integer values >0 (i.e. 1)? And indeed, if you add "maskedArea" and "maskedArea2" to the map, both have the exact same values and extent, so I don't see how running a sum reducer on each produces different results. Just want to get the right understanding, since I apparently don't get how .mask() works.
    – Evgeni
    Dec 3, 2019 at 18:30
  • 1
    Pixels between 0 and 1 indicate that a pixels is partly masked. code.earthengine.google.com/f497a832742117b77e65516320cb30ac Dec 3, 2019 at 18:40
  • 1
    To clarify more. A mask of 0.5 means that half the pixel is masked, so the area of the pixel is half of the unmasked one. Dec 3, 2019 at 18:46
  • Holy crap, OK that explains a lot of things. Is this documented anywhere?? I looked at both ee.Image.mask in the API reference and the "Compositing, Masking, & Mosaicking" tutorial page in the docs and don't see where I could've learned this. Also: in your code, why isn't the result of area(1) (3,088,985) replicated in the print-outs of area.divide(fractionMasked)? Those values all get higher and higher (3.14M, 3.17M, 3.23M). I tried it with a rectangular geography and same issue. E.g. area(0.5) should be half of area(1).
    – Evgeni
    Dec 3, 2019 at 19:03
  • I ran into these floating-point mask values when clipping images. code.earthengine.google.com/12b5c418fefea128aa6eefe51a0c0254 I didn’t know that the pixelArea() took that into account, but I suppose it makes sense. Never seen any docs about any of this, as far as I can recall. I also noticed that the numbers didn’t add up properly. My guess is that it has to do with pixel alignment somehow (moving the center of the geometry very slightly changes the values), but it’s really not obvious to me how. Dec 4, 2019 at 8:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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