Exemplo n.º 1
0
def saveRaster(Z,
               X=None,
               Y=None,
               fname_or_file='testRaster_py.tif',
               proj_ref=None,
               geotrans_rot_tup=(0, 0),
               like_raster=None,
               nodata_val=None,
               dtype_out=None,
               overwrite=False):
    testFile = validateTestFileSave(fname_or_file, overwrite)
    if testFile is None:
        return

    rat.saveArrayAsTiff(Z,
                        testFile,
                        X,
                        Y,
                        proj_ref,
                        geotrans_rot_tup,
                        nodata_val,
                        dtype_out,
                        like_raster=like_raster)

    print("'{}' saved".format(testFile))
Exemplo n.º 2
0
def diff_strips(demFile1, demFile2, diff_demFile, save_match):
    # TODO: Write docstring.

    # Construct filenames.
    demSuffix1 = getDemSuffix(demFile1)
    demSuffix2 = getDemSuffix(demFile2)
    diff_demFile_root, diff_demFile_ext = os.path.splitext(diff_demFile)
    matchFile1 = selectBestMatchtag(demFile1)
    matchFile2 = selectBestMatchtag(demFile2)
    metaFile1 = demFile1.replace(demSuffix1, 'mdf.txt')
    metaFile2 = demFile2.replace(demSuffix2, 'mdf.txt')
    regFile1 = demFile1.replace(demSuffix1, 'reg.txt')
    regFile2 = demFile2.replace(demSuffix2, 'reg.txt')
    diff_matchFile = '{}_matchtag{}'.format(diff_demFile_root,
                                            diff_demFile_ext)
    diff_metaFile = '{}_meta.txt'.format(diff_demFile_root, diff_demFile_ext)

    # Read georeferenced strip geometries.
    x1, y1, spatref1 = rat.extractRasterData(demFile1, 'x', 'y', 'spat_ref')
    x2, y2, spatref2 = rat.extractRasterData(demFile2, 'x', 'y', 'spat_ref')

    # Make sure strips have same projection.
    if spatref2.IsSame(spatref1) != 1:
        raise SpatialRefError(
            "Base strip '{}' spatial reference ({}) mismatch with "
            "compare strip spatial reference ({})".format(
                demFile1, spatref1.ExportToWkt(), spatref2.ExportToWkt()))
    spat_ref = spatref1

    # Find area of overlap.
    z1_c0, z1_r0 = 0, 0
    z1_c1, z1_r1 = None, None
    z2_c0, z2_r0 = 0, 0
    z2_c1, z2_r1 = None, None
    try:
        if x1[0] < x2[0]:
            overlap_ind = np.where(x1 == x2[0])[0]
            if overlap_ind.size == 0:
                raise NoOverlapError("")
            z1_c0 = overlap_ind[0]
        else:
            overlap_ind = np.where(x1[0] == x2)[0]
            if overlap_ind.size == 0:
                raise NoOverlapError("")
            z2_c0 = overlap_ind[0]
        if x1[-1] > x2[-1]:
            overlap_ind = np.where(x1 == x2[-1])[0]
            if overlap_ind.size == 0:
                raise NoOverlapError("")
            z1_c1 = overlap_ind[0] + 1
        else:
            overlap_ind = np.where(x1[-1] == x2)[0]
            if overlap_ind.size == 0:
                raise NoOverlapError("")
            z2_c1 = overlap_ind[0] + 1
        if y1[0] > y2[0]:
            overlap_ind = np.where(y1 == y2[0])[0]
            if overlap_ind.size == 0:
                raise NoOverlapError("")
            z1_r0 = overlap_ind[0]
        else:
            overlap_ind = np.where(y1[0] == y2)[0]
            if overlap_ind.size == 0:
                raise NoOverlapError("")
            z2_r0 = overlap_ind[0]
        if y1[-1] < y2[-1]:
            overlap_ind = np.where(y1 == y2[-1])[0]
            if overlap_ind.size == 0:
                raise NoOverlapError("")
            z1_r1 = overlap_ind[0] + 1
        else:
            overlap_ind = np.where(y1[-1] == y2)[0]
            if overlap_ind.size == 0:
                raise NoOverlapError("")
            z2_r1 = overlap_ind[0] + 1
    except NoOverlapError:
        raise NoOverlapError("Strip geometries do not overlap")

    if save_match:
        # Load matchtag data into arrays.
        print("Loading matchtag data")
        m1 = rat.extractRasterData(matchFile1, 'array')
        m2 = rat.extractRasterData(matchFile2, 'array')
        m1 = m1[z1_r0:z1_r1, z1_c0:z1_c1]
        m2 = m2[z2_r0:z2_r1, z2_c0:z2_c1]
        r0, r1, c0, c1 = crop_strip(m1, m2, method='data_density')
        # del m1, m2

    # Load DEM data into arrays.
    print("Loading raster data")
    z1 = rat.extractRasterData(demFile1, 'z')
    z2 = rat.extractRasterData(demFile2, 'z')
    z1[z1 == -9999] = np.nan
    z2[z2 == -9999] = np.nan

    # Crop arrays to area of overlap.
    x1 = x1[z1_c0:z1_c1]
    y1 = y1[z1_r0:z1_r1]
    x2 = x2[z2_c0:z2_c1]
    y2 = y2[z2_r0:z2_r1]
    z1 = z1[z1_r0:z1_r1, z1_c0:z1_c1]
    z2 = z2[z2_r0:z2_r1, z2_c0:z2_c1]

    # Crop arrays further to decrease memory use.
    if 'r0' not in vars():
        # r0, r1, c0, c1 = crop_strip(z1, method='center')
        r0, r1, c0, c1 = crop_strip(rat.getDataArray(z1, np.nan),
                                    rat.getDataArray(z2, np.nan),
                                    method='data_density')
    x1_crop = x1[c0:c1]
    y1_crop = y1[r0:r1]
    x2_crop = x2[c0:c1]
    y2_crop = y2[r0:r1]
    z1_crop = z1[r0:r1, c0:c1]
    z2_crop = z2[r0:r1, c0:c1]

    # Get initial guess of translation vector to
    # hopefully speed up coregistration...
    trans1 = get_trans_vector(regFile1)
    trans2 = get_trans_vector(regFile2)
    trans_guess = trans2 - trans1

    # Coregister the two DEMs.
    print("Beginning coregistration")
    _, trans, _, rmse = coregisterdems(x1_crop,
                                       y1_crop,
                                       z1_crop,
                                       x2_crop,
                                       y2_crop,
                                       z2_crop,
                                       trans_guess=trans_guess)
    dz, dx, dy = trans

    # Interpolate comparison DEM to reference DEM.
    print("Interpolating dem2 to dem1")
    z2i = rat.interp2_gdal(x2 - dx, y2 - dy, z2 - dz, x1, y1, 'linear')
    del z2

    # Difference DEMs and save result.
    print("Saving difference DEM")
    z_diff = z2i - z1
    z_diff[np.isnan(z_diff)] = -9999
    del z1, z2i
    rat.saveArrayAsTiff(z_diff,
                        diff_demFile,
                        x1,
                        y1,
                        spat_ref,
                        nodata_val=-9999,
                        dtype_out='float32')

    print("Extracting footprint vertices for metadata")
    fp_vertices = rat.getFPvertices(z_diff,
                                    x1,
                                    y1,
                                    label=-9999,
                                    label_type='nodata',
                                    replicate_matlab=True,
                                    dtype_out_int64_if_equal=True)
    del z_diff

    if save_match:
        if 'm2' not in vars():
            print("Loading match2")
            m2 = rat.extractRasterData(matchFile2, 'array').astype(np.float32)
            m2 = m2[z2_r0:z2_r1, z2_c0:z2_c1]
        elif m2.dtype != np.float32:
            m2 = m2.astype(np.float32)

        print("Interpolating match2 to match1")
        m2i = rat.interp2_gdal(x2 - dx, y2 - dy, m2, x1, y1, 'nearest')
        del m2
        m2i[np.isnan(m2i)] = 0  # convert back to uint8
        m2i = m2i.astype(np.bool)

        if 'm1' not in vars():
            print("Loading match1")
            m1 = rat.extractRasterData(matchFile1, 'array').astype(np.bool)
            m1 = m1[z1_r0:z1_r1, z1_c0:z1_c1]
        elif m1.dtype != np.bool:
            m1 = m1.astype(np.bool)

        print("Saving difference matchtag")
        m_diff = (m1 & m2i)
        del m1
        rat.saveArrayAsTiff(m_diff,
                            diff_matchFile,
                            x1,
                            y1,
                            spat_ref,
                            nodata_val=0,
                            dtype_out='uint8')
        del m_diff

    # Write metadata for difference image.
    proj4 = spat_ref.ExportToProj4()
    time = datetime.today().strftime("%d-%b-%Y %H:%M:%S")
    writeDiffMeta(diff_metaFile, demFile1, demFile2, trans, rmse, proj4,
                  fp_vertices, time)
Exemplo n.º 3
0
def mask_rasters(maskFile, suffix_maskval_dict, args):
    import numpy as np
    import lib.raster_array_tools as rat

    global SRC_SUFFIX_CATCH_ALL
    nodata_opt = args.get(ARGSTR_DST_NODATA)
    bitmaskSuffix = getBitmaskSuffix(maskFile)
    bitmask_is_strip_lsf = (bitmaskSuffix == SUFFIX_STRIP_BITMASK_LSF)

    if suffix_maskval_dict is None:
        # maskFile_base = maskFile.replace(bitmaskSuffix, '')
        # suffix_maskval_dict = {src_rasterFile.replace(maskFile_base, ''): None
        #                        for src_rasterFile in glob.glob(maskFile_base+SRC_SUFFIX_CATCH_ALL)
        #                        if not src_rasterFile.endswith(bitmaskSuffix)}
        suffix_maskval_dict = {SRC_SUFFIX_CATCH_ALL: None}

    if True in args.get(ARGSTR_EDGE, ARGSTR_WATER, ARGSTR_CLOUD):
        # Read in mask raster, then unset bits that will not be used to mask.
        mask_select, mask_x, mask_y = rat.extractRasterData(
            maskFile, 'z', 'x', 'y')
        mask_ones = np.ones_like(mask_select)
        if not args.get(ARGSTR_EDGE):
            np.bitwise_and(mask_select,
                           ~np.left_shift(mask_ones, MASKCOMP_EDGE_BIT),
                           out=mask_select)
        if not args.get(ARGSTR_WATER):
            np.bitwise_and(mask_select,
                           ~np.left_shift(mask_ones, MASKCOMP_WATER_BIT),
                           out=mask_select)
        if not args.get(ARGSTR_CLOUD):
            np.bitwise_and(mask_select,
                           ~np.left_shift(mask_ones, MASKCOMP_CLOUD_BIT),
                           out=mask_select)
        del mask_ones

        # Convert remaining component bits to a binary boolean mask.
        mask_select = mask_select.astype(np.bool)
    else:
        mask_select = None

    # Make list for downsampled mask array "pyramids"
    # that may be built on-the-fly.
    mask_pyramids = [mask_select]
    mask_pyramid_current = mask_pyramids[0]

    # Apply mask to source raster images and save results.
    for src_suffix, maskval in suffix_maskval_dict.items():
        bitmaskSuffix_temp = bitmaskSuffix
        if src_suffix.startswith(STRIP_LSF_PREFIX):
            if not bitmask_is_strip_lsf:
                continue
        elif bitmask_is_strip_lsf:
            bitmaskSuffix_temp = SUFFIX_STRIP_BITMASK

        src_rasterFile = maskFile.replace(bitmaskSuffix_temp, src_suffix)
        if '*' in src_rasterFile:
            src_rasterFile_list = glob.glob(src_rasterFile)
            if len(src_rasterFile_list) == 0:
                print("No source rasters found matching filename pattern: {}".
                      format(src_rasterFile))
                continue
            maskFile_globbed = None
            for src_rasterFile in src_rasterFile_list:
                if src_rasterFile.endswith(bitmaskSuffix_temp):
                    maskFile_globbed = src_rasterFile
                    break
            if maskFile_globbed is not None:
                src_rasterFile_list.remove(maskFile_globbed)
        else:
            src_rasterFile_list = [src_rasterFile]

        for src_rasterFile in src_rasterFile_list:
            if not os.path.isfile(src_rasterFile):
                print(
                    "Source raster does not exist: {}".format(src_rasterFile))
                continue
            dst_rasterFile = get_dstFile(src_rasterFile, args)
            if os.path.isfile(dst_rasterFile):
                print(
                    "Output raster already exists: {}".format(dst_rasterFile))
                if not args.get(ARGSTR_OVERWRITE):
                    continue

            print("Masking source raster ({}) to output raster ({})".format(
                src_rasterFile, dst_rasterFile))

            # Read in source raster.
            dst_array, src_nodataval = rat.extractRasterData(
                src_rasterFile, 'array', 'nodata_val')

            print("Source NoData value: {}".format(src_nodataval))

            # Set masking value to source NoDataVal if necessary.
            if maskval is None:
                if src_nodataval is None:
                    print(
                        "Source raster does not have a set NoData value, "
                        "so masking value cannot be automatically determined; skipping"
                    )
                    continue
                else:
                    maskval = src_nodataval

            print("Masking value: {}".format(maskval))

            if mask_pyramid_current is not None:
                # Apply mask.
                if mask_pyramid_current.shape != dst_array.shape:
                    # See if the required mask pyramid level has already been built.
                    mask_pyramid_current = None
                    for arr in mask_pyramids:
                        if arr.shape == dst_array.shape:
                            mask_pyramid_current = arr
                            break
                    if mask_pyramid_current is None:
                        # Build the required mask pyramid level and add to pyramids.
                        mask_pyramid_current = rat.imresize(mask_select,
                                                            dst_array.shape,
                                                            interp='nearest')
                        mask_pyramids.append(mask_pyramid_current)
                dst_array[mask_pyramid_current] = maskval

            # Handle nodata options.
            if nodata_opt == ARGCHO_DST_NODATA_SAME:
                dst_nodataval = src_nodataval
            elif nodata_opt == ARGCHO_DST_NODATA_ADD:
                dst_nodataval = maskval if src_nodataval is None else src_nodataval
            elif nodata_opt == ARGCHO_DST_NODATA_SWITCH:
                dst_nodataval = maskval
            elif nodata_opt == ARGCHO_DST_NODATA_CONVERT:
                if src_nodataval is not None:
                    dst_nodata = ((dst_array == src_nodataval)
                                  if not np.isnan(src_nodataval) else
                                  np.isnan(dst_array))
                    dst_array[dst_nodata] = maskval
                dst_nodataval = maskval
            elif nodata_opt == ARGCHO_DST_NODATA_UNSET:
                dst_nodataval = None

            print("Output NoData value: {}".format(dst_nodataval))

            # Save output masked raster.
            rat.saveArrayAsTiff(dst_array,
                                dst_rasterFile,
                                nodata_val=dst_nodataval,
                                like_raster=src_rasterFile)