Example #1
0
def test_metadata_valid():
    """Get bounds and get stats for all bands."""
    meta = main.metadata(ADDRESS)
    assert meta["address"] == ADDRESS
    assert len(meta["bounds"]["value"]) == 4
    assert len(meta["statistics"].items()) == 3
    assert meta["statistics"][1]["pc"] == [12, 198]
Example #2
0
def metadata():
    """Handle metadata requests."""
    url = request.args.get('url', default='', type=str)
    url = requote_uri(url)

    # address = query_args['url']
    info = main.metadata(url)
    return (jsonify(info))
Example #3
0
def metadata(url: str,
             pmin: Union[str, float] = 2.,
             pmax: Union[str, float] = 98.) -> Tuple[str, str, str]:
    """Handle bounds requests."""
    pmin = float(pmin) if isinstance(pmin, str) else pmin
    pmax = float(pmax) if isinstance(pmax, str) else pmax
    info = main.metadata(url, pmin=pmin, pmax=pmax)
    return ("OK", "application/json", json.dumps(info))
Example #4
0
def metadata(url=None, pmin=2, pmax=98):
    """Handle bounds requests."""
    if not url:
        raise TilerError("Missing 'url' parameter")
    pmin = float(pmin) if isinstance(pmin, str) else pmin
    pmax = float(pmax) if isinstance(pmax, str) else pmax
    info = main.metadata(url, pmin=pmin, pmax=pmax)
    return ("OK", "application/json", json.dumps(info))
Example #5
0
def test_metadata_valid_custom():
    """Get bounds and get stats for all bands with custom percentiles."""
    meta = main.metadata(ADDRESS, pmin=5, pmax=90, dst_crs="epsg:3857")
    assert meta["address"] == ADDRESS
    assert meta["bounds"]["crs"] == "epsg:3857"
    assert len(meta["bounds"]["value"]) == 4
    assert len(meta["statistics"].items()) == 3
    assert meta["statistics"][1]["pc"] == [30, 191]
Example #6
0
def metadata(b64url):
    url = str(base64.b64decode(b64url).decode('utf-8'))
    app.logger.debug(f"Getting metadata at url {url}")
    try:
        metadata = main.metadata(url)
        app.logger.debug(metadata)
    except Exception as e:
        app.logger.debug(e)
        return abort(500)
    return jsonify(metadata)
Example #7
0
def test_metadata_valid():
    """Get bounds and get stats for all bands."""
    meta = main.metadata(ADDRESS)
    assert meta["address"] == ADDRESS
    assert len(meta["bounds"]["value"]) == 4
    assert meta["minzoom"]
    assert meta["maxzoom"]
    assert len(meta["band_descriptions"]) == 3
    assert (1, "band1") == meta["band_descriptions"][0]
    assert len(meta["statistics"].items()) == 3
    assert meta["statistics"][1]["pc"] == [11, 199]
Example #8
0
def metadata_handler(
    url: str,
    pmin: Union[str, float] = 2.0,
    pmax: Union[str, float] = 98.0,
    nodata: Union[str, float, int] = None,
    indexes: Union[str, Tuple, int] = None,
    overview_level: Union[str, int] = None,
    max_size: Union[str, int] = 1024,
    histogram_bins: Union[str, int] = 20,
    histogram_range: Union[str, int] = None,
) -> Tuple[str, str, str]:
    """Handle /metadata requests."""
    pmin = float(pmin) if isinstance(pmin, str) else pmin
    pmax = float(pmax) if isinstance(pmax, str) else pmax

    if nodata is not None and isinstance(nodata, str):
        nodata = numpy.nan if nodata == "nan" else float(nodata)

    if indexes is not None and isinstance(indexes, str):
        indexes = tuple(int(s) for s in re.findall(r"\d+", indexes))

    if overview_level is not None and isinstance(overview_level, str):
        overview_level = int(overview_level)

    max_size = int(max_size) if isinstance(max_size, str) else max_size
    histogram_bins = (
        int(histogram_bins) if isinstance(histogram_bins, str) else histogram_bins
    )

    if histogram_range is not None and isinstance(histogram_range, str):
        histogram_range = tuple(map(float, histogram_range.split(",")))

    info = cogTiler.metadata(
        url,
        pmin=pmin,
        pmax=pmax,
        nodata=nodata,
        indexes=indexes,
        overview_level=overview_level,
        histogram_bins=histogram_bins,
        histogram_range=histogram_range,
    )
    return ("OK", "application/json", json.dumps(info))
Example #9
0
    def get(self, request, pk=None, project_pk=None, tile_type=""):
        """
        Get the metadata for this tasks's asset type
        """
        task = self.get_and_check_task(request, pk)

        formula = self.request.query_params.get('formula')
        bands = self.request.query_params.get('bands')

        if formula == '': formula = None
        if bands == '': bands = None

        try:
            expr, hrange = lookup_formula(formula, bands)
        except ValueError as e:
            raise exceptions.ValidationError(str(e))

        pmin, pmax = 2.0, 98.0
        raster_path = get_raster_path(task, tile_type)

        if not os.path.isfile(raster_path):
            raise exceptions.NotFound()

        try:
            with rasterio.open(raster_path, "r") as src:
                band_count = src.meta['count']
                if has_alpha_band(src):
                    band_count -= 1

                info = main.metadata(src,
                                     pmin=pmin,
                                     pmax=pmax,
                                     histogram_bins=255,
                                     histogram_range=hrange,
                                     expr=expr)
        except IndexError as e:
            # Caught when trying to get an invalid raster metadata
            raise exceptions.ValidationError(
                "Cannot retrieve raster metadata: %s" % str(e))

        # Override min/max
        if hrange:
            for b in info['statistics']:
                info['statistics'][b]['min'] = hrange[0]
                info['statistics'][b]['max'] = hrange[1]

        cmap_labels = {
            "jet": "Jet",
            "terrain": "Terrain",
            "gist_earth": "Earth",
            "rdylgn": "RdYlGn",
            "rdylgn_r": "RdYlGn (Reverse)",
            "spectral": "Spectral",
            "spectral_r": "Spectral (Reverse)",
            "pastel1": "Pastel",
        }

        colormaps = []
        algorithms = []
        if tile_type in ['dsm', 'dtm']:
            colormaps = ['jet', 'terrain', 'gist_earth', 'pastel1']
        elif formula and bands:
            colormaps = ['rdylgn', 'spectral', 'rdylgn_r', 'spectral_r']
            algorithms = *get_algorithm_list(band_count),

        info['color_maps'] = []
        info['algorithms'] = algorithms

        if colormaps:
            for cmap in colormaps:
                try:
                    info['color_maps'].append({
                        'key':
                        cmap,
                        'color_map':
                        get_colormap(cmap, format="gdal"),
                        'label':
                        cmap_labels.get(cmap, cmap)
                    })
                except FileNotFoundError:
                    raise exceptions.ValidationError(
                        "Not a valid color_map value: %s" % cmap)

        del info['address']
        info['name'] = task.name
        info['scheme'] = 'xyz'
        info['tiles'] = [
            get_tile_url(task, tile_type, self.request.query_params)
        ]

        if info['maxzoom'] < info['minzoom']:
            info['maxzoom'] = info['minzoom']
        info['maxzoom'] += ZOOM_EXTRA_LEVELS
        info['minzoom'] -= ZOOM_EXTRA_LEVELS

        return Response(info)
Example #10
0
def meta(
    url,
    nodata=None,
    indexes=None,
    overview_level=None,
    max_size=1024,
    histogram_bins=20,
    histogram_range=None,
):
    """
    Handle /metadata requests.

    Note: All the querystring parameters are translated to function keywords
    and passed as string value by lambda_proxy

    Attributes
    ----------
    url : str, required
        Dataset url to read from.
    nodata, str, optional
        Custom nodata value if not preset in dataset.
    indexes : str, optional, (defaults: None)
        Comma separated band index number (e.g "1,2,3").
    overview_level, str, optional
        Select the overview level to fetch for statistic calculation.
        By default if will grabb the one closer to the `max_size` value.
    max_size: str, optional
        Maximum size of dataset to retrieve
        (will be used to calculate the overview level to fetch).
    histogram_bins: int, optional
        Defines the number of equal-width histogram bins (default: 20).
    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
    -------
    status : str
        Status of the request (e.g. OK, NOK).
    MIME type : str
        response body MIME type (e.g. image/jpeg).
    body : str
        String encoded json statistic metadata.

    """
    if indexes is not None and isinstance(indexes, str):
        indexes = tuple(int(s) for s in re.findall(r"\d+", indexes))

    if overview_level is not None and isinstance(overview_level, str):
        overview_level = int(overview_level)

    if nodata is not None and isinstance(nodata, str):
        nodata = numpy.nan if nodata == "nan" else float(nodata)

    if max_size is not None and isinstance(max_size, str):
        max_size = int(max_size)

    if histogram_bins is not None and isinstance(histogram_bins, str):
        histogram_bins = int(histogram_bins)

    if histogram_range is not None and isinstance(histogram_range, str):
        histogram_range = tuple(map(float, histogram_range.split(",")))

    info = main.metadata(
        url,
        nodata=nodata,
        indexes=indexes,
        overview_level=overview_level,
        histogram_bins=histogram_bins,
        histogram_range=histogram_range,
    )

    return ("OK", "application/json", json.dumps(info))