Esempio n. 1
0
File: rst.py Progetto: jasp382/gasp
def get_percentage_value(rst, value, includeNodata=None):
    """
    Return the % of cells with a certain value
    """
    
    import numpy
    from osgeo            import gdal
    from gasp.pyt.num     import count_where
    from gasp.gt.fmrst    import rst_to_array
    from gasp.gt.prop.rst import get_nodata
    
    array = rst_to_array(rst)
    
    lnh, col = array.shape
    nrcell = lnh * col
    
    if not includeNodata:
        nd = get_nodata(rst, gisApi='gdal')
        
        nd_cells = count_where(array, array == nd)
        
        nrcell = nrcell - nd_cells
    
    valCount = count_where(array, array == value)
    
    perc = (valCount / float(nrcell)) * 100
    
    return perc
Esempio n. 2
0
def bands_to_rst(inRst, outFolder):
    """
    Export all bands of a raster to a new dataset
    
    TODO: this could be done using gdal_translate
    """

    import numpy
    import os
    from osgeo import gdal
    from gasp.gt.torst import obj_to_rst
    from gasp.gt.prop.rst import get_nodata

    rst = gdal.Open(inRst)

    if rst.RasterCount == 1:
        return

    nodata = get_nodata(inRst, gisApi='gdal')

    for band in range(rst.RasterCount):
        band += 1
        src_band = rst.GetRasterBand(band)
        if src_band is None:
            continue
        else:
            # Convert to array
            array = numpy.array(src_band.ReadAsArray())
            obj_to_rst(array,
                       os.path.join(
                           outFolder, '{r}_{b}.tif'.format(r=os.path.basename(
                               os.path.splitext(inRst)[0]),
                                                           b=str(band))),
                       inRst,
                       noData=nodata)
Esempio n. 3
0
File: rst.py Progetto: jasp382/gasp
def count_cells(raster, countNodata=None):
    """
    Return number of cells in a Raster Dataset
    """
    
    from gasp.gt.fmrst import rst_to_array
    from gasp.pyt.num  import count_where
    
    a = rst_to_array(raster)
    
    lnh, col = a.shape
    nrcell   = lnh * col
    
    if countNodata:
        return nrcell
    
    else:
        NoDataValue = get_nodata(raster)
        NrNodata = count_where(a, a == NoDataValue)
        return nrcell - NrNodata
Esempio n. 4
0
File: rst.py Progetto: jasp382/gasp
def percentage_nodata(rst):
    """
    Return the % of cells with nodata value
    """
    
    import numpy
    from gasp.pyt.num     import count_where
    from gasp.gt.fmrst    import rst_to_array
    from gasp.gt.prop.rst import get_nodata
    
    array = rst_to_array(rst)
    
    lnh, col = array.shape
    nrcell = lnh * col
    
    nd = get_nodata(rst, gisApi='gdal')
    nd_cells = count_where(array, array == nd)
    
    perc = (nd_cells / float(nrcell)) * 100
    
    return perc
Esempio n. 5
0
def comp_bnds(rsts, outRst):
    """
    Composite Bands
    """

    from osgeo import gdal, gdal_array
    from gasp.gt.fmrst import rst_to_array
    from gasp.gt.prop.ff import drv_name
    from gasp.gt.prop.rst import get_nodata
    from gasp.gt.prop.prj import get_rst_epsg, epsg_to_wkt

    # Get Arrays
    _as = [rst_to_array(r) for r in rsts]

    # Get nodata values
    nds = [get_nodata(r) for r in rsts]

    # Assume that first raster is the template
    img_temp = gdal.Open(rsts[0])
    geo_tran = img_temp.GetGeoTransform()
    band = img_temp.GetRasterBand(1)
    dataType = gdal_array.NumericTypeCodeToGDALTypeCode(_as[0].dtype)
    rows, cols = _as[0].shape
    epsg = get_rst_epsg(rsts[0])

    # Create Output
    drv = gdal.GetDriverByName(drv_name(outRst))
    out = drv.Create(outRst, cols, rows, len(_as), dataType)
    out.SetGeoTransform(geo_tran)
    out.SetProjection(epsg_to_wkt(epsg))

    # Write all bands
    for i in range(len(_as)):
        outBand = out.GetRasterBand(i + 1)
        outBand.SetNoDataValue(nds[i])
        outBand.WriteArray(_as[i])

        outBand.FlushCache()

    return outRst
Esempio n. 6
0
def rst_rotation(inFolder, template, outFolder, img_format='.tif'):
    """
    Invert raster data
    """

    import os
    from osgeo import gdal
    from gasp.pyt.oss import lst_ff
    from gasp.gt.fmrst import rst_to_array
    from gasp.gt.prop.rst import get_nodata
    from gasp.gt.torst import obj_to_rst

    rasters = lst_ff(inFolder, file_format=img_format)

    for rst in rasters:
        a = rst_to_array(rst)
        nd = get_nodata(rst)

        obj_to_rst(a[::-1],
                   os.path.join(outFolder, os.path.basename(rst)),
                   template,
                   noData=nd)
Esempio n. 7
0
def update_globe_land_cover(original_globe_raster, osm_urban_atlas_raster,
                            osm_globe_raster, epsg, updated_globe_raster,
                            detailed_globe_raster):
    """
    Update the original Glob Land 30 with the result of the conversion of
    OSM DATA to the Globe Land Cover nomenclature;
    
    Also updates he previous updated Glob Land 30 with the result of the
    conversion of osm data to the Urban Atlas Nomenclature
    """

    import os
    import numpy as np
    from gasp.gt.fmrst import rst_to_array
    from gasp.gt.prop.rst import get_cellsize, get_nodata
    from gasp.gt.torst import obj_to_rst

    # ############################# #
    # Convert images to numpy array #
    # ############################# #
    np_globe_original = rst_to_array(original_globe_raster)
    np_globe_osm = rst_to_array(osm_globe_raster)
    np_ua_osm = rst_to_array(osm_urban_atlas_raster)

    # ################################## #
    # Check the dimension of both images #
    # ################################## #
    if np_globe_original.shape != np_globe_osm.shape:
        return (
            'The Globe Land 30 raster (original) do not have the same number'
            ' of columns/lines comparing with the Globe Land 30 derived '
            'from OSM data')

    elif np_globe_original.shape != np_ua_osm.shape:
        return (
            'The Globe Land 30 raster (original) do not have the same '
            'number of columns/lines comparing with the Urban Atlas raster '
            'derived from OSM data')

    elif np_globe_osm.shape != np_ua_osm.shape:
        return (
            'The Globe Land 30 derived from OSM data do not have the same '
            'number of columns/lines comparing with the Urban Atlas raster '
            'derived from OSM data')

    # ############## #
    # Check Cellsize #
    # ############## #
    cell_of_rsts = get_cellsize(
        [original_globe_raster, osm_globe_raster, osm_urban_atlas_raster],
        xy=True,
        gisApi='gdal')

    cell_globe_original = cell_of_rsts[original_globe_raster]
    cell_globe_osm = cell_of_rsts[osm_globe_raster]
    cell_ua_osm = cell_of_rsts[osm_urban_atlas_raster]

    if cell_globe_original != cell_globe_osm:
        return (
            'The cellsize of the Globe Land 30 raster (original) is not the '
            'same comparing with the Globe Land 30 derived from OSM data')

    elif cell_globe_original != cell_ua_osm:
        return (
            'The cellsize of the Globe Land 30 raster (original) is not the '
            'same comparing with the Urban Atlas raster derived from OSM data')

    elif cell_ua_osm != cell_globe_osm:
        return (
            'The cellsize of the Globe Land 30 derived from OSM data is not '
            'the same comparing with the Urban Atlas raster derived from '
            'OSM data')

    # ############################# #
    # Get the Value of Nodata Cells #
    # ############################# #
    nodata_glob_original = get_nodata(original_globe_raster, gisApi='gdal')
    nodata_glob_osm = get_nodata(osm_globe_raster, gisApi='gdal')
    nodata_ua_osm = get_nodata(osm_urban_atlas_raster, gisApi='gdal')

    # ######################################## #
    # Create a new map - Globe Land 30 Updated #
    # ######################################## #
    """
    Create a new array with zeros...
    
    1) The zeros will be replaced by the values in the Globe Land derived from
    OSM.
    
    2) The zeros will be replaced by the values in the Original Globe Land at
    the cells with NULL data in the Globe Land derived from OSM.
    
    The meta array will identify values origins in the updated raster:
    1 - Orinal Raster
    2 - OSM Derived Raster
    """

    update_array = np.zeros(
        (np_globe_original.shape[0], np_globe_original.shape[1]))

    update_meta_array = np.zeros(
        (np_globe_original.shape[0], np_globe_original.shape[1]))

    # 1)
    np.copyto(update_array, np_globe_osm, 'no',
              np_globe_osm != nodata_glob_osm)
    # 1) meta
    np.place(update_meta_array, update_array != 0, 2)
    # 2) meta
    np.place(update_meta_array, update_array == 0, 1)
    # 2)
    np.copyto(update_array, np_globe_original, 'no', update_array == 0)
    # 2) meta
    np.place(update_meta_array, update_array == nodata_glob_original,
             int(nodata_glob_original))
    # noData to int
    np.place(update_array, update_array == nodata_glob_original,
             int(nodata_glob_original))

    updated_meta = os.path.join(
        os.path.dirname(updated_globe_raster), '{n}_meta{e}'.format(
            n=os.path.splitext(os.path.basename(updated_globe_raster))[0],
            e=os.path.splitext(os.path.basename(updated_globe_raster))[1]))
    # Create Updated Globe Cover 30
    obj_to_rst(update_array,
               updated_globe_raster,
               original_globe_raster,
               noData=int(nodata_glob_original))
    # Create Updated Globe Cover 30 meta
    obj_to_rst(update_meta_array,
               updated_meta,
               original_globe_raster,
               noData=int(nodata_glob_original))

    # ################################################# #
    # Create a new map - Globe Land 30 Detailed with UA #
    # ################################################# #
    np_update = rst_to_array(updated_globe_raster)

    detailed_array = np.zeros((np_update.shape[0], np_update.shape[1]))

    detailed_meta_array = np.zeros((np_update.shape[0], np_update.shape[1]))
    """
    Replace 80 Globe Land for 11, 12, 13, 14 of Urban Atlas
    
    The meta array will identify values origins in the detailed raster:
    1 - Updated Raster
    2 - UA Derived Raster from OSM
    """
    # Globe - Mantain some classes
    np.place(detailed_array, np_update == 30, 8)
    np.place(detailed_array, np_update == 30, 1)

    np.place(detailed_array, np_update == 40, 9)
    np.place(detailed_array, np_update == 40, 1)

    np.place(detailed_array, np_update == 50, 10)
    np.place(detailed_array, np_update == 50, 1)

    np.place(detailed_array, np_update == 10, 5)
    np.place(detailed_array, np_update == 10, 1)

    # Water bodies
    np.place(detailed_array, np_ua_osm == 50 or np_update == 60, 7)
    np.place(detailed_meta_array, np_ua_osm == 50 or np_update == 60, 1)

    # Urban - Where Urban Atlas IS NOT NULL
    np.place(detailed_array, np_ua_osm == 11, 1)
    np.place(detailed_meta_array, np_ua_osm == 11, 2)

    np.place(detailed_array, np_ua_osm == 12, 2)
    np.place(detailed_meta_array, np_ua_osm == 12, 2)

    np.place(detailed_array, np_ua_osm == 13, 3)
    np.place(detailed_meta_array, np_ua_osm == 13, 2)

    np.place(detailed_array, np_ua_osm == 14, 4)
    np.place(detailed_meta_array, np_ua_osm == 14, 2)

    # Urban Atlas - Class 30 to 6
    np.place(detailed_array, np_ua_osm == 30, 6)
    np.place(detailed_meta_array, np_ua_osm == 30, 2)

    # Create Detailed Globe Cover 30
    obj_to_rst(detailed_array,
               detailed_globe_raster,
               original_globe_raster,
               noData=0)

    # Create Detailed Globe Cover 30 meta
    detailed_meta = os.path.join(
        os.path.dirname(detailed_globe_raster), '{n}_meta{e}'.format(
            n=os.path.splitext(os.path.basename(detailed_meta))[0],
            e=os.path.splitext(os.path.basename(detailed_meta))[1]))
    obj_to_rst(detailed_meta_array,
               detailed_meta,
               original_globe_raster,
               noData=0)
Esempio n. 8
0
def gdal_slope(dem, srs, slope, unit='DEGREES'):
    """
    Create Slope Raster
    
    TODO: Test and see if is running correctly
    """

    import numpy
    import math
    from osgeo import gdal
    from scipy.ndimage import convolve
    from gasp.gt.fmrst import rst_to_array
    from gasp.gt.torst import obj_to_rst
    from gasp.gt.prop.rst import get_cellsize, get_nodata

    # ################ #
    # Global Variables #
    # ################ #
    cellsize = get_cellsize(dem, gisApi='gdal')
    # Get Nodata Value
    NoData = get_nodata(dem)

    # #################### #
    # Produce Slope Raster #
    # #################### #
    # Get Elevation array
    arr_dem = rst_to_array(dem)
    # We have to get a array with the number of nearst cells with values
    with_data = numpy.zeros((arr_dem.shape[0], arr_dem.shape[1]))
    numpy.place(with_data, arr_dem != NoData, 1.0)
    mask = numpy.array([[1, 1, 1], [1, 0, 1], [1, 1, 1]])
    arr_neigh = convolve(with_data, mask, mode='constant')
    numpy.place(arr_dem, arr_dem == NoData, 0.0)
    # The rate of change in the x direction for the center cell e is:
    kernel_dz_dx_left = numpy.array([[0, 0, 1], [0, 0, 2], [0, 0, 1]])
    kernel_dz_dx_right = numpy.array([[1, 0, 0], [2, 0, 0], [1, 0, 0]])
    dz_dx = (convolve(arr_dem, kernel_dz_dx_left, mode='constant') - convolve(
        arr_dem, kernel_dz_dx_right, mode='constant')) / (arr_neigh * cellsize)
    # The rate of change in the y direction for cell e is:
    kernel_dz_dy_left = numpy.array([[0, 0, 0], [0, 0, 0], [1, 2, 1]])
    kernel_dz_dy_right = numpy.array([[1, 2, 1], [0, 0, 0], [0, 0, 0]])
    dz_dy = (convolve(arr_dem, kernel_dz_dy_left, mode='constant') - convolve(
        arr_dem, kernel_dz_dy_right, mode='constant')) / (arr_neigh * cellsize)
    # Taking the rate of change in the x and y direction, the slope for the center cell e is calculated using
    rise_run = ((dz_dx)**2 + (dz_dy)**2)**0.5
    if unit == 'DEGREES':
        arr_slope = numpy.arctan(rise_run) * 57.29578
    elif unit == 'PERCENT_RISE':
        arr_slope = numpy.tan(numpy.arctan(rise_run)) * 100.0
    # Estimate the slope for the cells with less than 8 neigh
    aux_dem = rst_to_array(dem)
    index_vizinhos = numpy.where(arr_neigh < 8)
    for idx in range(len(index_vizinhos[0])):
        # Get Value of the cell
        lnh = index_vizinhos[0][idx]
        col = index_vizinhos[1][idx]
        e = aux_dem[lnh][col]
        a = aux_dem[lnh - 1][col - 1]
        if a == NoData:
            a = e
        if lnh == 0 or col == 0:
            a = e
        b = aux_dem[lnh - 1][col]
        if b == NoData:
            b = e
        if lnh == 0:
            b = e
        try:
            c = aux_dem[lnh - 1][col + 1]
            if c == NoData:
                c = e
            if lnh == 0:
                c = e
        except:
            c = e
        d = aux_dem[lnh][col - 1]
        if d == NoData:
            d = e
        if col == 0:
            d = e
        try:
            f = aux_dem[lnh][col + 1]
            if f == NoData:
                f = e
        except:
            f = e
        try:
            g = aux_dem[lnh + 1][col - 1]
            if g == NoData:
                g = e
            if col == 0:
                g = e
        except:
            g = e
        try:
            h = aux_dem[lnh + 1][col]
            if h == NoData:
                h = e
        except:
            h = e
        try:
            i = aux_dem[lnh + 1][col + 1]
            if i == NoData:
                i = e
        except:
            i = e
        dz_dx = ((c + 2 * f + i) - (a + 2 * d + g)) / (8 * cellsize)
        dz_dy = ((g + 2 * h + i) - (a + 2 * b + c)) / (8 * cellsize)
        rise_sun = ((dz_dx)**2 + (dz_dy)**2)**0.5
        if unit == 'DEGREES':
            arr_slope[lnh][col] = math.atan(rise_sun) * 57.29578
        elif unit == 'PERCENT_RISE':
            arr_slope[lnh][col] = math.tan(math.atan(rise_sun)) * 100.0
    # Del value originally nodata
    numpy.place(arr_slope, aux_dem == NoData, numpy.nan)
    #arr_slope[lnh][col] = slope_degres
    obj_to_rst(arr_slope, slope, dem)