Seitenkarten GL Runde 2: Events, Gassi, Routen + Facade-Erweiterung
- Facade: Polyline (geojson line-source, addTo/setLatLngs/getBounds/remove), clusterGroup,
marker.getLatLng, map.distance(Haversine), on('click') normalisiert e.latlng aus e.lngLat, _ll objekttauglich
- events: L.markerClusterGroup→UI.map.clusterGroup
- walks: window.L-Guard, L.featureGroup→UI.map.featureGroup, fitBounds ohne .pad
- routes: L.polyline/L.circleMarker→UI.map.*, navMap/Pfeil-Marker→svgMarker, latLngBounds→coords,
trimMap distance/click, Mini-Vorschauen auf SVG (kein WebGL-Limit, kein OSM-Raster)
This commit is contained in:
parent
5844f1ef51
commit
96119e02ef
10 changed files with 146 additions and 88 deletions
|
|
@ -6,7 +6,11 @@
|
|||
(function () {
|
||||
'use strict';
|
||||
|
||||
function _ll(latlon) { return [latlon[1], latlon[0]]; } // [lat,lon] → [lng,lat]
|
||||
// [lat,lon]-Array ODER {lat,lng}-Objekt → [lng,lat] für MapLibre.
|
||||
function _ll(latlon) {
|
||||
if (latlon && latlon.lat != null) return [latlon.lng, latlon.lat];
|
||||
return [latlon[1], latlon[0]];
|
||||
}
|
||||
|
||||
// ---- Map-Wrapper ----
|
||||
function _wrapMap(map) {
|
||||
|
|
@ -33,10 +37,24 @@
|
|||
addLayer: function (layer) { if (layer && layer.addTo) layer.addTo(this); return this; },
|
||||
hasLayer: function () { return true; },
|
||||
remove: function () { try { map.remove(); } catch (e) {} },
|
||||
on: function (ev, fn) { map.on(ev, fn); return this; },
|
||||
on: function (ev, fn) {
|
||||
if (ev === 'click') {
|
||||
map.on('click', function (e) { if (e.lngLat && !e.latlng) e.latlng = { lat: e.lngLat.lat, lng: e.lngLat.lng }; fn(e); });
|
||||
} else { map.on(ev, fn); }
|
||||
return this;
|
||||
},
|
||||
off: function (ev, fn) { map.off(ev, fn); return this; },
|
||||
getZoom: function () { return map.getZoom(); },
|
||||
getCenter: function () { var c = map.getCenter(); return { lat: c.lat, lng: c.lng }; },
|
||||
// Distanz in Metern (Haversine) — Ersatz für Leaflets map.distance.
|
||||
distance: function (a, b) {
|
||||
var la = a.lat != null ? a.lat : a[0], lo = a.lng != null ? a.lng : a[1];
|
||||
var lb = b.lat != null ? b.lat : b[0], ob = b.lng != null ? b.lng : b[1];
|
||||
var R = 6371000, p1 = la * Math.PI / 180, p2 = lb * Math.PI / 180;
|
||||
var dp = (lb - la) * Math.PI / 180, dl = (ob - lo) * Math.PI / 180;
|
||||
var x = Math.sin(dp / 2) * Math.sin(dp / 2) + Math.cos(p1) * Math.cos(p2) * Math.sin(dl / 2) * Math.sin(dl / 2);
|
||||
return 2 * R * Math.asin(Math.sqrt(x));
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -74,13 +92,64 @@
|
|||
if (ev === 'click') el.addEventListener('click', function (e) { e.stopPropagation(); fn(e); });
|
||||
return this;
|
||||
},
|
||||
setLatLng: function (latlon) { m.setLngLat([latlon[1], latlon[0]]); return this; },
|
||||
setLatLng: function (latlon) { m.setLngLat(_ll(latlon)); return this; },
|
||||
getLatLng: function () { var c = m.getLngLat(); return { lat: c.lat, lng: c.lng }; },
|
||||
setOpacity: function (o) { el.style.opacity = o; return this; },
|
||||
remove: function () { try { m.remove(); } catch (e) {} return this; },
|
||||
};
|
||||
return wrap;
|
||||
}
|
||||
|
||||
// ---- Polyline-Wrapper (GL geojson line-source/-layer) ----
|
||||
var _seq = 0;
|
||||
function _toLngLat(p) { return (p && p.lat != null) ? [p.lng, p.lat] : [p[1], p[0]]; } // L.latLng | [lat,lon]
|
||||
function _wrapPolyline(latlngs, opts) {
|
||||
opts = opts || {};
|
||||
return {
|
||||
_latlngs: latlngs || [],
|
||||
_id: 'poly-' + (++_seq),
|
||||
_map: null,
|
||||
_opts: opts,
|
||||
_geo: function () { return { type: 'Feature', geometry: { type: 'LineString', coordinates: this._latlngs.map(_toLngLat) } }; },
|
||||
_ensure: function () {
|
||||
var self = this, m = self._map;
|
||||
var add = function () {
|
||||
if (!m.getSource(self._id)) m.addSource(self._id, { type: 'geojson', data: self._geo() });
|
||||
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 } });
|
||||
};
|
||||
if (m.isStyleLoaded && m.isStyleLoaded()) add(); else m.once('load', add);
|
||||
},
|
||||
addTo: function (mapWrap) { this._map = mapWrap && mapWrap._gl ? mapWrap._gl : mapWrap; this._ensure(); 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;
|
||||
},
|
||||
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 (m.getLayer(this._id)) m.removeLayer(this._id);
|
||||
if (m.getSource(this._id)) m.removeSource(this._id);
|
||||
return this;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// ---- Gruppe (Cluster-Ersatz: fügt Marker direkt hinzu; GL clustert Seitenkarten nicht) ----
|
||||
function _wrapGroup() {
|
||||
return {
|
||||
_markers: [], _map: null,
|
||||
addLayer: function (m) { this._markers.push(m); if (this._map) m.addTo(this._map); return this; },
|
||||
addLayers: function (ms) { (ms || []).forEach(this.addLayer, this); return this; },
|
||||
removeLayers: function (ms) { (ms || []).forEach(function (m) { m.remove(); }); this._markers = this._markers.filter(function (m) { return (ms || []).indexOf(m) === -1; }); return this; },
|
||||
addTo: function (mapWrap) { this._map = mapWrap; this._markers.forEach(function (m) { m.addTo(mapWrap); }); return this; },
|
||||
clearLayers: function () { this._markers.forEach(function (m) { m.remove(); }); this._markers = []; return this; },
|
||||
remove: function () { this.clearLayers(); this._map = null; return this; },
|
||||
};
|
||||
}
|
||||
|
||||
// Element aus HTML-String (für svgMarker mit custom HTML).
|
||||
function _elFromHtml(html, size, anchorY) {
|
||||
var wrap = document.createElement('div');
|
||||
|
|
@ -134,6 +203,9 @@
|
|||
return _wrapMarker(lat, lon, el, 'center');
|
||||
},
|
||||
|
||||
polyline: function (latlngs, opts) { return _wrapPolyline(latlngs, opts); },
|
||||
clusterGroup: function () { return _wrapGroup(); },
|
||||
|
||||
// featureGroup: nur als Bounds-Container (markers = Array von Wrappern mit _gl.getLngLat()).
|
||||
featureGroup: function (markers) {
|
||||
var coords = (markers || []).map(function (m) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue