Esempio n. 1
0
    def __call__(self, src_ds):
        dst_ds = create_mem(src_ds.RasterXSize, src_ds.RasterYSize, len(self.bands), self.datatype)
        dst_range = get_limits(self.datatype)

        multiple = 0

        for dst_index, (src_index, dmin, dmax) in enumerate(self.bands, 1):
            # check if next band is equal
            if dst_index < len(self.bands) and (src_index, dmin, dmax) == self.bands[dst_index]:
                multiple += 1
                continue
            # check that src band is available
            if src_index > src_ds.RasterCount:
                continue

            # initialize with zeros if band is 0
            if src_index == 0:
                src_band = src_ds.GetRasterBand(1)
                data = numpy.zeros((src_band.YSize, src_band.XSize), dtype=gdal_array.codes[self.datatype])
                src_min, src_max = (0, 0)
            # use src_ds band otherwise
            else:
                src_band = src_ds.GetRasterBand(src_index)
                data = src_band.ReadAsArray()
                src_min, src_max = src_band.ComputeRasterMinMax()

            # get min/max values or calculate from band
            if dmin is None:
                dmin = get_limits(src_band.DataType)[0]
            elif dmin == "min":
                dmin = src_min
            if dmax is None:
                dmax = get_limits(src_band.DataType)[1]
            elif dmax == "max":
                dmax = src_max
            src_range = (float(dmin), float(dmax))

            # perform clipping and scaling
            data = (dst_range[1] - dst_range[0]) * (
                (numpy.clip(data, dmin, dmax) - src_range[0]) / (src_range[1] - src_range[0])
            )

            # set new datatype
            data = data.astype(gdal_array.codes[self.datatype])

            # write result
            dst_band = dst_ds.GetRasterBand(dst_index)
            dst_band.WriteArray(data)

            # write equal bands at once
            if multiple > 0:
                for i in range(multiple):
                    dst_band = dst_ds.GetRasterBand(dst_index - 1 - i)
                    dst_band.WriteArray(data)
                multiple = 0

        copy_projection(src_ds, dst_ds)
        copy_metadata(src_ds, dst_ds)

        return dst_ds
Esempio n. 2
0
    def __call__(self, src_ds, footprint_wkt):
        logger.info("Applying AlphaBandOptimization")
        dt = src_ds.GetRasterBand(1).DataType
        if src_ds.RasterCount == 3:
            src_ds.AddBand(dt)
        elif src_ds.RasterCount == 4:
            pass  # okay
        else:
            raise Exception("Cannot add alpha band, as the current number of "
                            "bands '%d' does not match" % src_ds.RasterCount)

        # initialize the alpha band with zeroes (completely transparent)
        band = src_ds.GetRasterBand(4)
        band.Fill(0)

        # set up the layer with geometry
        ogr_ds = ogr.GetDriverByName('Memory').CreateDataSource('wkt')

        sr = osr.SpatialReference()
        sr.ImportFromEPSG(4326)
        layer = ogr_ds.CreateLayer('poly', srs=sr.sr)

        feat = ogr.Feature(layer.GetLayerDefn())
        feat.SetGeometryDirectly(ogr.Geometry(wkt=footprint_wkt))
        layer.CreateFeature(feat)

        # rasterize the polygon, burning the opaque value into the alpha band
        gdal.RasterizeLayer(src_ds, [4],
                            layer,
                            burn_values=[get_limits(dt)[1]])
Esempio n. 3
0
    def __call__(self, src_ds, footprint_wkt):
        logger.info("Applying AlphaBandOptimization")
        dt = src_ds.GetRasterBand(1).DataType
        if src_ds.RasterCount == 3:
            src_ds.AddBand(dt)
        elif src_ds.RasterCount == 4:
            pass  # okay
        else:
            raise Exception("Cannot add alpha band, as the current number of "
                            "bands '%d' does not match" % src_ds.RasterCount)

        # initialize the alpha band with zeroes (completely transparent)
        band = src_ds.GetRasterBand(4)
        band.Fill(0)

        # set up the layer with geometry
        ogr_ds = ogr.GetDriverByName('Memory').CreateDataSource('wkt')

        sr = osr.SpatialReference()
        sr.ImportFromEPSG(4326)
        layer = ogr_ds.CreateLayer('poly', srs=sr.sr)

        feat = ogr.Feature(layer.GetLayerDefn())
        feat.SetGeometryDirectly(ogr.Geometry(wkt=footprint_wkt))
        layer.CreateFeature(feat)

        # rasterize the polygon, burning the opaque value into the alpha band
        gdal.RasterizeLayer(src_ds, [4], layer, burn_values=[get_limits(dt)[1]])
Esempio n. 4
0
 def __call__(self, src_ds, color_to_alpha=0, color_to_alpha_margin=15):
     logger.info("Applying ColorToAlphaOptimization")
     dt = src_ds.GetRasterBand(1).DataType
     higher_cut = color_to_alpha + color_to_alpha_margin
     lower_cut = color_to_alpha - color_to_alpha_margin
     largest_value_of_datatype = get_limits(dt)[1]
     if src_ds.RasterCount == 3:
         src_ds.AddBand(dt)
         # prefill with not-transparent
         src_ds.GetRasterBand(4).fill(largest_value_of_datatype)
     elif src_ds.RasterCount == 4:
         pass  # okay
     else:
         raise Exception("Cannot add alpha band, as the current number of "
                         "bands '%d' does not match" % src_ds.RasterCount)
     try:
         # save all bands to memory -> np array
         as_array_3d = src_ds.ReadAsArray()
         # set alpha pixel to transparent if all three are that color
         [R, G, B, A] = numpy.split(as_array_3d, 4)
         # turn to two dimensional arrays
         R = R[0, :, :]
         G = G[0, :, :]
         B = B[0, :, :]
         A = A[0, :, :]
         # compute masks
         R_mask = numpy.zeros(R.shape, dtype=bool)
         G_mask = numpy.zeros(R.shape, dtype=bool)
         B_mask = numpy.zeros(R.shape, dtype=bool)
         R_mask = (R < higher_cut) & (R > lower_cut)
         G_mask = (G < higher_cut) & (G > lower_cut)
         B_mask = (B < higher_cut) & (B > lower_cut)
         # merge three separate masks with logical AND
         rg_mask = numpy.logical_and(R_mask, G_mask)
         rgb_mask = numpy.logical_and(rg_mask, B_mask)
         # insert into alpha channel
         A[rgb_mask] = 0
         src_ds.GetRasterBand(4).WriteArray(A)
         return src_ds
     except:
         raise
Esempio n. 5
0
    def __call__(self, src_ds):
        logger.info("Applying BandSelectionOptimization")
        try:
            dst_ds = create_temp(src_ds.RasterXSize,
                                 src_ds.RasterYSize,
                                 len(self.bands),
                                 self.datatype,
                                 temp_root=self.temporary_directory)
            dst_range = get_limits(self.datatype)

            multiple, multiple_written = 0, False

            for dst_index, (src_index, dmin, dmax) in enumerate(self.bands, 1):
                # check if next band is equal
                if dst_index < len(self.bands) and \
                        (src_index, dmin, dmax) == self.bands[dst_index]:
                    multiple += 1
                    continue
                # check that src band is available
                if src_index > src_ds.RasterCount:
                    continue

                # initialize with zeros if band is 0
                if src_index == 0:
                    src_band = src_ds.GetRasterBand(1)
                    data = numpy.zeros((src_band.YSize, src_band.XSize),
                                       dtype=gdal_array.codes[self.datatype])
                    src_min, src_max = (0, 0)
                # use src_ds band otherwise
                else:
                    src_band = src_ds.GetRasterBand(src_index)
                    src_min, src_max = src_band.ComputeRasterMinMax()

                # get min/max values or calculate from band
                if dmin is None:
                    dmin = get_limits(src_band.DataType)[0]
                elif dmin == "min":
                    dmin = src_min
                if dmax is None:
                    dmax = get_limits(src_band.DataType)[1]
                elif dmax == "max":
                    dmax = src_max
                src_range = (float(dmin), float(dmax))

                block_x_size, block_y_size = src_band.GetBlockSize()

                num_x = int(math.ceil(float(src_band.XSize) / block_x_size))
                num_y = int(math.ceil(float(src_band.YSize) / block_y_size))

                dst_band = dst_ds.GetRasterBand(dst_index)
                if src_band.GetNoDataValue() is not None:
                    dst_band.SetNoDataValue(src_band.GetNoDataValue())

                for block_x, block_y in product(range(num_x), range(num_y)):
                    offset_x = block_x * block_x_size
                    offset_y = block_y * block_y_size
                    size_x = min(src_band.XSize - offset_x, block_x_size)
                    size_y = min(src_band.YSize - offset_y, block_y_size)
                    data = src_band.ReadAsArray(offset_x, offset_y, size_x,
                                                size_y)

                    # perform clipping and scaling
                    data = ((dst_range[1] - dst_range[0]) *
                            ((numpy.clip(data, dmin, dmax) - src_range[0]) /
                             (src_range[1] - src_range[0])))

                    # set new datatype
                    data = data.astype(gdal_array.codes[self.datatype])

                    # write result
                    dst_band.WriteArray(data, offset_x, offset_y)

                    # write equal bands at once
                    if multiple > 0:
                        for i in range(multiple):
                            dst_band_multiple = dst_ds.GetRasterBand(
                                dst_index - 1 - i)
                            dst_band_multiple.WriteArray(
                                data, offset_x, offset_y)
                        multiple_written = True

                if multiple_written:
                    multiple = 0
                    multiple_written = False

            copy_projection(src_ds, dst_ds)
            copy_metadata(src_ds, dst_ds)

            return dst_ds

        except:
            cleanup_temp(dst_ds)
            raise
Esempio n. 6
0
    def __call__(self, src_ds):
        logger.info("Applying BandSelectionOptimization")
        try:
            dst_ds = create_temp(src_ds.RasterXSize, src_ds.RasterYSize,
                                 len(self.bands), self.datatype,
                                 temp_root=self.temporary_directory)
            dst_range = get_limits(self.datatype)

            multiple, multiple_written = 0, False

            for dst_index, (src_index, dmin, dmax) in enumerate(self.bands, 1):
                # check if next band is equal
                if dst_index < len(self.bands) and \
                        (src_index, dmin, dmax) == self.bands[dst_index]:
                    multiple += 1
                    continue
                # check that src band is available
                if src_index > src_ds.RasterCount:
                    continue

                # initialize with zeros if band is 0
                if src_index == 0:
                    src_band = src_ds.GetRasterBand(1)
                    data = numpy.zeros(
                        (src_band.YSize, src_band.XSize),
                        dtype=gdal_array.codes[self.datatype]
                    )
                    src_min, src_max = (0, 0)
                # use src_ds band otherwise
                else:
                    src_band = src_ds.GetRasterBand(src_index)
                    src_min, src_max = src_band.ComputeRasterMinMax()

                # get min/max values or calculate from band
                if dmin is None:
                    dmin = get_limits(src_band.DataType)[0]
                elif dmin == "min":
                    dmin = src_min
                if dmax is None:
                    dmax = get_limits(src_band.DataType)[1]
                elif dmax == "max":
                    dmax = src_max
                src_range = (float(dmin), float(dmax))

                block_x_size, block_y_size = src_band.GetBlockSize()

                num_x = int(math.ceil(float(src_band.XSize) / block_x_size))
                num_y = int(math.ceil(float(src_band.YSize) / block_y_size))

                dst_band = dst_ds.GetRasterBand(dst_index)
                if src_band.GetNoDataValue() is not None:
                    dst_band.SetNoDataValue(src_band.GetNoDataValue())

                for block_x, block_y in product(range(num_x), range(num_y)):
                    offset_x = block_x * block_x_size
                    offset_y = block_y * block_y_size
                    size_x = min(src_band.XSize - offset_x, block_x_size)
                    size_y = min(src_band.YSize - offset_y, block_y_size)
                    data = src_band.ReadAsArray(
                        offset_x, offset_y, size_x, size_y
                    )

                    # perform clipping and scaling
                    data = ((dst_range[1] - dst_range[0]) *
                            ((numpy.clip(data, dmin, dmax) - src_range[0]) /
                            (src_range[1] - src_range[0])))

                    # set new datatype
                    data = data.astype(gdal_array.codes[self.datatype])

                    # write result
                    dst_band.WriteArray(data, offset_x, offset_y)

                    # write equal bands at once
                    if multiple > 0:
                        for i in range(multiple):
                            dst_band_multiple = dst_ds.GetRasterBand(
                                dst_index-1-i
                            )
                            dst_band_multiple.WriteArray(
                                data, offset_x, offset_y
                            )
                        multiple_written = True

                if multiple_written:
                    multiple = 0
                    multiple_written = False

            copy_projection(src_ds, dst_ds)
            copy_metadata(src_ds, dst_ds)

            return dst_ds

        except:
            cleanup_temp(dst_ds)
            raise