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
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]])
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
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
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