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


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

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)

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)

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)





