SPB Git

Repository Public

units.ts 4.2 KB 84 lines typescript

1// UQO Éval — Métré : conversions métriques ↔ impériales des longueurs, aires, volumes. Module PUR.2import type { AreaUnit, LengthUnit, MeasureUnit, UnitSystem, VolumeUnit } from "./types";34export const M_PER_FT = 0.3048;5export const M_PER_IN = 0.0254;6export const M2_PER_FT2 = 0.09290304;7export const M3_PER_FT3 = 0.028316846592;8export const M3_PER_YD3 = 0.764554857984;910const LENGTH_TO_M: Record<LengthUnit, number> = { m: 1, ft: M_PER_FT, mm: 0.001, cm: 0.01, in: M_PER_IN };11const AREA_TO_M2: Record<AreaUnit, number> = { m2: 1, ft2: M2_PER_FT2 };12const VOLUME_TO_M3: Record<VolumeUnit, number> = { m3: 1, ft3: M3_PER_FT3, yd3: M3_PER_YD3 };1314export function isLengthUnit(u: string): u is LengthUnit { return u in LENGTH_TO_M; }15export function isAreaUnit(u: string): u is AreaUnit { return u in AREA_TO_M2; }16export function isVolumeUnit(u: string): u is VolumeUnit { return u in VOLUME_TO_M3; }1718export function lengthToMeters(v: number, u: LengthUnit): number { return v * LENGTH_TO_M[u]; }19export function metersToLength(m: number, u: LengthUnit): number { return m / LENGTH_TO_M[u]; }20export function areaToM2(v: number, u: AreaUnit): number { return v * AREA_TO_M2[u]; }21export function m2ToArea(m2: number, u: AreaUnit): number { return m2 / AREA_TO_M2[u]; }22export function volumeToM3(v: number, u: VolumeUnit): number { return v * VOLUME_TO_M3[u]; }23export function m3ToVolume(m3: number, u: VolumeUnit): number { return m3 / VOLUME_TO_M3[u]; }2425/** Dimension d'une unité de mesure (longueur, aire, volume, compte…). */26export function dimensionOf(u: MeasureUnit | string): "length" | "area" | "volume" | "count" | "time" | "lump" | "unknown" {27  if (isLengthUnit(u)) return "length";28  if (isAreaUnit(u)) return "area";29  if (isVolumeUnit(u)) return "volume";30  if (u === "unit") return "count";31  if (u === "h") return "time";32  if (u === "lump") return "lump";33  return "unknown";34}3536/**37 * Convertit une quantité d'une unité de mesure vers une autre de même38 * dimension. Lève une erreur si les dimensions diffèrent (jamais de39 * conversion silencieuse aire → longueur, etc.).40 */41export function convertQuantity(v: number, from: MeasureUnit | string, to: MeasureUnit | string): { value: number; factor: number } {42  if (from === to) return { value: v, factor: 1 };43  const df = dimensionOf(from), dt = dimensionOf(to);44  if (df !== dt || df === "unknown") throw new Error(`Conversion impossible : ${from} → ${to} (${df} ≠ ${dt})`);45  let factor = 1;46  if (df === "length") factor = LENGTH_TO_M[from as LengthUnit] / LENGTH_TO_M[to as LengthUnit];47  else if (df === "area") factor = AREA_TO_M2[from as AreaUnit] / AREA_TO_M2[to as AreaUnit];48  else if (df === "volume") factor = VOLUME_TO_M3[from as VolumeUnit] / VOLUME_TO_M3[to as VolumeUnit];49  return { value: v * factor, factor };50}5152/** Unités d'affichage préférées par système. */53export function preferredUnit(dim: "length" | "area" | "volume", sys: UnitSystem): MeasureUnit {54  if (sys === "imperial") return dim === "length" ? "ft" : dim === "area" ? "ft2" : "ft3";55  return dim === "length" ? "m" : dim === "area" ? "m2" : "m3";56}5758/** Correspondance entre les unités canoniques du catalogue de coûts (pi2, pi_lin, m2…) et celles du métré. */59export function catalogueUnitToMeasure(u: string): MeasureUnit | null {60  switch (u) {61    case "pi2": return "ft2";62    case "pi_lin": return "ft";63    case "pi3": return "ft3";64    case "m2": return "m2";65    case "m3": return "m3";66    case "unit": return "unit";67    case "h": return "h";68    case "lump": return "lump";69    default: return null;70  }71}7273export const UNIT_LABEL: Record<string, { fr: string; en: string }> = {74  m: { fr: "m", en: "m" }, ft: { fr: "pi", en: "ft" }, mm: { fr: "mm", en: "mm" }, cm: { fr: "cm", en: "cm" }, in: { fr: "po", en: "in" },75  m2: { fr: "m²", en: "m²" }, ft2: { fr: "pi²", en: "sq ft" }, m3: { fr: "m³", en: "m³" }, ft3: { fr: "pi³", en: "cu ft" }, yd3: { fr: "vg³", en: "cu yd" },76  unit: { fr: "unité", en: "each" }, h: { fr: "h", en: "h" }, lump: { fr: "forfait", en: "lump sum" },77  pi2: { fr: "pi²", en: "sq ft" }, pi_lin: { fr: "pi lin.", en: "lin ft" }, pi3: { fr: "pi³", en: "cu ft" },78};7980export function unitLabel(u: string, fr: boolean): string {81  const l = UNIT_LABEL[u];82  return l ? (fr ? l.fr : l.en) : u;83}84
Files main
Menu

Theme