Exemplo n.º 1
0
def test_statsFunction_valid():
    """Should return a valid dict with array statistics."""
    with rasterio.open(S3_ALPHA_PATH) as src:
        arr = src.read(indexes=[1], masked=True)
    stats = utils._stats(arr)
    assert stats["pc"] == [10, 200]
    assert stats["min"] == 0
    assert stats["max"] == 254
    assert int(stats["std"]) == 55
    assert len(stats["histogram"]) == 2
    assert len(stats["histogram"][0]) == 10

    stats = utils._stats(arr, percentiles=(5, 95))
    assert stats["pc"] == [31, 195]
Exemplo n.º 2
0
def _sentinel_stats(src_path, percentiles=(2, 98)):
    """
    src_path : str or PathLike object
        A dataset path or URL. Will be opened in "r" mode.
    """
    with rasterio.open(src_path) as src:
        arr = src.read(indexes=[1], masked=True)
        arr[arr == 0] = np.ma.masked

    return {1: utils._stats(arr, percentiles=percentiles)}
Exemplo n.º 3
0
def test_raster_get_stats_ovr():
    """Validate that overview level return the same result than reeading the overview."""
    resampling_method = "bilinear"
    rio_stats = utils.raster_get_stats(
        S3_PATH, overview_level=1, resampling_method=resampling_method
    )

    with rasterio.open(S3_PATH, overview_level=1) as src_dst:
        indexes = src_dst.indexes
        arr = src_dst.read(resampling=Resampling[resampling_method], masked=True)
        stats = {indexes[b]: utils._stats(arr[b], bins=10) for b in range(arr.shape[0])}
    assert rio_stats["statistics"] == stats
Exemplo n.º 4
0
def _sentinel_stats(
    src_path, percentiles=(2, 98), histogram_bins=10, histogram_range=None
):
    """
    src_path : str or PathLike object
        A dataset path or URL. Will be opened in "r" mode.
    """

    with rasterio.open(src_path) as src:
        arr = src.read(indexes=[1], masked=True)
        arr[arr == 0] = np.ma.masked

    params = {}
    if histogram_bins:
        params.update(dict(bins=histogram_bins))
    if histogram_range:
        params.update(dict(range=histogram_range))

    return {1: utils._stats(arr, percentiles=percentiles, **params)}
Exemplo n.º 5
0
def _landsat_stats(
    band,
    address_prefix,
    metadata,
    overview_level=None,
    max_size=1024,
    percentiles=(2, 98),
    dst_crs=CRS({"init": "EPSG:4326"}),
    histogram_bins=10,
    histogram_range=None,
):
    """
    Retrieve landsat dataset statistics.

    Attributes
    ----------
    band : str
        Landsat band number
    address_prefix : str
        A Landsat AWS S3 dataset prefix.
    metadata : dict
        Landsat metadata
    overview_level : int, optional
        Overview (decimation) level to fetch.
    max_size: int, optional
        Maximum size of dataset to retrieve
        (will be used to calculate the overview level to fetch).
    percentiles : tulple, optional
        Percentile or sequence of percentiles to compute,
        which must be between 0 and 100 inclusive (default: (2, 98)).
    dst_crs: CRS or dict
        Target coordinate reference system (default: EPSG:4326).
    histogram_bins: int, optional
        Defines the number of equal-width histogram bins (default: 10).
    histogram_range: tuple or list, optional
        The lower and upper range of the bins. If not provided, range is simply
        the min and max of the array.

    Returns
    -------
    out : dict
        (percentiles), min, max, stdev, histogram for each band,
        e.g.
        {
            "4": {
                'pc': [15, 121],
                'min': 1,
                'max': 162,
                'std': 27.22067722127997,
                'histogram': [
                    [102934, 135489, 20981, 13548, 11406, 8799, 7351, 5622, 2985, 662]
                    [1., 17.1, 33.2, 49.3, 65.4, 81.5, 97.6, 113.7, 129.8, 145.9, 162.]
                ]
            }
        }
    """
    src_path = "{}_B{}.TIF".format(address_prefix, band)
    with rasterio.open(src_path) as src:
        levels = src.overviews(1)
        width = src.width
        height = src.height
        bounds = transform_bounds(src.crs,
                                  dst_crs,
                                  *src.bounds,
                                  densify_pts=21)

        if len(levels):
            if overview_level:
                decim = levels[overview_level]
            else:
                # determine which zoom level to read
                for ii, decim in enumerate(levels):
                    if max(width // decim, height // decim) < max_size:
                        break
        else:
            decim = 1
            warnings.warn("Dataset has no overviews, reading the full dataset",
                          NoOverviewWarning)

        out_shape = (height // decim, width // decim)

        if band == "QA":
            nodata = 1
        else:
            nodata = 0

        vrt_params = dict(nodata=nodata,
                          add_alpha=False,
                          src_nodata=nodata,
                          init_dest_nodata=False)
        with WarpedVRT(src, **vrt_params) as vrt:
            arr = vrt.read(out_shape=out_shape, indexes=[1], masked=True)

    if band in ["1", "2", "3", "4", "5", "6", "7", "8", "9"]:  # OLI
        multi_reflect = metadata["RADIOMETRIC_RESCALING"].get(
            "REFLECTANCE_MULT_BAND_{}".format(band))
        add_reflect = metadata["RADIOMETRIC_RESCALING"].get(
            "REFLECTANCE_ADD_BAND_{}".format(band))
        sun_elev = metadata["IMAGE_ATTRIBUTES"]["SUN_ELEVATION"]

        arr = 10000 * reflectance.reflectance(
            arr, multi_reflect, add_reflect, sun_elev, src_nodata=0)
    elif band in ["10", "11"]:  # TIRS
        multi_rad = metadata["RADIOMETRIC_RESCALING"].get(
            "RADIANCE_MULT_BAND_{}".format(band))
        add_rad = metadata["RADIOMETRIC_RESCALING"].get(
            "RADIANCE_ADD_BAND_{}".format(band))
        k1 = metadata["TIRS_THERMAL_CONSTANTS"].get(
            "K1_CONSTANT_BAND_{}".format(band))
        k2 = metadata["TIRS_THERMAL_CONSTANTS"].get(
            "K2_CONSTANT_BAND_{}".format(band))

        arr = brightness_temp.brightness_temp(arr, multi_rad, add_rad, k1, k2)

    params = {}
    if histogram_bins:
        params.update(dict(bins=histogram_bins))
    if histogram_range:
        params.update(dict(range=histogram_range))

    stats = {band: utils._stats(arr, percentiles=percentiles, **params)}

    return {
        "bounds": {
            "value": bounds,
            "crs":
            dst_crs.to_string() if isinstance(dst_crs, CRS) else dst_crs,
        },
        "statistics": stats,
    }
Exemplo n.º 6
0
def get_area_stats(
    src,
    bounds,
    max_img_size=512,
    indexes=None,
    nodata=None,
    resampling_method="bilinear",
    bbox_crs="epsg:4326",
    histogram_bins=20,
    histogram_range=None,
):
    """
    Read data and mask.

    Attributes
    ----------
    srd_dst : rasterio.io.DatasetReader
        rasterio.io.DatasetReader object
    bounds : list
        bounds (left, bottom, right, top)
    tilesize : int
        Output image size
    indexes : list of ints or a single int, optional, (defaults: None)
        If `indexes` is a list, the result is a 3D array, but is
        a 2D array if it is a band index number.
    nodata: int or float, optional (defaults: None)
    resampling_method : str, optional (default: "bilinear")
         Resampling algorithm
    histogram_bins: int, optional
        Defines the number of equal-width histogram bins (default: 10).
    histogram_range: str, optional
        The lower and upper range of the bins. If not provided, range is simply
        the min and max of the array.

    Returns
    -------
    out : array, int
        returns pixel value.

    """
    if isinstance(indexes, int):
        indexes = [indexes]
    elif isinstance(indexes, tuple):
        indexes = list(indexes)

    with rasterio.open(src) as src_dst:
        bounds = transform_bounds(bbox_crs,
                                  src_dst.crs,
                                  *bounds,
                                  densify_pts=21)

        vrt_params = dict(add_alpha=True,
                          resampling=Resampling[resampling_method])

        indexes = indexes if indexes is not None else src_dst.indexes
        nodata = nodata if nodata is not None else src_dst.nodata

        def _get_descr(ix):
            """Return band description."""
            name = src_dst.descriptions[ix - 1]
            if not name:
                name = "band{}".format(ix)
            return name

        band_descriptions = [(ix, _get_descr(ix)) for ix in indexes]

        vrt_transform, vrt_width, vrt_height = get_vrt_transform(
            src_dst, bounds, bounds_crs=src_dst.crs)
        vrt_params.update(
            dict(transform=vrt_transform, width=vrt_width, height=vrt_height))

        width = round(vrt_width) if vrt_width < max_img_size else max_img_size
        height = round(
            vrt_height) if vrt_height < max_img_size else max_img_size
        out_shape = (len(indexes), width, height)
        if nodata is not None:
            vrt_params.update(
                dict(nodata=nodata, add_alpha=False, src_nodata=nodata))

        if has_alpha_band(src_dst):
            vrt_params.update(dict(add_alpha=False))

        with WarpedVRT(src_dst, **vrt_params) as vrt:
            arr = vrt.read(out_shape=out_shape, indexes=indexes, masked=True)
            if not arr.any():
                return None, band_descriptions

            params = {}
            if histogram_bins:
                params.update(dict(bins=histogram_bins))
            if histogram_range:
                params.update(dict(range=histogram_range))

            stats = {
                indexes[b]: _stats(arr[b], **params)
                for b in range(arr.shape[0])
                if vrt.colorinterp[b] != ColorInterp.alpha
            }

    return stats, band_descriptions