demcompare.dem_tools ==================== .. py:module:: demcompare.dem_tools .. autoapi-nested-parse:: This module contains main functions to manipulate DEM raster images. It represents the primary API to manipulate DEM as xarray dataset in demcompare. Dataset and associated internal functions are described in dataset_tools.py Attributes ---------- .. autoapisummary:: demcompare.dem_tools.DEFAULT_NODATA Classes ------- .. autoapisummary:: demcompare.dem_tools.SamplingSourceParameter Functions --------- .. autoapisummary:: demcompare.dem_tools.load_dem demcompare.dem_tools.copy_dem demcompare.dem_tools.save_dem demcompare.dem_tools.translate_dem demcompare.dem_tools.create_dem demcompare.dem_tools.reproject_dems demcompare.dem_tools.compute_waveform demcompare.dem_tools.accumulates_class_layers demcompare.dem_tools.compute_dem_slope demcompare.dem_tools.compute_and_save_image_plots demcompare.dem_tools.verify_fusion_layers demcompare.dem_tools.compute_curvature_filtering Module Contents --------------- .. py:data:: DEFAULT_NODATA :value: -32768 .. py:function:: load_dem(path: str, nodata: float = None, band: int = 1, geoid_georef: bool = False, geoid_path: Union[str, None] = None, zunit: str = 'm', input_roi: Union[bool, dict, Tuple] = False, classification_layers: Dict = None) -> xarray.Dataset Reads the input DEM path and parameters and generates the DEM object as xr.Dataset to be handled in demcompare functions. A DEM can be any raster file opened by rasterio. :param path: path to dem (readable by rasterio) :type path: str :param nodata: forcing dem no data value (None by default and if set inside metadata) :type nodata: float or None :param band: band to be read in DEM. Default: 1 :type band: int :param geoid_georef: is dem's georef is geoid :type geoid_georef: bool :param geoid_path: optional path to local geoid, default is EGM96 :type geoid_path: str or None :param zunit: dem z unit :type zunit: str :param input_roi: False if dem are to be fully loaded, other options are a dict roi or Tuple :type input_roi: bool, dict or Tuple :param classification_layers: input classification layers :type classification_layers: Dict or None :return: dem xr.DataSet containing : (see dataset_tools for details) - image : 2D (row, col) xr.DataArray float32 - georef_transform: 1D (trans_len) xr.DataArray - classification_layer_masks : 3D (row, col, indicator) xr.DataArray :rtype: xr.Dataset .. py:function:: copy_dem(dem: xarray.Dataset) -> xarray.Dataset Returns a copy of the input dem. :param dem: input dem to copy, xr.DataSet containing : - image : 2D (row, col) xr.DataArray float32 - georef_transform: 1D (trans_len) xr.DataArray - classification_layer_masks : 3D (row, col, indicator) xr.DataArray :type dem: xr.Dataset :return dem_copy: copy of the input dem, xr.DataSet containing : - image : 2D (row, col) xr.DataArray float32 - georef_transform: 1D (trans_len) xr.DataArray - classification_layer_masks : 3D (row, col, indicator) xr.DataArray :rtype: xr.Dataset .. py:function:: save_dem(dataset: xarray.Dataset, filename: str, nodata: float = DEFAULT_NODATA) -> xarray.Dataset Writes a Dataset in a tiff file. If new_array is set, new_array is used as data. Returns written dataset. :param dataset: xarray.DataSet containing the variables : - image : 2D (row, col) xr.DataArray float32 - georef_transform: 1D (trans_len) xr.DataArray - classification_layer_masks : 3D (row, col, indicator) xr.DataArray :type dataset: xr.Dataset :param filename: output filename :type filename: str :param nodata: value of nodata to use :type nodata: float :return: xr.DataSet containing : - image : 2D (row, col) xr.DataArray float32 - georef_transform: 1D (trans_len) xr.DataArray - classification_layer_masks : 3D (row, col, indicator) xr.DataArray :rtype: xr.Dataset .. py:function:: translate_dem(dataset: xarray.Dataset, x_offset: Union[float, int, numpy.ndarray], y_offset: Union[float, int, numpy.ndarray]) -> xarray.Dataset Applies pixellic offset to the input dataset's georeference origin by modifying its transform. :param dataset: xr.DataSet containing : - image : 2D (row, col) xr.DataArray float32 - georef_transform: 1D (trans_len) xr.DataArray - classification_layer_masks : 3D (row, col, indicator) xr.DataArray :type dataset: xr.Dataset :param x_offset: x offset :type x_offset: Union[float, int, ndarray] :param y_offset: y offset :type y_offset: Union[float, int, ndarray] :return: translated xr.DataSet containing : - image : 2D (row, col) xr.DataArray float32 - georef_transform: 1D (trans_len) xr.DataArray - classification_layer_masks : 3D (row, col, indicator) xr.DataArray :rtype: xr.Dataset .. py:function:: create_dem(data: numpy.ndarray, transform: Union[numpy.ndarray, rasterio.Affine] = None, img_crs: Union[rasterio.crs.CRS, None] = None, input_img: Union[str, None] = None, bounds: rasterio.coords.BoundingBox = None, classification_layer_masks: Union[Dict, xarray.DataArray] = None, nodata: float = None, geoid_georef: bool = False, geoid_path: Union[str, None] = None, zunit: str = 'm', source_rasterio: Dict[str, rasterio.DatasetReader] = None) -> xarray.Dataset Creates dem from input array and transform. The demcompare DEM is an xarray Dataset containing: - image : 2D (row, col) xr.DataArray float32 - georef_transform: 1D (trans_len) xr.DataArray - classification_layer_masks : 3D (row, col, indicator) xr.DataArray :param data: image data :type data: np.ndarray :param transform: rasterio georeferencing transformation matrix :type transform: np.ndarray or rasterio.Affine :img_crs: image CRS georef :type img_crs: Rasterio.crs.CRS :param input_img: image path :type input_img: str :param bounds: dem bounds :type bounds: rasterio.coords.BoundingBox or None :param classification_layer_masks: classification layers :type classification_layer_masks: Dict, xr.DataArray or None :param nodata: nodata value in the image :type nodata: float or None :param geoid_georef: if dem's georef is geoid :type geoid_georef: bool :param geoid_path: optional path to local geoid, default is EGM96 :type geoid_path: str or None :param zunit: unit :type zunit: str :param source_rasterio: rasterio dataset reader object :type source_rasterio: Dict[str,rasterio.DatasetReader] or None :return: xr.DataSet containing : - image : 2D (row, col) xr.DataArray float32 - georef_transform: 1D (trans_len) xr.DataArray - classification_layer_masks : 3D (row, col, indicator) xr.DataArray :rtype: xr.Dataset .. py:class:: SamplingSourceParameter Bases: :py:obj:`enum.Enum` Enum type definition for sampling_source parameter value are sec or ref to choose in reproject_dems .. py:attribute:: SEC :value: 'sec' .. py:attribute:: REF :value: 'ref' .. py:function:: reproject_dems(sec: xarray.Dataset, ref: xarray.Dataset, initial_shift_x: Union[int, float] = 0, initial_shift_y: Union[int, float] = 0, sampling_source: str = SamplingSourceParameter.SEC.value) -> Tuple[xarray.Dataset, xarray.Dataset, Tuple[float, float]] Reprojects both DEMs to common grid, common bounds and common georef origin. The common grid, bounds, georef origin are defined by the sampling_source parameter. It defines which is the sampling of the output DEMs. - If sampling_source is "ref": ref is cropped to the common bounds sec is cropped to the common bounds and resampled - If sampling_source is "sec": ref is cropped to the common bounds and resampled sec is cropped to the common bounds :param sec: dem to align xr.DataSet containing : - im : 2D (row, col) xarray.DataArray float32 - trans: 1D (trans_len) xarray.DataArray :type sec: xr.Dataset :param ref: ref xr.DataSet containing : - im : 2D (row, col) xarray.DataArray float32 - trans: 1D (trans_len) xarray.DataArray :type ref: xr.Dataset :param initial_shift_x: optional initial shift x :type initial_shift_x: Union[int, float] :param initial_shift_y: optional initial shift y :type initial_shift_y: Union[int, float] :param sampling_source: 'ref' or 'sec', the sampling value of the output dems, by defaut "sec" :type sampling_source: str :return: reproj_cropped_sec xr.DataSet, reproj_cropped_ref xr.DataSet, adapting_factor. The xr.Datasets containing : - im : 2D (row, col) xarray.DataArray float32 - trans: 1D (trans_len) xarray.DataArray :rtype: xr.Dataset, xr.Dataset, Tuple[float, float] .. py:function:: compute_waveform(dem: xarray.Dataset, output_dir: str = None) -> Tuple[numpy.ndarray, numpy.ndarray] Metric computation method :param dem: input data to compute the metric :type dem: xr.DataSet containing : - image : 2D (row, col) xr.DataArray float32 - georef_transform: 1D (trans_len) xr.DataArray - classification_layer_masks : 3D (row, col, indicator) xr.DataArray :param output_dir: optional output directory :type output_dir: str :return: the computed row and col waveforms :rtype: Tuple[np.ndarray, np.ndarray] .. py:function:: accumulates_class_layers(ref: xarray.Dataset, sec: xarray.Dataset, diff_ref_sec: xarray.Dataset) -> xarray.Dataset Accumulates the classification layers of each dem :param ref: ref dem :type ref: xr.DataSet containing : - image : 2D (row, col) xr.DataArray float32 - georef_transform: 1D (trans_len) xr.DataArray - classification_layer_masks : 3D (row, col, indicator) xr.DataArray :param sec: sec dem :type ref: xr.DataSet containing : - image : 2D (row, col) xr.DataArray float32 - georef_transform: 1D (trans_len) xr.DataArray - classification_layer_masks : 3D (row, col, indicator) xr.DataArray :param diff_ref_sec: difference (i.e angular, in altitude, ...) dem between ref and sec :type diff_ref_sec: xr.DataSet containing : - image : 2D (row, col) xr.DataArray float32 - georef_transform: 1D (trans_len) xr.DataArray - classification_layer_masks : 3D (row, col, indicator) xr.DataArray :return: the difference dem between ref and sec, with the classification layers :rtype: xr.Dataset containing : - image : 2D (row, col) xr.DataArray float32 - georef_transform: 1D (trans_len) xr.DataArray - classification_layer_masks : 3D (row, col, indicator) xr.DataArray .. py:function:: compute_dem_slope(dataset: xarray.Dataset, degree: bool = False, add_attribute: bool = True, unit_change: bool = True) -> xarray.Dataset Computes DEM's slope Slope is presented here : http://pro.arcgis.com/ fr/pro-app/tool-reference/spatial-analyst/how-aspect-works.htm TODO: modify code such as to remove double return at the end :param dataset: dataset :type dataset: xr.DataSet containing : - image : 2D (row, col) xr.DataArray float32 - georef_transform: 1D (trans_len) xr.DataArray - classification_layer_masks : 3D (row, col, indicator) xr.DataArray :param degree: True if is in degree :type degree: bool :param add_attribute: if True, add attribute to the input dataset if False, return the slope :type add_attribute: bool :param unit_change: if True change units of the slope if False, no units change :type unit_change: bool :return: slope :rtype: np.ndarray .. py:function:: compute_and_save_image_plots(dem: xarray.Dataset, plot_path: str = None, fig_title: str = None, colorbar_title: str = None, cmap: str = 'terrain', vmin_plot: float = None, vmax_plot: float = None) Compute and optionnally save plots from a dem using pyplot img_show. see https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.imshow.html :param dem: dem object to compute and save image plots :type dem: str :param plot_path: path to save the plots if present :type plot_path: str :param fig_title: optional plot figure title :type fig_title: str :param title_colorbar: optional dem path to save the original tif file :type title_colorbar: str :param cmap: registered colormap name used to map scalar data to colors. :type cmap: str :param vmin_plot: minimum value of the z axis when plotting :type vmin_plot: float :param vmax_plot: maximum value of the z axis when plotting :type vmax_plot: float .. py:function:: verify_fusion_layers(dem: xarray.Dataset, classif_cfg: Dict, support: str) Verifies that the input configuration and input dem contain the input necessary layers for the fusion classification. :param dem: name to save the plots :type dem: str :param classif_cfg: classification layers configuration :type classif_cfg: Dict :param support: fusion support, ref or sec :type support: str :return: None .. py:function:: compute_curvature_filtering(dem: xarray.Dataset, filter_intensity: float = 0.9, replication: bool = True) -> xarray.Dataset Return the curvature of the input dem. First, compute the FFT of the input dem: F(y) = FFT(DEM). Then, apply a filter y^filter_intensity with s=0.9: F(y) = F(y)* y^filter_intensity. Finally, apply the inverse FFT: IFFT(F(y)). We keep the real part (imaginary part = digital noise). :param dem: dem xr.DataSet containing : - image : 2D (row, col) xr.DataArray float32 - georef_transform: 1D (trans_len) xr.DataArray - classification_layer_masks : 3D (row, col, indicator) xr.DataArray :type dem: xr.Dataset :param filter_intensity: parameter of the DEM's FFT filter intensity. Should be close to 1. Default = 0.9. :type filter_intensity: float :param replication: if true, the image is replicated by x4 in order to improve resolution. Default = True. :type replication: bool :return: curvature xr.DataSet containing : - image : 2D (row, col) xr.DataArray float32 - georef_transform: 1D (trans_len) xr.DataArray - classification_layer_masks : 3D (row, col, indicator) xr.DataArray :rtype: xr.Dataset