def __call__(self, src_ds): dst_ds = create_mem(src_ds.RasterXSize, src_ds.RasterYSize, 1, gdal.GDT_Byte) if not self.palette_file: # create a color table as a median of the given dataset ct = gdal.ColorTable() gdal.ComputeMedianCutPCT(src_ds.GetRasterBand(1), src_ds.GetRasterBand(2), src_ds.GetRasterBand(3), 256, ct) else: # copy the color table from the given palette file pct_ds = gdal.Open(self.palette_file) pct_ct = pct_ds.GetRasterBand(1).GetRasterColorTable() if not pct_ct: raise ValueError("The palette file '%s' does not have a Color " "Table." % self.palette_file) ct = pct_ct.Clone() pct_ds = None dst_ds.GetRasterBand(1).SetRasterColorTable(ct) gdal.DitherRGB2PCT(src_ds.GetRasterBand(1), src_ds.GetRasterBand(2), src_ds.GetRasterBand(3), dst_ds.GetRasterBand(1), ct) copy_projection(src_ds, dst_ds) copy_metadata(src_ds, dst_ds) return dst_ds
def __call__(self, src_ds): # setup src_sr = osr.SpatialReference() src_sr.ImportFromWkt(src_ds.GetProjection()) dst_sr = osr.SpatialReference() dst_sr.ImportFromEPSG(self.srid) if src_sr.IsSame(dst_sr) and (src_ds.GetGeoTransform()[1] > 0) and (src_ds.GetGeoTransform()[5] < 0): logger.info( "Source and destination projection are equal and image " "is not flipped. Thus, no reprojection is required." ) return src_ds # create a temporary dataset to get information about the output size tmp_ds = gdal.AutoCreateWarpedVRT(src_ds, None, dst_sr.ExportToWkt(), gdal.GRA_Bilinear, 0.125) # create the output dataset dst_ds = create_mem( tmp_ds.RasterXSize, tmp_ds.RasterYSize, src_ds.RasterCount, src_ds.GetRasterBand(1).DataType ) # reproject the image dst_ds.SetProjection(dst_sr.ExportToWkt()) dst_ds.SetGeoTransform(tmp_ds.GetGeoTransform()) gdal.ReprojectImage(src_ds, dst_ds, src_sr.ExportToWkt(), dst_sr.ExportToWkt(), gdal.GRA_Bilinear) tmp_ds = None # copy the metadata copy_metadata(src_ds, dst_ds) return dst_ds
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): logger.info("Applying ReprojectionOptimization") # setup src_sr = osr.SpatialReference() src_sr.ImportFromWkt(src_ds.GetProjection()) dst_sr = osr.SpatialReference() dst_sr.ImportFromEPSG(self.srid) if src_sr.IsSame(dst_sr) and (src_ds.GetGeoTransform()[1] > 0) \ and (src_ds.GetGeoTransform()[5] < 0) \ and (src_ds.GetGeoTransform()[2] == 0) \ and (src_ds.GetGeoTransform()[4] == 0): logger.info( "Source and destination projection are equal and image " "is not flipped or has rotated axes. Thus, no " "reprojection is required.") return src_ds # create a temporary dataset to get information about the output size tmp_ds = gdal.AutoCreateWarpedVRT(src_ds, None, dst_sr.ExportToWkt(), gdal.GRA_Bilinear, 0.125) try: # create the output dataset dst_ds = create_temp(tmp_ds.RasterXSize, tmp_ds.RasterYSize, src_ds.RasterCount, src_ds.GetRasterBand(1).DataType, temp_root=self.temporary_directory) # initialize with no data for i in range(src_ds.RasterCount): src_band = src_ds.GetRasterBand(i + 1) if src_band.GetNoDataValue() is not None: dst_band = dst_ds.GetRasterBand(i + 1) dst_band.SetNoDataValue(src_band.GetNoDataValue()) dst_band.Fill(src_band.GetNoDataValue()) # reproject the image dst_ds.SetProjection(dst_sr.ExportToWkt()) dst_ds.SetGeoTransform(tmp_ds.GetGeoTransform()) gdal.ReprojectImage(src_ds, dst_ds, src_sr.ExportToWkt(), dst_sr.ExportToWkt(), gdal.GRA_Bilinear) tmp_ds = None # copy the metadata copy_metadata(src_ds, dst_ds) return dst_ds except: cleanup_temp(dst_ds) raise
def __call__(self, src_ds): logger.info("Applying ReprojectionOptimization") # setup src_sr = osr.SpatialReference() src_sr.ImportFromWkt(src_ds.GetProjection()) dst_sr = osr.SpatialReference() dst_sr.ImportFromEPSG(self.srid) if src_sr.IsSame(dst_sr) and (src_ds.GetGeoTransform()[1] > 0) \ and (src_ds.GetGeoTransform()[5] < 0) \ and (src_ds.GetGeoTransform()[2] == 0) \ and (src_ds.GetGeoTransform()[4] == 0): logger.info("Source and destination projection are equal and image " "is not flipped or has rotated axes. Thus, no " "reprojection is required.") return src_ds # create a temporary dataset to get information about the output size tmp_ds = gdal.AutoCreateWarpedVRT(src_ds, None, dst_sr.ExportToWkt(), gdal.GRA_Bilinear, 0.125) try: # create the output dataset dst_ds = create_temp(tmp_ds.RasterXSize, tmp_ds.RasterYSize, src_ds.RasterCount, src_ds.GetRasterBand(1).DataType, temp_root=self.temporary_directory) # initialize with no data for i in range(src_ds.RasterCount): src_band = src_ds.GetRasterBand(i+1) if src_band.GetNoDataValue() is not None: dst_band = dst_ds.GetRasterBand(i+1) dst_band.SetNoDataValue(src_band.GetNoDataValue()) dst_band.Fill(src_band.GetNoDataValue()) # reproject the image dst_ds.SetProjection(dst_sr.ExportToWkt()) dst_ds.SetGeoTransform(tmp_ds.GetGeoTransform()) gdal.ReprojectImage(src_ds, dst_ds, src_sr.ExportToWkt(), dst_sr.ExportToWkt(), gdal.GRA_Bilinear) tmp_ds = None # copy the metadata copy_metadata(src_ds, dst_ds) return dst_ds except: cleanup_temp(dst_ds) raise
def __call__(self, src_ds): logger.info("Applying ColorIndexOptimization") try: dst_ds = create_temp(src_ds.RasterXSize, src_ds.RasterYSize, 1, gdal.GDT_Byte, temp_root=self.temporary_directory) if not self.palette_file: # create a color table as a median of the given dataset ct = gdal.ColorTable() gdal.ComputeMedianCutPCT(src_ds.GetRasterBand(1), src_ds.GetRasterBand(2), src_ds.GetRasterBand(3), 256, ct) else: # copy the color table from the given palette file pct_ds = gdal.Open(self.palette_file) pct_ct = pct_ds.GetRasterBand(1).GetRasterColorTable() if not pct_ct: raise ValueError("The palette file '%s' does not have a " "Color Table." % self.palette_file) ct = pct_ct.Clone() pct_ds = None dst_ds.GetRasterBand(1).SetRasterColorTable(ct) gdal.DitherRGB2PCT(src_ds.GetRasterBand(1), src_ds.GetRasterBand(2), src_ds.GetRasterBand(3), dst_ds.GetRasterBand(1), ct) 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 ColorIndexOptimization") try: dst_ds = create_temp(src_ds.RasterXSize, src_ds.RasterYSize, 1, gdal.GDT_Byte, temp_root=self.temporary_directory) if not self.palette_file: # create a color table as a median of the given dataset ct = gdal.ColorTable() gdal.ComputeMedianCutPCT(src_ds.GetRasterBand(1), src_ds.GetRasterBand(2), src_ds.GetRasterBand(3), 256, ct) else: # copy the color table from the given palette file pct_ds = gdal.Open(self.palette_file) pct_ct = pct_ds.GetRasterBand(1).GetRasterColorTable() if not pct_ct: raise ValueError("The palette file '%s' does not have a " "Color Table." % self.palette_file) ct = pct_ct.Clone() pct_ds = None dst_ds.GetRasterBand(1).SetRasterColorTable(ct) gdal.DitherRGB2PCT(src_ds.GetRasterBand(1), src_ds.GetRasterBand(2), src_ds.GetRasterBand(3), dst_ds.GetRasterBand(1), ct) 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
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 apply(self, src_ds): # setup dst_sr = osr.SpatialReference() gcp_sr = osr.SpatialReference() dst_sr.ImportFromEPSG(self.srid if self.srid is not None else self.gcp_srid) gcp_sr.ImportFromEPSG(self.gcp_srid) logger.debug("Using GCP Projection '%s'" % gcp_sr.ExportToWkt()) logger.debug( "Applying GCPs: MULTIPOINT(%s) -> MULTIPOINT(%s)" % ( ", ".join([("(%f %f)") % (gcp.GCPX, gcp.GCPY) for gcp in self.gcps]), ", ".join([("(%f %f)") % (gcp.GCPPixel, gcp.GCPLine) for gcp in self.gcps]), ) ) # set the GCPs src_ds.SetGCPs(self.gcps, gcp_sr.ExportToWkt()) # Try to find and use the best transform method/order. # Orders are: -1 (TPS), 3, 2, and 1 (all GCP) # Loop over the min and max GCP number to order map. for min_gcpnum, max_gcpnum, order in [(3, None, -1), (10, None, 3), (6, None, 2), (3, None, 1)]: # if the number of GCP matches if len(self.gcps) >= min_gcpnum and (max_gcpnum is None or len(self.gcps) <= max_gcpnum): try: if order < 0: # let the reftools suggest the right interpolator rt_prm = rt.suggest_transformer(src_ds) else: # use the polynomial GCP interpolation as requested rt_prm = {"method": rt.METHOD_GCP, "order": order} logger.debug( "Trying order '%i' {method:%s,order:%s}" % (order, rt.METHOD2STR[rt_prm["method"]], rt_prm["order"]) ) # get the suggested pixel size/geotransform size_x, size_y, geotransform = rt.suggested_warp_output( src_ds, None, dst_sr.ExportToWkt(), **rt_prm ) if size_x > 100000 or size_y > 100000: raise RuntimeError("Calculated size exceeds limit.") logger.debug("New size is '%i x %i'" % (size_x, size_y)) # create the output dataset dst_ds = create_mem(size_x, size_y, src_ds.RasterCount, src_ds.GetRasterBand(1).DataType) # reproject the image dst_ds.SetProjection(dst_sr.ExportToWkt()) dst_ds.SetGeoTransform(geotransform) rt.reproject_image(src_ds, "", dst_ds, "", **rt_prm) copy_metadata(src_ds, dst_ds) # retrieve the footprint from the given GCPs footprint_wkt = rt.get_footprint_wkt(src_ds, **rt_prm) except RuntimeError, e: logger.debug("Failed using order '%i'. Error was '%s'." % (order, str(e))) # the given method was not applicable, use the next one continue else: logger.debug("Successfully used order '%i'" % order) # the transform method was successful, exit the loop break
def apply(self, src_ds): # setup dst_sr = osr.SpatialReference() gcp_sr = osr.SpatialReference() dst_sr.ImportFromEPSG(self.srid if self.srid is not None else self.gcp_srid) gcp_sr.ImportFromEPSG(self.gcp_srid) logger.debug("Using GCP Projection '%s'" % gcp_sr.ExportToWkt()) logger.debug("Applying GCPs: MULTIPOINT(%s) -> MULTIPOINT(%s)" % (", ".join([("(%f %f)") % (gcp.GCPX, gcp.GCPY) for gcp in self.gcps]) , ", ".join([("(%f %f)") % (gcp.GCPPixel, gcp.GCPLine) for gcp in self.gcps]))) # set the GCPs src_ds.SetGCPs(self.gcps, gcp_sr.ExportToWkt()) # Try to find and use the best transform method/order. # Orders are: -1 (TPS), 3, 2, and 1 (all GCP) # Loop over the min and max GCP number to order map. for min_gcpnum, max_gcpnum, order in [(3, None, -1), (10, None, 3), (6, None, 2), (3, None, 1)]: # if the number of GCP matches if len(self.gcps) >= min_gcpnum and (max_gcpnum is None or len(self.gcps) <= max_gcpnum): try: if ( order < 0 ) : # let the reftools suggest the right interpolator rt_prm = rt.suggest_transformer( src_ds ) else: # use the polynomial GCP interpolation as requested rt_prm = { "method":rt.METHOD_GCP, "order":order } logger.debug("Trying order '%i' {method:%s,order:%s}" % \ (order, rt.METHOD2STR[rt_prm["method"]] , rt_prm["order"] ) ) # get the suggested pixel size/geotransform size_x, size_y, geotransform = rt.suggested_warp_output( src_ds, None, dst_sr.ExportToWkt(), **rt_prm ) if size_x > 100000 or size_y > 100000: raise RuntimeError("Calculated size exceeds limit.") logger.debug("New size is '%i x %i'" % (size_x, size_y)) # create the output dataset dst_ds = create_mem(size_x, size_y, src_ds.RasterCount, src_ds.GetRasterBand(1).DataType) # reproject the image dst_ds.SetProjection(dst_sr.ExportToWkt()) dst_ds.SetGeoTransform(geotransform) rt.reproject_image(src_ds, "", dst_ds, "", **rt_prm ) copy_metadata(src_ds, dst_ds) # retrieve the footprint from the given GCPs footprint_wkt = rt.get_footprint_wkt(src_ds, **rt_prm ) except RuntimeError as e: logger.debug("Failed using order '%i'. Error was '%s'." % (order, str(e))) # the given method was not applicable, use the next one continue else: logger.debug("Successfully used order '%i'" % order) # the transform method was successful, exit the loop break else: # no method worked, so raise an error raise GCPTransformException("Could not find a valid transform method.") # reproject the footprint to a lon/lat projection if necessary if not gcp_sr.IsGeographic(): out_sr = osr.SpatialReference() out_sr.ImportFromEPSG(4326) geom = ogr.CreateGeometryFromWkt(footprint_wkt, gcp_sr) geom.TransformTo(out_sr) footprint_wkt = geom.ExportToWkt() logger.debug("Calculated footprint: '%s'." % footprint_wkt) return dst_ds, footprint_wkt
def apply(self, src_ds): # setup dst_sr = osr.SpatialReference() dst_sr.ImportFromEPSG(self.srid) logger.debug("Using internal GCP Projection.") num_gcps = src_ds.GetGCPCount() # Try to find and use the best transform method/order. # Orders are: -1 (TPS), 3, 2, and 1 (all GCP) # Loop over the min and max GCP number to order map. for min_gcpnum, max_gcpnum, order in [(3, None, -1), (10, None, 3), (6, None, 2), (3, None, 1)]: # if the number of GCP matches if num_gcps >= min_gcpnum and (max_gcpnum is None or num_gcps <= max_gcpnum): try: if (order < 0): # let the reftools suggest the right interpolator rt_prm = reftools.suggest_transformer(src_ds) else: # use the polynomial GCP interpolation as requested rt_prm = { "method": reftools.METHOD_GCP, "order": order } logger.debug("Trying order '%i' {method:%s,order:%s}" % (order, reftools.METHOD2STR[rt_prm["method"]], rt_prm["order"])) # get the suggested pixel size/geotransform size_x, size_y, gt = reftools.suggested_warp_output( src_ds, None, dst_sr.ExportToWkt(), **rt_prm) if size_x > 100000 or size_y > 100000: raise RuntimeError("Calculated size exceeds limit.") logger.debug("New size is '%i x %i'" % (size_x, size_y)) # create the output dataset dst_ds = create_mem(size_x, size_y, src_ds.RasterCount, src_ds.GetRasterBand(1).DataType) # reproject the image dst_ds.SetProjection(dst_sr.ExportToWkt()) dst_ds.SetGeoTransform(gt) reftools.reproject_image(src_ds, "", dst_ds, "", **rt_prm) copy_metadata(src_ds, dst_ds) # retrieve the footprint from the given GCPs footprint_wkt = reftools.get_footprint_wkt( src_ds, **rt_prm) except RuntimeError, e: logger.debug("Failed using order '%i'. Error was '%s'." % (order, str(e))) # the given method was not applicable, use the next one continue else: logger.debug("Successfully used order '%i'" % order) # the transform method was successful, exit the loop break