Karten: Routen-Übersichtskarte klickbar + Tagebuch-Karten auf GL
Punkt 2 (Routen-Übersicht 'Karte'): _renderRoutesOnMap crashte, weil die Polyline-Facade kein bindTooltip/on/setStyle/getLatLngs kannte. In map-gl-mini.js ergänzt — inkl. breiter, fast unsichtbarer Hit-Linie, damit Routen auf dem Handy gut antippbar sind (Klick → Detail). Hover-Tooltip (Name+km) + Hover-Highlight. Punkt 4 (Tagebuch): beide Leaflet/OSM-Karten (Standort-Übersicht + Einzeleintrag) auf UI.map.create + Facade-Marker migriert. popupopen-Wiring (kennt die GL-Facade nicht) → Klick-Delegation auf dem Karten-Container. Karten-Instanzen werden beim View-Wechsel/Verlassen freigegeben (destroy + _clearDiaryMaps) gegen WebGL-Kontext-Leak. Detail/Übersicht fitten mehrfach (Container-Timing). Nebenbei: _loadPraise warf NotFoundError (insertBefore) — #diary-list liegt in #diary-view-content, nicht direkt in _container. Jetzt vor der Liste in deren echtem Elternknoten einfügen. Verifiziert (headless, eingeloggt, echte Daten): Routenkarte 8 Marker klickbar → Detail; Detail+Vorschläge zoomen auf die Route; Tagebuch-Karte GL mit 108 Markern, Popup-Klick → Eintrag, keine Fehler.
This commit is contained in:
parent
1defeec537
commit
285928f6f7
7 changed files with 134 additions and 87 deletions
|
|
@ -115,7 +115,11 @@
|
|||
_id: 'poly-' + (++_seq),
|
||||
_map: null,
|
||||
_opts: opts,
|
||||
_handlers: {}, // ev → [fn]
|
||||
_tooltip: null,
|
||||
_tipPopup: null,
|
||||
_geo: function () { return { type: 'Feature', geometry: { type: 'LineString', coordinates: this._latlngs.map(_toLngLat) } }; },
|
||||
_hitId: function () { return this._id + '-hit'; },
|
||||
_ensure: function () {
|
||||
var self = this, m = self._map;
|
||||
var add = function () {
|
||||
|
|
@ -123,18 +127,75 @@
|
|||
if (!m.getLayer(self._id)) m.addLayer({ id: self._id, type: 'line', source: self._id,
|
||||
layout: { 'line-cap': 'round', 'line-join': 'round' },
|
||||
paint: { 'line-color': self._opts.color || '#C4843A', 'line-width': self._opts.weight || 4, 'line-opacity': self._opts.opacity != null ? self._opts.opacity : 0.9 } });
|
||||
// Breite, fast unsichtbare Hit-Linie → auf dem Handy gut antippbar.
|
||||
if (self._opts.interactive !== false && !m.getLayer(self._hitId())) {
|
||||
m.addLayer({ id: self._hitId(), type: 'line', source: self._id,
|
||||
layout: { 'line-cap': 'round', 'line-join': 'round' },
|
||||
paint: { 'line-color': '#000', 'line-opacity': 0.01, 'line-width': 18 } });
|
||||
}
|
||||
self._wireAll();
|
||||
};
|
||||
if (m.isStyleLoaded && m.isStyleLoaded()) add(); else m.once('load', add);
|
||||
},
|
||||
_wireOne: function (ev, fn) {
|
||||
var self = this, m = self._map, hit = self._hitId();
|
||||
if (!m.getLayer(hit)) return;
|
||||
if (ev === 'click') {
|
||||
m.on('click', hit, function (e) { if (e.originalEvent) e.originalEvent.stopPropagation(); fn(e); });
|
||||
} else if (ev === 'mouseover') {
|
||||
m.on('mouseenter', hit, function (e) { m.getCanvas().style.cursor = 'pointer'; fn(e); });
|
||||
} else if (ev === 'mouseout') {
|
||||
m.on('mouseleave', hit, function (e) { m.getCanvas().style.cursor = ''; fn(e); });
|
||||
}
|
||||
},
|
||||
_wireAll: function () {
|
||||
var self = this;
|
||||
Object.keys(self._handlers).forEach(function (ev) {
|
||||
self._handlers[ev].forEach(function (fn) { self._wireOne(ev, fn); });
|
||||
self._handlers[ev]._wired = true;
|
||||
});
|
||||
if (self._tooltip && !self._tipWired) self._wireTooltip();
|
||||
},
|
||||
_wireTooltip: function () {
|
||||
var self = this, m = self._map, hit = self._hitId();
|
||||
if (!m.getLayer(hit)) return;
|
||||
self._tipWired = true;
|
||||
m.on('mousemove', hit, function (e) {
|
||||
if (!self._tipPopup) self._tipPopup = new maplibregl.Popup({ closeButton: false, closeOnClick: false, offset: 10, className: 'rk-map-tip' });
|
||||
self._tipPopup.setLngLat(e.lngLat).setHTML(self._tooltip).addTo(m);
|
||||
});
|
||||
m.on('mouseleave', hit, function () { if (self._tipPopup) { self._tipPopup.remove(); } });
|
||||
},
|
||||
addTo: function (mapWrap) { this._map = mapWrap && mapWrap._gl ? mapWrap._gl : mapWrap; this._ensure(); return this; },
|
||||
on: function (ev, fn) {
|
||||
(this._handlers[ev] = this._handlers[ev] || []).push(fn);
|
||||
if (this._map && this._map.getLayer(this._hitId())) this._wireOne(ev, fn);
|
||||
return this;
|
||||
},
|
||||
bindTooltip: function (t) {
|
||||
this._tooltip = typeof t === 'string' ? t : '';
|
||||
if (this._map && this._map.getLayer(this._hitId())) this._wireTooltip();
|
||||
return this;
|
||||
},
|
||||
setStyle: function (s) {
|
||||
var m = this._map; if (!m || !m.getLayer(this._id)) return this;
|
||||
if (s.color != null) m.setPaintProperty(this._id, 'line-color', s.color);
|
||||
if (s.weight != null) m.setPaintProperty(this._id, 'line-width', s.weight);
|
||||
if (s.opacity != null) m.setPaintProperty(this._id, 'line-opacity', s.opacity);
|
||||
return this;
|
||||
},
|
||||
setLatLngs: function (lls) {
|
||||
this._latlngs = lls || [];
|
||||
if (this._map && this._map.getSource(this._id)) this._map.getSource(this._id).setData(this._geo());
|
||||
return this;
|
||||
},
|
||||
// Leaflet-kompatibel: Array von {lat,lng} (für fitBounds-Sammlung).
|
||||
getLatLngs: function () { return this._latlngs.map(function (p) { return (p && p.lat != null) ? { lat: p.lat, lng: p.lng } : { lat: p[0], lng: p[1] }; }); },
|
||||
getBounds: function () { return { _coords: this._latlngs.map(function (p) { return (p && p.lat != null) ? [p.lat, p.lng] : p; }) }; },
|
||||
remove: function () {
|
||||
var m = this._map; if (!m) return this;
|
||||
if (this._tipPopup) { try { this._tipPopup.remove(); } catch (e) {} }
|
||||
if (m.getLayer(this._hitId())) m.removeLayer(this._hitId());
|
||||
if (m.getLayer(this._id)) m.removeLayer(this._id);
|
||||
if (m.getSource(this._id)) m.removeSource(this._id);
|
||||
return this;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue