def fill(self, value, band=1): """Fill bands with value. Parameters ---------- value: nbr band: band index or sequence of band index (see `Band Indices` below) Band Indices ------------ | index type | index value | meaning | |------------|-----------------|------------------| | int | -1 | All bands | | int | 1, 2, 3, ... | Band `i` | | complex | -1j | All bands mask | | complex | 0j | Shared mask band | | complex | 1j, 2j, 3j, ... | Mask of band `i` | """ if self._c.mode != 'w': raise RuntimeError('Cannot write a read-only file') bands, _ = _tools.normalize_band_parameter(band, len(self), self._shared_band_index) del band for gdalband in [self._gdalband_of_index(i) for i in bands]: gdalband.Fill(value)
def fill(self, value, band=1): """Fill bands with value. This method is not thread-safe. Parameters ---------- value: nbr band: band ids or sequence of band ids (see `Band Identifiers` below) Band Identifiers ------------ | id type | id value | meaning | |------------|-----------------|------------------| | int | -1 | All bands | | int | 1, 2, 3, ... | Band `i` | | complex | -1j | All bands mask | | complex | 0j | Shared mask band | | complex | 1j, 2j, 3j, ... | Mask of band `i` | Caveat ------ When using a Raster backed by a driver (like a GDAL driver), the data might be flushed to disk only after the garbage collection of the driver object. To be absolutely sure that the driver cache is flushed to disk, call `.close` or `.deactivate` on this Raster. """ if self.mode != 'w': # pragma: no cover raise RuntimeError('Cannot write a read-only raster file') band_ids, _ = _tools.normalize_band_parameter(band, len(self), self.shared_band_id) self._back.fill( value=value, band_ids=band_ids, )
def _get_multi_data_queue(fp_iterable, band=-1, queue_size=5): """ returns a queue from a fp_iterable """ # Normalize and check band parameter bands, is_flat = _tools.normalize_band_parameter( band, len(self), None) fp_iterable = list(fp_iterable) for fp in fp_iterable: assert fp.same_grid(self.fp) q = queue.Queue(queue_size) query = Query(q, bands, is_flat) to_produce = [(fp, "sleeping", str(uuid.uuid4())) for fp in fp_iterable] # to_produce = [(fp, "sleeping", get_uname()) for fp in fp_iterable] query.to_produce += to_produce # self._backend._queries.append(query) self._backend._new_queries.append(query) return q
def set_data(self, array, fp=None, band=1, interpolation='cv_area', mask=None, op=np.rint): """Set `data` located at `fp` in raster file. An optional `mask` may be provided. fp can be partially or fully outside of target If `allow_interpolation` is enabled in the DataSource constructor, it is then possible to use a `fp` that is not aligned with the source raster, interpolation in then used to remap `array` from `fp` to raster. `nodata` values are also handled and spreaded to the raster through remapping. When remapping, if the input is not aligned with the raster file, at most one pixel pixel may be lost at edges due to interpolation. Provide more context in `array` to counter this effect. Parameters ---------- array: numpy.ndarray of shape (Y, X) or (Y, X, B) Input data fp: Footprint Of shape (Y, X) Within in raster file band: band index or sequence of band index (see `Band Indices` below) interpolation: one of ('cv_area', 'cv_nearest', 'cv_linear', 'cv_cubic', 'cv_lanczos4') Resampling method mask: numpy array of shape (Y, X) OR inputs accepted by Footprint.burn_polygons op: None or vector function Rounding function following an interpolation when file type is integer Band Indices ------------ | index type | index value | meaning | |------------|-----------------|------------------| | int | -1 | All bands | | int | 1, 2, 3, ... | Band `i` | | complex | -1j | All bands mask | | complex | 0j | Shared mask band | | complex | 1j, 2j, 3j, ... | Mask of band `i` | """ if self._c.mode != 'w': raise RuntimeError('Cannot write a read-only file') # Normalize fp parameter if fp is None: fp = self.fp elif not isinstance(fp, Footprint): raise ValueError('Bad fp type `%s`' % type(fp)) # pragma: no cover # Check array shape array = np.asarray(array) if array.shape[:2] != tuple(fp.shape): raise ValueError('Incompatible shape between array:%s and fp:%s' % (array.shape, fp.shape)) # pragma: no cover # Normalize and check band parameter bands, _ = _tools.normalize_band_parameter(band, len(self), self._shared_band_index) # Normalize and check mask parameter if mask is None: mask = np.ones(fp.shape, dtype=bool) elif isinstance(mask, np.ndarray): if mask.ndim != 2 or mask.shape != tuple(fp.shape): raise ValueError('Mask of shape %s instead of %s' % (mask.shape, fp.shape)) mask = mask.astype(bool) else: mask = fp.burn_polygons(mask) # 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] != len(bands): raise ValueError( 'Incompatible band count between array:%d and band:%d' % (array.shape[-1], len(bands))) # pragma: no cover # Check op parameter if not isinstance(np.zeros(1, dtype=self.dtype)[0], numbers.Integral): op = None # Normalize interpolation parameter if not self._ds._allow_interpolation: interpolation = None # Normalize array dtype array = array.astype(self.dtype) self._set_data_unsafe(array, fp, bands, interpolation, mask, op)
def get_data(self, fp=None, band=1, mask=None, nodata=None, interpolation='cv_area', dtype=None, op=np.rint): """Get `data` located at `fp` in raster file. If `nodata` is set in raster or provided as an argument, fp can lie partially or fully outside of raster. If `allow_interpolation` is enabled in the DataSource constructor, it is then possible to use a `fp` that is not aligned with the source raster, interpolation in then used to remap source to `fp`. `nodata` values are also handled and spreaded to the output through remapping. (experimental) An optional `mask` may be provided. GDAL band sampling is only performed near `True` pixels. Current implementation might be extremely slow. Parameters ---------- fp: Footprint of shape (Y, X) If None: return the full raster If Footprint: return this window from the raster band: band index or sequence of band index (see `Band Indices` below) mask: numpy array of shape (Y, X) nodata: Number Override self.get_nodata() interpolation: one of ('cv_area', 'cv_nearest', 'cv_linear', 'cv_cubic', 'cv_lanczos4') Resampling method dtype: type Override gdal output type op: None or vector function Rounding function following an interpolation when output type is integer Returns ------- numpy.ndarray of shape (Y, X) or (Y, X, B) Band Indices ------------ | index type | index value | meaning | |------------|-----------------|------------------| | int | -1 | All bands | | int | 1, 2, 3, ... | Band `i` | | complex | -1j | All bands masks | | complex | 0j | Shared mask band | | complex | 1j, 2j, 3j, ... | Mask of band `i` | """ # Normalize and check fp parameter if fp is None: fp = self.fp elif not isinstance(fp, Footprint): raise ValueError('Bad fp type `%s`' % type(fp)) # pragma: no cover # Normalize and check dtype parameter if dtype is None: dtype = self.dtype else: dtype = conv.dtype_of_any_downcast(dtype) # Normalize and check band parameter bands, is_flat = _tools.normalize_band_parameter(band, len(self), self._shared_band_index) if is_flat: outshape = fp.shape else: outshape = tuple(fp.shape) + (len(bands),) del band # Normalize and check nodata if nodata is None: nodataconv = False onodata = self.nodata # May be None else: if not isinstance(nodata, numbers.Number): raise ValueError('Bad nodata type') # pragma: no cover onodata = nodata nodataconv = self.nodata is not None # Check op parameter if not isinstance(np.zeros(1, dtype=dtype)[0], numbers.Integral): op = None # Check mask parameter if mask is not None: mask = np.asarray(mask).astype(bool) if mask.shape != tuple(fp.shape): raise ValueError('mask should have the same shape as `fp`') # pragma: no cover # Normalize interpolation parameter if not self._ds._allow_interpolation: interpolation = None # Work dilate_size = 4 * self.fp.pxsizex / fp.pxsizex # hyperparameter dilate_size = max(2, np.ceil(dilate_size)) samplefp = fp.dilate(dilate_size) if not samplefp.share_area(self.fp): if onodata is None: raise Exception( "Querying data fully outside of file's Footprint, but `nodata` is not known. " "Provide a `nodata` parameter or create a new file with a `nodata` value set." ) return np.full(outshape, onodata, dtype) samplefp = self.fp & samplefp samplebands = self._sample_bands(fp, samplefp, bands, mask, interpolation, onodata) if nodataconv: samplebands[samplebands == self.nodata] = onodata array = self._remap( samplefp, fp, interpolation=interpolation, array=samplebands, mask=None, nodata=onodata, mask_mode='erode', ) del samplebands if op is not None: array = op(array) return array.astype(dtype).reshape(outshape)
def set_data(self, array, fp=None, band=1, interpolation='cv_area', mask=None): """Write a rectangle of data on several channels to the destination raster. An optional `mask` may be provided to only write certain pixels of `array`. If `fp` is not fully within the destination raster, only the overlapping pixels are written. If `fp` is not on the same grid as the destination raster, remapping is performed using `interpolation` algorithm. (It fails if the `allow_interpolation` parameter is set to False in `DataSource` (default)). When remapping: - The nodata values are not interpolated, they are correctly spread to the output. - At most one pixel may be lost at edges due to interpolation. Provide more context in `array` to compensate this loss. - The mask parameter is also interpolated. The alpha bands are currently resampled like any other band, this behavior may change in the future. This method is not thread-safe. Parameters ---------- array: numpy.ndarray of shape (Y, X) or (Y, X, B) Input data fp: Footprint of shape (Y, X) or None If None: write the full source raster If Footprint: write this window to the raster band: band ids or sequence of band ids (see `Band Identifiers` below) interpolation: one of {'cv_area', 'cv_nearest', 'cv_linear', 'cv_cubic', 'cv_lanczos4'} or None Resampling method mask: numpy array of shape (Y, X) and dtype `bool` OR inputs accepted by Footprint.burn_polygons Band Identifiers ------------ | id type | id value | meaning | |------------|-----------------|------------------| | int | -1 | All bands | | int | 1, 2, 3, ... | Band `i` | | complex | -1j | All bands mask | | complex | 0j | Shared mask band | | complex | 1j, 2j, 3j, ... | Mask of band `i` | Caveat ------ When using a Raster backed by a driver (like a GDAL driver), the data might be flushed to disk only after the garbage collection of the driver object. To be absolutely sure that the driver cache is flushed to disk, call `.close` or `.deactivate` on this Raster. """ if self.mode != 'w': # pragma: no cover raise RuntimeError('Cannot write a read-only raster file') # Normalize and check fp parameter if fp is None: fp = self.fp elif not isinstance(fp, Footprint): raise ValueError( '`fp` parameter should be a Footprint (not {})'.format( fp)) # pragma: no cover # Normalize and check band parameter band_ids, _ = _tools.normalize_band_parameter(band, len(self), self.shared_band_id) # Normalize and check array parameter array = np.atleast_3d(array) if array.ndim != 3: # pragma: no cover raise ValueError('Input array should have 2 or 3 dimensions') if array.shape[:2] != tuple(fp.shape): # pragma: no cover raise ValueError( 'Incompatible shape between input `array` and `fp`') if len(band_ids) != array.shape[-1]: # pragma: no cover raise ValueError( 'Incompatible number of channels between input `array` and `band`' ) # Normalize and check mask parameter if mask is not None: if isinstance(mask, np.ndarray): mask = mask.astype(bool, copy=False) if mask.ndim != 2: # pragma: no cover raise ValueError('Input `mask` should 2 dimensions') if mask.shape[:2] != tuple(fp.shape): # pragma: no cover raise ValueError( 'Incompatible shape between input `mask` and `fp`') else: mask = fp.burn_polygons(mask) # Check interpolation parameter here if not (interpolation is None or interpolation in self._back.REMAP_INTERPOLATIONS): # pragma: no cover raise ValueError( '`interpolation` should be None or one of {}'.format( set(self._back.REMAP_INTERPOLATIONS.keys()))) return self._back.set_data( array=array, fp=fp, band_ids=band_ids, interpolation=interpolation, mask=mask, )
def get_data(self, fp=None, band=1, dst_nodata=None, interpolation='cv_area', **kwargs): """Read a rectangle of data on several channels from the source raster. If `fp` is not fully within the source raster, the external pixels are set to nodata. If nodata is missing, 0 is used. If `fp` is not on the same grid as the source raster, remapping is performed using `interpolation` algorithm. (It fails if the `allow_interpolation` parameter is set to False in `DataSource` (default)). When remapping, the nodata values are not interpolated, they are correctly spread to the output. If `dst_nodata` is provided, nodata pixels are set to `dst_nodata`. The alpha bands are currently resampled like any other band, this behavior may change in the future. To normalize a `rgba` array after a resampling operation, use this piece of code: >>> arr = np.where(arr[..., -1] == 255, arr, 0) This method is thread-safe (Unless you are using the GDAL::MEM driver). Parameters ---------- fp: Footprint of shape (Y, X) or None If None: return the full source raster If Footprint: return this window from the raster band: band id or sequence of band id (see `Band Identifiers` below) dst_nodata: nbr or None nodata value in output array If None and raster.nodata is not None: raster.nodata is used If None and raster.nodata is None: 0 is used interpolation: one of {'cv_area', 'cv_nearest', 'cv_linear', 'cv_cubic', 'cv_lanczos4'} or None Resampling method Returns ------- numpy.ndarray of shape (Y, X) or (Y, X, B) Band Identifiers ------------ | id type | id value | meaning | |------------|-----------------|------------------| | int | -1 | All bands | | int | 1, 2, 3, ... | Band `i` | | complex | -1j | All bands masks | | complex | 0j | Shared mask band | | complex | 1j, 2j, 3j, ... | Mask of band `i` | """ dst_nodata, kwargs = _tools.deprecation_pool.streamline_with_kwargs( new_name='dst_nodata', old_names={'nodata': '0.5.0'}, context='AProxyRaster.get_data', new_name_value=dst_nodata, new_name_is_provided=dst_nodata != None, user_kwargs=kwargs, ) if kwargs: # pragma: no cover raise TypeError( "get_data() got an unexpected keyword argument '{}'".format( list(kwargs.keys())[0])) # Normalize and check fp parameter if fp is None: fp = self.fp elif not isinstance(fp, Footprint): raise ValueError( '`fp` parameter should be a Footprint (not {})'.format( fp)) # pragma: no cover # Normalize and check band parameter band_ids, is_flat = _tools.normalize_band_parameter( band, len(self), self.shared_band_id) if is_flat: outshape = tuple(fp.shape) else: outshape = tuple(fp.shape) + (len(band_ids), ) del band # Normalize and check dst_nodata parameter if dst_nodata is not None: dst_nodata = self.dtype.type(dst_nodata) elif self.nodata is not None: dst_nodata = self.nodata else: dst_nodata = self.dtype.type(0) # Check interpolation parameter here if not (interpolation is None or interpolation in self._back.REMAP_INTERPOLATIONS): # pragma: no cover raise ValueError( '`interpolation` should be None or one of {}'.format( set(self._back.REMAP_INTERPOLATIONS.keys()))) return self._back.get_data( fp=fp, band_ids=band_ids, dst_nodata=dst_nodata, interpolation=interpolation, ).reshape(outshape)