Esempio n. 1
0
File: rst.py Progetto: jasp382/gasp
def frequencies(r, excludeNoData=True):
    """
    Return frequencies table
    """
    
    import numpy as np
    from osgeo           import gdal
    from gasp.g.prop.img import get_nd
    
    if type(r).__name__ == 'str':
        img = gdal.Open(r)
        arr = img.ReadAsArray()
    elif type(r).__name__ == 'Dataset':
        img = r
        arr = img.ReadAsArray()
    else:
        img = None
        arr = r
    
    unique = list(np.unique(arr))
    
    one_arr = arr.reshape(arr.shape[0] * arr.shape[1])
    freq    = np.bincount(one_arr)
    freq    = freq[freq != 0]
    
    if excludeNoData:
        if type(r).__name__ == 'str' or type(r).__name__ == 'Dataset':
            ndval = get_nd(img)
            return {unique[i] : freq[i] for i in range(len(unique)) if unique[i] != ndval}
        else:
            return {unique[i] : freq[i] for i in range(len(unique))}
    else:
        return {unique[i] : freq[i] for i in range(len(unique))}
Esempio n. 2
0
File: rmp.py Progetto: jasp382/gasp
def resample_by_majority(refrst, valrst, out_rst):
    """
    Resample valrst based on refrst:
        Get Majority value of valrst for each cell in refrst

    Useful when ref raster has cellsize greater
    than value raster.

    TODO: Valrst must be of int type
    """

    import numpy         as np
    from osgeo           import gdal
    from gasp.g.prop.img import get_cell_size, get_nd
    from gasp.gt.torst   import obj_to_rst

    # Data to Array
    if type(refrst) == gdal.Dataset:
        refsrc = refrst
    
    else:
        refsrc = gdal.Open(refrst)
    
    if type(valrst) == gdal.Dataset:
        valsrc = valrst
    else:
        valsrc = gdal.Open(valrst)

    refnum = refsrc.ReadAsArray()
    valnum = valsrc.ReadAsArray()

    # Get Ref shape
    ref_shape = refnum.shape

    # in a row, how many cells valnum are for each refnum cell
    refcs = int(get_cell_size(refsrc)[0])
    valcs = int(get_cell_size(valsrc)[0])
    dcell = int(refcs / valcs)

    # Valnum must be of int type

    # Create generalized/resampled raster
    resnum = np.zeros(ref_shape, dtype=valnum.dtype)

    for row in range(ref_shape[0]):
        for col in range(ref_shape[1]):
            resnum[row, col] = np.bincount(
                valnum[row*dcell:row*dcell+dcell, col*dcell : col*dcell+dcell].reshape(dcell*dcell)
            ).argmax()
    
    # Export out raster
    return obj_to_rst(resnum, out_rst, refsrc, noData=get_nd(valsrc))
Esempio n. 3
0
def gdal_mapcalc(expression,
                 exp_val_paths,
                 outRaster,
                 template_rst,
                 outNodata=-99999):
    """
    GDAL Raster Calculator
    
    TODO: Check if rasters dimensions are equal
    """

    import numpy as np
    import os
    from osgeo import gdal, osr
    from gasp.gt.prop.ff import drv_name
    from py_expression_eval import Parser
    from gasp.g.prop.img import get_nd
    from gasp.gt.torst import obj_to_rst

    parser = Parser()

    EXPRESSION = parser.parse(expression)

    evalValue = {}
    noDatas = {}
    for x in EXPRESSION.variables():
        img = gdal.Open(exp_val_paths[x])
        arr = img.ReadAsArray().astype(float)

        evalValue[x] = arr
        noDatas[x] = get_nd(img)

    result = EXPRESSION.evaluate(evalValue)

    for v in noDatas:
        np.place(result, evalValue[v] == noDatas[v], outNodata)

    # Write output and return

    return obj_to_rst(result, outRaster, template_rst, noData=outNodata)
Esempio n. 4
0
File: rst.py Progetto: jasp382/gasp
def get_nodata(r):
    """
    Returns the value defining NoData in a Raster file
    
    API'S Available:
    * gdal;
    """
    
    gisApi = 'gdal'
    
    if gisApi == 'gdal':
        from gasp.g.prop.img import get_nd
        from osgeo import gdal
        
        img = gdal.Open(r)
        
        ndVal = get_nd(img)
    
    else:
        raise ValueError('The api {} is not available'.format(gisApi))
    
    return ndVal
Esempio n. 5
0
def rcls_rst(inrst, rclsRules, outrst, api='gdal', maintain_ext=True):
    """
    Reclassify a raster (categorical and floating points)
    
    if api == 'gdal
    rclsRules = {
        1 : 99,
        2 : 100
        ...
    }
    
    or
    
    rclsRules = {
        (0, 8) : 1
        (8, 16) : 2
        '*'     : 'NoData'
    }
    
    elif api == grass:
    rclsRules should be a path to a text file
    """

    if api == 'gdal':
        import numpy as np
        import os
        from osgeo import gdal
        from gasp.gt.torst import obj_to_rst
        from gasp.g.fm import imgsrc_to_num
        from gasp.g.prop.img import get_nd

        if not os.path.exists(inrst):
            raise ValueError('File {} does not exist!'.format(inrst))

        # Open Raster
        img = gdal.Open(inrst)

        # Raster to Array
        rst_num = imgsrc_to_num(img)

        nodataVal = get_nd(img)

        rcls_num = np.full(rst_num.shape, 255, dtype=np.uint8)

        # Change values
        for k in rclsRules:
            if rclsRules[k] == 'NoData':
                continue

            if type(k) == str:
                continue

            elif type(k) == tuple:
                q = (rst_num > k[0]) & (rst_num <= k[1])

            else:
                q = rst_num == k

            np.place(rcls_num, q, rclsRules[k])

        if '*' in rclsRules and rclsRules['*'] != 'NoData':
            np.place(rcls_num, rcls_num == 255, rclsRules['*'])

        if 'NoData' in rclsRules and rclsRules['NoData'] != 'NoData':
            np.place(rcls_num, rst_num == nodataVal, rclsRules['NoData'])

        if not maintain_ext:
            from gasp.g.nop.rshp import rshp_to_data

            left, cellx, z, top, c, celly = img.GetGeoTransform()

            clip_rcls, n_left, n_top = rshp_to_data(rcls_num, 255, left, cellx,
                                                    top, celly)

            return obj_to_rst(clip_rcls,
                              outrst,
                              img,
                              noData=255,
                              geotrans=(n_left, cellx, z, n_top, c, celly))
        else:
            return obj_to_rst(rcls_num, outrst, img, noData=255)

    elif api == "pygrass":
        from grass.pygrass.modules import Module

        r = Module('r.reclass',
                   input=inrst,
                   output=outrst,
                   rules=rclsRules,
                   overwrite=True,
                   run_=False,
                   quiet=True)

        r()

    else:
        raise ValueError(("API {} is not available").format(api))
Esempio n. 6
0
def floatrst_to_intrst(in_rst, out_rst):
    """
    Raster with float data to Raster with Integer Values
    """

    import numpy as np
    from osgeo import gdal
    from gasp.g.prop.img import get_nd
    from gasp.gt.torst import obj_to_rst

    nds = {
        'int8': -128,
        'int16': -32768,
        'int32': -2147483648,
        'uint8': 255,
        'uint16': 65535,
        'uint32': 4294967295
    }

    # Open Raster
    img = gdal.Open(in_rst)

    # Raster to Array
    rstnum = img.ReadAsArray()

    # Round data
    rstint = np.around(rstnum, decimals=0)

    # Get min and max
    tstmin = rstint.min()
    tstmax = rstint.max()

    try:
        nd = int(round(get_nd(img), 0))
    except:
        nd = None

    if tstmin == nd:
        np.place(rstint, rstint == nd, np.nan)
        rstmin = rstint.min()
        rstmax = tstmax
    else:
        rstmin = tstmin

        if tstmax == nd:
            np.place(rstint, rstint == nd, np.nan)
            rstmax = rstint.max()
        else:
            rstmax = tstmax

    # Get dtype for output raster
    if rstmin < 0:
        if rstmin <= -128:
            if rstmin <= -32768:
                tmin = 'int32'
            else:
                tmin = 'int16'
        else:
            tmin = 'int8'
    else:
        tmin = 'u'

    if tmin == 'u':
        if rstmax >= 255:
            if rstmax >= 65535:
                tmax = 'uint32'
            else:
                tmax = 'uint16'
        else:
            tmax = 'uint8'

    else:
        if tmin == 'int8':
            if rstmax >= 127:
                if rstmax >= 32767:
                    tmax = 'int32'
                else:
                    tmax = 'int16'
            else:
                tmax = 'int8'

        elif tmin == 'int16':
            if rstmax >= 32767:
                tmax = 'int32'
            else:
                tmax = 'int16'
        else:
            tmax = 'int32'

    if tmax == 'int8':
        nt = np.int8
    elif tmax == 'int16':
        nt = np.int16
    elif tmax == 'int32':
        nt = np.int32
    elif tmax == 'uint8':
        nt = np.uint8
    elif tmax == 'uint16':
        nt = np.uint16
    else:
        nt = np.uint32

    # Get nodata for new raster
    new_nd = nds[tmax]

    # Place NoData value
    np.nan_to_num(rstint, copy=False, nan=new_nd)

    # Convert array type to integer
    rstint = rstint.astype(nt)

    # Export result to file and return
    return obj_to_rst(rstint, out_rst, img, noData=new_nd)