Beispiel #1
0
def test_rasterization_function_user_dtype(fill_value, dtype):
    resolution = 1

    line = GeoVector.from_bounds(xmin=2, ymin=0, xmax=3, ymax=3, crs=DEFAULT_CRS)
    roi = GeoVector.from_bounds(xmin=0, ymin=0, xmax=5, ymax=5, crs=DEFAULT_CRS)

    expected_data = np.zeros((5, 5), dtype=dtype)
    expected_data[2:, 2] = fill_value
    expected_mask = np.ones((5, 5), dtype=bool)
    expected_mask[2:, 2] = False
    expected_image = np.ma.masked_array(
        expected_data,
        expected_mask
    )

    expected_affine = Affine(1.0, 0.0, 0.0, 0.0, -1.0, 5.0)

    expected_crs = DEFAULT_CRS

    expected_result = GeoRaster2(expected_image, expected_affine, expected_crs)

    result = rasterize([line.get_shape(DEFAULT_CRS)], DEFAULT_CRS, roi.get_shape(DEFAULT_CRS),
                       resolution, fill_value=fill_value, dtype=dtype)

    assert result == expected_result
Beispiel #2
0
    def rasterize(self,
                  dest_resolution,
                  *,
                  fill_value=None,
                  bounds=None,
                  dtype=None,
                  crs=None,
                  **kwargs):
        # Import here to avoid circular imports
        from telluric import rasterization  # noqa
        crs = crs or self.crs
        shapes = [self.get_shape(crs)]
        if bounds is None:
            bounds = self.envelope.get_shape(crs)
        elif isinstance(bounds, GeoVector):
            bounds = bounds.get_shape(crs)

        if kwargs.pop("nodata_value", None):
            warnings.warn(rasterization.NODATA_DEPRECATION_WARNING,
                          DeprecationWarning)

        return rasterization.rasterize(shapes,
                                       crs,
                                       bounds,
                                       dest_resolution,
                                       fill_value=fill_value,
                                       dtype=dtype)
Beispiel #3
0
    def rasterize(self,
                  dest_resolution,
                  polygonize_width=0,
                  crs=WEB_MERCATOR_CRS,
                  fill_value=None,
                  nodata_value=None,
                  bounds=None,
                  **polygonize_kwargs):
        """Binarize a FeatureCollection and produce a raster with the target resolution.

        Parameters
        ----------
        dest_resolution: float
            Resolution in units of the CRS.
        polygonize_width : int, optional
            Width for the polygonized features (lines and points) in pixels, default to 0 (they won't appear).
        crs : ~rasterio.crs.CRS, dict (optional)
            Coordinate system, default to :py:data:`telluric.constants.WEB_MERCATOR_CRS`.
        fill_value : float, optional
            Value that represents data, default to None (will default to :py:data:`telluric.rasterization.FILL_VALUE`.
        nodata_value : float, optional
            Nodata value, default to None (will default to :py:data:`telluric.rasterization.NODATA_VALUE`.
        bounds : GeoVector, optional
            Optional bounds for the target image, default to None (will use the FeatureCollection convex hull).
        polygonize_kwargs : dict
            Extra parameters to the polygonize function.

        """
        # Compute the size in real units and polygonize the features
        if not isinstance(polygonize_width, int):
            raise TypeError("The width in pixels must be an integer")

        # If the pixels width is 1, render points as squares to avoid missing data
        if polygonize_width == 1:
            polygonize_kwargs.update(cap_style_point=CAP_STYLE.square)

        width = polygonize_width * dest_resolution
        polygonized = [
            feature.polygonize(width, **polygonize_kwargs) for feature in self
        ]

        # Discard the empty features
        shapes = [
            feature.geometry.get_shape(crs) for feature in polygonized
            if not feature.is_empty
        ]

        if bounds is None:
            bounds = self.convex_hull.get_shape(crs)

        if bounds.area == 0.0:
            raise ValueError("Specify non-empty ROI")

        elif isinstance(bounds, GeoVector):
            bounds = bounds.get_shape(crs)

        return rasterize(shapes, crs, bounds, dest_resolution, fill_value,
                         nodata_value)
Beispiel #4
0
    def rasterize(self,
                  dest_resolution,
                  fill_value=None,
                  nodata_value=None,
                  bounds=None):
        # Import here to avoid circular imports
        from telluric import rasterization  # noqa
        crs = self.crs
        shapes = [self.get_shape(crs)]
        if bounds is None:
            bounds = self.envelope.get_shape(crs)
        elif isinstance(bounds, GeoVector):
            bounds = bounds.get_shape(crs)

        return rasterization.rasterize(shapes, crs, bounds, dest_resolution,
                                       fill_value, nodata_value)
Beispiel #5
0
    def rasterize(self,
                  dest_resolution,
                  *,
                  polygonize_width=0,
                  crs=WEB_MERCATOR_CRS,
                  fill_value=None,
                  bounds=None,
                  dtype=None,
                  **polygonize_kwargs):
        """Binarize a FeatureCollection and produce a raster with the target resolution.

        Parameters
        ----------
        dest_resolution: float
            Resolution in units of the CRS.
        polygonize_width : int, optional
            Width for the polygonized features (lines and points) in pixels, default to 0 (they won't appear).
        crs : ~rasterio.crs.CRS, dict (optional)
            Coordinate system, default to :py:data:`telluric.constants.WEB_MERCATOR_CRS`.
        fill_value : float or function, optional
            Value that represents data, default to None (will default to :py:data:`telluric.rasterization.FILL_VALUE`.
            If given a function, it must accept a single :py:class:`~telluric.features.GeoFeature` and return a numeric
            value.
        nodata_value : float, optional
            Nodata value, default to None (will default to :py:data:`telluric.rasterization.NODATA_VALUE`.
        bounds : GeoVector, optional
            Optional bounds for the target image, default to None (will use the FeatureCollection convex hull).
        dtype : numpy.dtype, optional
            dtype of the result, required only if fill_value is a function.
        polygonize_kwargs : dict
            Extra parameters to the polygonize function.

        """
        # Avoid circular imports
        from telluric.georaster import merge_all, MergeStrategy
        from telluric.rasterization import rasterize, NODATA_DEPRECATION_WARNING

        # Compute the size in real units and polygonize the features
        if not isinstance(polygonize_width, int):
            raise TypeError("The width in pixels must be an integer")

        if polygonize_kwargs.pop("nodata_value", None):
            warnings.warn(NODATA_DEPRECATION_WARNING, DeprecationWarning)

        # If the pixels width is 1, render points as squares to avoid missing data
        if polygonize_width == 1:
            polygonize_kwargs.update(cap_style_point=CAP_STYLE.square)

        # Reproject collection to target CRS
        if (self.crs is not None and self.crs != crs):
            reprojected = self.reproject(crs)
        else:
            reprojected = self

        width = polygonize_width * dest_resolution
        polygonized = [
            feature.polygonize(width, **polygonize_kwargs)
            for feature in reprojected
        ]

        # Discard the empty features
        shapes = [
            feature.geometry.get_shape(crs) for feature in polygonized
            if not feature.is_empty
        ]

        if bounds is None:
            bounds = self.envelope

        if bounds.area == 0.0:
            raise ValueError("Specify non-empty ROI")

        if not len(self):
            fill_value = None

        if callable(fill_value):
            if dtype is None:
                raise ValueError(
                    "dtype must be specified for multivalue rasterization")

            rasters = []
            for feature in self:
                rasters.append(
                    feature.geometry.rasterize(dest_resolution,
                                               fill_value=fill_value(feature),
                                               bounds=bounds,
                                               dtype=dtype,
                                               crs=crs))

            return merge_all(rasters,
                             bounds.reproject(crs),
                             dest_resolution,
                             merge_strategy=MergeStrategy.INTERSECTION)

        else:
            return rasterize(shapes,
                             crs,
                             bounds.get_shape(crs),
                             dest_resolution,
                             fill_value=fill_value,
                             dtype=dtype)