Пример #1
0
def single_bands_to_multiband(gdal_bands_list, output=None):
    """ Convert several gdal single file to a single gdal datasource"""

    # Get mask
    # src_ds = gdal.OpenShared(gdal_bands_list[0])
    src_ds = GdalReader().gdal2ds(gdal_bands_list[0])
    # src_ds.SetMetadataItem('FilePath', gdal_bands_list[0])

    # Get output
    if not output:
        output = 'image_multiband'

    # Create new ds
    # tmp_ds = gdal.GetDriverByName('MEM').CreateCopy('', src_ds, 0)
    out_ds = gdalr.GdalReader().create_ds(output, src_ds.RasterXSize,
                                          src_ds.RasterYSize,
                                          len(gdal_bands_list),
                                          src_ds.GetRasterBand(1).DataType)

    out_ds.SetProjection(src_ds.GetProjection())
    out_ds.SetGeoTransform(src_ds.GetGeoTransform())

    i = 0
    for band_dataset in gdal_bands_list:

        i = i + 1
        band_ds = GdalReader().gdal2ds(band_dataset)
        # mask_ds = gdal.OpenShared(band_dataset)
        array_i = band_ds.GetRasterBand(1).ReadAsArray()

        out_ds.GetRasterBand(i).WriteArray(array_i)
        band_ds = None
        del array_i

    if GdalReader().isvalid(out_ds):
        return out_ds
Пример #2
0
def merge(src_ds_list, outname, smooth_edges=False):
    # First layer metadata
    src_ds = GdalReader().gdal2ds(src_ds_list[0])
    src_ds_list = [GdalReader().gdal2ds(r) for r in src_ds_list]
    geotransform = src_ds.GetGeoTransform()
    xres = geotransform[1]
    yres = geotransform[5]
    projection = src_ds.GetProjection()
    nodata = src_ds.GetRasterBand(1).GetNoDataValue()

    # Get common extent
    xmin, xmax, ymin, ymax = GdalReader().get_extent(src_ds)

    bands = src_ds.RasterCount

    for src_i in src_ds_list:

        xmin_i, xmax_i, ymin_i, ymax_i = GdalReader().get_extent(src_i)
        xmax = max(xmax, xmax_i)
        xmin = min(xmin, xmin_i)
        ymax = max(ymax, ymax_i)
        ymin = min(ymin, ymin_i)
        bands = max(bands, src_i.RasterCount)

    # Aligne Pixels
    xmin = math.floor(xmin / xres) * xres
    xmax = math.ceil(xmax / xres) * xres
    ymin = math.floor(ymin / -yres) * -yres
    ymax = math.ceil(ymax / -yres) * -yres

    # Create output if it does not already exist.
    geotransform = [xmin, xres, 0, ymax, 0, yres]
    xsize = int(math.ceil((xmax - xmin) / xres))
    ysize = int(math.ceil((ymin - ymax) / yres))

    # Copy data from source files into output file 1.
    out_array = np.empty((ysize, xsize))
    out_array[:] = np.nan

    borders = []
    for src_i in src_ds_list:
        for band in xrange(1, src_ds.RasterCount + 1):

            geotransform_i = src_i.GetGeoTransform()
            if not int(xres) == int(geotransform_i[1]) or not int(yres) == int(
                    geotransform_i[5]):
                logging.error(
                    'Merge cannot be performed because the layer resolution are different: '
                    + str(xres) + ',' + str(yres) + ' vs. ' +
                    str(geotransform_i[1]) + ',' + str(geotransform_i[5]))

                continue

            xmin_i, xmax_i, ymin_i, ymax_i = GdalReader().get_extent(src_i)
            xoff = int(math.ceil((xmin_i - xmin) / xres))
            yoff = int(math.ceil((ymax_i - ymax) / yres))

            x_size_i = src_i.RasterXSize
            y_size_i = src_i.RasterYSize
            array_i = GdalReader().ds2array(src_i)

            out_array[yoff:yoff + y_size_i, xoff:xoff + x_size_i] = array_i

            #slice_i = out_array[yoff:yoff + y_size_i, xoff:xoff + x_size_i]
            #out_array[yoff:yoff + y_size_i, xoff:xoff + x_size_i] = np.where(
            #    np.ma.getmask(np.ma.masked_invalid(array_i[band - 1])), slice_i, array_i[band - 1])

            # Edges smoothing
            if smooth_edges:
                mask = np.where(
                    np.ma.getmask(np.ma.masked_invalid(array_i[band - 1])),
                    np.nan, 1)

                if smooth_edges:
                    borders_i = [
                        ([i + yoff, j + xoff] if 0 < [
                            mask[i - 1,
                                 j], mask[i + 1,
                                          j], mask[i, j - 1], mask[i, j + 1]
                        ].count(1) < 4 else None) if
                        (1 <= i < mask.shape[0] - 1) and
                        (1 <= j < mask.shape[1] - 1) else None
                        # ([i+yoff, j+xoff] if mask[i, j] == 1 else None)
                        for i, j in np.ndindex(mask.shape)
                    ]
                    borders = borders + borders_i

    # Edges smoothing
    if smooth_edges:
        for k in borders:
            if k:
                out_array[k[0],
                          k[1]] = np.nanmean(out_array[k[0] - 1:k[0] + 1,
                                                       k[1] - 1:k[1] + 1])

    return GdalReader().array2ds(src_array=out_array,
                                 output=outname,
                                 projection=projection,
                                 geotransform=geotransform,
                                 nodata=nodata)