48 lines
1.7 KiB
TypeScript
48 lines
1.7 KiB
TypeScript
import { EMISSION_FACTORS } from '#shared/emissions'
|
|
import type { Coord } from '#shared/types'
|
|
|
|
const TRAIN_AVG_KMH = 90
|
|
|
|
/**
|
|
* Distance a vol d oiseau entre deux points geographiques en km.
|
|
* Formule de Haversine, rayon terrestre moyen 6371 km.
|
|
*/
|
|
function haversineKm(a: { lat: number, lon: number }, b: { lat: number, lon: number }): number {
|
|
const toRad = (d: number) => (d * Math.PI) / 180
|
|
const R = 6371
|
|
const dLat = toRad(b.lat - a.lat)
|
|
const dLon = toRad(b.lon - a.lon)
|
|
const s = Math.sin(dLat / 2) ** 2
|
|
+ Math.cos(toRad(a.lat)) * Math.cos(toRad(b.lat)) * Math.sin(dLon / 2) ** 2
|
|
return 2 * R * Math.asin(Math.sqrt(s))
|
|
}
|
|
|
|
/**
|
|
* Fabrique une estimation train quand Transitous ne couvre pas le trajet.
|
|
* Distance vol d oiseau x 1.2 pour approximer le detour ferroviaire,
|
|
* vitesse pratique moyenne 90 km/h (compromis TGV/TER), facteur ADEME train
|
|
* generique. C est un ordre de grandeur, pas un horaire.
|
|
*/
|
|
export function estimateTrainTrip(
|
|
from: { lat: number, lon: number },
|
|
to: { lat: number, lon: number },
|
|
) {
|
|
const straightKm = haversineKm(from, to)
|
|
// Facteur 1.2 : les voies ferrees suivent rarement une ligne droite.
|
|
const distanceKm = Math.round(straightKm * 1.2 * 10) / 10
|
|
const durationMin = Math.round((distanceKm / TRAIN_AVG_KMH) * 60)
|
|
const co2Grams = Math.round(distanceKm * EMISSION_FACTORS.train)
|
|
|
|
// Geometrie ligne droite [depart, arrivee] pour que la carte affiche
|
|
// quelque chose de coherent avec l estimation textuelle.
|
|
const geometry: Coord[] = [[from.lon, from.lat], [to.lon, to.lat]]
|
|
|
|
return {
|
|
mode: 'train' as const,
|
|
distanceKm,
|
|
durationMin,
|
|
co2Grams,
|
|
geometry,
|
|
estimated: true,
|
|
}
|
|
}
|