Rapport de comparaison entre des sections en travers et un Modèle Numérique

L’objectif de ce Notebook est d’illustrer l’utilisation de la classe CompareMultipleCSvsDEM pour générer un rapport de comparaison entre des sections en travers levées sur le terrain et une matrice de données (MNT/MNS/…).

Import des modules

[ ]:
# import _add_path # for debugging purposes only - can be removed in production

try:
    from wolfhece import is_enough
    if not is_enough('2.2.46'):
        raise ImportError("Please update wolfhece to at least version 2.2.46")
except ImportError:
    raise ImportError("Please install the required version of wolfhece: pip install wolfhece>=2.2.30")

from pathlib import Path
import numpy as np
import matplotlib.pyplot as plt

from wolfhece.report.compare_cs_dem import CompareMultipleCSvsDEM, CSvsDEM, CSvsDEM_MainLayout, CSvsDEM_IndividualLayout, profile
from wolfhece.report.common import convert_report_to_images

import logging
logging.basicConfig(level=logging.INFO)
pdfviewer using PyMuPDF (GPL)

Mise en page du rapport

Le rapport se base sur 2 pages type :

  • la page de synthèse reprenant les informations principales:

    • carte d’emprise spatiale

    • valeurs caractéristiques des différences

    • histogrammes des différences

    • tableaux des plus grandes différences (à l’extrêmité gauche et droite) triés par ordre décroissant

  • la page associée à un différence spécifique et son groupe

    • position spatiale

    • vue en coupe

[2]:
main_layout = CSvsDEM_MainLayout('test')
indiv_layout = CSvsDEM_IndividualLayout('section 1')

main_layout.plot()
indiv_layout.plot()
[2]:
(<Figure size 826.772x1169.29 with 1 Axes>,
 <Axes: title={'center': 'Layout of the report'}, xlabel='Width (cm)', ylabel='Height (cm)'>)
../_images/tutorials_compare_cross_sections2dem_4_1.png
../_images/tutorials_compare_cross_sections2dem_4_2.png

Préparation du rapport

Pour créer le rapport, il faut fournir a minima:

  • Un fichier de sections en travers (dans un des formats supportés) ou un objet de sections en travers crosssesctions

  • Un fichier de données à comparer (dans un des formats supportés) ou un objet WolfArray

  • Un répertoire vers les données LAZ (au format Numpy WOLF)

Il est également possible de spécifier :

  • Le vecteur support à exploiter pour trier les sections d’amont vers l’aval

  • De définir le seuil à partir duquel une section doit être sélectionnée (sur base des différenttiels à ses extrêmités)

  • De définir le seuil de longueur qui permet de grouper les sections

[3]:
dir_cs = Path(r'C:\Users\pierre\Universite de Liege\HECE - Contrats\En cours\2025 - ARNE - Orne\Rapports\Report data inconsistencies\data')
file_cs = 'cross-sections_forRawCS.vecz'

dir_Ornedata = Path(r'E:\Orne\orne_data')
file_dem = dir_Ornedata / 'Topographie' / 'Orne_50cm_2021_2022.tif'

dir_laz = dir_Ornedata / 'LAZ_numpy'

report  = CompareMultipleCSvsDEM(cross_sections=dir_cs/file_cs,  # can be a file path or a crosssection object
                                 dem=file_dem,  # can be a file path or a WolfArray object
                                 laz_directory=dir_laz, # can be None or a directory path
                                 support= None, # can be None, a file path or a vector object
                                 threshold_z= 0.5, # vertical threshold in meters
                                 distance_threshold= 50.) # horizontal threshold in meters
WARNING:root:The support is not a valid file or vector. Centers will be used.
WARNING:root:The DEM has more than 1 million valid cells. Plotting a rebin one.

Interrogation de l’objet

Avant de créer le rapport, il est possible de connaître quelques informations.

Statistiques générales

[4]:
print(f"Number of highlighted cross-sections: {report.count_differences}")
print(f'Number of groups : {report.count_groups}')
print(f'Number of groups with more than x sections: {report.count_groups_greater_than(1)}')
Number of highlighted cross-sections: 46
Number of groups : 19
Number of groups with more than x sections: 10
[5]:
print(report)
Array information :
Number of cells: 135000000
Resolution (m): 0.5 x 0.5
Extent: (163000.0, 144500.0) - (170500.0, 149000.0)
Width x Height (m): 7500.0 x 4500.0

Differences information :
Number of groups: 19
Number of cross-sections: 46
Median difference (m): 1.515
Min difference (m): 0.509
Max difference (m): 5.126
Left - Median difference (m): 1.493
Left - Min difference (m): 0.509
Left - Max difference (m): 4.503
Right - Median difference (m): 1.537
Right - Min difference (m): 0.512
Right - Max difference (m): 5.126

Histogramme

[6]:
report.plot_histogram_differences()
[6]:
(<Figure size 800x300 with 1 Axes>, <Axes: >)
../_images/tutorials_compare_cross_sections2dem_12_1.png

Groupes

[7]:
print(report.get_group_info(0))
Group 1 - Number of cross-sections: 2
  - Cross-section 473: Left difference = 0.053 m, Right difference = 5.126 m
  - Cross-section 474: Left difference = 0.097 m, Right difference = 2.920 m

Différences à gauche et à droite

[8]:
print(report.print_left_differences())
Left bank differences:
  - Cross-section 229: 4.503 m
  - Cross-section 230: 3.737 m
  - Cross-section 369: 2.953 m
  - Cross-section 173: 2.372 m
  - Cross-section 307: 2.028 m
  - Cross-section 418: 1.844 m
  - Cross-section 171: 1.838 m
  - Cross-section 231: 1.765 m
  - Cross-section 174: 1.575 m
  - Cross-section 235: 1.539 m
  - Cross-section 172: 1.493 m
  - Cross-section 417: 1.420 m
  - Cross-section 420: 0.980 m
  - Cross-section 120: 0.968 m
  - Cross-section 419: 0.925 m
  - Cross-section 365: 0.824 m
  - Cross-section 157: 0.777 m
  - Cross-section 28: 0.706 m
  - Cross-section 122: 0.691 m
  - Cross-section 159: 0.613 m
  - Cross-section 281: 0.509 m
[9]:
print(report.print_right_differences())
Right bank differences:
  - Cross-section 473: 5.126 m
  - Cross-section 236: 3.027 m
  - Cross-section 474: 2.920 m
  - Cross-section 270: 2.548 m
  - Cross-section 269: 2.382 m
  - Cross-section 219: 2.258 m
  - Cross-section 214: 2.250 m
  - Cross-section 221: 2.211 m
  - Cross-section 224: 2.176 m
  - Cross-section 210: 2.013 m
  - Cross-section 215: 1.982 m
  - Cross-section 216: 1.965 m
  - Cross-section 234: 1.766 m
  - Cross-section 267: 1.537 m
  - Cross-section 364: 1.225 m
  - Cross-section 349: 0.904 m
  - Cross-section 287: 0.899 m
  - Cross-section 160: 0.892 m
  - Cross-section 286: 0.851 m
  - Cross-section 363: 0.686 m
  - Cross-section 306: 0.612 m
  - Cross-section 365: 0.574 m
  - Cross-section 38: 0.549 m
  - Cross-section 435: 0.534 m
  - Cross-section 463: 0.533 m
  - Cross-section 307: 0.530 m
  - Cross-section 312: 0.512 m

Accéder à un groupe spécifique

Un groupe est une liste contenant des dictionnaires (un pour chaque section du groupe).

Chaque dictionnaire contient :

  • ‘profile’ : un objet profile pointant vers la section problématique

  • ‘diff_left’ : la différence à l’extrêimté gauche du profil

  • ‘diff_right’ : la différebce à l’extrêmité droite du profil

[10]:
group = report[0]

print(group)
print('Nom de la section :', group[0]['profile'].myname)
print('Nom de la section :', group[1]['profile'].myname)
[{'profile': <wolfhece.PyCrosssections.profile object at 0x000001EDF968BF50>, 'diff_left': 0.05287286376952949, 'diff_right': 5.125999847412103}, {'profile': <wolfhece.PyCrosssections.profile object at 0x000001EDF9698350>, 'diff_left': 0.09699847412109364, 'diff_right': 2.9197499999999934}]
Nom de la section : 473
Nom de la section : 474

Accéder à une section spécifique

Comme le groupe stocke un pointeur vers la section en travers, il est possible d’appeler toutes les fonctions de cet objet profile (voir le Notebook dédié à cet objet).

[11]:
cs:profile
cs = group[0]['profile']
cs.plot_cs(fwl= 63.)
[11]:
(-99999.0, -99999.0, -99999.0, -99999.0, -99999.0, -99999.0)
../_images/tutorials_compare_cross_sections2dem_21_1.png

Création du rapport

Lors de la création du rapport, il est possible de :

  • Spécifier le chemin et le nom du rapport

  • Indiquer si les pages des sections doivent être incluses ou non

  • Indiquer le nombre de pages maximum à générer

[12]:
report.create_report(output_file= None, # can be None or a file path. If None, a default name is generated 'compare_cs_dem_report.pdf'
                     append_subpages=False, # if True, all individual sections are included in the report
                     nb_max_pages= -1) # maximum number of individual sections to include in the report. If -1, all sections are included.
WARNING:root:Output file compare_cs_dem_report.pdf already exists. It will be overwritten.

Visualisation du rapport dans le Notebook

Il n’est pas toujours aisé de visualiser un fichier PDF dans un Notebook Jupyter.

Une façon de faire est de créer des images sur base des pages et d’afficher les images.

[13]:
from IPython.display import display
images = convert_report_to_images(report.pdf_path, dpi=100)
# Afficher les images dans le notebook
for image in images:
    display(image)
../_images/tutorials_compare_cross_sections2dem_25_0.png

Exemple avec des sous-pages

[14]:
report.create_report(output_file= None, # can be None or a file path. If None, a default name is generated 'compare_cs_dem_report.pdf'
                     append_subpages=True, # if True, all individual sections are included in the report
                     nb_max_pages= 5) # maximum number of individual sections to include in the report. If -1, all sections are included.
WARNING:root:Output file compare_cs_dem_report.pdf already exists. It will be overwritten.
Preparing individual difference reports: 100%|██████████| 5/5 [00:29<00:00,  5.83s/it]
Compiling PDFs: 100%|██████████| 5/5 [00:00<00:00, 37.46it/s]
[15]:
from IPython.display import display
images = convert_report_to_images(report.pdf_path, dpi=100)
# Afficher les images dans le notebook
for image in images:
    display(image)
../_images/tutorials_compare_cross_sections2dem_28_0.png
../_images/tutorials_compare_cross_sections2dem_28_1.png
../_images/tutorials_compare_cross_sections2dem_28_2.png
../_images/tutorials_compare_cross_sections2dem_28_3.png
../_images/tutorials_compare_cross_sections2dem_28_4.png
../_images/tutorials_compare_cross_sections2dem_28_5.png