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.
This commit is contained in:
2026-07-24 12:52:09 +02:00
parent 39321d680f
commit c7e3246b44
3 changed files with 114 additions and 2 deletions
+40 -2
View File
@@ -4,16 +4,18 @@
(function () {
const { DEFAULT_MAP_CENTER } = EventMap.config;
const { subscribe, setState, getFilteredPlaces } = EventMap.store;
const { subscribe, getState, setState, getFilteredPlaces } = EventMap.store;
const { getPlaceLatLng } = EventMap.models;
const { createMarkerForPlace } = EventMap.map;
const { createMarkerForPlace, createUserLocationMarker } = EventMap.map;
let map = null;
let clusterGroup = null;
let userLocationMarker = null;
const markersByPlaceId = new Map();
let lastFilteredKey = null;
let lastSelectedPlaceId = null;
let lastUserLocationKey = null;
/** Günstiger Vergleichsschlüssel für eine gefilterte Trefferliste (Reihenfolge + IDs). */
function computeFilteredKey(places) {
@@ -72,6 +74,30 @@
map.setView([lat, lng], zoom);
}
/**
* Zeigt den übermittelten/manuell eingegebenen Nutzerstandort als eigenen
* Marker auf der Karte an (Gitea Issue #2). Läuft außerhalb der
* clusterGroup, damit er nie mit Ausflugsziel-Markern geclustert wird und
* immer sichtbar bleibt.
*/
function renderUserLocation(userLocation) {
if (!userLocation) {
if (userLocationMarker) {
map.removeLayer(userLocationMarker);
userLocationMarker = null;
}
return;
}
const { lat, lng } = userLocation;
if (userLocationMarker) {
userLocationMarker.setLatLng([lat, lng]);
} else {
userLocationMarker = createUserLocationMarker(lat, lng);
userLocationMarker.addTo(map);
}
}
function getMapInstance() {
return map;
}
@@ -111,6 +137,10 @@
fitToPlaces(initialFiltered);
lastFilteredKey = computeFilteredKey(initialFiltered);
const initialUserLocation = getState().userLocation;
renderUserLocation(initialUserLocation);
lastUserLocationKey = initialUserLocation ? `${initialUserLocation.lat},${initialUserLocation.lng}` : null;
subscribe((state) => {
// Filter/Standort können sich ändern, ohne dass sich state.places
// ändert - daher bei jeder Store-Änderung neu filtern und nur bei
@@ -128,6 +158,14 @@
centerOnPlace(state.selectedPlaceId);
}
}
const userLocationKey = state.userLocation
? `${state.userLocation.lat},${state.userLocation.lng}`
: null;
if (userLocationKey !== lastUserLocationKey) {
lastUserLocationKey = userLocationKey;
renderUserLocation(state.userLocation);
}
});
return map;