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
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)
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)
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)
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)