Find Total Area of Cells With Data

4833
5
Jump to solution
03-31-2015 02:26 AM
DavidMartin
Occasional Contributor II

Is there a simple way to find the total area of a raster EXCLUDING NoData cells?

 

I can load my raster into a Mosaic Dataset, run the Build Footprints tool, and get a footprint that cuts out NoData around the margins, but this will not handle any NoData areas that are within a data-filled area.

 

Counting cells is no good if the raster covers a large latitudinal range (as cells are likely to have different areas across latitudes).

 

So I guess that leaves either Spatial Analyst or a mixture of RasterToNumPyArray / NumPyArrayToRaster (converting all cells with values to a single value), followed by the Raster To Polygon tool.

 

Somehow it seems like I'm missing something though - as the task "feels" like it should have a simpler solution!

 

Any ideas?

1 Solution

Accepted Solutions
EricRice
Esri Regular Contributor

Zonal Geometry as Table, then Sum the area field in the output is probably the fastest method unless you really like Python.  If you don't want to Sum the output table records, you can multiply your input raster by 0 so your input is either 0 or NoData - in which case the output table will be 1 record showing you area for all zeros.

Best,

Eric

View solution in original post

0 Kudos
5 Replies
ChrisDonohue__GISP
MVP Alum

Just a thought - based on your comments it sounds like the data currently is in a Geographic Coordinate System (GCS).  Using a Projected Coordinate System instead of GCS would allow you to derive an accurate area.

Chris Donohue, GISP

0 Kudos
DavidMartin
Occasional Contributor II

Chris,

That's a very good point. I guess simply choosing an Equal Area Projection for the raster should mean that all cells are the same area, so the proportion of those with data to those without should allow me to define the area. Which I guess then just leaves the question of what the simplest way would be to determine the number of cells that contain data (or NoData)?

0 Kudos
XanderBakker
Esri Esteemed Contributor

You could use some python code:

import arcpy

# reference your raster
ras = r"path to raster data"
raster = arcpy.Raster(ras)

# determine number of pixels
cnt_pix = raster.height * raster.width

# determine if raster has no data values
if int(arcpy.GetRasterProperties_management(ras, "ANYNODATA").getOutput(0)) == 1:

    # determine if raster has all data values
    if int(arcpy.GetRasterProperties_management(ras, "ALLNODATA").getOutput(0)) == 1:
        print "All cells of raster are NoData"
        print "Data pixels  : {0} ({1}%)".format(0, 0.0)
        print "Nodata pixels: {0} ({1}%)".format(cnt_pix, 100.0)

    else:
        # handle integer different from float
        if raster.isInteger and raster.hasRAT:
            print "Integer raster with RAT"
            lst_cnt = [r.COUNT for r in arcpy.SearchCursor(raster)]
            cnt_data = sum(lst_cnt)
            cnt_nodata = cnt_pix - cnt_data

        else:
            # raster is float or has no RAT, determine nodata pixels
            print "Floating raster"
            arcpy.CheckOutExtension("Spatial")
            ras_isn = arcpy.sa.IsNull(raster)
            arcpy.CheckInExtension("Spatial")

            where = "VALUE = 1"
            lst_cnt = [r.COUNT for r in arcpy.SearchCursor(ras_isn, where_clause=where)]
            cnt_nodata = sum(lst_cnt)
            cnt_data = cnt_pix - cnt_nodata

        # now determine percentages
        print "Data pixels  : {0} ({1}%)".format(cnt_data, round(float(cnt_data) * 100.0 / float(cnt_pix),2))
        print "Nodata pixels: {0} ({1}%)".format(cnt_nodata, round(float(cnt_nodata) * 100.0 / float(cnt_pix),2))

else:
    print "Raster without NoData"
    print "Data pixels  : {0} ({1}%)".format(cnt_pix, 100.0)
    print "Nodata pixels: {0} ({1}%)".format(0, 0.0)
DavidMartin
Occasional Contributor II

That's a very comprehensive answer - thanks!

0 Kudos
EricRice
Esri Regular Contributor

Zonal Geometry as Table, then Sum the area field in the output is probably the fastest method unless you really like Python.  If you don't want to Sum the output table records, you can multiply your input raster by 0 so your input is either 0 or NoData - in which case the output table will be 1 record showing you area for all zeros.

Best,

Eric

0 Kudos