Files
eventmap/js/map/markers.js
T
dapelza c7e3246b44 Fix: Nutzerstandort auf der Karte anzeigen
Behebt Gitea Issue #2 "Standort auf Karte anzeigen": der per
Browser-Geolocation ermittelte oder manuell eingegebene Standort
(state.userLocation) wurde bisher nur zum Zentrieren/Entfernungsfilter
verwendet, aber nie selbst auf der Karte dargestellt.

Neuer, nicht interaktiver "Hier bist du"-Marker (blauer Punkt mit
Puls-Ring, js/map/markers.js: createUserLocationMarker()) wird direkt
auf die Karte gelegt (ausserhalb der clusterGroup, damit er nie mit
Ausflugsziel-Markern geclustert wird) und reagiert reaktiv auf
Aenderungen von state.userLocation in js/map/mapController.js.
2026-07-24 12:52:09 +02:00

94 lines
2.9 KiB
JavaScript

/* global L */
// Erzeugt Leaflet-Marker für Places inkl. Kategorie-Icon (L.divIcon) und
// Popup-Inhalt. Popup-Inhalte werden als DOM-Nodes (nicht als HTML-String)
// erzeugt, damit Place-Daten niemals ungesichert als innerHTML landen.
(function () {
const { getCategoryById } = EventMap.config;
const { getPlaceCategory, getPlaceLatLng } = EventMap.models;
const { el } = EventMap.utils;
const iconCache = new Map();
function buildDivIcon(category) {
return L.divIcon({
className: 'eventmap-marker',
html: `<span class="eventmap-marker__glyph" style="background:${category.color}">${category.icon}</span>`,
iconSize: [32, 32],
iconAnchor: [16, 16],
popupAnchor: [0, -16],
});
}
function getIconForCategory(categoryId) {
if (!iconCache.has(categoryId)) {
iconCache.set(categoryId, buildDivIcon(getCategoryById(categoryId)));
}
return iconCache.get(categoryId);
}
function buildPopupContent(place) {
const category = getPlaceCategory(place);
return el('div', { className: 'eventmap-popup' }, [
el('strong', { className: 'eventmap-popup__title', text: place.name }),
el('div', {
className: 'eventmap-popup__category',
style: { color: category.color },
text: `${category.icon} ${category.label}`,
}),
el('p', { className: 'eventmap-popup__desc', text: place.shortDescription }),
]);
}
/**
* Erzeugt einen Leaflet-Marker für ein Place-Objekt.
* @param {object} place
* @param {{onSelect?: (placeId: string) => void}} [handlers]
*/
function createMarkerForPlace(place, { onSelect } = {}) {
const { lat, lng } = getPlaceLatLng(place);
const marker = L.marker([lat, lng], { icon: getIconForCategory(place.category) });
marker.bindPopup(buildPopupContent(place));
marker.on('click', () => {
if (onSelect) {
onSelect(place.id);
}
});
return marker;
}
let userLocationIcon = null;
function getUserLocationIcon() {
if (!userLocationIcon) {
userLocationIcon = L.divIcon({
className: 'eventmap-user-marker',
html: '<span class="eventmap-user-marker__pulse"></span><span class="eventmap-user-marker__dot"></span>',
iconSize: [22, 22],
iconAnchor: [11, 11],
});
}
return userLocationIcon;
}
/**
* Erzeugt einen (nicht klickbaren) Marker für den übermittelten/manuell
* eingegebenen Nutzerstandort (Gitea Issue #2 "Standort auf Karte
* anzeigen"). Bewusst kein Popup/Interaktion, da es kein Ausflugsziel ist.
*/
function createUserLocationMarker(lat, lng) {
return L.marker([lat, lng], {
icon: getUserLocationIcon(),
interactive: false,
keyboard: false,
zIndexOffset: 1000,
});
}
EventMap.map.createMarkerForPlace = createMarkerForPlace;
EventMap.map.createUserLocationMarker = createUserLocationMarker;
})();