[GRASS-user] computing percent cover (Adam Smith)

Adam Smith Adam.Smith at mobot.org
Thu Jun 6 13:34:44 PDT 2024


Hi Janet,

I believe you could do this using the `clump()` and `zonalGeog()` functions in the fasterRaster package for R, which calls GRASS (https://github.com/adamlilith/fasterRaster).

It's not clear from your description if the "patch" raster is the reclassed NLCD raster or another raster, but I'll assume it is.  So the "patch" raster has groups of cells that had had same ID but are composed of cells that, before reclassing, may have had a different class.

I would:

# Setup fasterRaster
devtools::install_github(' https://github.com/adamlilith/fasterRaster', dependencies = TRUE)
library(fasterRaster)

faster('C:/Program Files/GRASS GIS 8.3') # install path for GRASS on your system... should be the stand-alone version, not OSGeo

# Use fast() to create the rasters:

nlcd <- fast('C:/folder/nlcd_raster.tif')
nlcd_reclass <- fast('C:/folder/nlcd_reclassed_raster.tif')

names(nlcd) <- 'nlcd'
names(nlcd_reclass) <- 'nlcd_reclass'

# Use clump() to assign unique IDs to each reclassed clump cells. Clumps are sets of adjacent cells with the same value (assuming argument minDiff = 0):

clumps <- clump(nlcd_reclass, minDiff = 0)

# Get unique clump IDs
clump_ids <- freq(clumps)
clump_ids <- clump_ids$value

# for saving results
results <- data.frame(clump_ids = clump_ids)

# Loop over each vegetation type of interest in the NLCD
# Assumes you have a vector veg_ids with integers indicating the veg types of interest
for (veg_id in veg_ids) {

   # create mask for just this vegetation type
   fun <- paste0('= if(nlcd == ', veg_id, ', 1, null())`
   veg_mask <- app(nlcd, fun = fun)

   # raster of clumps but only with cells in clumps overlapping this veg type
   veg_by_clump <- veg_mask * clumps
   names(veg_by_clump) <- 'veg_by_clump'

   # calculate area of cells in each masked clump
   stats <- zonalGeog(veg_by_clump)
   stats <- stats$veg_by_clump # output is a list of data frames, so just get the df

   # remember the value of "area" for each relevant patch
   # I'm hazy on this part, as I always have to try match() to see how it works, but you can figure it out.
   areas <- stats$area[match(stats$value, results$clump_ids)]
   results$NEW <- areas # add to results
   names(results)[ncol(results)] <- paste0('veg_id_', veg_id) # rename column

}

To get % of each patch with each veg type, simply sum across the "area" rows and divide each value by that sum.

I think you could do something similar with a) patches() to assign cell numbers to patches, b) cycle over unique patch IDs and mask out anything that does not have that ID, then c) count the number of cells in the veg-type-by-clump raster using global(..., fun = 'sum', na.rm = TRUE). If you have a lot of patches x veg-type combinations, it could take a while, though.

Adam

Center for Conservation & Sustainable Development
Missouri Botanical Garden
4344 Shaw Boulevard
Saint Louis, MO 63110 USA
+01 314-577-9473 ext. 76314
www.earthSkySea.org



-----Original Message-----
From: grass-user <grass-user-bounces at lists.osgeo.org> On Behalf Of grass-user-request at lists.osgeo.org
Sent: Thursday, June 6, 2024 2:00 PM
To: grass-user at lists.osgeo.org
Subject: grass-user Digest, Vol 218, Issue 8

Send grass-user mailing list submissions to
	grass-user at lists.osgeo.org

To subscribe or unsubscribe via the World Wide Web, visit
	https://lists.osgeo.org/mailman/listinfo/grass-user
or, via email, send a message with subject or body 'help' to
	grass-user-request at lists.osgeo.org

You can reach the person managing the list at
	grass-user-owner at lists.osgeo.org

When replying, please edit your Subject line so it is more specific than "Re: Contents of grass-user digest..."


Today's Topics:

   1. computing percent cover (Janet Choate)
   2. Re: computing percent cover (Anna Petr??ov?)
   3. Re: computing percent cover (Micha Silver)


----------------------------------------------------------------------

Message: 1
Date: Wed, 5 Jun 2024 17:09:45 -0700
From: Janet Choate <jsc.eco at gmail.com>
To: grass list <grass-user at lists.osgeo.org>
Subject: [GRASS-user] computing percent cover
Message-ID:
	<CAEqw1VzTdprBBQoO=ywbJog910j2mvkO75npu4yAFRifn2DToA at mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

Hi GRASS community,
I downloaded land cover data from NLCD and reclassed values into 6 categories to generate a vegetation/landcover type raster (tree, shrub, grass, non-veg, water, developed) that is composed of IDs (i.e. 11=tree, 5-shrub, etc...) I also have a 90 meter patch raster.
Any given 90 meter patch may have more than one vegetation type ID occurring in it.
I would like to generate percent coverage maps to find the percent that each vegetation type occupies of each patch (i.e. patch 1 is composed of 60% tree, 30% shrub, 10%grass).
Is it possible to compute percent cover from a vegetation type ID map?
Any advice would be much appreciated, I have unsuccessfully tried to do this in GRASS as well as R.
thank you,
Janet

--
Tague Team Lab Manager
1005 Bren Hall
UCSB, Santa Barbara, CA.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/grass-user/attachments/20240605/9011d229/attachment-0001.htm>

------------------------------

Message: 2
Date: Wed, 5 Jun 2024 23:24:39 -0400
From: Anna Petr??ov? <kratochanna at gmail.com>
To: Janet Choate <jsc.eco at gmail.com>
Cc: grass list <grass-user at lists.osgeo.org>
Subject: Re: [GRASS-user] computing percent cover
Message-ID:
	<CAE0EDEqJnbJ+7TrF8kwLdOJgQKuGrrpTh0FCK352Rn8R86o1Lw at mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

Hi Janet,

you could run r.report:
r.report map=patches,landcover

But the output is not easily parseable. r.report internally runs r.stats:

r.stats -a  input=patches,landcover separator=comma

you get output like (patch id, landcover id, area):
2,1,1205379.000000
1,5,938148.750000
3,1,904034.250000
2,3,557203.500000
1,1,512529.750000
1,4,361451.250000

so you need to postprocess it then.



On Wed, Jun 5, 2024 at 8:10?PM Janet Choate via grass-user < grass-user at lists.osgeo.org> wrote:

> Hi GRASS community,
> I downloaded land cover data from NLCD and reclassed values into 6 
> categories to generate a vegetation/landcover type raster (tree, 
> shrub, grass, non-veg, water, developed) that is composed of IDs (i.e. 
> 11=tree, 5-shrub, etc...) I also have a 90 meter patch raster.
> Any given 90 meter patch may have more than one vegetation type ID 
> occurring in it.
> I would like to generate percent coverage maps to find the percent 
> that each vegetation type occupies of each patch (i.e. patch 1 is 
> composed of 60% tree, 30% shrub, 10%grass).
> Is it possible to compute percent cover from a vegetation type ID map?
> Any advice would be much appreciated, I have unsuccessfully tried to 
> do this in GRASS as well as R.
> thank you,
> Janet
>
> --
> Tague Team Lab Manager
> 1005 Bren Hall
> UCSB, Santa Barbara, CA.
> _______________________________________________
> grass-user mailing list
> grass-user at lists.osgeo.org
> https://lists.osgeo.org/mailman/listinfo/grass-user
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/grass-user/attachments/20240605/edef6674/attachment-0001.htm>

------------------------------

Message: 3
Date: Thu, 6 Jun 2024 17:55:42 +0300
From: Micha Silver <tsvibar at gmail.com>
To: Janet Choate <jsc.eco at gmail.com>, grass list
	<grass-user at lists.osgeo.org>
Subject: Re: [GRASS-user] computing percent cover
Message-ID: <83520995-0be6-4875-87be-d5676db5bb8b at gmail.com>
Content-Type: text/plain; charset="us-ascii"

An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/grass-user/attachments/20240606/69b6193b/attachment-0001.htm>

------------------------------

Subject: Digest Footer

_______________________________________________
grass-user mailing list
grass-user at lists.osgeo.org
https://lists.osgeo.org/mailman/listinfo/grass-user


------------------------------

End of grass-user Digest, Vol 218, Issue 8
******************************************


More information about the grass-user mailing list