コード例 #1
0
def find_tile_overlap(indir, ref):
    """
    Find overlapping areas (polygons) between a reference (ref) and target
    rasters. Polygons are written to disk

    indir : strg
            Full path to the directory containing all raster files

    ref : strg
          Filename of the reference raster. Filenames are expected to have
          the following format: tileName_date.tif,
          e.g. 'T20MPA_20200729.tif'

    """

    rfiles = [rfile for rfile in os.listdir(indir) if rfile.endswith('.tif')
            and rfile != ref]

    outdir = os.path.join(indir, 'overlaps')
    if not os.path.exists(outdir):
        os.makedirs(outdir)

    with ExitStack() as stack_files:

        src_ref = stack_files.enter_context(rasterio.open(os.path.join(indir, ref)))


        srcs = [stack_files.enter_context(rasterio.open(os.path.join(indir, f)))
                for f in rfiles]

        poly_ref = box(*src_ref.bounds)

        for idx, src in enumerate(srcs, start=1):
            print("")
            print(f"Check overlap between {src_ref.files[0]} and {src.files[0]}")
            poly = box(*src.bounds)
            intersect = poly_ref.intersection(poly)
            try:
                arr, meta = rst.load_raster_from_poly(src, intersect)
                meta.update({
                    "interleave": "band"})
                arr_ref, meta_ref = rst.load_raster_from_poly(src_ref, intersect)
                meta_ref.update({
                    "interleave": "band"})
                print(f"Overlap found, getting arrays from polygon: {idx}")
            except ValueError:
                print(f"No overlap found for poly: {idx}")
                continue
            else:
                tile_ref = src_ref.files[0].split("/")[-1].split("_")[0]
                tile_target = src.files[0].split("/")[-1].split("_")[0]
                fname_ref = "_".join([f"poly_{idx}", tile_ref]) + ".tif"
                fname_target = "_".join([f"poly_{idx}", tile_target]) + ".tif"
                rst.write_array_as_raster(arr, meta, os.path.join(outdir, fname_target))
                rst.write_array_as_raster(arr_ref, meta_ref,
                        os.path.join(outdir, fname_ref))
コード例 #2
0
def make_raster_stack():

    with ExitStack() as stack_files:

        # use SCL file to create a cloud-mask array
        ras_scl = stack_files.enter_context(rasterio.open(s20.get_fpaths('SCL_20m')[0]))
        arr_scl, meta_scl = rst.load_raster_from_poly(ras_scl, poly)
        arr_mask, _ = rst.mask_vals(arr_scl, meta_scl, [3,7,8,9,10])

        # collect all relevant bands
        ras10 = [stack_files.enter_context(rasterio.open(fp))
            for fp in s10.get_fpaths( 'B08_10m')]
        ras20 = [stack_files.enter_context(rasterio.open(fp))
            for fp in s20.get_fpaths('B02_20m', 'B03_20m', 'B04_20m', 'B05_20m', 'B06_20m', 'B07_20m', 'B8A_20m', 'B11_20m', 'B12_20m')]
        ras_collect = ras10+ras20

        with ExitStack() as stack_action:
            rstack = Rstack()
            for idx_ras, src in enumerate(ras_collect):
                if int(src.res[0]) == 10: # resample to 20 m
                    logger.info(f"Resampling: {src.files[0]} to 20 m resolution")
                    arr_r, meta = rst.load_resample(src, 0.5)
                    src = stack_action.enter_context(rst.to_src(arr_r, meta))
                arr, meta = rst.load_raster_from_poly(src, poly)
                arr_masked = rst.apply_mask(arr, arr_mask.mask, fill_value=9999)
                src = stack_action.enter_context(rst.to_src(arr_masked, meta))
                logger.info(f"Add raster with resulution: {src.res} to the stack")
                rstack.add_item(src)

            # calc indexes
            indexes_to_calc = OrderedDict([("calc_ndvi", [rstack.items[3], rstack.items[0]]),
                                           ("calc_nbr", [rstack.items[0], rstack.items[9]]),
                                           ("calc_bsi", [rstack.items[1], rstack.items[3], rstack.items[0], rstack.items[9]]),
                                           ("calc_ndwi", [rstack.items[2], rstack.items[0]])])

            indexes = Indexes(metadata=rstack.items[0].profile)

            for idx,vals in indexes_to_calc.items():
                arr_idx, meta_idx = getattr(indexes, idx)(*vals)
                arr_idx_masked = rst.apply_mask(arr_idx, arr_mask.mask, fill_value=9999)
                src_idx = stack_action.enter_context(rst.to_src(arr_idx_masked, meta_idx))
                rstack.add_item(src_idx)
            # final bands order of the stack
            rstack.set_metadata_param('interleave', 'band')
            order = [1, 2, 3, 4, 5, 6, 0, 7, 8, 9, 10, 11, 12, 13]
            rstack.reorder_items(order)
            fname = "_".join([s20.get_tile_number("B02_20m"), s20.get_datetake("B02_20m")])+"_stack.tif"
            fpath = rst.write_raster(rstack.items, rstack.metadata_collect, os.path.join(OUTDIR, fname))
    return fpath
コード例 #3
0
def find_total_overlaps(indir):

    fpaths = [os.path.join(indir, rfile) for rfile in os.listdir(indir)
            if rfile.endswith('.tif')]

    with ExitStack() as stack_files:
        srcs = [stack_files.enter_context(rasterio.open(fp)) for fp in fpaths]
        polys = [box(*src.bounds) for src in srcs]

        intersects = []

        for poly, poly_front in ut.gen_current_front_pairs(polys):
            if poly.intersects(poly_front) and poly.intersection(poly_front) not in intersects:
                intersects.append(poly.intersection(poly_front))
        print(intersects)

        # save a polygon
        #gdf1 = gpd.GeoDataFrame({"geometry": intersects}, crs=f"EPSG:{srcs[0].crs.to_epsg()}")
        #gdf1.to_file(os.path.join(BASEDIR, "overlap_polygon"))

        for src in srcs:
            print("")
            print(f"Run for raster: {src.files[0]} ..")
            for idx, intersect in enumerate(intersects, start=1):
                try:
                    arr, meta = rst.load_raster_from_poly(src, intersect)
                    print(f"Overlap found, getting arr from poly: {idx}")
                except ValueError:
                    print(f"No overlap found for poly: {idx}")
                    continue
                else:
                    fname = "_".join([f"poly_{idx}", str(arr.shape[1]), str(arr.shape[2])]) + ".tif"
                    print(fname)
                    print(arr.shape)
                    meta.update({
                    "interleave": "band"})
                    outdir = os.path.join(indir, src.files[0].split("/")[-1].split("_")[1])
                    if not os.path.exists(outdir):
                        os.makedirs(outdir)
                    rst.write_array_as_raster(arr, meta, os.path.join(outdir, fname))
コード例 #4
0
def stack_sent2_bands(indir, bands, outdir, resolution=10, mask=False,
        window=None, polygon=None, indexes=None, fname=None):
    """
    Create a stack of sentinel 2 bands with defined spacial resolution

    **********

    params
    ---------

    indir : strg
            full path to the IMG_DATA folder. This directory is expected to have
            the standard sent2 structure, i.e. three subdirerctories: R10m, R20m
            and R60m

    bands : list
            Bands that should be included into the stack, e.g. 'B02_10m' or 'B05_20m'

    outdir : strg
             full path to the output directory

    resolution : int
                 final resolution of all the bands of the stack

    mask : numpy boolean mask arr

    window : rasterio.windows.Window
             Define a final extent of the stack

    polygon : GEOJson-like dict
              e.g. { 'type': 'Polygon', 'coordinates': [[(),(),(),()]] }
             Define a final extent of the stack
    
    fnam: strg
          Name of the output raster stack; e.g. my_stack.tif

    indexes: OrderDict
    """
    s10 = Sentinel2(os.path.join(indir, 'R10m'))
    s20 = Sentinel2(os.path.join(indir, 'R20m'))

    if window is not None and polygon is not None:
        raise ValueError("Cannot choose both window and polygon params!")

    with ExitStack() as stack_files:

        fpaths = []
        for band in bands:
            try:
                fpaths.append(s10.get_fpath(band))
            except KeyError:
                try:
                    fpaths.append(s20.get_fpath(band))
                except KeyError:
                    raise ValueError(f"Cannot find band: '{band}'. Please provide valid band name.")

        srcs = [stack_files.enter_context(rasterio.open(fp))
            for fp in fpaths]

        band_src_map = dict(zip(bands, srcs))

        with ExitStack() as stack_action:
            rstack = Rstack()
            for band, src in band_src_map.items():
                print(f'Band {band} to be processed..')

                if int(src.res[0]) != resolution: # resample to match res param
                    print(f'Band: {band} will be resampled to {resolution} m resolution..')
                    scale_factor = src.res[0] / resolution
                    arr, meta = rst.load_resample(src, scale_factor)
                    src = stack_action.enter_context(rst.to_src(arr, meta))

                if window:
                    print(f'Selected a window: {window} as AOI')
                    arr, meta = rst.load_window(src, window)
                    src = stack_action.enter_context(rst.to_src(arr, meta))

                if polygon:
                    print(f"Selected a polygon as AOI")
                    arr, meta = rst.load_raster_from_poly(src, polygon)
                    src = stack_action.enter_context(rst.to_src(arr, meta))

                if np.any(mask):
                    print(f"Selected a mask for band {band}")
                    # check that mask and array are the same dimension
                    arr, meta = rst.load(src)
                    assert mask.shape == arr.shape, 'Array and mask must the have same shape'
                    arr = rst.apply_mask(arr, mask, fill_value=9999)
                    src = stack_action.enter_context(rst.to_src(arr, meta))

                band_src_map[band] = src # update the mapping
                rstack.add_item(src)

            if indexes:
                print(f'Compute indexes: {indexes.keys()} and add them to the stack')

                to_calc = Indexes(metadata=rstack.items[0].profile)

                for idx,vals in indexes.items():
                    try:
                        vals = [band_src_map[v] for v in vals]
                    except KeyError:
                        raise ValueError(f"One or more bands: '{vals}' were not defined as part of the stack.")
                    try:
                        arr_idx, meta_idx = getattr(to_calc, idx)(*vals)
                    except AttributeError:
                        raise ValueError(f"'{idx}' is not a valid Index method")
                    arr_idx, meta_idx = getattr(to_calc, idx)(*vals)
                    src_idx = stack_action.enter_context(rst.to_src(arr_idx, meta_idx))
                    band_src_map[idx] = src_idx # update the mapping
                    rstack.add_item(src_idx)

            rstack.set_metadata_param('interleave', 'band')
            print(band_src_map.keys())
            
            if not fname:
                fname = '_'.join([s10.get_tile_number('B02_10m'), s10.get_datetake('B02_10m')])+'.tif'
            if not os.path.exists(outdir):
                os.makedirs(outdir)
            fpath = rst.write_raster(rstack.items, rstack.metadata_collect, os.path.join(outdir, fname))
        return fpath
コード例 #5
0
if __name__ == "__main__":

    # Globals
    OUTDIR = "" # change me
    BASEDIR = "" # change me (Full path to IMG_DATA)
    DATA10 = "R10m/"
    DATA20 = "R20m/"
    POINTS_FP = "" # change me
    s10 = Sentinel2(os.path.join(BASEDIR, DATA10))
    s20 = Sentinel2(os.path.join(BASEDIR, DATA20))
    gdf = gpd.read_file(POINTS_FP)
    poly = box(*list(gdf.total_bounds))

    with rasterio.open(s20.get_fpaths('TCI_20m')[0]) as ras_tci:
        # get the AOI over TCI and save to disk
        arr_tci, meta_tci = rst.load_raster_from_poly(ras_tci, poly)
        fname_tci = "_".join([s20.get_tile_number("TCI_20m"), s20.get_datetake("TCI_20m")])+"_AOI.tif"
        rst.write_array_as_raster(arr_tci, meta_tci, os.path.join(OUTDIR, fname_tci))

    fp = make_raster_stack()
    X, y = extract_Xy(fp)

    for run in range(1, 31):

        logger.info("")
        logger.info(f"Start run {run}")

        clf = train_RandomForestClf(X, y, estimators=200)

        with rasterio.open(fp) as src:
            fname_cls = "_".join([os.path.basename(fp).split(".")[0], "classification_map_" , str(run) +".json"])
コード例 #6
0
        for poly, poly_front in ut.gen_current_front_pairs(polys):
            if poly.intersects(poly_front) and poly.intersection(
                    poly_front) not in intersects:
                intersects.append(poly.intersection(poly_front))
        print(intersects)

        # save a polygon
        #gdf1 = gpd.GeoDataFrame({"geometry": intersects}, crs=f"EPSG:{srcs[0].crs.to_epsg()}")
        #gdf1.to_file(os.path.join(BASEDIR, "overlap_polygon"))

        for src in srcs:
            print("")
            print(f"Run for raster: {src.files[0]} ..")
            for idx, intersect in enumerate(intersects, start=1):
                try:
                    arr, meta = rst.load_raster_from_poly(src, intersect)
                    print(f"Overlap found, getting arr from poly: {idx}")
                except ValueError:
                    print(f"No overlap found for poly: {idx}")
                    continue
                else:
                    fname = "_".join([
                        os.path.dirname(
                            src.files[0]).split("/")[-1].split("_")[0],
                        f"poly_{idx}",
                        str(arr.shape[1]),
                        str(arr.shape[2])
                    ]) + ".tif"
                    print(fname)
                    print(arr.shape)
                    meta.update({"interleave": "band"})