def create_file(cls, path, fp, dtype, channel_count, channels_schema, driver, options, wkt, ow): """Create a raster dataset""" # Step 0 - Find driver ********************************************** ** success, payload = GDALErrorCatcher(gdal.GetDriverByName, none_is_error=True)(driver) if not success: raise ValueError( 'Could not find a driver named `{}` (gdal error: `{}`)'.format( driver, payload[1])) dr = payload # Step 1 - Overwrite ************************************************ ** if dr.ShortName != 'MEM' and os.path.exists(path): if ow: success, payload = GDALErrorCatcher( dr.Delete, nonzero_int_is_error=True)(path) if not success: msg = 'Could not delete `{}` using driver `{}` (gdal error: `{}`)'.format( path, dr.ShortName, payload[1]) raise RuntimeError(msg) else: msg = "Can't create `{}` with `ow=False` (overwrite) because file exist".format( path, ) raise RuntimeError(msg) # Step 2 - Create gdal_ds ******************************************* ** options = [str(arg) for arg in options] success, payload = GDALErrorCatcher(dr.Create)( path, fp.rsizex, fp.rsizey, channel_count, conv.gdt_of_any_equiv(dtype), options) if not success: # pragma: no cover raise RuntimeError( 'Could not create `{}` using driver `{}` (gdal error: `{}`)'. format(path, dr.ShortName, payload[1])) gdal_ds = payload # Step 3 - Set spatial reference ************************************ ** if wkt is not None: gdal_ds.SetProjection(wkt) gdal_ds.SetGeoTransform(fp.gt) # Step 4 - Set channels schema ************************************** ** channels_schema = _tools.sanitize_channels_schema( channels_schema, channel_count) cls._apply_channels_schema(gdal_ds, channels_schema) gdal_ds.FlushCache() return gdal_ds
def _create_vrt_band_xml(i, uuidstr, dtype, nodata, interpretation, offset, scale, mask): band = xml.Element('VRTRasterBand') band.set('dataType', gdal.GetDataTypeName(conv.gdt_of_any_equiv(dtype))) band.set('band', str(i)) band.set('subClass', 'VRTDerivedRasterBand') elt = xml.Element('PixelFunctionLanguage') elt.text = 'Python' band.append(elt) elt = xml.Element('PixelFunctionType') elt.text = 'buzzard._raster_recipe._pixel_function_entry_point' band.append(elt) elt = xml.Element('PixelFunctionArguments') elt.set('band_index', str(i)) elt.set('proxy_uuid', uuidstr) band.append(elt) if nodata is not None: elt = xml.Element('NoDataValue') elt.text = str(nodata) band.append(elt) if interpretation is not None: elt = xml.Element('ColorInterp') elt.text = conv.str_of_gci(interpretation).replace('band', '') band.append(elt) if offset is not None: elt = xml.Element('Offset') elt.text = str(offset) band.append(elt) if scale is not None: elt = xml.Element('Scale') elt.text = str(scale) band.append(elt) if mask is not None: elt = xml.Element('MaskBand') elt.text = str(mask) band.append(elt) return band
def _create_file(cls, path, fp, dtype, band_count, band_schema, driver, options, sr): """Create a raster datasource""" dr = gdal.GetDriverByName(driver) if os.path.isfile(path): err = dr.Delete(path) if err: raise Exception('Could not delete %s' % path) options = [str(arg) for arg in options] gdal_ds = dr.Create(path, fp.rsizex, fp.rsizey, band_count, conv.gdt_of_any_equiv(dtype), options) if gdal_ds is None: raise Exception('Could not create gdal dataset (%s)' % gdal.GetLastErrorMsg()) if sr is not None: gdal_ds.SetProjection(osr.GetUserInputAsWKT(sr)) gdal_ds.SetGeoTransform(fp.gt) band_schema = cls._sanitize_band_schema(band_schema, band_count) cls._apply_band_schema(gdal_ds, band_schema) gdal_ds.FlushCache() return gdal_ds
def create_file(cls, path, fp, dtype, band_count, band_schema, driver, options, wkt): """Create a raster datasource""" dr = gdal.GetDriverByName(driver) if os.path.isfile(path): err = dr.Delete(path) if err: # pragma: no cover raise Exception('Could not delete %s' % path) options = [str(arg) for arg in options] gdal_ds = dr.Create(path, fp.rsizex, fp.rsizey, band_count, conv.gdt_of_any_equiv(dtype), options) if gdal_ds is None: # pragma: no cover raise Exception('Could not create gdal dataset (%s)' % str(gdal.GetLastErrorMsg()).strip('\n')) if wkt is not None: gdal_ds.SetProjection(wkt) gdal_ds.SetGeoTransform(fp.gt) band_schema = _tools.sanitize_band_schema(band_schema, band_count) cls._apply_band_schema(gdal_ds, band_schema) gdal_ds.FlushCache() return gdal_ds
def _write_cache_data(self, cache_tile, data): """ writes cache data """ # print(self.h, "writing ") sr = self.wkt_origin filepath = os.path.join(self._cache_dir, str(uuid.uuid4())) dr = gdal.GetDriverByName("GTiff") if os.path.isfile(filepath): err = dr.Delete(filepath) if err: raise Exception('Could not delete %s' % filepath) options = () gdal_ds = dr.Create(filepath, cache_tile.rsizex, cache_tile.rsizey, self.nbands, conv.gdt_of_any_equiv(self.dtype), options) if gdal_ds is None: raise Exception('Could not create gdal dataset (%s)' % gdal.GetLastErrorMsg()) if sr is not None: gdal_ds.SetProjection(osr.GetUserInputAsWKT(sr)) gdal_ds.SetGeoTransform(cache_tile.gt) if self.nodata is not None: for i in range(self.nbands): gdal_ds.GetRasterBand(i + 1).SetNoDataValue(self.nodata) # band_schema = None # band_schema = None # Check array shape array = np.asarray(data) if array.shape[:2] != tuple(cache_tile.shape): raise ValueError( 'Incompatible shape between array:%s and fp:%s' % (array.shape, cache_tile.shape)) # pragma: no cover # Normalize and check array shape if array.ndim == 2: array = array[:, :, np.newaxis] elif array.ndim != 3: raise ValueError('Array has shape %d' % array.shape) # pragma: no cover if array.shape[-1] != self.nbands: raise ValueError( 'Incompatible band count between array:%d and band:%d' % (array.shape[-1], self.nbands)) # pragma: no cover # Normalize array dtype array = array.astype(self.dtype) if array.dtype == np.int8: array = array.astype('uint8') def _blocks_of_footprint(fp, bands): for i, band in enumerate(bands): yield fp, band, i # Todo use tile_count and gdal block size bands = list(range(1, self.nbands + 1)) for tile, band, dim in _blocks_of_footprint(cache_tile, bands): tilearray = array[:, :, dim][tile.slice_in(cache_tile)] assert np.array_equal(tilearray.shape[0:2], cache_tile.shape) gdalband = gdal_ds.GetRasterBand(band) gdalband.WriteArray(tilearray) gdal_ds.FlushCache() del gdalband del gdal_ds file_hash = md5(filepath) new_file_path = self._get_cache_tile_path_prefix( cache_tile) + "_" + file_hash + ".tif" os.rename(filepath, new_file_path)