Files
Atlas/lib/distance-calculator.ts
Julia Wehden a2c95c70e7 feat: Equipment-System, Buchungsbearbeitung, Kundenadresse, LexOffice-Fix
- Vintage Modell hinzugefuegt
- Equipment Multi-Select (Neue Buchung + Bearbeitung)
- Kundenadresse in Formularen
- Bearbeiten-Seite fuer Buchungen
- Abbau-Zeiten in Formularen und Uebersicht
- Vertrag PDF nur bei Privatkunden
- LexOffice Kontakt-Erstellung Fix (BUSINESS)
- Zurueck-Pfeil auf Touren-Seite
2026-03-19 16:21:55 +01:00

89 lines
2.3 KiB
TypeScript

interface Coordinates {
lat: number;
lon: number;
}
interface DistanceResult {
distance: number;
duration: number;
}
export class DistanceCalculator {
private static readonly OSRM_API = 'https://router.project-osrm.org/route/v1/driving';
static async geocodeAddress(address: string): Promise<Coordinates | null> {
try {
const nominatimUrl = `https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(address)}&limit=1`;
const response = await fetch(nominatimUrl, {
headers: {
'User-Agent': 'SaveTheMoment-Atlas/1.0',
},
});
if (!response.ok) {
throw new Error(`Geocoding failed: ${response.statusText}`);
}
const data = await response.json();
if (!data || data.length === 0) {
console.warn(`No results found for address: ${address}`);
return null;
}
return {
lat: parseFloat(data[0].lat),
lon: parseFloat(data[0].lon),
};
} catch (error) {
console.error('Geocoding error:', error);
return null;
}
}
static async calculateDistance(
fromAddress: string,
toAddress: string
): Promise<DistanceResult | null> {
try {
const fromCoords = await this.geocodeAddress(fromAddress);
const toCoords = await this.geocodeAddress(toAddress);
if (!fromCoords || !toCoords) {
console.error('Failed to geocode one or both addresses');
return null;
}
const url = `${this.OSRM_API}/${fromCoords.lon},${fromCoords.lat};${toCoords.lon},${toCoords.lat}?overview=false`;
const response = await fetch(url);
if (!response.ok) {
throw new Error(`OSRM API failed: ${response.statusText}`);
}
const data = await response.json();
if (!data.routes || data.routes.length === 0) {
console.error('No route found');
return null;
}
const route = data.routes[0];
return {
distance: Math.round(route.distance / 1000 * 100) / 100,
duration: Math.round(route.duration / 60),
};
} catch (error) {
console.error('Distance calculation error:', error);
return null;
}
}
static formatAddress(address: string, zip: string, city: string): string {
return `${address}, ${zip} ${city}`.trim();
}
}