Esempio n. 1
0
def test_calculate_src_window_nonexact():
    bounds = BoundingBox(0, 0, 10, 10)
    transform = Affine(5., 0., 0., 0., -5., 10.)
    dst_bounds = BoundingBox(-1., 0., 12, 13)
    ans = geom.calculate_src_window(bounds, transform, dst_bounds)
    assert ans[0] == Window(0, 0, 2, 2)
    assert ans[1] == bounds
Esempio n. 2
0
def get_bounds(ds):
    """Extract the bounding box in projection coordinates.

    Parameters
    ----------
    ds : xarray.Dataset
        The input dataset

    Returns
    -------
    tuple
        The bounding box in projection coordinates
        (left, bottom, right, top).
    """

    trans = get_transform(ds)
    if trans is not None:
        if isinstance(ds, xr.Dataset):
            dims = ds.dims
        elif isinstance(ds, xr.DataArray):
            dims = dict(zip(ds.dims, ds.shape))
        nrows = dims['y']
        ncols = dims['x']
        corners = (np.array([0, 0, ncols - 1, ncols - 1]),
                   np.array([0, nrows - 1, 0, nrows - 1]))
        corner_x, corner_y = trans * corners
        return BoundingBox(left=corner_x.min(),
                           bottom=corner_y.min(),
                           right=corner_x.max(),
                           top=corner_y.max())
    else:
        return BoundingBox(left=ds['x'].min(),
                           bottom=ds['y'].min(),
                           right=ds['x'].max(),
                           top=ds['y'].max())
Esempio n. 3
0
    def test_mask_image(self):
        with self.assertRaises(TypeError, msg="bbox must be of type tuple or Shapely Polygon"):
            self.img.mask([1, 2, 3])

        self.img.mask(box(11.9027457562112939, 51.4664152338322580, 11.9477435281016131, 51.5009522690838750,))
        self.assertEqual(
            self.img.dataset.bounds,
            BoundingBox(
                left=11.902702941366716, bottom=51.46639813686387, right=11.947798368783504, top=51.50098327545026,
            ),
        )

        self.img.mask((11.9027457562112939, 51.4664152338322580, 11.9477435281016131, 51.5009522690838750,))
        self.assertEqual(
            self.img.dataset.bounds,
            BoundingBox(
                left=11.902702941366716, bottom=51.46639813686387, right=11.947798368783504, top=51.50098327545026,
            ),
        )

        self.img.mask(
            box(11.8919236802142620, 51.4664152338322580, 11.9477435281016131, 51.5009522690838750,), fill=True,
        )
        self.assertEqual(
            self.img.dataset.bounds,
            BoundingBox(
                left=11.891923157920472, bottom=51.46639813686387, right=11.947798368783504, top=51.50098327545026
            ),
        )
Esempio n. 4
0
def test_calculate_dst_window():
    src_bounds = BoundingBox(0, 0, 120, 120)
    dst_transform = Affine(30., 0., 0,
                           0., -30., 120)
    ans = geom.calculate_dst_window(src_bounds, dst_transform)
    assert ans == Window(0, 0, 4, 4)

    # dst_transform further left & up
    src_bounds = BoundingBox(0, 0, 65, 95)
    dst_transform = Affine(30., 0., -35,
                           0., -30., 155)
    ans = geom.calculate_dst_window(src_bounds, dst_transform)
    assert ans == Window(1, 2, 2, 3)
Esempio n. 5
0
def _inspect_coords(y, x, center=True, assume_unique=True):
    # returns transform, bounds, shape
    y_ = np.atleast_1d(y)
    x_ = np.atleast_1d(x)

    if not assume_unique:
        logger.warning('Computing unique values of coordinates...')
        y_ = np.unique(y_)
        x_ = np.unique(x_)

    minmax_y = y_[0], y_[-1]
    minmax_x = x_[0], x_[-1]

    if minmax_y[0] > minmax_y[1]:
        logger.warning('Unreversing y coordinate min/max')
        minmax_y = (minmax_y[1], minmax_y[0])

    # If spacing is not equal we guess from `(max - min) / n`
    dy = _check_spacing(y_)
    if dy is False:
        warnings.warn('"y" coordinate does not have equal spacing')
        ny = len(y_)
        dy = (minmax_y[0] - minmax_y[1]) / (ny - 1)
    else:
        ny = (minmax_y[0] - minmax_y[1]) / dy
        # np.unique returns sorted y so dy is negative, but not if unsorted
        if not assume_unique:
            dy *= -1

    dx = _check_spacing(x_)
    if dx is False:
        warnings.warn('"x" coordinate does not have equal spacing')
        nx = len(x_)
        dx = (minmax_x[1] - minmax_x[0]) / (nx - 1)
    else:
        nx = (minmax_x[1] - minmax_x[0]) / dx

    transform = Affine(dx, 0.0, minmax_x[0], 0., dy, minmax_y[1])

    if center:
        # affine transform is relative to upper-left, not pixel center
        transform = transform * Affine.translation(-0.5, -0.5)
        # create bounds that cover pixel area
        bounds = BoundingBox(minmax_x[0] - dx / 2, minmax_y[0] + dy / 2,
                             minmax_x[1] + dx / 2, minmax_y[1] - dy / 2)
    else:
        # create bounds that cover pixel area
        bounds = BoundingBox(minmax_x[0], minmax_y[0] + dy, minmax_x[1] + dx,
                             minmax_y[1])

    return transform, bounds, (nx, ny)
Esempio n. 6
0
def test_attribute_compare_bounds():
    from rasterio.coords import BoundingBox
    props = ['bounds']
    values = [BoundingBox(0, 0, 1, 1)]
    src1 = mockobj(props, values)
    values = [BoundingBox(0, 0, 2, 2)]
    src2 = mockobj(props, values)
    compared = raster_tester.compare_properties(src1, src2, props)
    assert compared == [{
        'bounds': {
            'src1': BoundingBox(left=0, bottom=0, right=1, top=1),
            'src2': BoundingBox(left=0, bottom=0, right=2, top=2)
        }
    }]
Esempio n. 7
0
def test_4326_not_crossing():
    crs = {'init': 'epsg:4326'}

    boundsArr = densify(make_bounds_array(BoundingBox(-120., 45., -115., 50.)))

    transformedBounds = transform_bounds(boundsArr, crs)
    assert not winding_order(transformedBounds)
Esempio n. 8
0
def get_bounds(datasets, crs):
    left = min([d.extent.to_crs(crs).boundingbox.left for d in datasets])
    right = max([d.extent.to_crs(crs).boundingbox.right for d in datasets])
    top = max([d.extent.to_crs(crs).boundingbox.top for d in datasets])
    bottom = min([d.extent.to_crs(crs).boundingbox.bottom for d in datasets])
    return GeoPolygon.from_boundingbox(BoundingBox(left, bottom, right, top),
                                       crs)
Esempio n. 9
0
 def bounds(self):
     geo_ref_points = self.metadata_doc['grid_spatial']['projection'][
         'geo_ref_points']
     return BoundingBox(geo_ref_points['ll']['x'],
                        geo_ref_points['ll']['y'],
                        geo_ref_points['ur']['x'],
                        geo_ref_points['ur']['y'])
Esempio n. 10
0
def test_sun_elev_calc(sun_elev_test_data):
    for d in sun_elev_test_data:
        pred_sun_el = sun_utils.sun_elevation(BoundingBox(*d['bbox']),
                                              (10, 10), d['date_acquired'],
                                              d['scene_center_time'])
        assert pred_sun_el.max() > d['mtl_sun_elevation']
        assert pred_sun_el.min() < d['mtl_sun_elevation']
Esempio n. 11
0
    def bounds(self):
        """
        Get bounding box.

        """
        return BoundingBox(*(self.transform * (0, self.shape[0])) +
                           (self.transform * (self.shape[1], 0)))
Esempio n. 12
0
def bounds_intersection(*bounds):
    """Return the intersection of some BoundingBox(s)

    Parameters
    ----------
    bounds : BoundingBox
        Bounding boxes

    Returns
    -------
    BoundingBox
        The intersection of all input BoundingBox
    """
    assert len(bounds) > 0
    assert all([
        isinstance(b, BoundingBox) or (list_like(b) and len(b) == 4)
        for b in bounds
    ])

    left = max([b[0] for b in bounds])
    bottom = max([b[1] for b in bounds])
    right = min([b[2] for b in bounds])
    top = min([b[3] for b in bounds])

    return BoundingBox(left, bottom, right, top)
Esempio n. 13
0
def bounds_union(*bounds):
    """Return the union of some BoundingBox(s)

    Parameters
    ----------
    bounds : BoundingBox
        Bounding boxes

    Returns
    -------
    BoundingBox
        The union of all input BoundingBox
    """
    assert len(bounds) > 0
    assert all([
        isinstance(b, BoundingBox) or (list_like(b) and len(b) == 4)
        for b in bounds
    ])

    xs, ys = [], []
    for b in bounds:
        left, bottom, right, top = b
        xs.extend([left, right])
        ys.extend([bottom, top])
    return BoundingBox(min(xs), min(ys), max(xs), max(ys))
Esempio n. 14
0
def test_transform_to_coords_bbox(transform, off_y, off_x):
    left = transform.c + off_x * transform.a
    top = transform.f + off_y * transform.e
    right = left + off_x * transform.a
    bottom = top + off_y * transform.e

    bbox = BoundingBox(left, bottom, right, top)

    y, x = coords.transform_to_coords(transform, bbox=bbox, center=False)

    # Was the bbox evenly offset?
    if int(off_y) == off_y:
        assert y.max() == top
        assert y.min() + transform.e == bottom
        assert len(y) == off_y
    # Or was it not aligned to grid set by transform?
    else:
        # Should cover extent and have more area
        assert y.max() > top
        assert y.min() + transform.e < bottom
        assert y.max() - y.min() > top - (bottom - transform.e)

    if int(off_x) == off_x:
        assert x.max() + transform.a == right
        assert x.min() == left
        assert len(x) == off_x
    else:
        # Should cover extent and have more area
        assert x.max() + transform.a > right
        assert x.min() < left
        assert x.max() - x.min() > (right - transform.a) - left
Esempio n. 15
0
def get_common_bounds(datasets):
    """Calculate the common bounding box of the input datasets.

    Parameters
    ----------
    datasets : list of xarray.Dataset
        The input datasets.

    Returns
    -------
    tuple
        The common bounding box (left, bottom, right, top) in projected
        coordinates.
    """
    bounds = []
    common_crs = get_crs(datasets[0])

    for ds in datasets:
        ds_bounds = get_bounds(ds)
        crs = get_crs(ds)
        proj_bounds = rasterio.warp.transform_bounds(crs, common_crs,
                                                     **ds_bounds._asdict())
        bounds.append(proj_bounds)

    # Get largest extent:
    bounds = np.array(bounds)
    common_bounds = np.concatenate(
        (bounds[:, :2].min(axis=0), bounds[:, 2:].max(axis=0)))

    return BoundingBox(*common_bounds)
Esempio n. 16
0
    def get_tile_bounds(self, grid_id) -> BoundingBox:
        """BBox for a given tile."""
        nb_tiles = int(math.sqrt(self.nb_tiles))

        _row, _col = grid_id.split("_")
        row = int(_row[:-1])
        col = int(_col[:-1])

        # Top left corner is (0,0)
        false_easting = self.bounds.left * -1
        false_southing = self.bounds.top * -1

        grid_height = self.bounds.top + self.bounds.bottom + (2 * false_southing)
        grid_width = self.bounds.left + self.bounds.right + (2 * false_easting)

        tile_height = grid_height / nb_tiles
        tile_width = grid_width / nb_tiles

        tile_left = col * tile_width - false_easting
        tile_right = (col + 1) * tile_width - false_easting
        tile_top = row * tile_height - false_southing
        tile_bottom = (row + 1) * tile_height - false_southing

        return BoundingBox(
            left=tile_left, top=tile_top, right=tile_right, bottom=tile_bottom
        )
Esempio n. 17
0
def test_reproject(generator):
    src_crs = epsg4326
    dst_crs = sinusoidal
    ds = generator(crs=src_crs)
    src_bounds = get_bounds(ds)
    dst_bounds_latlon = BoundingBox(
        left=src_bounds.left - 1,
        bottom=src_bounds.bottom - 1,
        right=src_bounds.right + 1,
        top=src_bounds.top + 1,
    )
    dst_bounds = BoundingBox(*rasterio.warp.transform_bounds(
        src_crs, dst_crs, **dst_bounds_latlon._asdict()))
    dst_width, dst_height = 35, 21
    resx = (dst_bounds.right - dst_bounds.left) / (dst_width - 1)
    resy = (dst_bounds.bottom - dst_bounds.top) / (dst_height - 1)
    res = (abs(resx), abs(resy))
    xoff = dst_bounds.left
    yoff = dst_bounds.top
    dst_transform = Affine(resx, 0, xoff, 0, resy, yoff)

    projected = [
        _reproject(ds,
                   dst_crs=dst_crs,
                   dst_transform=dst_transform,
                   width=dst_width,
                   height=dst_height),
        _reproject(ds,
                   dst_crs=dst_crs,
                   dst_transform=dst_transform,
                   extent=dst_bounds),
        _reproject(ds, dst_crs=dst_crs, extent=dst_bounds, res=res),
        _reproject(ds,
                   dst_crs=dst_crs,
                   extent=dst_bounds,
                   width=dst_width,
                   height=dst_height)
    ]
    for proj in projected[1:]:
        xr_assert_equal(proj, projected[0])
        assert_almost_equal(get_resolution(proj), res)
        assert_almost_equal(get_bounds(proj), dst_bounds)
        assert_almost_equal(get_transform(proj), dst_transform)
        assert_equal_crs(get_crs(proj), dst_crs)
Esempio n. 18
0
def test_reprojection_with_target(generator):
    src_crs = epsg4326
    dst_crs = sinusoidal
    ds = generator(crs=src_crs)
    src_bounds = warp.get_bounds(ds)
    dst_bounds_latlon = BoundingBox(
        left=src_bounds.left - 1,
        bottom=src_bounds.bottom - 1,
        right=src_bounds.right + 1,
        top=src_bounds.top + 1,
    )
    dst_bounds = BoundingBox(*rasterio.warp.transform_bounds(
        src_crs, dst_crs, **dst_bounds_latlon._asdict()
    ))
    dst_width, dst_height = 35, 21
    resx = (dst_bounds.right - dst_bounds.left) / (dst_width - 1)
    resy = (dst_bounds.bottom - dst_bounds.top) / (dst_height - 1)
    res = (abs(resx), abs(resy))
    xoff = dst_bounds.left
    yoff = dst_bounds.top
    dst_transform = Affine(resx, 0, xoff, 0, resy, yoff)

    target = generator(
        dims={'x': dst_width, 'y': dst_height, 'time': 1},
        extent=dst_bounds, crs=dst_crs
    )

    projected = [
        warp.Reprojection(crs=dst_crs, transform=dst_transform,
                          width=dst_width, height=dst_height).apply(ds),
        warp.Reprojection(crs=dst_crs, extent=dst_bounds,
                          res=res).apply(ds),
        warp.Reprojection(crs=dst_crs, extent=dst_bounds,
                          width=dst_width, height=dst_height).apply(ds),
        warp.Reprojection(target=target).apply(ds),
    ]
    for i, proj in enumerate(projected[1:]):
        print(i)
        xr_assert_equal(proj, projected[0])
        assert_almost_equal(warp.get_resolution(proj), res)
        assert_almost_equal(warp.get_bounds(proj), dst_bounds)
        assert_almost_equal(warp.get_transform(proj), dst_transform)
        assert_equal_crs(warp.get_crs(proj), dst_crs)
Esempio n. 19
0
def global_reader_invalid_bounds(path=''):
    reader = Mock(spec=RasterReader)
    reader.shape = (360, 720)
    reader.affine = Affine(-180., 0.5, 0.0, 90., 0.0, -0.5)
    reader.bounds = BoundingBox(-180., 90., 0.5, 0.)

    context = Mock()
    context.__enter__ = Mock(return_value=reader)
    context.__exit__ = Mock(return_value=False)
    return context
Esempio n. 20
0
def round_bounds(bounds):
    # TODO thesis, round method ceil, floor
    attrs = ('left', 'bottom', 'right', 'top')

    coords = []
    for attr in attrs:
        coord = bounds.__getattribute__(attr)
        coords.append(round(coord))

    return BoundingBox(*coords)
Esempio n. 21
0
def test_bounds_tranform_union_1():
    # Should all be the same
    n = 3
    bounds = BoundingBox(365385.0, 2901915.0, 380385.0, 2916915.0)
    transform = Affine(30.0, 0.0, 365385.0, 0.0, -30.0, 2916915.0)

    test = geom.bounds_transform_union((bounds, ) * n, transform)
    assert test[0] == bounds
    assert test[1] == transform
    assert test[2][0] == int((bounds.top - bounds.bottom) / 30)
    assert test[2][1] == int((bounds.right - bounds.left) / 30)
Esempio n. 22
0
def get_image_bound_box(file_path, buffer=None):
    # get the bounding box: (left, bottom, right, top)
    with rasterio.open(file_path) as src:
        # the extent of the raster
        raster_bounds = src.bounds
        if buffer is not None:
            # Create new instance of BoundingBox(left, bottom, right, top)
            new_box_obj = BoundingBox(raster_bounds.left-buffer, raster_bounds.bottom-buffer,
                       raster_bounds.right+buffer, raster_bounds.top+ buffer)
            # print(raster_bounds, new_box_obj)
            return new_box_obj
        return raster_bounds
Esempio n. 23
0
    def roi_to_tiles(self, roi):
        """ Yield tiles overlapping a Region of Interest `shapely` geometry

        Args:
            roi (shapely.geometry.Polygon): A geometry in the tile
                specifications' crs
        Yields:
            Tile: A :class`Tile` that intersects the ROI
        """
        bounds = BoundingBox(roi.bounds)
        grid_ys, grid_xs = self._frame_bounds(bounds)
        return self._yield_tiles(grid_ys, grid_xs, bounds)
Esempio n. 24
0
def bbox_intersection(bounds1, bounds2):
    if disjoint_bounds(bounds1, bounds2):
        raise Exception("Bounds are disjoint, no interseciton exists")
    
    bbox = BoundingBox(
                left=max(bounds1.left, bounds2.left),
                right=min(bounds1.right, bounds2.right),
                top=min(bounds1.top, bounds2.top),
                bottom=max(bounds1.bottom, bounds2.bottom)
            )

    return bbox
Esempio n. 25
0
def _reflectance_worker(open_files, window, ij, g_args):
    """rio mucho worker for reflectance. It reads input
    files and perform reflectance calculations on each window.

    Parameters
    ------------
    open_files: list of rasterio open files
    window: tuples
    g_args: dictionary

    Returns
    ---------
    out: None
        Output is written to dst_path

    """
    data = riomucho.utils.array_stack([
      src.read(window=window).astype(np.float32)
      for src in open_files
    ])

    depth, rows, cols = data.shape

    if g_args['pixel_sunangle']:
        bbox = BoundingBox(
                    *warp.transform_bounds(
                        g_args['src_crs'],
                        {'init': u'epsg:4326'},
                        *open_files[0].window_bounds(window)))

        E = sun_utils.sun_elevation(
                        bbox,
                        (rows, cols),
                        g_args['date_collected'],
                        g_args['time_collected_utc']).reshape(rows, cols, 1)

    else:
        # We're doing whole-scene (instead of per-pixel) sunangle:
        E = np.array([g_args['E'] for i in range(depth)])

    output = toa_utils.rescale(
        reflectance(
            data,
            g_args['M'],
            g_args['A'],
            E,
            g_args['src_nodata']),
        g_args['rescale_factor'],
        g_args['dst_dtype'],
        clip=g_args['clip'])

    return output
Esempio n. 26
0
def ingest_cmd(index, config, dry_run, executor):
    _, config = next(read_documents(Path(config)))
    source_type = index.datasets.types.get_by_name(config['source_type'])
    if not source_type:
        _LOG.error("Source DatasetType %s does not exist",
                   config['source_type'])
#    print (source_type)
#    print ("abcdefghijklmnopqrstuvwxyz")
    output_type = morph_dataset_type(source_type, config)
    #    print (output_type)
    _LOG.info('Created DatasetType %s', output_type.name)
    output_type = index.datasets.types.add(output_type)

    datacube = Datacube(index=index)

    grid_spec = output_type.grid_spec
    namemap = get_namemap(config)
    measurements = get_measurements(source_type, config)
    variable_params = get_variable_params(config)
    file_path_template = str(
        Path(config['location'], config['file_path_template']))

    bbox = BoundingBox(**config['ingestion_bounds'])
    tasks = find_diff(source_type, output_type, bbox, datacube)

    def ingest_work(tile_index, sources):
        geobox = GeoBox.from_grid_spec(grid_spec, tile_index)
        #        print ("in ingest.py in ingest_word")
        data = Datacube.product_data(sources, geobox, measurements)

        nudata = data.rename(namemap)

        file_path = file_path_template.format(
            tile_index=tile_index,
            start_time=to_datetime(
                sources.time.values[0]).strftime('%Y%m%d%H%M%S%f'),
            end_time=to_datetime(
                sources.time.values[-1]).strftime('%Y%m%d%H%M%S%f'))
        # TODO: algorithm params
        print("Writing product")
        nudatasets = write_product(nudata, sources, output_type,
                                   config['global_attributes'],
                                   variable_params, Path(file_path))
        return nudatasets

    do_work(tasks, ingest_work, index, executor)
    temp = str(Path(config['location']))
    files_path = temp + "/cache"
    if not os.path.isfile(temp + "/archive"):
        os.system("mkdir " + temp + "/archive")
    print("Compressing files")
    compress(files_path)
Esempio n. 27
0
def test_sun_angle3(test_data):
    # South, Winter
    mtl = test_data[2]
    mtl_sun = mtl['L1_METADATA_FILE']['IMAGE_ATTRIBUTES']['SUN_ELEVATION']
    bbox = BoundingBox(*toa_utils._get_bounds_from_metadata(
        mtl['L1_METADATA_FILE']['PRODUCT_METADATA']))

    sunangles = sun_utils.sun_elevation(
        bbox, (100, 100),
        mtl['L1_METADATA_FILE']['PRODUCT_METADATA']['DATE_ACQUIRED'],
        mtl['L1_METADATA_FILE']['PRODUCT_METADATA']['SCENE_CENTER_TIME'])

    assert sunangles[49][49] - mtl_sun < 5
Esempio n. 28
0
def reader_context(**attrs):
    reader = Mock(
        spec=DatasetReader,
        shape=(360, 720),
        transform=Affine(-180., 0.5, 0.0, -90., 0.0, 0.5),
        bounds=BoundingBox(-180., -90., 0., 0.),
        crs={"init": "epsg:4326"},
    )
    reader.configure_mock(**attrs)
    context = Mock()
    context.__enter__ = Mock(return_value=reader)
    context.__exit__ = Mock(return_value=False)
    return context
Esempio n. 29
0
def get_extent(ds):
    """Extract the extent (bounding box) from the dataset.

    Parameters
    ----------
    ds : xarray.Dataset
        The input dataset

    Returns
    -------
    tuple
        The extent (left, bottom, right, top) in latitude and longitude
        coordinates.
    """

    #
    # Check if latitude and longitude are stored as coordinates.
    #
    if 'lon' in ds.coords and 'lat' in ds.coords:
        return BoundingBox(left=ds.lon.values.min(),
                           bottom=ds.lat.values.min(),
                           right=ds.lon.values.max(),
                           top=ds.lat.values.max())

    #
    # Otherwise, get extent from projection information
    # by projecting the corner coordinates onto EPSG:4326
    # to obtain the latitude and longitude at the four corners.
    #
    src_crs = get_crs(ds)
    if src_crs is None:
        raise CRSError('Could not determine the CRS.')

    dst_crs = CRS(init='epsg:4326')
    proj_bounds = get_bounds(ds)
    bounds = rasterio.warp.transform_bounds(src_crs, dst_crs,
                                            **proj_bounds._asdict())
    return BoundingBox(*bounds)
Esempio n. 30
0
def _grid_datasets(datasets, bounds_override, grid_proj, grid_size):
    tiles = defaultdict(list)
    for dataset in datasets:
        dataset_proj = dataset.crs
        dataset_bounds = dataset.bounds
        bounds = bounds_override or BoundingBox(*transform_bounds(dataset_proj, grid_proj, *dataset_bounds))

        for y in range(int(bounds.bottom // grid_size[1]), int(bounds.top // grid_size[1]) + 1):
            for x in range(int(bounds.left // grid_size[0]), int(bounds.right // grid_size[0]) + 1):
                tile_index = (x, y)
                if _check_intersect(tile_index, grid_size, grid_proj, dataset_bounds, dataset_proj):
                    tiles[tile_index].append(dataset)

    return tiles