import * as dt from './datetime.js' import * as utils from "./chart_utilities.js" import { showChart, loadAll} from './showcharts.js' import * as mapu from './map_utilities.js' import * as spin from './spinner.js' export const colorscale = ['#d53e4f', '#fc8d59', '#fee08b', '#e6f598', '#99d594', '#3288bd', '#808080']; const dba = [100, 80, 60, 40, 20, 0, -999]; export function getColor(d) { let val = parseInt(d); for (let i = 0; i < dba.length; i++) { if (val >= dba[i]) { return (colorscale[i]); } } } export const buildLegend = (mpp) => { let legend = L.control({position: 'bottomright'}) legend.onAdd = function () { let div = L.DomUtil.create('div', 'info legend') let div_color = L.DomUtil.create('div', 'info legend inner', div) div_color.innerHTML += 'dbA
'; // loop through our density intervals and generate a label with a colored square for each interval for (let i = 0; i < dba.length - 1; i++) { div_color.innerHTML += '' + '  ' + dba[i] + (i == 0 ? '+' : '') + '
' } div_color.innerHTML += '  offline' return div }; legend.addTo(mpp.map) } export async function buildMarkers(params, mpp) { const url = mpp.APIURL + `type=noise&box=${mpp.bounds.toBBoxString()}` let sensors = await utils.fetchfromserver(url) if (!sensors.err) { let markers = L.markerClusterGroup({ spiderfyOnMaxZoom: true, showCoverageOnHover: false, zoomToBoundsOnClick: true, // disableClusteringAtZoom: 14, iconCreateFunction: function (cluster) { let mymarkers = cluster.getAllChildMarkers(); let color = getMedian(mymarkers); return new L.Icon({ iconUrl: buildIcon(color, cluster.getChildCount(), 0), iconSize: [35, 35] }); }, }); for (let x of sensors.values) { if ((params.weeks > 0) && (x.weeks > params.weeks)) { continue } if (x.value <= -5) { continue } let marker = L.marker([x.location[1], x.location[0]], { icon: new L.Icon({ iconUrl: buildIcon(getColor(parseInt(x.value)), 0, x.indoor), iconSize: [35, 35], }), name: x.id, value: x.value, url: '/graph?sid=' + x.id, lastseen: dt.formatISODate(x.lastseen), indoor: x.indoor }) .on('click', e => onMarkerClick(e, true, sensors.popuptxt, params, mpp)) // define click- and markers.addLayer(marker); } mpp.map.addLayer(markers); return sensors.lastdate } else { utils.showError(sensors.err) } } function buildIcon(color, n, indoor) { let x = 100; if (n < 10) { x = 200; } else if (n < 100) { x = 150; } let txtColor = "black"; if (color == colorscale[5]) { txtColor = "white" } let icon = '' + ''; if (n !== 0) { icon += '' + n + ''; } if(indoor) { icon += '' } icon += ''; return encodeURI("data:image/svg+xml," + icon).replace(new RegExp('#', 'g'), '%23'); } async function bauPopupText(item, txts) { let addr = '' let offlinetext = ` ${txts.offline} ${txts.lastseen}:${item.lastseen}` let normaltext = ` LA_max:${item.value}` let popuptext = `

${txts.sensor}: ${item.name}

${addr}
${item.value < 0 ? offlinetext : normaltext}
${item.indoor==1 ? "indoor" : ""}
` return popuptext } async function onMarkerClick(e, click, txts, params, mpp) { let item = e.target.options; let popuptext = await bauPopupText(item, txts) e.target.bindPopup(popuptext).openPopup(); // show the popup let addr = await utils.addAddress(item.name) document.querySelector('#infoTitle .addr').innerHTML = `${addr.street}
${addr.plz} ${addr.city}` let link = document.querySelector('.speciallink') link.addEventListener('click', async function (ev) { console.log(`Event clicked: ${mpp.clickedSensor}`) params.sid = item.name history.pushState({}, '', `/${params.sid}`) utils.setCurrentTab('livetab') spin.spinner.spin(spin.spindiv) let ok = await showChart(params, ttIndex.live) spin.spinner.stop() if (ok) { let triggerEl = document.querySelector(`#livetab`) bootstrap.Tab.getInstance(triggerEl).show() // Select tab by name params.center.coords = [e.latlng.lat, e.latlng.lng] ev.preventDefault() await loadAll(params) } }) } // With all Markers in cluster (markers) calculate the median // of the values. With this median fetch the color and return it. // If there are 'offline' sensors (value == -1) strip then before // calculating the median. If there are only offline sensor, return // color of value==-1 (dark gray). function getMedian(markers, value) { markers.sort(function (a, b) { // first sort, the lowest first let y1 = a.options.value; let y2 = b.options.value; if (y1 < y2) { return -1; } if (y2 < y1) { return 1; } return 0; }); // console.log(markers); let i = 0; // now find the 'offlines' (value == -1) for (i = 0; i < markers.length; i++) { if (markers[i].options.value > 0) { break; } } markers.splice(0, i); // remove these from array let lang = markers.length; if (lang > 1) { // if ((lang % 2) == 1) { // uneven -> return getColor(markers[(Math.floor(lang / 2))].options.value); // median is in the middle } else { // evaen -> lang = lang / 2; // median is mean of both middle values // console.log(lang); let wert = (markers[lang - 1].options.value + markers[lang].options.value) / 2; return getColor(wert); } } else if (lang == 1) { // only one marker -> return its color return getColor(markers[0].options.value); } return getColor(-1); // only offlines }