Files
eventmap/js/utils/geo.js
T
dapelza ee55fb1cf9 Phase 0+1: Scaffold, Datenmodell, Karte und Liste
Reines HTML5/CSS3/JavaScript ohne Build-Tooling, lauffaehig direkt per
Doppelklick auf index.html (file://, kein Server noetig):

- Datenmodell fuer Ausflugsziele mit allen Feldern aus der Anforderung,
  15 feste Kategorien inkl. Farbe/Icon
- Zentraler Pub/Sub-Store mit LocalStorage-Persistenz und
  Migrations-Grundgeruest
- Interaktive Karte (Leaflet + Leaflet.markercluster, lokal vendored)
  mit kategoriefarbenen Markern, Clustering, Popups, Geolocation-Button
- Kartengrundlage ueber CARTO-Basemaps statt tile.openstreetmap.org, da
  dessen Referer-Pflicht file://-Aufrufe blockiert
- Seed-Daten als eingebettetes Script (data/seed.js) statt JSON-Datei,
  da fetch() auf lokale Dateien unter file:// nicht zuverlaessig
  funktioniert
- Ergebnisliste mit 10 Beispiel-Ausflugszielen, sicher gerendert ueber
  textContent/DOM-APIs statt innerHTML (Vorbereitung fuer spaeteren
  KI-JSON-Import mit Fremddaten)
- Responsives Layout (Desktop nebeneinander, Mobile gestapelt)
2026-07-24 11:24:47 +02:00

45 lines
1.1 KiB
JavaScript

// Geografische Hilfsfunktionen.
(function () {
const EARTH_RADIUS_KM = 6371;
function toRad(deg) {
return (deg * Math.PI) / 180;
}
/**
* Entfernung zwischen zwei Koordinaten in Kilometern (Haversine-Formel).
* @param {{lat:number,lng:number}} a
* @param {{lat:number,lng:number}} b
*/
function haversineDistanceKm(a, b) {
const dLat = toRad(b.lat - a.lat);
const dLng = toRad(b.lng - a.lng);
const lat1 = toRad(a.lat);
const lat2 = toRad(b.lat);
const h =
Math.sin(dLat / 2) ** 2 +
Math.cos(lat1) * Math.cos(lat2) * Math.sin(dLng / 2) ** 2;
const c = 2 * Math.atan2(Math.sqrt(h), Math.sqrt(1 - h));
return EARTH_RADIUS_KM * c;
}
function isValidCoordinate(lat, lng) {
return (
typeof lat === 'number' &&
typeof lng === 'number' &&
Number.isFinite(lat) &&
Number.isFinite(lng) &&
lat >= -90 &&
lat <= 90 &&
lng >= -180 &&
lng <= 180
);
}
EventMap.utils.haversineDistanceKm = haversineDistanceKm;
EventMap.utils.isValidCoordinate = isValidCoordinate;
})();