Pendelzeit-API

Vorauswahl der Ziele (Faustregel 90 Minuten)

Eine Anfrage darf höchstens 100 Ziele enthalten, und Reisezeiten über 90 Minuten liefert die API nur als over_limit. Wer mehr Standorte hat – etwa 3.000 Filialen oder 500 Stellen – wählt vorher selbst aus, welche Ziele er schickt. Die API speichert keine Standorte; die Auswahl gehört deshalb zum Client.

Faustregel

Schicken Sie die nächsten 100 Ziele nach Luftlinie, und davon nur solche innerhalb dieser Entfernungen:

Verkehrsmittel Luftlinie höchstens (ca.)
PKW, ÖPNV 120 km
E-Bike 20 km
Fahrrad 17 km
zu Fuß 5 km

Weiter entfernte Ziele sind in 90 Minuten praktisch nicht erreichbar. Schickt ein Client sie trotzdem, liefert die API sie ohne Berechnung als over_limit – das ist kein Fehler, kostet aber einen Platz der 100.

Werden mehrere Verkehrsmittel abgefragt, gilt die größte Entfernung der abgefragten Verkehrsmittel.

Beispiel in JavaScript

JavaScript
// Luftlinie in km (Haversine-Formel)
function distanceKm(a, b) {
  const rad = (d) => (d * Math.PI) / 180;
  const dLat = rad(b.lat - a.lat);
  const dLon = rad(b.lon - a.lon);
  const h = Math.sin(dLat / 2) ** 2 + Math.cos(rad(a.lat)) * Math.cos(rad(b.lat)) * Math.sin(dLon / 2) ** 2;
  return 2 * 6371 * Math.asin(Math.sqrt(h));
}

const MAX_KM = { car: 120, transit: 120, ebike: 20, bike: 17, walk: 5 };

// Die bis zu 100 nächsten Standorte, die für die gewählten Verkehrsmittel in Frage kommen
function preselect(origin, locations, modes) {
  const limit = Math.max(...modes.map((m) => MAX_KM[m]));
  return locations
    .map((l) => ({ ...l, km: distanceKm(origin, l.location) }))
    .filter((l) => l.km <= limit)
    .sort((a, b) => a.km - b.km)
    .slice(0, 100)
    .map(({ km, ...destination }) => destination);
}

const ulm = { lat: 48.39842, lon: 9.99173 };
const filialen = [
  { id: 'ulm', label: 'Ulm', location: { lat: 48.4011, lon: 9.9876 } },
  { id: 'augsburg', label: 'Augsburg', location: { lat: 48.3705, lon: 10.8978 } },
  { id: 'muenchen', label: 'München', location: { lat: 48.1374, lon: 11.5755 } },
  { id: 'hamburg', label: 'Hamburg', location: { lat: 53.5511, lon: 9.9937 } },
];
console.log(preselect(ulm, filialen, ['car']).map((d) => d.id)); // [ 'ulm', 'augsburg' ] – München liegt knapp 121 km entfernt
console.log(preselect(ulm, filialen, ['walk']).map((d) => d.id)); // [ 'ulm' ]

Filtern und begrenzen lassen

Die API sortiert nach dem Verkehrsmittel sortBy und kann das Ergebnis weiter eingrenzen:

meta.counts nennt, wie viele Ziele angefragt, geliefert und herausgefiltert wurden.