Ejemplo n.º 1
0
    def ndarray(
            self,
            inputs,
            bands=None,
            scales=None,
            data_type=None,
            srs=None,
            resolution=None,
            dimensions=None,
            cutline=None,
            place=None,
            bounds=None,
            bounds_srs=None,
            align_pixels=False,
            resampler=None,
            order='image',
            dltile=None,
            **pass_through_params
    ):
        """Retrieve a raster as a NumPy array.

        :param inputs: List of :class:`Metadata` identifiers.
        :param bands: List of requested bands. If the last item in the list is an alpha
            band (with data range `[0, 1]`) it affects rastering of all other bands:
            When rastering multiple images, they are combined image-by-image only where
            each respective image's alpha band is `1` (pixels where the alpha band is not
            `1` are "transparent" in the overlap between images). If a pixel is fully
            masked considering all combined alpha bands it will be `0` in all non-alpha
            bands.
        :param scales: List of tuples specifying the scaling to be applied to each band.
            A tuple has 4 elements in the order ``(src_min, src_max, out_min, out_max)``,
            meaning values in the source range ``src_min`` to ``src_max`` will be scaled
            to the output range ``out_min`` to ``out_max``. A tuple with 2 elements
            ``(src_min, src_max)`` is also allowed, in which case the output range
            defaults to ``(0, 255)`` (a useful default for the common output type
            ``Byte``).  If no scaling is desired for a band, use ``None``. This tuple
            format and behaviour is identical to GDAL's scales during translation.
            Example argument: ``[(0, 10000, 0, 127), None, (0, 10000)]`` - the first
            band will have source values 0-10000 scaled to 0-127, the second band will
            not be scaled, the third band will have 0-10000 scaled to 0-255.
        :param str data_type: Output data type (one of ``Byte``, ``UInt16``, ``Int16``,
            ``UInt32``, ``Int32``, ``Float32``, ``Float64``).
        :param str srs: Output spatial reference system definition understood by GDAL.
        :param float resolution: Desired resolution in output SRS units. Incompatible with
            `dimensions`
        :param tuple dimensions: Desired output (width, height) in pixels. Incompatible with
            `resolution`
        :param str cutline: A GeoJSON feature or geometry to be used as a cutline.
        :param str place: A slug identifier to be used as a cutline.
        :param tuple bounds: ``(min_x, min_y, max_x, max_y)`` in target SRS.
        :param str bounds_srs: Override the coordinate system in which bounds are expressed.
        :param bool align_pixels: Align pixels to the target coordinate system.
        :param str resampler: Resampling algorithm to be used during warping (``near``,
            ``bilinear``, ``cubic``, ``cubicsplice``, ``lanczos``, ``average``, ``mode``,
            ``max``, ``min``, ``med``, ``q1``, ``q3``).
        :param str order: Order of the returned array. `image` returns arrays as
            ``(row, column, band)`` while `gdal` returns arrays as ``(band, row, column)``.
        :param str dltile: a dltile key used to specify the resolution, bounds, and srs.

        :return: A tuple of ``(np_array, metadata)``. The first element (``np_array``) is
            the rastered scene as a NumPy array. The second element (``metadata``) is a
            dictionary containing details about the raster operation that happened. These
            details can be useful for debugging but shouldn't otherwise be relied on (there
            are no guarantees that certain keys will be present).
        """
        cutline = as_json_string(cutline)

        if place is not None:
            places = Places(auth=self.auth)
            shape = places.shape(place, geom='low')
            cutline = json.dumps(shape['geometry'])

        params = {
            'keys': inputs,
            'bands': bands,
            'scales': scales,
            'ot': data_type,
            'srs': srs,
            'resolution': resolution,
            'shape': cutline,
            'outputBounds': bounds,
            'outputBoundsSRS': bounds_srs,
            'outsize': dimensions,
            'targetAlignedPixels': align_pixels,
            'resampleAlg': resampler,
        }
        params.update(pass_through_params)

        if dltile is not None:
            if isinstance(dltile, dict):
                params['dltile'] = dltile['properties']['key']
            else:
                params['dltile'] = dltile

        can_blosc = not isinstance(blosc, ThirdParty)

        if can_blosc:
            params['of'] = 'blosc'
        else:
            params['of'] = 'npz'

        r = self.session.post('/npz', json=params, stream=True)

        if can_blosc:
            metadata = json.loads(r.raw.readline().decode('utf-8').strip())
            array_meta = json.loads(r.raw.readline().decode('utf-8').strip())
            array = read_blosc_array(array_meta, r.raw)
        else:
            npz = np.load(BytesIO(r.content))
            array = npz['data']
            metadata = json.loads(npz['metadata'].tostring().decode('utf-8'))

        if len(array.shape) > 2:
            if order == 'image':
                return array.transpose((1, 2, 0)), metadata
            elif order == 'gdal':
                return array, metadata
        else:
            return array, DotDict(metadata)
Ejemplo n.º 2
0
    def ndarray(
        self,
        inputs,
        bands=None,
        scales=None,
        data_type=None,
        srs=None,
        resolution=None,
        dimensions=None,
        cutline=None,
        place=None,
        bounds=None,
        bounds_srs=None,
        align_pixels=False,
        resampler=None,
        order="image",
        dltile=None,
        processing_level=None,
        **pass_through_params
    ):
        """Retrieve a raster as a NumPy array.

        :param list(str) inputs: List of catalog image identifiers.
        :param list(str) bands: List of requested bands. If the last item in the list is an alpha
            band (with data range ``[0, 1]``) it affects rastering of all other bands:
            When rastering multiple images, they are combined image-by-image only where
            each respective image's alpha band is ``1`` (pixels where the alpha band is not
            ``1`` are "transparent" in the overlap between images). If a pixel is fully
            masked considering all combined alpha bands it will be ``0`` in all non-alpha
            bands. Not specifying bands returns all bands in the product.
        :param list(tuple()) scales: List of tuples specifying the scaling to be applied to each band.
            A tuple has 4 elements in the order ``(src_min, src_max, out_min, out_max)``,
            meaning values in the source range ``src_min`` to ``src_max`` will be scaled
            to the output range ``out_min`` to ``out_max``. A tuple with 2 elements
            ``(src_min, src_max)`` is also allowed, in which case the output range
            defaults to ``(0, 255)`` (a useful default for the common output type
            ``Byte``).  If no scaling is desired for a band, use ``None``.  This tuple
            format and behaviour is identical to GDAL's scales during translation.
            Example argument: ``[(0, 10000, 0, 127), (0, 1, 0, 1), (0, 10000)]`` - the first
            band will have source values 0-10000 scaled to 0-127, the second band will
            not be scaled, the third band will have 0-10000 scaled to 0-255.
        :param str data_type: Output data type (one of ``Byte``, ``UInt16``, ``Int16``,
            ``UInt32``, ``Int32``, ``Float32``, ``Float64``).
        :param str srs: Output spatial reference system definition understood by GDAL.
        :param float resolution: Desired resolution in output SRS units. Incompatible with
            ``dimensions``
        :param tuple dimensions: Desired output ``(width, height)`` in pixels within which
            the raster should fit; i.e. the longer side of the raster will be min(dimensions).
            Incompatible with ``resolution``.
        :param str cutline: A GeoJSON object to be used as a cutline, or WKT string.
            GeoJSON coordinates must be in WGS84 lat-lon.
        :param str place: A slug identifier to be used as a cutline.
        :param tuple bounds: ``(min_x, min_y, max_x, max_y)`` in target SRS.
        :param str bounds_srs:
            Override the coordinate system in which bounds are expressed.
            If not given, bounds are assumed to be expressed in the output SRS.
        :param bool align_pixels: Align pixels to the target coordinate system.
        :param str resampler: Resampling algorithm to be used during warping (``near``,
            ``bilinear``, ``cubic``, ``cubicsplice``, ``lanczos``, ``average``, ``mode``,
            ``max``, ``min``, ``med``, ``q1``, ``q3``).
        :param str order: Order of the returned array. ``image`` returns arrays as
            ``(row, column, band)`` while ``gdal`` returns arrays as ``(band, row, column)``.
        :param str dltile: a dltile key used to specify the resolution, bounds, and srs.
        :param str processing_level: How the processing level of the underlying data
            should be adjusted, one of ``toa`` (top of atmosphere) and ``surface``. For
            products that support it, ``surface`` applies Descartes Labs' general surface
            reflectance algorithm to the output.

        :return: A tuple of ``(np_array, metadata)``.

            * ``np_array``: the rastered scene as a NumPy array
            * ``metadata``: a dictionary containing details about the raster operation
              that happened. These details can be useful for debugging but shouldn't
              otherwise be relied on (there are no guarantees that certain keys will be
              present).

        :rtype: tuple(numpy.ndarray, DotDict)
        """
        cutline = as_json_string(cutline)

        if place is not None:
            places = Places(auth=self.auth)
            shape = places.shape(place, geom="low")
            cutline = json.dumps(shape["geometry"])

        params = {
            "ids": inputs,
            "bands": bands,
            "scales": scales,
            "ot": data_type,
            "srs": srs,
            "resolution": resolution,
            "shape": cutline,
            "outputBounds": bounds,
            "outputBoundsSRS": bounds_srs,
            "outsize": dimensions,
            "targetAlignedPixels": align_pixels,
            "resampleAlg": resampler,
            "processing_level": processing_level,
        }
        params.update(pass_through_params)

        if dltile is not None:
            if isinstance(dltile, dict):
                params["dltile"] = dltile["properties"]["key"]
            else:
                params["dltile"] = dltile

        can_blosc = not isinstance(blosc, ThirdParty)

        if can_blosc:
            params["of"] = "blosc"
        else:
            params["of"] = "npz"

        r = self.session.post("/npz", json=params, stream=True)

        if can_blosc:
            metadata = json.loads(r.raw.readline().decode("utf-8").strip())
            array_meta = json.loads(r.raw.readline().decode("utf-8").strip())
            array = read_blosc_array(array_meta, r.raw)
        else:
            npz = np.load(BytesIO(r.content))
            array = npz["data"]
            metadata = json.loads(npz["metadata"].tostring().decode("utf-8"))

        if len(array.shape) > 2:
            if order == "image":
                return array.transpose((1, 2, 0)), metadata
            elif order == "gdal":
                return array, metadata
        else:
            return array, DotDict(metadata)