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.
94 lines
2.9 KiB
JavaScript
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;
|
|
})();
|