73 lines
2.2 KiB
TypeScript
73 lines
2.2 KiB
TypeScript
|
|
/**
|
||
|
|
* Calcule la durée estimée d'un trajet en heures à partir des adresses.
|
||
|
|
* Utilise Nominatim pour géocoder et la formule de Haversine pour la distance.
|
||
|
|
*/
|
||
|
|
export async function calculerDureeTrajet(
|
||
|
|
adresseDepart: string,
|
||
|
|
adresseArrivee: string
|
||
|
|
): Promise<number | null> {
|
||
|
|
if (!adresseDepart?.trim() || !adresseArrivee?.trim()) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
const departResponse = await fetch(
|
||
|
|
`https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(adresseDepart.trim())}&limit=1&countrycodes=fr`,
|
||
|
|
{
|
||
|
|
headers: {
|
||
|
|
'User-Agent': 'MAD Platform',
|
||
|
|
'Accept-Language': 'fr-FR,fr;q=0.9',
|
||
|
|
},
|
||
|
|
}
|
||
|
|
);
|
||
|
|
|
||
|
|
if (!departResponse.ok) return null;
|
||
|
|
|
||
|
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||
|
|
|
||
|
|
const arriveeResponse = await fetch(
|
||
|
|
`https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(adresseArrivee.trim())}&limit=1&countrycodes=fr`,
|
||
|
|
{
|
||
|
|
headers: {
|
||
|
|
'User-Agent': 'MAD Platform',
|
||
|
|
'Accept-Language': 'fr-FR,fr;q=0.9',
|
||
|
|
},
|
||
|
|
}
|
||
|
|
);
|
||
|
|
|
||
|
|
if (!arriveeResponse.ok) return null;
|
||
|
|
|
||
|
|
const [departData, arriveeData] = await Promise.all([
|
||
|
|
departResponse.json(),
|
||
|
|
arriveeResponse.json(),
|
||
|
|
]);
|
||
|
|
|
||
|
|
if (!departData?.length || !arriveeData?.length) return null;
|
||
|
|
|
||
|
|
const lat1 = parseFloat(departData[0].lat);
|
||
|
|
const lon1 = parseFloat(departData[0].lon);
|
||
|
|
const lat2 = parseFloat(arriveeData[0].lat);
|
||
|
|
const lon2 = parseFloat(arriveeData[0].lon);
|
||
|
|
|
||
|
|
const R = 6371; // Rayon de la Terre en km
|
||
|
|
const dLat = ((lat2 - lat1) * Math.PI) / 180;
|
||
|
|
const dLon = ((lon2 - lon1) * Math.PI) / 180;
|
||
|
|
const a =
|
||
|
|
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
|
||
|
|
Math.cos((lat1 * Math.PI) / 180) *
|
||
|
|
Math.cos((lat2 * Math.PI) / 180) *
|
||
|
|
Math.sin(dLon / 2) *
|
||
|
|
Math.sin(dLon / 2);
|
||
|
|
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
||
|
|
const distance = R * c;
|
||
|
|
|
||
|
|
const distanceWithDetour = distance * 1.3;
|
||
|
|
const vitesseMoyenne = 50; // km/h
|
||
|
|
const dureeEnHeures = distanceWithDetour / vitesseMoyenne;
|
||
|
|
|
||
|
|
return Math.round(dureeEnHeures * 10) / 10;
|
||
|
|
} catch {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
}
|