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)
Exemple #2
0
    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,
        )
Exemple #3
0
        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)
Exemple #5
0
    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)
Exemple #6
0
    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)