Réserver la colonne de la flèche du nord pour que le titre de la cartouche ne la chevauche plus

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Antoine Jacquin
2026-09-27 16:07:00 +02:00
parent b85c29e5f1
commit 3cf5bbce6e
2 changed files with 40 additions and 4 deletions

View File

@ -366,6 +366,15 @@ def _fit_title(c, text, font, size, max_width, min_size=7.0):
return text, size return text, size
_ARROW_COLUMN_MM = 16.0 # largeur (mm) réservée à la flèche du nord + son "N", coin haut droit
def _cartouche_text_max_width(w, mm):
"""Largeur (pt) disponible pour le titre/sous-titre de la cartouche, hors
colonne réservée à la flèche du nord (coin haut droit du bloc, même ligne)."""
return max(0.0, w - _ARROW_COLUMN_MM) * mm
def _draw_hatch(c, x, y, w, h, mm, step=3.0): def _draw_hatch(c, x, y, w, h, mm, step=3.0):
"""Hachures grises sur fond blanc (maille sans donnée), comme sur la carte.""" """Hachures grises sur fond blanc (maille sans donnée), comme sur la carte."""
from reportlab.lib.colors import Color, white from reportlab.lib.colors import Color, white
@ -561,12 +570,17 @@ def _draw_cartouche(c, box, lay, bbox, cx, cy, title, now, mm):
"""Titre, échelle graphique et numérique, nord, date, source.""" """Titre, échelle graphique et numérique, nord, date, source."""
from reportlab.lib.colors import black, white from reportlab.lib.colors import black, white
x, y, w, h = box x, y, w, h = box
txt, title_size = _fit_title(c, _pdf_text(title), "Helvetica-Bold", 10, w * mm) # Titre et sous-titre partagent la ligne du haut avec la flèche du nord
# (coin haut droit) : largeur bornée pour ne jamais la chevaucher.
max_w_head = _cartouche_text_max_width(w, mm)
txt, title_size = _fit_title(c, _pdf_text(title), "Helvetica-Bold", 10, max_w_head)
c.setFillColor(black); c.setFont("Helvetica-Bold", title_size) c.setFillColor(black); c.setFont("Helvetica-Bold", title_size)
c.drawString(x * mm, (y + h - 5) * mm, txt) c.drawString(x * mm, (y + h - 5) * mm, txt)
c.setFont("Helvetica", 7) subtitle, subtitle_size = _fit_title(
c.drawString(x * mm, (y + h - 9) * mm, c, _pdf_text(f"Échelle 1:{_fmt_int(lay.scale)} - {lay.paper} {lay.orient} - {lay.dpi} dpi"),
_pdf_text(f"Échelle 1:{_fmt_int(lay.scale)} - {lay.paper} {lay.orient} - {lay.dpi} dpi")) "Helvetica", 7, max_w_head, min_size=6.0)
c.setFont("Helvetica", subtitle_size)
c.drawString(x * mm, (y + h - 9) * mm, subtitle)
# Échelle graphique : longueur ronde ≤ 40 % de la largeur du bloc # Échelle graphique : longueur ronde ≤ 40 % de la largeur du bloc
max_m = w * 0.4 / 1000 * lay.scale max_m = w * 0.4 / 1000 * lay.scale
length = max((s for s in _SCALEBAR_STEPS if s <= max_m), default=_SCALEBAR_STEPS[0]) length = max((s for s in _SCALEBAR_STEPS if s <= max_m), default=_SCALEBAR_STEPS[0])

View File

@ -294,3 +294,25 @@ def test_fit_title_shrinks_then_elides():
text, size = _fit_title(c, long_title, "Helvetica-Bold", 10, 60 * mm, min_size=7.0) text, size = _fit_title(c, long_title, "Helvetica-Bold", 10, 60 * mm, min_size=7.0)
assert size >= 7.0 assert size >= 7.0
assert c.stringWidth(text, "Helvetica-Bold", size) <= 60 * mm + 1e-6 assert c.stringWidth(text, "Helvetica-Bold", size) <= 60 * mm + 1e-6
def test_cartouche_title_avoids_north_arrow_column():
"""Le titre (et le sous-titre) de la cartouche ne doit jamais empiéter sur
la colonne réservée à la flèche du nord, en paysage comme en portrait."""
from reportlab.pdfgen import canvas as rl_canvas
from reportlab.lib.units import mm
from io import BytesIO
from lidar_pipeline.export_pdf import (
_cartouche_text_max_width, _fit_title, _panel_boxes, layout)
c = rl_canvas.Canvas(BytesIO())
long_title = "Relief orienté - " + ", ".join(f"{1050 + i:04d}_6882" for i in range(6))
for paper, orient, scale in (("A4", "paysage", 2000), ("A4", "portrait", 10000),
("A3", "portrait", 2000)):
lay = layout(paper, orient, scale)
_legend_box, _quality_box, cart_box = _panel_boxes(lay)
x, y, w, h = cart_box
max_w = _cartouche_text_max_width(w, mm)
txt, size = _fit_title(c, long_title, "Helvetica-Bold", 10, max_w)
title_right_mm = x + c.stringWidth(txt, "Helvetica-Bold", size) / mm
arrow_left_mm = (x + w - 8) - 1.8 # bord gauche du triangle de la flèche
assert title_right_mm <= arrow_left_mm, (paper, orient, scale)