def mk_sample_xr_dataset(crs="EPSG:3578",
                         shape=(33, 74),
                         resolution=None,
                         xy=(0, 0),
                         time='2020-02-13T11:12:13.1234567Z',
                         name='band',
                         dtype='int16',
                         nodata=-999,
                         units='1'):
    """ Note that resolution is in Y,X order to match that of GeoBox.

        shape (height, width)
        resolution (y: float, x: float) - in YX, to match GeoBox/shape notation

        xy (x: float, y: float) -- location of the top-left corner of the top-left pixel in CRS units
    """

    if isinstance(crs, str):
        crs = CRS(crs)

    if resolution is None:
        resolution = (-10, 10) if crs is None or crs.projected else (-0.01, 0.01)

    t_coords = {}
    if time is not None:
        t_coords['time'] = mk_time_coord([time])

    transform = Affine.translation(*xy)*Affine.scale(*resolution[::-1])
    h, w = shape
    geobox = GeoBox(w, h, transform, crs)

    return Datacube.create_storage(t_coords, geobox, [Measurement(name=name, dtype=dtype, nodata=nodata, units=units)])
Exemple #2
0
def odc_style_xr_dataset():
    """An xarray.Dataset with ODC style coordinates and CRS, and no time dimension.

    Contains an EPSG:4326, single variable 'B10' of 100x100 int16 pixels."""
    affine = Affine.scale(0.1, 0.1) * Affine.translation(20, 30)
    geobox = geometry.GeoBox(100, 100, affine, geometry.CRS(GEO_PROJ))

    return Datacube.create_storage({}, geobox, [Measurement(name='B10', dtype='int16', nodata=0, units='1')])
Exemple #3
0
def fractional_cover(nbar_tile,
                     measurements=None,
                     regression_coefficients=None):
    """
    Given a tile of spectral observations compute the fractional components.
    The data should be a 2D array

    :param xarray.Dataset nbar_tile:
        A dataset with the following data variables (0-10000):
            * green
            * red
            * nir
            * swir1
            * swir2

    :param list(dict) measurements:
        A list of measurement item dicts, each containing:
            * name - name of output data_var
            * src_var - (optional) if `name` is not one of `['PV', 'NPV', 'BS', 'UE']`, use one of them here
            * dtype - dtype to use, eg `'int8'`
            * nodata - value to fill in for no data, eg `-1`
            * units' - eg `'percent'`

    :param dict regression_coefficients:
        A dictionary with six pairs of coefficients to apply to the green, red, nir, swir1 and swir2 values
        (blue is not used)

    :return:
        An xarray.Dataset containing:
            * Green vegetation (PV)
            * Non-green vegetation (NPV)
            * Bare soil (BS)
            * Unmixing error (UE)

    :rtype:
        xarray.Dataset
    """
    if measurements is None:
        measurements = DEFAULT_MEASUREMENTS

    # Ensure the bands are all there and in the right order
    nbar_tile = nbar_tile[['green', 'red', 'nir', 'swir1', 'swir2']]

    # Set nodata to 0
    no_data = 0
    is_valid_array = valid_data_mask(nbar_tile).to_array(dim='band').all(
        dim='band')

    nbar = nbar_tile.to_array(dim='band')
    nbar.data[:, ~is_valid_array.data] = no_data

    output_data = compute_fractions(nbar.data, regression_coefficients)

    def data_func(measurement):
        band_names = ['PV', 'NPV', 'BS', 'UE']
        src_var = measurement.get('src_var', None) or measurement.get('name')
        i = band_names.index(src_var)

        # Set nodata value into output array
        band_nodata = numpy.dtype(measurement['dtype']).type(
            measurement['nodata'])
        compute_error = (output_data[i, :, :] == -1)
        output_data[i, compute_error] = band_nodata
        output_data[i, ~is_valid_array.data] = band_nodata

        return output_data[i, :, :]

    dataset = Datacube.create_storage({}, nbar_tile.geobox, measurements,
                                      data_func)

    return dataset
Exemple #4
0
def fractional_cover(
    nbar_tile: xarray.Dataset,
    measurements: Sequence[Measurement] = None,
    regression_coefficients: Mapping[str,
                                     Sequence[int]] = None) -> xarray.Dataset:
    """
    Given a tile of spectral observations compute the fractional components.
    The data should be a 2D array

    :param nbar_tile:
        A dataset with the following data variables (0-10000):
            * green
            * red
            * nir
            * swir1
            * swir2

    :param measurements:
        A list of Measurements, each containing:
            * name - name of output data_var
            * src_var - (optional) if `name` is not one of `['PV', 'NPV', 'BS', 'UE']`, use one of them here
            * dtype - dtype to use, eg `'int8'`
            * nodata - value to fill in for no data, eg `-1`
            * units' - eg `'percent'`

    :param regression_coefficients:
        A dictionary with six pairs of coefficients to apply to the green, red, nir, swir1 and swir2 values
        (blue is not used)

    :return:
        An xarray.Dataset containing:
            * Green vegetation (PV)
            * Non-green vegetation (NPV)
            * Bare soil (BS)
            * Unmixing error (UE)

    :rtype:
        xarray.Dataset
    """
    if measurements is None:
        measurements = DEFAULT_MEASUREMENTS

    # Ensure the bands are all there and in the right order
    nbar_tile = nbar_tile[['green', 'red', 'nir', 'swir1', 'swir2']]

    # Set nodata to 0
    no_data = 0
    is_valid_array = valid_data_mask(nbar_tile).to_array(dim='band').all(
        dim='band')

    nbar = nbar_tile.to_array(dim='band')
    nbar = nbar.where(is_valid_array, no_data)

    output_data = compute_fractions(nbar.data, regression_coefficients)
    error_val = -1
    where = numpy.where if not isinstance(
        output_data, dask_array_type) else dask.array.where

    def data_func(measurement):
        band_names = ['PV', 'NPV', 'BS', 'UE']
        src_var = measurement.get('src_var', None) or measurement.get('name')
        i = band_names.index(src_var.upper())
        unmasked_var = output_data[i]

        # Set nodata value into output array
        band_nodata = numpy.dtype(measurement['dtype']).type(
            measurement['nodata'])
        no_error = (unmasked_var != error_val)
        return where(is_valid_array.data & no_error, unmasked_var, band_nodata)

    dataset = Datacube.create_storage({}, nbar_tile.geobox, measurements,
                                      data_func)

    return dataset