Exemplo n.º 1
0
def test_native_load(tmpdir):
    from datacube.testutils.io import native_load, native_geobox

    tmpdir = Path(str(tmpdir))
    spatial = dict(resolution=(15, -15),
                   offset=(11230, 1381110),)
    nodata = -999
    aa = mk_test_image(96, 64, 'int16', nodata=nodata)
    cc = mk_test_image(32, 16, 'int16', nodata=nodata)

    bands = [SimpleNamespace(name=name, values=aa, nodata=nodata)
             for name in ['aa', 'bb']]
    bands.append(SimpleNamespace(name='cc', values=cc, nodata=nodata))

    ds, gbox = gen_tiff_dataset(bands[:2],
                                tmpdir,
                                prefix='ds1-',
                                timestamp='2018-07-19',
                                **spatial)

    assert set(get_raster_info(ds)) == set(ds.measurements)

    xx = native_load(ds)
    assert xx.geobox == gbox
    np.testing.assert_array_equal(aa, xx.isel(time=0).aa.values)
    np.testing.assert_array_equal(aa, xx.isel(time=0).bb.values)

    ds, gbox_cc = gen_tiff_dataset(bands,
                                   tmpdir,
                                   prefix='ds2-',
                                   timestamp='2018-07-19',
                                   **spatial)

    # cc is different size from aa,bb
    with pytest.raises(ValueError):
        xx = native_load(ds)

    # cc is different size from aa,bb
    with pytest.raises(ValueError):
        xx = native_geobox(ds)

    # aa and bb are the same
    assert native_geobox(ds, ['aa', 'bb']) == gbox
    xx = native_load(ds, ['aa', 'bb'])
    assert xx.geobox == gbox
    np.testing.assert_array_equal(aa, xx.isel(time=0).aa.values)
    np.testing.assert_array_equal(aa, xx.isel(time=0).bb.values)

    # cc will be reprojected
    assert native_geobox(ds, basis='aa') == gbox
    xx = native_load(ds, basis='aa')
    assert xx.geobox == gbox
    np.testing.assert_array_equal(aa, xx.isel(time=0).aa.values)
    np.testing.assert_array_equal(aa, xx.isel(time=0).bb.values)

    # cc is compatible with self
    xx = native_load(ds, ['cc'])
    assert xx.geobox == gbox_cc
    np.testing.assert_array_equal(cc, xx.isel(time=0).cc.values)
Exemplo n.º 2
0
def test_native_geobox_eo3(eo3_dataset_s2):
    ds = eo3_dataset_s2
    assert ds.crs is not None
    assert 'blue' in ds.measurements

    gb1 = native_geobox(ds, basis='blue')

    assert gb1.width == 10980
    assert gb1.height == 10980
    assert gb1.crs == ds.crs

    gb1_ = native_geobox(ds, ('blue', 'red', 'green'))
    assert gb1_ == gb1

    gb2 = native_geobox(ds, ['swir_1', 'swir_2'])
    assert gb2 != gb1
    assert gb2.width == 5490
    assert gb2.height == 5490
    assert gb2.crs == ds.crs

    with pytest.raises(ValueError):
        native_geobox(ds)

    with pytest.raises(ValueError):
        native_geobox(ds, ['no_such_band'])

    ds.metadata_doc['measurements']['red_edge_1']['grid'] = 'no-such-grid'

    with pytest.raises(ValueError):
        native_geobox(ds, ['red_edge_1'])
Exemplo n.º 3
0
def compute_native_load_geobox(dst_geobox: GeoBox,
                               ds: Dataset,
                               band: str,
                               buffer: Optional[float] = None) -> GeoBox:
    """
    Compute area of interest for a given Dataset given query.

    Take native projection and resolution from ``ds, band`` pair and compute
    region in that projection that fully encloses footprint of the
    ``dst_geobox`` with some padding. Construct GeoBox that encloses that
    region fully with resolution/pixel alignment copied from supplied band.

    :param dst_geobox:
    :param ds: Sample dataset (only resolution and projection is used, not footprint)
    :param band: Reference band to use (resolution of output GeoBox will match resolution of this band)
    :param buffer: Buffer in units of CRS of ``ds`` (meters usually), default is 10 pixels worth
    """
    native: GeoBox = native_geobox(ds, basis=band)
    if buffer is None:
        buffer = 10 * cast(float, max(map(abs,
                                          native.resolution)))  # type: ignore

    assert native.crs is not None
    return GeoBox.from_geopolygon(
        dst_geobox.extent.to_crs(native.crs).buffer(buffer),
        crs=native.crs,
        resolution=native.resolution,
        align=native.alignment,
    )
Exemplo n.º 4
0
    def fetch(self, grouped: VirtualDatasetBox,
              **load_settings: Dict[str, Any]) -> xarray.Dataset:
        """ Convert grouped datasets to `xarray.Dataset`. """

        load_keys = self._LOAD_KEYS - {'measurements'}
        merged = merge_search_terms(select_keys(self, load_keys),
                                    select_keys(load_settings, load_keys))

        product = grouped.product_definitions[self._product]

        if 'measurements' in self and 'measurements' in load_settings:
            for measurement in load_settings['measurements']:
                self._assert(
                    measurement in self['measurements'],
                    '{} not found in {}'.format(measurement, self._product))

        measurement_dicts = self.output_measurements(
            grouped.product_definitions, load_settings.get('measurements'))

        if grouped.load_natively:
            canonical_names = [
                product.canonical_measurement(measurement)
                for measurement in measurement_dicts
            ]
            dataset_geobox = geobox_union_conservative([
                native_geobox(ds,
                              measurements=canonical_names,
                              basis=merged.get('like'))
                for ds in grouped.box.sum().item()
            ])

            if grouped.geopolygon is not None:
                reproject_roi = compute_reproject_roi(
                    dataset_geobox,
                    GeoBox.from_geopolygon(
                        grouped.geopolygon,
                        crs=dataset_geobox.crs,
                        align=dataset_geobox.alignment,
                        resolution=dataset_geobox.resolution))

                self._assert(reproject_roi.is_st,
                             "native load is not axis-aligned")
                self._assert(numpy.isclose(reproject_roi.scale, 1.0),
                             "native load should not require scaling")

                geobox = dataset_geobox[reproject_roi.roi_src]
            else:
                geobox = dataset_geobox
        else:
            geobox = grouped.geobox

        result = Datacube.load_data(grouped.box,
                                    geobox,
                                    list(measurement_dicts.values()),
                                    fuse_func=merged.get('fuse_func'),
                                    dask_chunks=merged.get('dask_chunks'),
                                    resampling=merged.get(
                                        'resampling', 'nearest'))

        return result
Exemplo n.º 5
0
def test_native_geobox_ingested():
    from datacube.testutils.io import native_geobox
    from datacube.testutils.geom import AlbersGS

    gbox = AlbersGS.tile_geobox((15, -40))
    ds = mk_sample_dataset([dict(name='a')],
                           geobox=gbox,
                           product_opts=dict(with_grid_spec=True))

    assert native_geobox(ds) == gbox

    # check that dataset covering several tiles is detected as invalid
    ds = mk_sample_dataset([dict(name='a')],
                           geobox=gbox.buffered(10, 10),
                           product_opts=dict(with_grid_spec=True))

    with pytest.raises(ValueError):
        native_geobox(ds)
Exemplo n.º 6
0
def compute_native_load_geobox(dst_geobox: GeoBox,
                               ds: Dataset,
                               band: str,
                               buffer: Optional[float] = None):

    native = native_geobox(ds, basis=band)
    if buffer is None:
        buffer = 10*max(map(abs, native.resolution))

    return GeoBox.from_geopolygon(dst_geobox.extent.to_crs(native.crs).buffer(buffer),
                                  crs=native.crs,
                                  resolution=native.resolution,
                                  align=native.alignment)
Exemplo n.º 7
0
def get_shape_and_transform(dataset, measurements):
    """
    Get shape and transform for the given set of measurements. It try
    each measurement until it succeeds.
    """

    for m in measurements:
        try:
            geo = native_geobox(dataset, [m])
        except Exception:
            _LOG.warn("Failed to compute shape and transform %s", m)
            continue
        return geo.shape, geo.transform

    # All the bands failed use default shape [1,1]
    _LOG.warn("All measurements failed to compute shape and transform %s",
              measurements)
    return [1, 1], dataset.transform
Exemplo n.º 8
0
 def _native_resolution(self, task: AlchemistTask) -> float:
     geobox = native_geobox(task.dataset,
                            basis=list(task.dataset.measurements.keys())[0])
     return geobox.affine[0]