Maps: trim tile retention, simplify big tracks by zoom, thin POIs when zoomed out

Canvas (prev commit) made the big-track map self-recover but the Chromium
compositor still hit 'tile memory limits exceeded' ~46x and 10k segments
still janked. Three cheap levers:
- tilecache: keepBuffer 2->1 and updateWhenZooming:false - fewer retained
  off-screen tiles in the compositor's raster budget on a high-DPI screen.
- track/roads polylines: smoothFactor 2.5 (Douglas-Peucker in pixels) - a
  10k-point track draws far fewer segments zoomed out, full detail zoomed in.
- POI: cap markers by zoom (z>=16:500, 15:200, 14:80, 13:30) instead of a
  flat 500 - a handful near min-zoom, everything only when zoomed in close.
This commit is contained in:
4aiman 2026-09-29 15:49:02 +03:00
commit 06cc77fdec
4 changed files with 42 additions and 5 deletions

View file

@ -5675,8 +5675,11 @@ async function showSessionDetail(sessionId) {
let allCoords = [];
segments.forEach(seg => {
if (seg.length < 2) { allCoords.push(...seg); return; }
L.polyline(seg, { color: "#ffffff", weight: 8, opacity: 0.8 }).addTo(map);
L.polyline(seg, { color: GPS.config.trackColor || "#bb86fc", weight: 5 }).addTo(map);
// smoothFactor: Douglas-Peucker tolerance in PIXELS, so it drops points that collapse
// together on screen - full detail zoomed in, far fewer segments when zoomed out (where
// a 10k-point track otherwise janks and floods the compositor). 2.5px is imperceptible.
L.polyline(seg, { color: "#ffffff", weight: 8, opacity: 0.8, smoothFactor: 2.5 }).addTo(map);
L.polyline(seg, { color: GPS.config.trackColor || "#bb86fc", weight: 5, smoothFactor: 2.5 }).addTo(map);
L.circleMarker(seg[0], { radius: 5, color: "#4caf50", fillColor: "#4caf50", fillOpacity: 1 }).addTo(map);
L.circleMarker(seg[seg.length - 1], { radius: 5, color: "#f44336", fillColor: "#f44336", fillOpacity: 1 }).addTo(map);
allCoords.push(...seg);
@ -8458,7 +8461,7 @@ async function showRoadsMap() {
let allCoords = [];
for (let s of segments) {
let color = roadColor(s.atype);
L.polyline(s.coords, { color, weight: 4, opacity: 1 }).addTo(map);
L.polyline(s.coords, { color, weight: 4, opacity: 1, smoothFactor: 2.5 }).addTo(map); // px-space simplify: fewer points zoomed out
allCoords.push(...s.coords);
}

View file

@ -49,7 +49,11 @@
function render() {
group.clearLayers();
if (!shown || map.getZoom() < MINZOOM || !POI._data) return;
let z = map.getZoom();
if (!shown || z < MINZOOM || !POI._data) return;
// Fewer markers the further you zoom out: a wide view spans too many POIs to read (and to
// draw). Scale the cap with zoom - a handful near MINZOOM, the full CAP once zoomed in.
let cap = z >= 16 ? CAP : z >= 15 ? 200 : z >= 14 ? 80 : 30;
let b = map.getBounds(), n = 0;
for (let i = 0; i < POI._data.length; i++) {
let p = POI._data[i];
@ -59,7 +63,7 @@
let c = CATS[p.c] || { l: p.c };
m.bindPopup((p.n ? "<b>" + p.n + "</b><br>" : "") + c.l);
group.addLayer(m);
if (++n >= CAP) break;
if (++n >= cap) break;
}
}
map.on("moveend zoomend", render);

View file

@ -127,6 +127,13 @@ TileCache.downloadArea = async function(bounds, zoomMin, zoomMax, onProgress) {
// Custom Leaflet TileLayer that checks IndexedDB first
TileCache.createLayer = function() {
return L.TileLayer.extend({
options: {
// Keep fewer off-screen tile rings and don't reload tiles mid-zoom: on a high-DPI
// screen the compositor's raster-tile budget (cc/tiles "tile memory limits exceeded")
// is filled by the map tiles themselves, so trimming retained tiles keeps content drawing.
keepBuffer: 1, // default 2
updateWhenZooming: false, // defer tile loads until the zoom gesture settles
},
createTile: function(coords, done) {
const tile = document.createElement("img");
const key = `${coords.z}/${coords.x}/${coords.y}`;