// Wegwerf-Perf-Test: beweist MapLibre-GPU-Rendering auf dem Handy mit realistischer // Marker-Last (600 Punkte, GeoJSON-Clustering) auf unserer DACH-Basemap — die Kombi, // die mit protomaps-leaflet (Main-Thread) den UI-Thread blockierte. // Cluster-Zahlen weggelassen (Text bräuchte Glyphs → kommt erst in M3). (function () { 'use strict'; var st = document.getElementById('status'); function set(t) { if (st) st.textContent = t; } try { var proto = new pmtiles.Protocol(); maplibregl.addProtocol('pmtiles', proto.tile); var isDark = document.documentElement.dataset.theme === 'dark'; var map = new maplibregl.Map({ container: 'map', style: MapGLStyle.build({ dark: isDark }), center: [11.576, 48.137], zoom: 12, hash: true, }); map.addControl(new maplibregl.NavigationControl(), 'top-right'); map.addControl(new maplibregl.ScaleControl()); // Kategorie-Icon (farbiger Kreis) per Canvas → addImage (Icons brauchen KEINE Glyphs). function makeIcon(color) { var s = 34, c = document.createElement('canvas'); c.width = c.height = s; var x = c.getContext('2d'); x.beginPath(); x.arc(s / 2, s / 2, s / 2 - 3, 0, Math.PI * 2); x.fillStyle = color; x.fill(); x.lineWidth = 2; x.strokeStyle = 'rgba(52,68,36,0.6)'; x.stroke(); return x.getImageData(0, 0, s, s); } // 600 deterministische Pseudo-POIs um München (3 Kategorien). function genPois(n) { var feats = [], seed = 42; function rnd() { seed = (seed * 9301 + 49297) % 233280; return seed / 233280; } for (var i = 0; i < n; i++) { feats.push({ type: 'Feature', properties: { cat: i % 3 }, geometry: { type: 'Point', coordinates: [11.40 + rnd() * 0.36, 48.03 + rnd() * 0.24] } }); } return { type: 'FeatureCollection', features: feats }; } map.on('load', function () { map.addImage('cat0', makeIcon('#e8590c')); map.addImage('cat1', makeIcon('#2f9e44')); map.addImage('cat2', makeIcon('#1971c2')); map.addSource('pois', { type: 'geojson', data: genPois(600), cluster: true, clusterRadius: 50, clusterMaxZoom: 16 }); map.addLayer({ id: 'clusters', type: 'circle', source: 'pois', filter: ['has', 'point_count'], paint: { 'circle-color': '#5b4a2f', 'circle-stroke-color': 'rgba(52,68,36,0.65)', 'circle-stroke-width': 2, 'circle-radius': ['step', ['get', 'point_count'], 14, 10, 18, 50, 24], } }); map.addLayer({ id: 'poi', type: 'symbol', source: 'pois', filter: ['!', ['has', 'point_count']], layout: { 'icon-image': ['match', ['get', 'cat'], 0, 'cat0', 1, 'cat1', 2, 'cat2', 'cat0'], 'icon-allow-overlap': true, 'icon-size': 0.7, } }); set('✅ MapLibre + 600 Marker — jetzt zoomen/schieben, fühlt sich das flüssig an?'); }); map.on('error', function (e) { set('⚠️ ' + (e && e.error ? e.error.message : 'Fehler')); if (e && e.error) console.error(e.error); }); } catch (e) { set('❌ ' + (e && e.message ? e.message : e)); } })();