Esempio n. 1
0
def null_define(rastlist, NoData_Value):
    """
    Simple batch NoData setting function. Makes raster data more arcmap viewing friendly

    Function inputs a list of raster (usually tifs) files and sets no data values. This
    function does not actually change the raster values in any way, and simply defines which
    numerical values to be considered NoData in metadata.

    :param rastlist:        list of rasters for which to set nodata value
    :param NoData_Value:    Value to declare as NoData (usually 0 or -9999)

    :return rastlist:       returns list of modified files
    """

    rastlist = enf_rastlist(rastlist)

    # iterate through each file in the filelist and set nodata values
    for rastname in rastlist:

        arcpy.SetRasterProperties_management(rastname,
                                             data_type="#",
                                             statistics="#",
                                             stats_file="#",
                                             nodata="1 " + str(NoData_Value))

        print("Set nulls in {0}".format(rastname))
    return rastlist
Esempio n. 2
0
def clip_to_shape(rasterlist, shapefile, outdir = False):
    """
    Simple batch clipping script to clip rasters to shapefiles.

    :param rasterlist:      single file, list of files, or directory for which to clip rasters
    :param shapefile:       shapefile to which rasters will be clipped
    :param outdir:          desired output directory. If no output directory is specified, the
                            new files will simply have '_c' added as a suffix.

    :return output_filelist:    list of files created by this function.
    """

    rasterlist = enf_rastlist(rasterlist)
    output_filelist = []

    # ensure output directorycore.exists
    if outdir and not os.path.exists(outdir):
        os.makedirs(outdir)

    for raster in rasterlist:

        # create output filename with "c" suffix
        outname = core.create_outname(outdir,raster,'c')

        # perform double clip , first using clip_management (preserves no data values)
        # then using arcpy.sa module which can actually do clipping geometry unlike the management tool.
        arcpy.Clip_management(raster, "#", outname, shapefile, "ClippingGeometry")
        out = ExtractByMask(outname, shapefile)
        out.save(outname)
        output_filelist.append(outname)
        print("Clipped and saved: {0}".format(outname))

    return output_filelist
Esempio n. 3
0
def null_set_range(rastlist, high_thresh = None, low_thresh = None, NoData_Value = None):
    """
    Changes values within a certain range to NoData

     similar to raster.null_define, but can take an entire range of values to set to NoData.
     useful in filtering obviously erroneous high or low values from a raster dataset.

     inputs:
       rastlist     list of files for which to set NoData values. easily created with
                    "core.list_files" function
       high_thresh  will set all values above this to  NoData
       low_thresh   will set all values below this to NoData
    """

    # sanitize filelist input
    rastlist = enf_rastlist(rastlist)

    # iterate through each file in the filelist and set nodata values
    for rastname in rastlist:
        #load raster as numpy array and save spatial referencing.
        rast, meta = to_numpy(rastname)

        if not NoData_Value == None:
            NoData_Value = meta.NoData_Value

        if not high_thresh == None:
            rast[rast >= high_thresh] = NoData_Value
        if not low_thresh == None:
            rast[rast <= low_thresh] = NoData_Value

        from_numpy(rast, meta, rastname)
        arcpy.SetRasterProperties_management(rastname, data_type="#",statistics="#",
                    stats_file = "#", nodata = "1 " + str(NoData_Value))

    return
Esempio n. 4
0
def null_define(rastlist, NoData_Value):
    """
    Simple batch NoData setting function. Makes raster data more arcmap viewing friendly

     Function inputs a list of raster (usually tifs) files and sets no data values. This
     function does not actually change the raster values in any way, and simply defines which
     numerical values to be considered NoData in metadata.

     inputs:
       rastlist        list of files for which to set NoData values. easily created with
                       "core.list_files" function
       NoData_Value    Value to declare as NoData (usually 0 or -9999)
       Quiet           Set Quiet to 'True' if you don't want anything printed to screen.
                       Defaults to 'False' if left blank.
    """

    rastlist = enf_rastlist(rastlist)

    # iterate through each file in the filelist and set nodata values
    for rastname in rastlist:

        arcpy.SetRasterProperties_management(rastname,data_type="#",statistics="#",
                    stats_file="#",nodata="1 "+str(NoData_Value))

        print("Set nulls in {0}".format(rastname))
    return
Esempio n. 5
0
def clip_to_shape(rasterlist, shapefile, outdir = False):
    """
     Simple batch clipping script to clip rasters to shapefiles.

     Inputs:
       rasterlist      single file, list of files, or directory for which to clip rasters
       shapefile       shapefile to which rasters will be clipped
       outdir          desired output directory. If no output directory is specified, the
                       new files will simply have '_c' added as a suffix.
    """

    rasterlist = enf_rastlist(rasterlist)

    # ensure output directorycore.exists
    if outdir and not os.path.exists(outdir):
        os.makedirs(outdir)

    for raster in rasterlist:

        # create output filename with "c" suffix
        outname = core.create_outname(outdir,raster,'c')

        # perform double clip , first using clip_management (preserves no data values)
        # then using arcpy.sa module which can actually do clipping geometry unlike the management tool.
        arcpy.Clip_management(raster, "#", outname, shapefile, "ClippingGeometry")
        out = ExtractByMask(outname, shapefile)
        out.save(outname)
        print("Clipped and saved: {0}".format(outname))

    return
Esempio n. 6
0
def in_dir(dir_name, recursive=False):
    """ lists all the rasters in an input directory """

    rast_list = core.list_files(recursive, dir_name)
    rast_list = enf_rastlist(rast_list)

    print("Found {0} file with valid raster format".format(len(rast_list)))

    return rast_list
Esempio n. 7
0
def in_dir(dir_name, recursive = False):
    """ lists all the rasters in an input directory """

    rast_list = core.list_files(recursive, dir_name)
    rast_list = enf_rastlist(rast_list)

    print("Found {0} file with valid raster format".format(len(rast_list)))

    return rast_list
Esempio n. 8
0
def new_mosaic(rasterpaths,
               output_path,
               mosaic_method=None,
               cell_size=None,
               number_of_bands=None):
    """
    Simply creates a new raster dataset mosaic of input rasters by wrapping the
    arcpy.MosaicToNewRaster_management function. learn more about the fields here

    http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//001700000098000000

    :param rasterpaths:     list of complete filepaths to raster data to mosaic
    :param output_path:     place to save new mosaic raster dataset
    :param mosaic_method:   options are "FIRST", "LAST", "BLEND", "MEAN", "MINIMUM","MAXIMUM"
    :param cell_size:       of format "[cellwidth] [cellheight]" in the appropriate linear units,
                            usually meters.

    :return output_path:    returns filepath to new file, same as input ``output_path``
    """

    # set up input parameters
    if mosaic_method is None:
        mosaic_method = "FIRST"

    if cell_size is not None:
        print("using custom cell size of '{0}'".format(cell_size))

    if number_of_bands is None:
        number_of_bands = 1

    rasterpaths = enf_rastlist(rasterpaths)

    # get some metadata about the first raster in the mosaic
    numpy, meta = to_numpy(rasterpaths[0])

    # check output directories and set up inputs for arcpy function
    outdir, outname = os.path.split(output_path)

    if not os.path.exists(outdir):
        os.makedirs(outdir)

    arcpy.MosaicToNewRaster_management(
        rasterpaths,
        outdir,
        outname,
        None,  # coordinate system
        meta.pixel_type,
        cell_size,
        str(number_of_bands),
        mosaic_method=mosaic_method)

    print("Created raster mosaic at {0}".format(output_path))
    return output_path
Esempio n. 9
0
def in_dir(dir_name, recursive = False):
    """
    Lists all the rasters in an input directory. finds all formats
    supported by ``raster.enf_rastlist()``.

    :param dir_name:    directory to search rasters for
    :param recursive:   Set to "True" to search within subfolders of input
                        directory "dir_name"
    """

    rast_list = core.list_files(recursive, dir_name)
    rast_list = enf_rastlist(rast_list)

    print("Found {0} file with valid raster format".format(len(rast_list)))

    return rast_list
Esempio n. 10
0
def in_dir(dir_name, recursive=False):
    """
    Lists all the rasters in an input directory. finds all formats
    supported by ``raster.enf_rastlist()``.

    :param dir_name:    directory to search rasters for
    :param recursive:   Set to "True" to search within subfolders of input
                        directory "dir_name"
    """

    rast_list = core.list_files(recursive, dir_name)
    rast_list = enf_rastlist(rast_list)

    print("Found {0} file with valid raster format".format(len(rast_list)))

    return rast_list
Esempio n. 11
0
def null_set_range(rastlist,
                   high_thresh=None,
                   low_thresh=None,
                   NoData_Value=None):
    """
    Changes values within a certain range to NoData. similar to ``raster.null_define``,
    but can take an entire range of values to set to NoData. useful in filtering
    obviously erroneous high or low values from a raster dataset.

    :param rastlist:     list of rasters for which to set no dta values
    :param high_thresh:  will set all values above this to  NoData
    :param low_thresh:   will set all values below this to NoData

    :return rastlist:    list of all rasters modified by this function
    """

    # sanitize filelist input
    rastlist = enf_rastlist(rastlist)

    # iterate through each file in the filelist and set nodata values
    for rastname in rastlist:

        #load raster as numpy array and save spatial referencing.
        rast, meta = to_numpy(rastname)

        if not NoData_Value is None:
            NoData_Value = meta.NoData_Value

        if not high_thresh is None:
            rast[rast >= high_thresh] = NoData_Value

        if not low_thresh is None:
            rast[rast <= low_thresh] = NoData_Value

        from_numpy(rast, meta, rastname)
        try:
            arcpy.SetRasterProperties_management(rastname,
                                                 data_type="#",
                                                 statistics="#",
                                                 stats_file="#",
                                                 nodata="1 " +
                                                 str(NoData_Value))
        except RuntimeError:
            print("failed to set nodata in {0}".format(rastname))

    return
Esempio n. 12
0
def new_mosaic(rasterpaths, output_path, mosaic_method = None, cell_size = None, number_of_bands = None):
    """
    Simply creates a new raster dataset mosaic of input rasters by wrapping the
    arcpy.MosaicToNewRaster_management function. learn more about the fields here

    http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//001700000098000000

    :param rasterpaths:     list of complete filepaths to raster data to mosaic
    :param output_path:     place to save new mosaic raster dataset
    :param mosaic_method:   options are "FIRST", "LAST", "BLEND", "MEAN", "MINIMUM","MAXIMUM"
    :param cell_size:       of format "[cellwidth] [cellheight]" in the appropriate linear units,
                            usually meters.

    :return output_path:    returns filepath to new file, same as input ``output_path``
    """

    # set up input parameters
    if mosaic_method is None:
        mosaic_method = "FIRST"

    if cell_size is not None:
        print("using custom cell size of '{0}'".format(cell_size))

    if number_of_bands is None:
        number_of_bands = 1

    rasterpaths = enf_rastlist(rasterpaths)

    # get some metadata about the first raster in the mosaic
    numpy, meta = to_numpy(rasterpaths[0])

    # check output directories and set up inputs for arcpy function
    outdir, outname = os.path.split(output_path)

    if not os.path.exists(outdir):
        os.makedirs(outdir)

    arcpy.MosaicToNewRaster_management(rasterpaths, outdir, outname,
                                        None,                # coordinate system
                                        meta.pixel_type,
                                        cell_size,
                                        str(number_of_bands),
                                        mosaic_method = mosaic_method)

    print("Created raster mosaic at {0}".format(output_path))
    return output_path
Esempio n. 13
0
def null_set_range(rastlist,
                   high_thresh=None,
                   low_thresh=None,
                   NoData_Value=None):
    """
    Changes values within a certain range to NoData

     similar to raster.null_define, but can take an entire range of values to set to NoData.
     useful in filtering obviously erroneous high or low values from a raster dataset.

     inputs:
       rastlist     list of files for which to set NoData values. easily created with
                    "core.list_files" function
       high_thresh  will set all values above this to  NoData
       low_thresh   will set all values below this to NoData
    """

    # sanitize filelist input
    rastlist = enf_rastlist(rastlist)

    # iterate through each file in the filelist and set nodata values
    for rastname in rastlist:
        #load raster as numpy array and save spatial referencing.
        rast, meta = to_numpy(rastname)

        if not NoData_Value == None:
            NoData_Value = meta.NoData_Value

        if not high_thresh == None:
            rast[rast >= high_thresh] = NoData_Value
        if not low_thresh == None:
            rast[rast <= low_thresh] = NoData_Value

        from_numpy(rast, meta, rastname)
        arcpy.SetRasterProperties_management(rastname,
                                             data_type="#",
                                             statistics="#",
                                             stats_file="#",
                                             nodata="1 " + str(NoData_Value))

    return
Esempio n. 14
0
def null_set_range(rastlist, high_thresh = None, low_thresh = None, NoData_Value = None):
    """
    Changes values within a certain range to NoData. similar to ``raster.null_define``,
    but can take an entire range of values to set to NoData. useful in filtering
    obviously erroneous high or low values from a raster dataset.

    :param rastlist:     list of rasters for which to set no dta values
    :param high_thresh:  will set all values above this to  NoData
    :param low_thresh:   will set all values below this to NoData

    :return rastlist:    list of all rasters modified by this function
    """

    # sanitize filelist input
    rastlist = enf_rastlist(rastlist)

    # iterate through each file in the filelist and set nodata values
    for rastname in rastlist:

        #load raster as numpy array and save spatial referencing.
        rast, meta = to_numpy(rastname)

        if not NoData_Value is None:
            NoData_Value = meta.NoData_Value

        if not high_thresh is None:
            rast[rast >= high_thresh] = NoData_Value

        if not low_thresh is None:
            rast[rast <= low_thresh] = NoData_Value

        from_numpy(rast, meta, rastname)
        try:
            arcpy.SetRasterProperties_management(rastname, data_type = "#", statistics = "#",
                    stats_file = "#", nodata = "1 " + str(NoData_Value))
        except RuntimeError:
            print("failed to set nodata in {0}".format(rastname))

    return
Esempio n. 15
0
def null_define(rastlist, NoData_Value):
    """
    Simple batch NoData setting function. Makes raster data more arcmap viewing friendly

    Function inputs a list of raster (usually tifs) files and sets no data values. This
    function does not actually change the raster values in any way, and simply defines which
    numerical values to be considered NoData in metadata.

    :param rastlist:        list of rasters for which to set nodata value
    :param NoData_Value:    Value to declare as NoData (usually 0 or -9999)

    :return rastlist:       returns list of modified files
    """

    rastlist = enf_rastlist(rastlist)

    # iterate through each file in the filelist and set nodata values
    for rastname in rastlist:

        arcpy.SetRasterProperties_management(rastname,data_type="#",statistics="#",
                    stats_file="#",nodata="1 "+str(NoData_Value))

        print("Set nulls in {0}".format(rastname))
    return rastlist
Esempio n. 16
0
def project_resample(filelist,
                     reference_file,
                     outdir=False,
                     resampling_type=None,
                     cell_size=None):
    """
    Wrapper for multiple arcpy projecting functions. Projects to reference file
    
     Inputs a filelist and a reference file, then projects all rasters or feature classes
     in the filelist to match the projection of the reference file. Writes new files with a
     "_p" appended to the end of the input filenames. This also will perform resampling.

     Inputs:
       filelist            list of files to be projected
       outdir              optional desired output directory. If none is specified, output files
                           will be named with '_p' as a suffix.
       reference_file      Either a file with the desired projection, or a .prj file.
       resampling type     exactly as the input for arcmaps project_Raster_management function
       cell_size           exactly as the input for arcmaps project_Raster_management function

     Output:
       Spatial reference   spatial referencing information for further checking.
    """

    output_filelist = []
    # sanitize inputs
    core.exists(reference_file)

    rasterlist = enf_rastlist(filelist)
    featurelist = core.enf_featlist(filelist)
    cleanlist = rasterlist + featurelist

    # ensure output directory exists
    if not os.path.exists(outdir):
        os.makedirs(outdir)

    # grab data about the spatial reference of the reference file. (prj or otherwise)
    if reference_file[-3:] == 'prj':
        Spatial_Reference = arcpy.SpatialReference(reference_file)
    else:
        Spatial_Reference = arcpy.Describe(reference_file).spatialReference

        # determine cell size
        if cell_size is None:
            cx = arcpy.GetRasterProperties_management(reference_file,
                                                      "CELLSIZEX").getOutput(0)
            cy = arcpy.GetRasterProperties_management(reference_file,
                                                      "CELLSIZEY").getOutput(0)
            cell_size = "{0} {1}".format(cx, cy)

    # determine wether coordinate system is projected or geographic and print info
    if Spatial_Reference.type == 'Projected':
        print('Found {0} projected coord system'.format(
            Spatial_Reference.PCSName))
    else:
        print('Found {0} geographic coord system'.format(
            Spatial_Reference.GCSName))

    for filename in cleanlist:

        # create the output filename
        outname = core.create_outname(outdir, filename, 'p')
        output_filelist.append(Spatial_Reference)

        # use ProjectRaster_management for rast files
        if is_rast(filename):
            arcpy.ProjectRaster_management(filename, outname,
                                           Spatial_Reference, resampling_type,
                                           cell_size)
            print('Wrote projected and resampled file to {0}'.format(outname))

        # otherwise, use Project_management for featureclasses and featurelayers
        else:
            arcpy.Project_management(filename, outname, Spatial_Reference)
            print('Wrote projected file to {0}'.format(outname))

    print("finished projecting!")
    return output_filelist
Esempio n. 17
0
def project_resample(filelist, reference_file, outdir = False,
                   resampling_type = None, cell_size = None):

    """
    Wrapper for multiple arcpy projecting functions. Projects to reference file
    
     Inputs a filelist and a reference file, then projects all rasters or feature classes
     in the filelist to match the projection of the reference file. Writes new files with a
     "_p" appended to the end of the input filenames. This also will perform resampling.

     Inputs:
       filelist            list of files to be projected
       outdir              optional desired output directory. If none is specified, output files
                           will be named with '_p' as a suffix.
       reference_file      Either a file with the desired projection, or a .prj file.
       resampling type     exactly as the input for arcmaps project_Raster_management function
       cell_size           exactly as the input for arcmaps project_Raster_management function

     Output:
       Spatial reference   spatial referencing information for further checking.
    """

    output_filelist = []
    # sanitize inputs
    core.exists(reference_file)
           
    rasterlist  = enf_rastlist(filelist)
    featurelist = core.enf_featlist(filelist)
    cleanlist   = rasterlist + featurelist

    # ensure output directory exists
    if not os.path.exists(outdir):
        os.makedirs(outdir)
        
    # grab data about the spatial reference of the reference file. (prj or otherwise)
    if reference_file[-3:]=='prj':
        Spatial_Reference = arcpy.SpatialReference(reference_file)
    else:
        Spatial_Reference = arcpy.Describe(reference_file).spatialReference

        # determine cell size
        if cell_size is None:
            cx = arcpy.GetRasterProperties_management(reference_file, "CELLSIZEX").getOutput(0)
            cy = arcpy.GetRasterProperties_management(reference_file, "CELLSIZEY").getOutput(0)
            cell_size = "{0} {1}".format(cx,cy)

        
    # determine wether coordinate system is projected or geographic and print info
    if Spatial_Reference.type == 'Projected':
        print('Found {0} projected coord system'.format(Spatial_Reference.PCSName))
    else:
        print('Found {0} geographic coord system'.format(Spatial_Reference.GCSName))


    for filename in cleanlist:
        
        # create the output filename
        outname = core.create_outname(outdir, filename, 'p')
        output_filelist.append(Spatial_Reference)

        # use ProjectRaster_management for rast files
        if is_rast(filename):
            arcpy.ProjectRaster_management(filename,
                        outname, Spatial_Reference, resampling_type, cell_size)
            print('Wrote projected and resampled file to {0}'.format(outname))
                
        # otherwise, use Project_management for featureclasses and featurelayers
        else:
            arcpy.Project_management(filename,outname,Spatial_Reference)
            print('Wrote projected file to {0}'.format(outname))

    print("finished projecting!")
    return output_filelist
Esempio n. 18
0
def many_stats(rasterlist,
               outdir,
               outname,
               saves=['AVG', 'NUM', 'STD', 'SUM'],
               low_thresh=None,
               high_thresh=None,
               numtype='float32'):
    """
    Take statitics across many input rasters
    
     this function is used to take statistics on large groups of rasters with identical
     spatial extents. Similar to Rolling_Raster_Stats

     Inputs:
        rasterlist      list of raster filepaths for which to take statistics
        outdir          Directory where output should be stored.
        saves           which statistics to save in a raster. In addition to the options
                        supported by 
                           
                        Defaults to all three ['AVG','NUM','STD'].
        low_thresh      values below low_thresh are assumed erroneous and set to NoData
        high_thresh     values above high_thresh are assumed erroneous and set to NoData.
        numtype         type of numerical value. defaults to 32bit float.
    """

    if not os.path.isdir(outdir):
        os.makedirs(outdir)

    rasterlist = enf_rastlist(rasterlist)

    # build the empty numpy array based on size of first raster
    temp_rast, metadata = to_numpy(rasterlist[0])
    xs, ys = temp_rast.shape
    zs = len(rasterlist)
    rast_3d = numpy.zeros((xs, ys, zs))

    metadata.NoData_Value = numpy.nan

    # open up the initial figure
    rastfig = raster_fig(temp_rast)

    # populate the 3d matrix with values from all rasters
    for i, raster in enumerate(rasterlist):

        # print a status and open a figure
        print('working on file {0}'.format(os.path.basename(raster)))
        new_rast, new_meta = to_numpy(raster, numtype)

        new_rast = new_rast.data

        if not new_rast.shape == (xs, ys):
            print new_rast.shape

        # set rasters to have 'nan' NoData_Value
        if new_meta.NoData_Value != metadata.NoData_Value:
            new_rast[new_rast == new_meta.NoData_Value] = metadata.NoData_Value

        # set values outside thresholds to nodata values
        if not low_thresh == None:
            new_rast[new_rast < low_thresh] = metadata.NoData_Value
        if not high_thresh == None:
            new_rast[new_rast > high_thresh] = metadata.NoData_Value

        new_rast = numpy.ma.masked_array(new_rast, numpy.isnan(new_rast))

        # display a figure
        rastfig.update_fig(new_rast)

        rast_3d[:, :, i] = new_rast

    # build up our statistics by masking nan values and performin matrix opperations
    rastfig.close_fig()
    rast_3d_masked = numpy.ma.masked_array(rast_3d, numpy.isnan(rast_3d))

    if "AVG" in saves:
        avg_rast = numpy.mean(rast_3d_masked, axis=2)
        avg_rast = numpy.array(avg_rast)
        rastfig = raster_fig(avg_rast, title="Average")

        avg_name = core.create_outname(outdir, outname, 'AVG', 'tif')
        print("Saving AVERAGE output raster as {0}".format(avg_name))
        from_numpy(avg_rast, metadata, avg_name)
        rastfig.close_fig()
        del avg_rast

    if "STD" in saves:
        std_rast = numpy.std(rast_3d_masked, axis=2)
        std_rast = numpy.array(std_rast)
        rastfig = raster_fig(std_rast, title="Standard Deviation")

        std_name = core.create_outname(outdir, outname, 'STD', 'tif')
        print(
            "Saving STANDARD DEVIATION output raster as {0}".format(std_name))
        from_numpy(std_rast, metadata, std_name)
        rastfig.close_fig()
        del std_rast

    if "NUM" in saves:
        num_rast = (numpy.zeros(
            (xs, ys)) + zs) - numpy.sum(rast_3d_masked.mask, axis=2)
        num_rast = numpy.array(num_rast)
        rastfig = raster_fig(num_rast, title="Good pixel count (NUM)")
        rastfig.close_fig()

        num_name = core.create_outname(outdir, outname, 'NUM', 'tif')
        print("Saving NUMBER output raster as {0}".format(num_name))
        from_numpy(num_rast, metadata, num_name)
        rastfig.close_fig()
        del num_rast

    if "SUM" in saves:
        sum_rast = numpy.sum(rast_3d_masked, axis=2)
        sum_rast = numpy.array(sum_rast)
        rastfig = raster_fig(sum_rast, title="Good pixel count (NUM)")
        rastfig.close_fig()

        sum_name = core.create_outname(outdir, outname, 'SUM', 'tif')
        print("Saving NUMBER output raster as {0}".format(sum_name))
        from_numpy(sum_rast, metadata, sum_name)
        rastfig.close_fig()
        del sum_rast

    rastfig.close_fig()

    return
Esempio n. 19
0
def spatially_match(snap_raster,
                    rasterlist,
                    outdir,
                    NoData_Value=False,
                    resamp_type=False):
    """
    Prepares input rasters for further numerical processing

     This function simply ensures all rasters in "rasterlist" are identically projected
     and have the same cell size, then calls the raster.clip_and_snap function to ensure
     that the cells are perfectly coincident and that the total spatial extents of the images
     are identical, even when NoData values are considered. This is useful because it allows
     the two images to be passed on for numerical processing as nothing more than matrices
     of values, and the user can be sure that any index in any matrix is exactly coincident
     with the same index in any other matrix. This is especially important to use when
     comparing different datasets from different sources outside arcmap, for example MODIS
     and Landsat data with an ASTER DEM.

     inputs:
       snap_raster     raster to which all other images will be snapped
       rasterlist      list of rasters, a single raster, or a directory full of tiffs which
                       will be clipped to the extent of "snap_raster" and aligned such that
                       the cells are perfectly coincident.
       outdir          the output directory to save newly created spatially matched tifs.
       resamp_type     The resampling type to use if images are not identical cell sizes.
                           "NEAREST","BILINEAR",and "CUBIC" are the most common.

    this function automatically invokes
        clip_and_snap
        project_resample
    """

    # import modules and sanitize inputs
    tempdir = os.path.join(outdir, 'temp')

    if not os.path.isdir(outdir):
        os.makedirs(outdir)
    if not os.path.isdir(tempdir):
        os.makedirs(tempdir)

    rasterlist = enf_rastlist(rasterlist)
    core.exists(snap_raster)

    usetemp = False

    # set the snap raster environment in arcmap.
    arcpy.env.snapRaster = snap_raster

    print('Loading snap raster {0}'.format(snap_raster))
    _, snap_meta = to_numpy(snap_raster)
    print('Bounds of rectangle to define boundaries: [{0}]'.format(
        snap_meta.rectangle))

    # for every raster in the raster list, snap rasters and clip.
    for rastname in rasterlist:

        _, meta = to_numpy(rastname)
        head, tail = os.path.split(rastname)

        if snap_meta.projection.projectionName != meta.projection.projectionName:
            print('Projection discrepancy found. Reprojecting...')
            project_resample(rastname, snap_raster, tempdir, resamp_type)
            tempname = core.create_outname(tempdir, tail, "p")
            usetemp = True

        # define an output name and run the Clip_ans_Snap_Raster function on formatted tifs
        outname = core.create_outname(outdir, rastname, "sm")

        # if a temporary file was created in previous steps, use that one for clip and snap
        if usetemp:
            clip_and_snap(snap_raster, tempname, outname, NoData_Value)
        else:
            clip_and_snap(snap_raster, rastname, outname, NoData_Value)

        print('Finished matching raster {0}'.format(rastname))

    return
Esempio n. 20
0
def spatially_match(snap_raster, rasterlist, outdir,
                    NoData_Value = False, resamp_type = False):
    """
    Prepares input rasters for further numerical processing

     This function simply ensures all rasters in "rasterlist" are identically projected
     and have the same cell size, then calls the raster.clip_and_snap function to ensure
     that the cells are perfectly coincident and that the total spatial extents of the images
     are identical, even when NoData values are considered. This is useful because it allows
     the two images to be passed on for numerical processing as nothing more than matrices
     of values, and the user can be sure that any index in any matrix is exactly coincident
     with the same index in any other matrix. This is especially important to use when
     comparing different datasets from different sources outside arcmap, for example MODIS
     and Landsat data with an ASTER DEM.

     inputs:
       snap_raster     raster to which all other images will be snapped
       rasterlist      list of rasters, a single raster, or a directory full of tiffs which
                       will be clipped to the extent of "snap_raster" and aligned such that
                       the cells are perfectly coincident.
       outdir          the output directory to save newly created spatially matched tifs.
       resamp_type     The resampling type to use if images are not identical cell sizes.
                           "NEAREST","BILINEAR",and "CUBIC" are the most common.

    this function automatically invokes
        clip_and_snap
        project_resample
    """

    # import modules and sanitize inputs
    tempdir = os.path.join(outdir, 'temp')

    if not os.path.isdir(outdir):
        os.makedirs(outdir)
    if not os.path.isdir(tempdir):
        os.makedirs(tempdir)

    rasterlist = enf_rastlist(rasterlist)
    core.exists(snap_raster)

    usetemp = False

    # set the snap raster environment in arcmap.
    arcpy.env.snapRaster = snap_raster

    print('Loading snap raster {0}'.format(snap_raster))
    _,snap_meta = to_numpy(snap_raster)
    print('Bounds of rectangle to define boundaries: [{0}]'.format(snap_meta.rectangle))

    # for every raster in the raster list, snap rasters and clip.
    for rastname in rasterlist:

        _,meta      = to_numpy(rastname)
        head,tail   = os.path.split(rastname)

        if snap_meta.projection.projectionName != meta.projection.projectionName:
            print('Projection discrepancy found. Reprojecting...')
            project_resample(rastname, snap_raster, tempdir, resamp_type)
            tempname    = core.create_outname(tempdir,tail,"p")
            usetemp     = True

        # define an output name and run the Clip_ans_Snap_Raster function on formatted tifs
        outname      = core.create_outname(outdir, rastname, "sm")

        # if a temporary file was created in previous steps, use that one for clip and snap
        if usetemp:
            clip_and_snap(snap_raster, tempname, outname, NoData_Value)
        else:
            clip_and_snap(snap_raster, rastname, outname, NoData_Value)

        print('Finished matching raster {0}'.format(rastname))

    return
Esempio n. 21
0
def degree_days_accum(rasterlist, critical_values=None, outdir=None):
    """
    Accumulates degree days in a time series rasterlist

    This function is the logical successor to calc.degree_days. Input a list of rasters
    containing daily data to be accumulated. Output raster for a given day will be the sum
    total of the input raster for that day and all preceding days. The last output raster in
    a years worth of data (image 356) would be the sum of all 365 images. The 25th output
    raster would be a sum of the first 25 days.
    Critical value rasters will also be created. Usefull for example: we wish to know on what day
    of our 365 day sequence every pixel hits a value of 100. Input 100 as a critical value
    and that output raster will be generated.

    :param rasterlist:          list of files, or directory containing rasters to accumulate
    :param critical_values:     Values at which the user wishes to know WHEN the total accumulation
                                value reaches this point. For every critical value, an output
                                raster will be created. This raster contains integer values denoting
                                the index number of the file at which the value was reached.
                                This input must be a list of ints or floats, not strings.
    :param outdir:              Desired output directory for all output files.

    :return output_filelist:    a list of all files created by this function.
    """

    output_filelist = []
    rasterlist = enf_rastlist(rasterlist)

    if critical_values:
        critical_values = core.enf_list(critical_values)

    # critical values of zero are problematic, so replace it with a small value.
    if 0 in critical_values:
        critical_values.remove(0)
        critical_values.append(0.000001)

    if outdir is not None and not os.path.exists(outdir):
        os.makedirs(outdir)

    for i, rast in enumerate(rasterlist):

        image, meta = to_numpy(rast, "float32")
        xs, ys = image.shape

        if i == 0:
            Sum = numpy.zeros((xs, ys))
            Crit = numpy.zeros((len(critical_values), xs, ys))

        if image.shape == Sum.shape:

            # only bother to proceed if at least one pixel is positive
            if numpy.max(image) >= 0:
                for x in range(xs):
                    for y in range(ys):

                        if image[x, y] >= 0:
                            Sum[x, y] = Sum[x, y] + image[x, y]

                        if critical_values is not None:
                            for z, critical_value in enumerate(
                                    critical_values):
                                if Sum[x,
                                       y] >= critical_value and Crit[z, x,
                                                                     y] == 0:
                                    Crit[z, x, y] = i
        else:
            print "Encountered an image of incorrect size! Skipping it!"

        Sum = Sum.astype('float32')
        outname = core.create_outname(outdir, rast, "Accum")
        from_numpy(Sum, meta, outname)
        output_filelist.append(outname)

        del image

    # output critical accumulation rasters using some data from the last raster in previous loop
    Crit = Crit.astype('int16')
    crit_meta = meta
    crit_meta.NoData_Value = 0
    head, tail = os.path.split(
        outname)  # place these in the last raster output location
    for z, critical_value in enumerate(critical_values):
        outname = os.path.join(
            head, "Crit_Accum_Index_Val-{0}.tif".format(str(critical_value)))
        print("Saving {0}".format(outname))
        from_numpy(Crit[z, :, :], crit_meta, outname)

    return output_filelist
Esempio n. 22
0
def many_stats(rasterlist, outdir, outname, saves = ['AVG','NUM','STD','SUM'],
                                low_thresh = None, high_thresh = None, numtype = 'float32'):
    """
    Take statitics across many input rasters
    
     this function is used to take statistics on large groups of rasters with identical
     spatial extents. Similar to Rolling_Raster_Stats

     Inputs:
        rasterlist      list of raster filepaths for which to take statistics
        outdir          Directory where output should be stored.
        saves           which statistics to save in a raster. In addition to the options
                        supported by 
                           
                        Defaults to all three ['AVG','NUM','STD'].
        low_thresh      values below low_thresh are assumed erroneous and set to NoData
        high_thresh     values above high_thresh are assumed erroneous and set to NoData.
        numtype         type of numerical value. defaults to 32bit float.
    """

    if not os.path.isdir(outdir):
        os.makedirs(outdir)
    
    rasterlist = enf_rastlist(rasterlist)

    # build the empty numpy array based on size of first raster
    temp_rast, metadata = to_numpy(rasterlist[0])
    xs, ys              = temp_rast.shape
    zs                  = len(rasterlist)
    rast_3d             = numpy.zeros((xs,ys,zs))

    metadata.NoData_Value = numpy.nan

    # open up the initial figure
    rastfig = raster_fig(temp_rast)

    # populate the 3d matrix with values from all rasters
    for i, raster in enumerate(rasterlist):

        # print a status and open a figure
        print('working on file {0}'.format(os.path.basename(raster)))
        new_rast, new_meta  = to_numpy(raster, numtype)

        new_rast = new_rast.data

        if not new_rast.shape == (xs, ys):
            print new_rast.shape

        # set rasters to have 'nan' NoData_Value
        if new_meta.NoData_Value != metadata.NoData_Value:
            new_rast[new_rast == new_meta.NoData_Value] = metadata.NoData_Value
            
        # set values outside thresholds to nodata values
        if not low_thresh == None:
            new_rast[new_rast < low_thresh] = metadata.NoData_Value
        if not high_thresh == None:
            new_rast[new_rast > high_thresh] = metadata.NoData_Value

        new_rast = numpy.ma.masked_array(new_rast, numpy.isnan(new_rast))

        # display a figure
        rastfig.update_fig(new_rast)

        rast_3d[:,:,i] = new_rast


    # build up our statistics by masking nan values and performin matrix opperations
    rastfig.close_fig()
    rast_3d_masked  = numpy.ma.masked_array(rast_3d, numpy.isnan(rast_3d))

    if "AVG" in saves:
        avg_rast        = numpy.mean(rast_3d_masked, axis = 2)
        avg_rast        = numpy.array(avg_rast)
        rastfig         = raster_fig(avg_rast, title = "Average")

        avg_name = core.create_outname(outdir, outname, 'AVG', 'tif')
        print("Saving AVERAGE output raster as {0}".format(avg_name))
        from_numpy(avg_rast, metadata, avg_name)
        rastfig.close_fig()
        del avg_rast

    if "STD" in saves:
        std_rast        = numpy.std(rast_3d_masked, axis = 2)
        std_rast        = numpy.array(std_rast)
        rastfig         = raster_fig(std_rast, title = "Standard Deviation")

        std_name = core.create_outname(outdir, outname, 'STD', 'tif')
        print("Saving STANDARD DEVIATION output raster as {0}".format(std_name))
        from_numpy(std_rast, metadata, std_name)
        rastfig.close_fig()
        del std_rast
        
    if "NUM" in saves:
        num_rast        = (numpy.zeros((xs,ys)) + zs) - numpy.sum(rast_3d_masked.mask, axis = 2)
        num_rast        = numpy.array(num_rast)
        rastfig         = raster_fig(num_rast, title =  "Good pixel count (NUM)")
        rastfig.close_fig()

        num_name = core.create_outname(outdir, outname, 'NUM', 'tif')
        print("Saving NUMBER output raster as {0}".format(num_name))
        from_numpy(num_rast, metadata, num_name)
        rastfig.close_fig()
        del num_rast

    if "SUM" in saves:
        sum_rast        = numpy.sum(rast_3d_masked, axis = 2)
        sum_rast        = numpy.array(sum_rast)
        rastfig         = raster_fig(sum_rast, title = "Good pixel count (NUM)")
        rastfig.close_fig()

        sum_name = core.create_outname(outdir, outname, 'SUM', 'tif')
        print("Saving NUMBER output raster as {0}".format(sum_name))
        from_numpy(sum_rast, metadata, sum_name)
        rastfig.close_fig()
        del sum_rast
                   
    rastfig.close_fig()

    return
Esempio n. 23
0
def degree_days_accum(rasterlist, critical_values = None, outdir = None):
    """
    Accumulates degree days in a time series rasterlist

    This function is the logical successor to calc.degree_days. Input a list of rasters
    containing daily data to be accumulated. Output raster for a given day will be the sum
    total of the input raster for that day and all preceding days. The last output raster in
    a years worth of data (image 356) would be the sum of all 365 images. The 25th output
    raster would be a sum of the first 25 days.
    Critical value rasters will also be created. Usefull for example: we wish to know on what day
    of our 365 day sequence every pixel hits a value of 100. Input 100 as a critical value
    and that output raster will be generated.

    :param rasterlist:          list of files, or directory containing rasters to accumulate
    :param critical_values:     Values at which the user wishes to know WHEN the total accumulation
                                value reaches this point. For every critical value, an output
                                raster will be created. This raster contains integer values denoting
                                the index number of the file at which the value was reached.
                                This input must be a list of ints or floats, not strings.
    :param outdir:              Desired output directory for all output files.

    :return output_filelist:    a list of all files created by this function.
    """

    output_filelist = []
    rasterlist = enf_rastlist(rasterlist)

    if critical_values:
        critical_values = core.enf_list(critical_values)

    # critical values of zero are problematic, so replace it with a small value.
    if 0 in critical_values:
        critical_values.remove(0)
        critical_values.append(0.000001)

    if outdir is not None and not os.path.exists(outdir):
        os.makedirs(outdir)

    for i, rast in enumerate(rasterlist):

        image, meta = to_numpy(rast,"float32")
        xs, ys = image.shape

        if i == 0:
            Sum  = numpy.zeros((xs,ys))
            Crit = numpy.zeros((len(critical_values),xs,ys))

        if image.shape == Sum.shape:

            # only bother to proceed if at least one pixel is positive
            if numpy.max(image) >= 0:
                for x in range(xs):
                    for y in range(ys):

                        if image[x,y] >= 0:
                            Sum[x,y] = Sum[x,y]+image[x,y]

                        if critical_values is not None:
                            for z,critical_value in enumerate(critical_values):
                                if Sum[x,y] >= critical_value and Crit[z,x,y]==0:
                                    Crit[z,x,y] = i
        else:
            print "Encountered an image of incorrect size! Skipping it!"

        Sum     = Sum.astype('float32')
        outname = core.create_outname(outdir, rast, "Accum")
        from_numpy(Sum, meta, outname)
        output_filelist.append(outname)

        del image

    # output critical accumulation rasters using some data from the last raster in previous loop
    Crit = Crit.astype('int16')
    crit_meta = meta
    crit_meta.NoData_Value = 0
    head , tail = os.path.split(outname)        # place these in the last raster output location
    for z, critical_value in enumerate(critical_values):
        outname = os.path.join(head, "Crit_Accum_Index_Val-{0}.tif".format(str(critical_value)))
        print("Saving {0}".format(outname))
        from_numpy(Crit[z,:,:], crit_meta, outname)

    return output_filelist