def geotiff_save(self, filename, compression=6, tags=None, gdal_options=None, blocksize=0, geotransform=None, spatialref=None, floating_point=False): """Save the image to the given *filename* in geotiff_ format, with the *compression* level in [0, 9]. 0 means not compressed. The *tags* argument is a dict of tags to include in the image (as metadata). By default it uses the 'area' instance to generate geotransform and spatialref information, this can be overwritten by the arguments *geotransform* and *spatialref*. *floating_point* allows the saving of 'L' mode images in floating point format if set to True. .. _geotiff: http://trac.osgeo.org/geotiff/ """ from osgeo import gdal, osr raster = gdal.GetDriverByName("GTiff") if floating_point: if self.mode != "L": raise ValueError("Image must be in 'L' mode for floating point" " geotif saving") channels = [self.channels[0].astype(np.float64)] fill_value = self.fill_value or 0 gformat = gdal.GDT_Float64 else: channels, fill_value = self._finalize() gformat = gdal.GDT_Byte LOG.debug("Saving to GeoTiff.") if tags is not None: self.tags.update(tags) if gdal_options is not None: self.gdal_options.update(gdal_options) g_opts = ["=".join(i) for i in self.gdal_options.items()] if compression != 0: g_opts.append("COMPRESS=DEFLATE") g_opts.append("ZLEVEL=" + str(compression)) if blocksize != 0: g_opts.append("TILED=YES") g_opts.append("BLOCKXSIZE=" + str(blocksize)) g_opts.append("BLOCKYSIZE=" + str(blocksize)) if(self.mode == "L"): ensure_dir(filename) if fill_value is not None: dst_ds = raster.Create(filename, self.width, self.height, 1, gformat, g_opts) else: g_opts.append("ALPHA=YES") dst_ds = raster.Create(filename, self.width, self.height, 2, gformat, g_opts) self._gdal_write_channels(dst_ds, channels, 255, fill_value) elif(self.mode == "LA"): ensure_dir(filename) g_opts.append("ALPHA=YES") dst_ds = raster.Create(filename, self.width, self.height, 2, gformat, g_opts) self._gdal_write_channels(dst_ds, channels[:-1], channels[1], fill_value) elif(self.mode == "RGB"): ensure_dir(filename) if fill_value is not None: dst_ds = raster.Create(filename, self.width, self.height, 3, gformat, g_opts) else: g_opts.append("ALPHA=YES") dst_ds = raster.Create(filename, self.width, self.height, 4, gformat, g_opts) self._gdal_write_channels(dst_ds, channels, 255, fill_value) elif(self.mode == "RGBA"): ensure_dir(filename) g_opts.append("ALPHA=YES") dst_ds = raster.Create(filename, self.width, self.height, 4, gformat, g_opts) self._gdal_write_channels(dst_ds, channels[:-1], channels[3], fill_value) else: raise NotImplementedError("Saving to GeoTIFF using image mode" " %s is not implemented."%self.mode) # Create raster GeoTransform based on upper left corner and pixel # resolution ... if not overwritten by argument geotranform. if geotransform: dst_ds.SetGeoTransform(geotransform) if spatialref: if not isinstance(spatialref, str): spatialref = spatialref.ExportToWkt() dst_ds.SetProjection(spatialref) else: try: from pyresample import utils from mpop.projector import get_area_def area = get_area_def(self.area) except (utils.AreaNotFound, AttributeError): area = self.area try: adfgeotransform = [area.area_extent[0], area.pixel_size_x, 0, area.area_extent[3], 0, -area.pixel_size_y] dst_ds.SetGeoTransform(adfgeotransform) srs = osr.SpatialReference() srs.ImportFromProj4(area.proj4_string) srs.SetProjCS(area.proj_id) try: srs.SetWellKnownGeogCS(area.proj_dict['ellps']) except KeyError: pass try: # Check for epsg code. srs.SetAuthority('PROJCS', 'EPSG', int(area.proj_dict['init']. split('epsg:')[1])) except (KeyError, IndexError): pass srs = srs.ExportToWkt() dst_ds.SetProjection(srs) except AttributeError: LOG.exception("Could not load geographic data, invalid area") self.tags.update({'TIFFTAG_DATETIME': self.time_slot.strftime("%Y:%m:%d %H:%M:%S")}) dst_ds.SetMetadata(self.tags, '') # Close the dataset dst_ds = None
def geotiff_save( self, filename, compression=6, tags=None, gdal_options=None, blocksize=0, geotransform=None, spatialref=None ): """Save the image to the given *filename* in geotiff_ format, with the *compression* level in [0, 9]. 0 means not compressed. The *tags* argument is a dict of tags to include in the image (as metadata). By default it uses the 'area' instance to generate geotransform and spatialref information, this can be overwritte by the arguments *geotransform* and *spatialref*. .. _geotiff: http://trac.osgeo.org/geotiff/ """ from osgeo import gdal, osr raster = gdal.GetDriverByName("GTiff") channels, fill_value = self._finalize() LOG.debug("Saving to GeoTiff.") if tags is not None: self.tags.update(tags) if gdal_options is not None: self.gdal_options.update(gdal_options) g_opts = ["=".join(i) for i in self.gdal_options.items()] if compression != 0: g_opts.append("COMPRESS=DEFLATE") g_opts.append("ZLEVEL=" + str(compression)) if blocksize != 0: g_opts.append("TILED=YES") g_opts.append("BLOCKXSIZE=" + str(blocksize)) g_opts.append("BLOCKYSIZE=" + str(blocksize)) if self.mode == "L": ensure_dir(filename) if fill_value is not None: dst_ds = raster.Create(filename, self.width, self.height, 1, gdal.GDT_Byte, g_opts) else: dst_ds = raster.Create(filename, self.width, self.height, 2, gdal.GDT_Byte, g_opts) self._gdal_write_channels(dst_ds, channels, 255, fill_value) elif self.mode == "RGB": ensure_dir(filename) if fill_value is not None: dst_ds = raster.Create(filename, self.width, self.height, 3, gdal.GDT_Byte, g_opts) else: dst_ds = raster.Create(filename, self.width, self.height, 4, gdal.GDT_Byte, g_opts) self._gdal_write_channels(dst_ds, channels, 255, fill_value) elif self.mode == "RGBA": ensure_dir(filename) dst_ds = raster.Create(filename, self.width, self.height, 4, gdal.GDT_Byte, g_opts) self._gdal_write_channels(dst_ds, channels, channels[3], fill_value) else: raise NotImplementedError("Saving to GeoTIFF using image mode" " %s is not implemented." % self.mode) # Create raster GeoTransform based on upper left corner and pixel # resolution ... if not overwritten by argument geotranform. if geotransform: dst_ds.SetGeoTransform(geotransform) if spatialref: if not isinstance(spatialref, str): spatialref = spatialref.ExportToWkt() dst_ds.SetProjection(spatialref) else: try: from pyresample import utils from mpop.projector import get_area_def area = get_area_def(self.area_id) except (utils.AreaNotFound, AttributeError): area = self.area_id try: adfgeotransform = [ area.area_extent[0], area.pixel_size_x, 0, area.area_extent[3], 0, -area.pixel_size_y, ] dst_ds.SetGeoTransform(adfgeotransform) srs = osr.SpatialReference() srs.SetProjCS(area.proj_id) srs.ImportFromProj4(area.proj4_string) srs = srs.ExportToWkt() dst_ds.SetProjection(srs) except AttributeError: LOG.exception("Could not load geographic data, invalid area") self.tags.update({"TIFFTAG_DATETIME": self.time_slot.strftime("%Y:%m:%d %H:%M:%S")}) dst_ds.SetMetadata(self.tags, "") # Close the dataset dst_ds = None