Пример #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
Пример #2
0
def download_tiles(shp, tile_pixel):
    # create the output layer
    out_shp = '/vsimem/outline_wgs84.shp'
    shp_projection(shp, out_shp)
    outDataSet = ogr.Open(out_shp)
    outLayer = outDataSet.GetLayer()

    # Create the destination data source
    x_res = int(360 / tile_pixel)
    y_res = int(180 / tile_pixel)
    target_ds = gdal.GetDriverByName('GTiff').Create(
        '/vsimem/_tile.tif', x_res, y_res, 1, gdal.GDT_Byte)
    target_ds.SetGeoTransform((-180, tile_pixel, 0, 90, 0, -tile_pixel))
    target_ds.SetSpatialRef(read_srs('+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs'))
    band = target_ds.GetRasterBand(1)
    band.SetNoDataValue(0)

    # Rasterize
    gdal.RasterizeLayer(target_ds, [1], outLayer, burn_values=[
                        1], options=['ALL_TOUCHED=TRUE'])
    burn_tiles = target_ds.GetRasterBand(1).ReadAsArray()
    rows, cols = np.where(burn_tiles == 1)
    if rows.shape == 0:
        return None
    lon, lat = np.int_(imagexy2geo(target_ds, rows - 0.5, cols - 0.5))
    return lon, lat
Пример #3
0
def polygonize(ds, shp_path):
    if os.path.exists(shp_path):
        return
    # mapping between gdal type and ogr field type
    type_mapping = {
        gdal.GDT_Byte: ogr.OFTInteger,
        gdal.GDT_UInt16: ogr.OFTInteger,
        gdal.GDT_Int16: ogr.OFTInteger,
        gdal.GDT_UInt32: ogr.OFTInteger,
        gdal.GDT_Int32: ogr.OFTInteger,
        gdal.GDT_Float32: ogr.OFTReal,
        gdal.GDT_Float64: ogr.OFTReal,
        gdal.GDT_CInt16: ogr.OFTInteger,
        gdal.GDT_CInt32: ogr.OFTInteger,
        gdal.GDT_CFloat32: ogr.OFTReal,
        gdal.GDT_CFloat64: ogr.OFTReal
    }

    srcband = ds.GetRasterBand(1)
    dst_layername = "Shape"
    drv = ogr.GetDriverByName("ESRI Shapefile")
    dst_ds = drv.CreateDataSource(shp_path)

    dst_layer = dst_ds.CreateLayer(dst_layername, srs=read_srs(ds))
    raster_field = ogr.FieldDefn('id', type_mapping[srcband.DataType])
    dst_layer.CreateField(raster_field)
    gdal.Polygonize(srcband, srcband, dst_layer, 0, [], callback=None)
    return shp_path
Пример #4
0
def shp_geom_map(in_shp, out_shp, in_srs=None,
                 out_srs=None, idxs=None, func=None):
    gdal.SetConfigOption("SHAPE_ENCODING", 'utf-8')

    # Filename of input OGR file
    driver = ogr.GetDriverByName("ESRI Shapefile")
    if isinstance(in_shp, ogr.Layer):
        inLayer = in_shp
    else:
        source_ds = ogr.Open(in_shp)
        inLayer = source_ds.GetLayer()

    # output SpatialReference
    outSpatialRef = read_srs([out_srs, inLayer, in_srs])

    # create the output layer
    if 'vsimem' not in os.path.dirname(out_shp):
        if (not os.path.exists(os.path.dirname(out_shp)) and
                os.path.dirname(out_shp) != ''):
            os.makedirs(os.path.dirname(out_shp))
    if os.path.exists(out_shp):
        driver.DeleteDataSource(out_shp)
    outDataSet = driver.CreateDataSource(out_shp)
    outLayer = outDataSet.CreateLayer(out_shp, outSpatialRef)

    # add fields
    inLayerDefn = inLayer.GetLayerDefn()
    for i in range(0, inLayerDefn.GetFieldCount()):
        fieldDefn = inLayerDefn.GetFieldDefn(i)
        outLayer.CreateField(fieldDefn)

    # get the output layer's feature definition
    outLayerDefn = outLayer.GetLayerDefn()

    # set all feature idxs if not assigned
    if idxs is None:
        idxs = range(inLayer.GetFeatureCount())
    elif isinstance(idxs, int):
        idxs = [idxs]

    # loop through the input features
    for i in idxs:
        inFeature = inLayer.GetFeature(i)
        # get the input geometry
        geom = inFeature.GetGeometryRef()
        # create a new feature
        outFeature = ogr.Feature(outLayerDefn)
        # set the geometry and attribute
        outFeature.SetGeometry(geom if func is None else func(geom))
        for i in range(0, outLayerDefn.GetFieldCount()):
            outFeature.SetField(outLayerDefn.GetFieldDefn(
                i).GetNameRef(), inFeature.GetField(i))
        # add the feature to the shapefile
        outLayer.CreateFeature(outFeature)
        # dereference the features and get the next input feature
        outFeature = None

    return out_shp
Пример #5
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
Пример #6
0
def bound_layers(layers):
    # clip extent
    if not isinstance(layers, list):
        layers = [layers]
    if isinstance(layers[0], str):
        shp_in = [ogr.Open(lyr) for lyr in layers]
        layers = [s.GetLayer() for s in shp_in]
    win = np.array([lyr.GetExtent() for lyr in layers])
    bound = [win[:, 0:2].min(), win[:, 2:].min(),
             win[:, 0:2].max(), win[:, 2:].max()]

    return bound, read_srs(layers).ExportToProj4()
Пример #7
0
def shp_projection(in_shp, out_shp, in_srs=None,
                   out_srs="+proj=longlat +datum=WGS84 +ellps=WGS84"):
    gdal.SetConfigOption("SHAPE_ENCODING", 'utf-8')

    # Filename of input OGR file
    if isinstance(in_shp, ogr.Layer):
        inLayer = in_shp
    else:
        source_ds = ogr.Open(in_shp)
        inLayer = source_ds.GetLayer()

    # input SpatialReference
    inSpatialRef = read_srs([inLayer, in_srs])

    # output SpatialReference
    outSpatialRef = read_srs(out_srs)

    # create the CoordinateTransformation
    coordTrans = coord_trans(inSpatialRef, outSpatialRef)

    return shp_geom_map(in_shp, out_shp,
                        out_srs=outSpatialRef,
                        func=lambda geom: geom.Transform(coordTrans))
Пример #8
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()
Пример #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
Пример #10
0
def zeros_tif(out_file,
              x_size,
              y_size,
              n_band,
              data_type,
              trans,
              srs,
              no_data=2):

    ds = gdal.GetDriverByName('GTiff').Create(out_file, x_size, y_size, n_band,
                                              data_type, CREATION)

    # fill with 0 and set no data
    band = ds.GetRasterBand(1)
    band.Fill(0)
    band.SetNoDataValue(no_data)

    # set geotransform
    ds.SetGeoTransform(tuple(trans))

    # set SpatialReference
    ds.SetSpatialRef(read_srs(srs))

    return out_file
Пример #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
Пример #12
0
def extract(ras, shp, PROJ=None, no_data=None, stat=False, **kwargs):
    if stat:
        return _extract_stat(ras, shp, PROJ=PROJ, no_data=no_data, **kwargs)

    if isinstance(ras, str):
        ds = gdal.Open(ras)
    else:
        ds = ras

    out_shp = '/vsimem/outline.shp'
    shp_projection(shp, out_shp, out_srs=read_srs([ds, PROJ]))
    outDataSet = ogr.Open(out_shp)
    outLayer = outDataSet.GetLayer()

    # set no data
    if ds.GetRasterBand(1).GetNoDataValue() is not None:
        no_data = ds.GetRasterBand(1).GetNoDataValue()
    if no_data is None:
        raise (ValueError("no_data must be initialed"))

    # clip with shapefile
    rect, _ = clip(ds, outLayer, no_data=no_data, **kwargs)

    return rect.GetDescription()
Пример #13
0
def _extract_stat(ras, shp, PROJ=None, no_data=None, **kwargs):
    if isinstance(ras, str):
        ds = gdal.Open(ras)
    else:
        ds = ras

    # Filename of input OGR file
    driver = ogr.GetDriverByName("ESRI Shapefile")
    source_ds = ogr.Open(shp)
    inLayer = source_ds.GetLayer()
    inLayerDefn = inLayer.GetLayerDefn()

    # output SpatialReference
    outSpatialRef = read_srs([ds, PROJ])

    coordTrans = coord_trans(inLayer, outSpatialRef)

    # initial output
    row = inLayer.GetFeatureCount()
    col = ds.RasterCount
    stat = np.full((row, col), np.nan)

    for r in range(row):
        inFeature = inLayer.GetFeature(r)
        # create the output layer
        outFile = '/vsimem/outline.shp'
        if os.path.exists(outFile):
            driver.DeleteDataSource(outFile)
        outDataSet = driver.CreateDataSource(outFile)
        outLayer = outDataSet.CreateLayer(outFile, outSpatialRef)

        # add fields
        for i in range(0, inLayerDefn.GetFieldCount()):
            fieldDefn = inLayerDefn.GetFieldDefn(i)
            outLayer.CreateField(fieldDefn)

        # get the output layer's feature definition
        outLayerDefn = outLayer.GetLayerDefn()

        # get the input geometry
        geom = inFeature.GetGeometryRef()
        # reproject the geometry
        geom.Transform(coordTrans)
        # create a new feature
        outFeature = ogr.Feature(outLayerDefn)
        # set the geometry and attribute
        outFeature.SetGeometry(geom)
        for i in range(0, outLayerDefn.GetFieldCount()):
            outFeature.SetField(
                outLayerDefn.GetFieldDefn(i).GetNameRef(),
                inFeature.GetField(i))
        # add the feature to the shapefile
        outLayer.CreateFeature(outFeature)

        if ds.GetRasterBand(1).GetNoDataValue() is not None:
            no_data = ds.GetRasterBand(1).GetNoDataValue()
        if no_data is None:
            raise (ValueError("no_data must be initialed"))
        rect = None
        rect, burn_data = clip(ds, outLayer, no_data=no_data, **kwargs)

        # iterate all bands
        for c in range(1, col + 1):
            rect_band = rect.GetRasterBand(c)
            rect_data = rect_band.ReadAsArray()
            no_data = rect_band.GetNoDataValue()
            select = (rect_data != no_data)
            try:
                stat[r, c - 1] = np.average(rect_data[select],
                                            weights=burn_data[select])
            except ZeroDivisionError:
                pass

    return stat