Beispiel #1
0
def project_raster(ds, out_path, **kwargs):
    ds, ras = ds_name(ds)
    out_file = context_file(ras, out_path)

    if os.path.exists(out_file):
        return out_file

    # input SpatialReference
    in_srs = kwargs.pop('srcSRS', None)
    inSpatialRef = read_srs([ds, in_srs])

    # output SpatialReference
    out_srs = kwargs.pop('dstSRS', "+proj=longlat +datum=WGS84 +ellps=WGS84")
    outSpatialRef = read_srs(out_srs)

    resample_alg = kwargs.pop('resampleAlg', gdal.GRA_Average)
    option = gdal.WarpOptions(creationOptions=CREATION,
                              resampleAlg=resample_alg,
                              srcSRS=inSpatialRef,
                              dstSRS=outSpatialRef,
                              multithread=True,
                              **kwargs)
    gdal.Warp(out_file, ds, options=option)

    return out_file
Beispiel #2
0
def convert_uint8(ds, in_no_data=None, out_no_data=255):
    ds, ras = ds_name(ds)
    frist_band = ds.GetRasterBand(1)

    if (frist_band.DataType != gdal.GDT_Byte
            or frist_band.ReadAsArray(0, 0, 1, 1).dtype != np.int8):
        return ras

    if frist_band.GetNoDataValue() is not None:
        in_no_data = frist_band.GetNoDataValue()
    if in_no_data is None:
        raise (ValueError("in_no_data must be initialed"))

    option = gdal.WarpOptions(multithread=True,
                              creationOptions=CREATION,
                              outputType=gdal.GDT_Byte)
    out_file = rep_file(os.path.dirname(ras), ras)
    ds_out = gdal.Warp(out_file, ras, options=option)

    for i in range(1, 1 + ds.RasterCount):
        band = ds.GetRasterBand(i)
        band_out = ds_out.GetRasterBand(i)
        if band.GetNoDataValue() is None:
            band.SetNoDataValue(in_no_data)
        band_out.SetNoDataValue(out_no_data)
        block_write(ds, band, band_out, _map_no_data)

    ds = None
    ds_out = None
    gdal.GetDriverByName('GTiff').Delete(ras)
    os.rename(out_file, ras)

    return ras
Beispiel #3
0
def masked_outside(shp, ds):
    try:
        import psutil
    except Exception:
        print('psutil must be installed first')

    ds, ras = ds_name(ds)
    ds = gdal.Open(ras, gdal.GA_Update)
    trans = ds.GetGeoTransform()
    ratio = int(ds.RasterYSize * ds.RasterXSize /
                (psutil.virtual_memory().available * 0.5 /
                 (2 + ds.ReadAsArray(0, 0, 1, 1).dtype.itemsize)) + 1)

    # create the output layer
    out_shp = '/vsimem/outline_wgs84.shp'
    shp_projection(shp, out_shp, out_srs=read_srs(ds))
    outDataSet = ogr.Open(out_shp)
    outLayer = outDataSet.GetLayer()

    band = ds.GetRasterBand(1)
    b_xsize, b_ysize = band.GetBlockSize()
    xsize = max(ds.RasterXSize // ratio + 1, b_xsize)
    ysize = max(ds.RasterYSize // ratio + 1, b_ysize)
    xoffs = range(0, ds.RasterXSize, xsize)
    yoffs = range(0, ds.RasterYSize, ysize)
    for i in range(ds.RasterCount):
        band = ds.GetRasterBand(i + 1)
        for xoff in xoffs:
            for yoff in yoffs:
                win_xsize = min(xsize, ds.RasterXSize - xoff)
                win_ysize = min(ysize, ds.RasterYSize - yoff)

                # Create the destination data source
                target_ds = gdal.GetDriverByName('GTiff').Create(
                    '/vsimem/_outside.tif', win_xsize, win_ysize, 1, gdal.GDT_Byte)
                left_up_lon, left_up_lat = imagexy2geo(ds, yoff - 0.5, xoff - 0.5)
                target_ds.SetGeoTransform((left_up_lon, trans[1], 0, left_up_lat, 0, trans[5]))
                target_ds.SetProjection(ds.GetProjection())
                target_band = target_ds.GetRasterBand(1)
                target_band.SetNoDataValue(0)

                # Rasterize
                gdal.RasterizeLayer(target_ds, [1], outLayer, burn_values=[1],
                                    options=['ALL_TOUCHED=TRUE'])
                outside = np.logical_not(target_ds.GetRasterBand(1).ReadAsArray())
                target_band = None
                target_ds = None

                if outside.any():
                    arr = ds.ReadAsArray(xoff=xoff, yoff=yoff,
                                         xsize=win_xsize, ysize=win_ysize)
                    arr[outside] = band.GetNoDataValue()
                    band.WriteArray(arr, xoff=xoff, yoff=yoff)
                    del arr
                del outside
        band = None
Beispiel #4
0
def resample(ds, out_path, **kwargs):
    ds, ras = ds_name(ds)
    out_file = context_file(ras, out_path)

    if os.path.exists(out_file):
        return out_file

    resample_alg = kwargs.pop('resampleAlg', gdal.GRA_Average)
    option = gdal.WarpOptions(multithread=True,
                              creationOptions=CREATION,
                              resampleAlg=resample_alg,
                              **kwargs)
    gdal.Warp(out_file, ds, options=option)

    return out_file
Beispiel #5
0
def grid_bound(ds, regions):
    """return gridded bound whose resolution exactly matches that of ds

    Args:
        ds (gdal.dataset): dataset or path
        regions (list or str): regions of interest

    Returns:
        bound: spatial range of the regions in the ds
        crs_transform: like bound but used in GEE
    """
    ds = ds_name(ds)[0]
    t = ds.GetGeoTransform()
    bound, bound_srs = bound_layers(regions)
    bound = bound_raster(ds, bound, bound_srs)[0]
    crs_transform = [t[1], 0, bound[0], 0, t[5], bound[-1]]
    return bound, crs_transform
Beispiel #6
0
def bound_raster(ds, bound, bound_srs="+proj=longlat +datum=WGS84 +ellps=WGS84"):
    ds, _ = ds_name(ds)
    t = ds.GetGeoTransform()
    x_min, y_min, x_max, y_max = _prj_bound(ds, bound, bound_srs)
    ulX, ulY = geo2imagexy(ds, x_min, y_min)
    lrX, lrY = geo2imagexy(ds, x_max, y_max)
    clip_range = [min(ulX, lrX), min(ulY, lrY),
                  abs(ulX - lrX) + 1, abs(ulY - lrY) + 1]
    ul_lon = t[0] + t[1] * clip_range[0] + t[2] * clip_range[1]
    ul_lat = t[3] + t[4] * clip_range[0] + t[5] * clip_range[1]
    lr_lon = t[0] + t[1] * (clip_range[0] + clip_range[2]) + \
        t[2] * (clip_range[1] + clip_range[3])
    lr_lat = t[3] + t[4] * (clip_range[0] + clip_range[2]) + \
        t[5] * (clip_range[1] + clip_range[3])
    bound = [min(ul_lon, lr_lon), min(ul_lat, lr_lat),
             max(ul_lon, lr_lon), max(ul_lat, lr_lat)]

    return bound, read_srs(ds).ExportToProj4()
Beispiel #7
0
def mosaic(ras_paths, out_path, **kwargs):
    ds = ras_paths[0]
    ds, ras = ds_name(ds)
    out_file = context_file(ras, out_path)

    if os.path.exists(out_file):
        return out_file

    separate = kwargs.pop('separate', False)
    resample_alg = kwargs.pop('resampleAlg', gdal.GRA_Average)
    ds = gdal.BuildVRT('/vsimem/Mosaic.vrt', ras_paths, separate=separate)

    option = gdal.WarpOptions(multithread=True,
                              creationOptions=CREATION,
                              resampleAlg=resample_alg,
                              **kwargs)
    gdal.Warp(out_file, ds, options=option)

    return out_file
Beispiel #8
0
def broadcast_args(ds_multi, calc_args, band_idxs):
    iter_ds_multi, iter_calc_args, iter_band_idxs = check_iter(
        ds_multi, calc_args, band_idxs)

    if iter_ds_multi:
        ds = ds_multi[0]
    else:
        ds = ds_multi

    ds, ras = ds_name(ds)
    if band_idxs is not None:
        if iter_band_idxs and iter_calc_args:
            if len(band_idxs) != len(calc_args):
                raise Exception(
                    'length of band list not equal to that of calc args')
        elif iter_band_idxs:
            calc_args = [calc_args] * len(band_idxs)
        elif iter_calc_args:
            band_idxs = [band_idxs] * len(calc_args)
        else:
            calc_args = [calc_args]
            band_idxs = [band_idxs]
    else:
        n_band = ds.RasterCount
        if iter_calc_args:
            if len(calc_args) != n_band:
                raise Exception('calc args length not equal to band counts')
        else:
            calc_args = [calc_args] * n_band

        if iter_ds_multi:
            band_idxs = np.repeat(np.arange(1, n_band + 1, dtype=int),
                                  len(ds_multi)).reshape(-1, len(ds_multi))
        else:
            band_idxs = np.arange(1, n_band + 1, dtype=int)

    if not iter_ds_multi:
        ds_multi = [ras]
        band_idxs = np.array(band_idxs).reshape(len(band_idxs), 1)

    return ds_multi, calc_args, band_idxs
Beispiel #9
0
def tif_copy_assign(out_file, ds_eg, array, srs=None, no_data=None):
    if os.path.exists(out_file):
        return out_file
    ds_eg = ds_name(ds_eg)[0]

    if array.ndim == 2:
        array = array.reshape([1, *array.shape])
    if array.ndim != 3:
        raise (Exception('array must be 2 dims or 3 dims'))

    # set nodata value
    if no_data is None:
        if ds_eg.GetRasterBand(1).GetNoDataValue() is not None:
            no_data = ds_eg.GetRasterBand(1).GetNoDataValue()
        else:
            raise (Exception('nodata must be passed'))
    if isinstance(array, np.ma.core.MaskedArray):
        array.set_fill_value(no_data)
        array = array.filled()

    ds = gdal.GetDriverByName('GTiff').Create(out_file, array.shape[2],
                                              array.shape[1], array.shape[0],
                                              TYPE_MAP[array.dtype.name],
                                              CREATION)

    # fill with array
    for i in range(1, 1 + ds.RasterCount):
        band = ds.GetRasterBand(i)
        band.SetNoDataValue(no_data)
        band.WriteArray(array[i - 1])

    # set geotransform
    trans = ds_eg.GetGeoTransform()
    ds.SetGeoTransform(tuple(trans))

    # set SpatialReference
    ds.SetSpatialRef(read_srs([srs, ds_eg]))

    return out_file
Beispiel #10
0
def map_calc(ds_multi, calc_args, out_path, band_idxs=None, multiprocess=True):
    iter_ds_multi = isinstance(ds_multi,
                               Iterable) and not isinstance(ds_multi, str)

    if iter_ds_multi:
        ds = ds_multi[0]
    else:
        ds = ds_multi

    ds, ras = ds_name(ds)
    out_file = context_file(ras, out_path)

    if os.path.exists(out_file):
        return out_file

    ds_multi, calc_args, band_idxs = broadcast_args(ds_multi, calc_args,
                                                    band_idxs)

    n = len(calc_args)
    args = zip(np.arange(1, n + 1, dtype=int), [ds_multi] * n, band_idxs,
               calc_args, [out_file] * n)

    if multiprocess:
        with Pool(min(cpu_count() - 1, n)) as p:
            tem_files = p.starmap(band_map, args)
    else:
        tem_files = []
        for arg in args:
            tem_files.append(band_map(*arg))

    if len(tem_files) == 1:
        os.rename(tem_files[0], out_file)
    else:
        mosaic(tem_files, out_file, separate=True)
        [os.remove(f) for f in tem_files]

    return out_file
Beispiel #11
0
def grib_to_tif(ds, out_path=None, **kwargs):
    ds, ras = ds_name(ds)

    if os.path.splitext(os.path.basename(ras))[1] != '.grib':
        return

    if out_path:
        out_file = context_file(ras, out_path)
    else:
        out_file = os.path.join(
            os.path.dirname(ras),
            os.path.splitext(os.path.basename(ras))[0] + '.tif')

    if os.path.exists(out_file):
        return out_file

    srs = kwargs.pop('dstSRS', "+proj=longlat +datum=WGS84 +ellps=WGS84")
    option = gdal.WarpOptions(multithread=True,
                              dstSRS=read_srs(srs),
                              creationOptions=CREATION,
                              **kwargs)
    gdal.Warp(out_file, ds, options=option)

    return out_file