Пример #1
0
def compute_grid_info(cells: Dict[TileIdx_xy, Any],
                      resolution: float = math.inf,
                      title_width: int = 0) -> Dict[TileIdx_xy, Any]:
    """
    Compute geojson feature for every cell in ``cells``.
    Where ``cells`` is produced by ``odc.index.bin_dataset_stream``
    """
    if title_width == 0:
        nmax = max([max(abs(ix), abs(iy)) for ix, iy in cells])
        # title_width is the number of digits in the index, +1 for positive or negative
        title_width = len(str(nmax)) + 1

    grid_info = {}

    for idx, cell in cells.items():
        geobox = cell.geobox
        utc_offset = timedelta_to_hours(solar_offset(geobox.extent))
        wrapdateline = utc_offset <= -11 or utc_offset >= 11

        geom = geobox.extent.to_crs("epsg:4326",
                                    resolution=resolution,
                                    wrapdateline=wrapdateline)
        ix, iy = idx
        grid_info[idx] = {
            "type": "Feature",
            "geometry": geom.json,
            "properties": {
                "title": f"{ix:+0{title_width}d},{iy:+0{title_width}d}",
                "utc_offset": utc_offset,
                "total": len(cell.dss),
            },
        }

    return grid_info
Пример #2
0
def compute_grid_info(cells: Dict[TileIdx_xy, Any],
                      resolution: float = math.inf,
                      title_width: int = 5) -> Dict[TileIdx_xy, Any]:
    """
    Compute geojson feature for every cell in ``cells``.
    Where ``cells`` is produced by ``odc.index.bin_dataset_stream``
    """
    grid_info = {}

    for idx, cell in cells.items():
        geobox = cell.geobox
        utc_offset = timedelta_to_hours(solar_offset(geobox.extent))
        wrapdateline = (utc_offset <= -11 or utc_offset >= 11)

        geom = geobox.extent.to_crs('epsg:4326',
                                    resolution=resolution,
                                    wrapdateline=wrapdateline)
        ix, iy = idx
        grid_info[idx] = {
            'type': 'Feature',
            'geometry': geom.json,
            'properties': {
                'title': f'{ix:+0{title_width}d},{iy:+0{title_width}d}',
                'utc_offset': utc_offset,
                'total': len(cell.dss),
            },
        }

    return grid_info
Пример #3
0
def load_with_native_transform(dss: List[Dataset],
                               bands: Tuple[str, ...],
                               geobox: GeoBox,
                               native_transform: Callable[[xr.Dataset], xr.Dataset],
                               basis: Optional[str] = None,
                               groupby: Optional[str] = None,
                               fuser: Optional[Callable[[xr.Dataset], xr.Dataset]] = None,
                               resampling: str = 'nearest',
                               chunks: Optional[Dict[str, int]] = None,
                               load_chunks: Optional[Dict[str, int]] = None,
                               **kw) -> xr.Dataset:
    """
    Load a bunch of datasets with native pixel transform.

    :param dss: A list of datasets to load
    :param bands: Which measurements to load
    :param geobox: GeoBox of the final output
    :param native_transform: ``xr.Dataset -> xr.Dataset`` transform, should support Dask inputs/outputs
    :param basis: Name of the band to use as a reference for what is "native projection"
    :param groupby: One of 'solar_day'|'time'|'idx'|None
    :param fuser: Optional ``xr.Dataset -> xr.Dataset`` transform
    :param resampling: Any resampling mode supported by GDAL as a string:
                       nearest, bilinear, average, mode, cubic, etc...
    :param chunks: If set use Dask, must be in dictionary form ``{'x': 4000, 'y': 4000}``
    :param load_chunks: Defaults to ``chunks`` but can be different if supplied
                        (different chunking for native read vs reproject)
    :param kw: Used to support old names ``dask_chunks`` and ``group_by``

    1. Partition datasets by native Projection
    2. For every group do
       - Load data
       - Apply native_transform
       - [Optional] fuse rasters that happened on the same day/time
       - Reproject to final geobox
    3. Stack output of (2)
    4. [Optional] fuse rasters that happened on the same day/time

    """
    if fuser is None:
        fuser = _nodata_fuser

    if groupby is None:
        groupby = kw.get('group_by', 'idx')
    if chunks is None:
        chunks = kw.get('dask_chunks', None)

    sources = group_by_nothing(dss, solar_offset(geobox.extent))
    xx = [_load_with_native_transform_1(srcs,
                                        bands,
                                        geobox,
                                        native_transform,
                                        basis=basis,
                                        resampling=resampling,
                                        groupby=groupby,
                                        fuser=fuser,
                                        chunks=chunks,
                                        load_chunks=load_chunks)
          for srcs in _split_by_grid(sources)]

    if len(xx) == 1:
        xx = xx[0]
    else:
        xx = xr.concat(xx, sources.dims[0])
        if groupby != 'idx':
            xx = xx.groupby(groupby).map(fuser)

    # TODO: probably want to replace spec MultiIndex with just `time` component

    return xx