GEOINT Performance-Fix: Canvas-Renderer statt DOM-Marker
Vorher: 18.000+ DOM-Elemente (divIcon) -> Browser-Absturz Jetzt: Canvas-basierte circleMarker (L.canvas Renderer) - Flugzeuge: max 400 im sichtbaren Bereich, gruene Punkte - Schiffe: max 500 im sichtbaren Bereich, blaue Punkte - Canvas rendert tausende Marker als ein einzelnes HTML-Element - Popups weiterhin per Klick verfuegbar
Dieser Commit ist enthalten in:
@@ -53,6 +53,7 @@ const GEOINT = {
|
|||||||
if (cb2) cb2.checked = enabled;
|
if (cb2) cb2.checked = enabled;
|
||||||
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
|
if (!this._canvasRenderer) this._canvasRenderer = L.canvas({ padding: 0.5 });
|
||||||
this._applySatelliteTiles(map);
|
this._applySatelliteTiles(map);
|
||||||
this._createSubControl(map);
|
this._createSubControl(map);
|
||||||
this._restoreSublayers(map);
|
this._restoreSublayers(map);
|
||||||
@@ -202,7 +203,7 @@ const GEOINT = {
|
|||||||
self._moveDebounce = setTimeout(function() {
|
self._moveDebounce = setTimeout(function() {
|
||||||
self._renderFlights(map);
|
self._renderFlights(map);
|
||||||
self._renderShips(map);
|
self._renderShips(map);
|
||||||
}, 300);
|
}, 500);
|
||||||
};
|
};
|
||||||
map.on('moveend', this._moveHandler);
|
map.on('moveend', this._moveHandler);
|
||||||
},
|
},
|
||||||
@@ -256,18 +257,11 @@ const GEOINT = {
|
|||||||
if (!map || !this._flightLayer || !this._flightsData) return;
|
if (!map || !this._flightLayer || !this._flightsData) return;
|
||||||
var newLayer = L.layerGroup();
|
var newLayer = L.layerGroup();
|
||||||
var bounds = map.getBounds();
|
var bounds = map.getBounds();
|
||||||
this._flightsData.forEach(function(a) {
|
var count = 0;
|
||||||
if (!a.lat || !a.lon || !bounds.contains([a.lat, a.lon])) return;
|
for (var i = 0; i < this._flightsData.length && count < 400; i++) {
|
||||||
var heading = a.track || a.true_heading || 0;
|
var a = this._flightsData[i];
|
||||||
var icon = L.divIcon({
|
if (!a.lat || !a.lon || !bounds.contains([a.lat, a.lon])) continue;
|
||||||
className: '',
|
count++;
|
||||||
html: '<div class="geoint-aircraft" style="transform:rotate(' + heading + 'deg)">' +
|
|
||||||
'<svg viewBox="0 0 24 24" fill="#00ff88" stroke="#004422" stroke-width="1">' +
|
|
||||||
'<path d="M12 2L8 10h-4l2 4-2 4h4l4 4 4-4h4l-2-4 2-4h-4z"/>' +
|
|
||||||
'</svg></div>',
|
|
||||||
iconSize: [14, 14],
|
|
||||||
iconAnchor: [7, 7],
|
|
||||||
});
|
|
||||||
var callsign = (a.flight || a.callsign || a.hex || '???').trim();
|
var callsign = (a.flight || a.callsign || a.hex || '???').trim();
|
||||||
var alt = a.alt_baro || a.altitude || '?';
|
var alt = a.alt_baro || a.altitude || '?';
|
||||||
var spd = a.gs || a.ground_speed || '?';
|
var spd = a.gs || a.ground_speed || '?';
|
||||||
@@ -277,10 +271,12 @@ const GEOINT = {
|
|||||||
(typ ? ' <span style="opacity:0.6">(' + typ + ')</span>' : '') +
|
(typ ? ' <span style="opacity:0.6">(' + typ + ')</span>' : '') +
|
||||||
'<br><span class="geoint-popup-key">ALT</span> ' + (typeof alt === 'number' ? alt.toLocaleString() + ' ft' : alt) +
|
'<br><span class="geoint-popup-key">ALT</span> ' + (typeof alt === 'number' ? alt.toLocaleString() + ' ft' : alt) +
|
||||||
'<br><span class="geoint-popup-key">SPD</span> ' + (typeof spd === 'number' ? Math.round(spd) + ' kts' : spd) +
|
'<br><span class="geoint-popup-key">SPD</span> ' + (typeof spd === 'number' ? Math.round(spd) + ' kts' : spd) +
|
||||||
'<br><span class="geoint-popup-key">HDG</span> ' + Math.round(heading) + '\u00b0' +
|
|
||||||
'</div>';
|
'</div>';
|
||||||
L.marker([a.lat, a.lon], { icon: icon }).bindPopup(popup, { className: 'geoint-leaflet-popup' }).addTo(newLayer);
|
L.circleMarker([a.lat, a.lon], {
|
||||||
});
|
radius: 3, fillColor: '#00ff88', color: '#004422',
|
||||||
|
fillOpacity: 0.9, weight: 1, renderer: this._canvasRenderer
|
||||||
|
}).bindPopup(popup, { className: 'geoint-leaflet-popup' }).addTo(newLayer);
|
||||||
|
}
|
||||||
if (this._map) {
|
if (this._map) {
|
||||||
this._map.removeLayer(this._flightLayer);
|
this._map.removeLayer(this._flightLayer);
|
||||||
this._flightLayer = newLayer.addTo(this._map);
|
this._flightLayer = newLayer.addTo(this._map);
|
||||||
@@ -345,30 +341,26 @@ const GEOINT = {
|
|||||||
if (!map || !this._shipsLayer || !this._shipsData) return;
|
if (!map || !this._shipsLayer || !this._shipsData) return;
|
||||||
var newLayer = L.layerGroup();
|
var newLayer = L.layerGroup();
|
||||||
var bounds = map.getBounds();
|
var bounds = map.getBounds();
|
||||||
this._shipsData.forEach(function(s) {
|
var count = 0;
|
||||||
if (!s.lat || !s.lon || !bounds.contains([s.lat, s.lon])) return;
|
for (var i = 0; i < this._shipsData.length && count < 500; i++) {
|
||||||
var heading = s.heading || s.cog || 0;
|
var s = this._shipsData[i];
|
||||||
|
if (!s.lat || !s.lon || !bounds.contains([s.lat, s.lon])) continue;
|
||||||
|
count++;
|
||||||
var sog = s.sog || 0;
|
var sog = s.sog || 0;
|
||||||
var icon = L.divIcon({
|
var color = sog > 0.5 ? '#4499ff' : '#556688';
|
||||||
className: '',
|
|
||||||
html: '<div class="geoint-ship" style="transform:rotate(' + heading + 'deg)">' +
|
|
||||||
'<svg viewBox="0 0 24 24" width="10" height="10">' +
|
|
||||||
'<path d="M12 2l-4 8h-3l3 12h8l3-12h-3z" fill="' + (sog > 0.5 ? '#4499ff' : '#666688') + '" stroke="#223355" stroke-width="1"/>' +
|
|
||||||
'</svg></div>',
|
|
||||||
iconSize: [10, 10],
|
|
||||||
iconAnchor: [5, 5],
|
|
||||||
});
|
|
||||||
var mmsi = s.mmsi || '?';
|
var mmsi = s.mmsi || '?';
|
||||||
var navLabels = {0:'Motorbetrieb', 1:'Vor Anker', 2:'Nicht steuerbar', 3:'Eingeschraenkt', 5:'Festgemacht', 7:'Fischfang', 8:'Unter Segel'};
|
var navLabels = {0:'Motorbetrieb', 1:'Vor Anker', 2:'Nicht steuerbar', 3:'Eingeschraenkt', 5:'Festgemacht', 7:'Fischfang', 8:'Unter Segel'};
|
||||||
var navText = navLabels[s.navStat] || 'Status ' + s.navStat;
|
var navText = navLabels[s.navStat] || 'Status ' + s.navStat;
|
||||||
var popup = '<div class="geoint-popup">' +
|
var popup = '<div class="geoint-popup">' +
|
||||||
'<strong>MMSI ' + mmsi + '</strong>' +
|
'<strong>MMSI ' + mmsi + '</strong>' +
|
||||||
'<br><span class="geoint-popup-key">SOG</span> ' + sog.toFixed(1) + ' kn' +
|
'<br><span class="geoint-popup-key">SOG</span> ' + sog.toFixed(1) + ' kn' +
|
||||||
'<br><span class="geoint-popup-key">COG</span> ' + Math.round(s.cog || 0) + '\u00b0' +
|
|
||||||
'<br><span class="geoint-popup-key">NAV</span> ' + navText +
|
'<br><span class="geoint-popup-key">NAV</span> ' + navText +
|
||||||
'</div>';
|
'</div>';
|
||||||
L.marker([s.lat, s.lon], { icon: icon }).bindPopup(popup, { className: 'geoint-leaflet-popup' }).addTo(newLayer);
|
L.circleMarker([s.lat, s.lon], {
|
||||||
});
|
radius: 2.5, fillColor: color, color: '#223355',
|
||||||
|
fillOpacity: 0.85, weight: 0.5, renderer: this._canvasRenderer
|
||||||
|
}).bindPopup(popup, { className: 'geoint-leaflet-popup' }).addTo(newLayer);
|
||||||
|
}
|
||||||
if (this._map) {
|
if (this._map) {
|
||||||
this._map.removeLayer(this._shipsLayer);
|
this._map.removeLayer(this._shipsLayer);
|
||||||
this._shipsLayer = newLayer.addTo(this._map);
|
this._shipsLayer = newLayer.addTo(this._map);
|
||||||
|
|||||||
In neuem Issue referenzieren
Einen Benutzer sperren