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' const colorscale = ['#d73027','#fc8d59','#fee08b','#ffffbf','#d9ef8b','#91cf60','#1a9850', '#808080']; const grades = [ 10, 5, 2, 1, 0.5, 0.2, 0.1, -999]; const cpms = [1482, 741, 296, 148, 74, 30, 15, -999]; const sv_factor = {'SBM-20': 1 / 2.47, 'SBM-19': 1 / 9.81888, 'Si22G': 0.081438}; let showOnlySi22G = false; export function getColor(d) { let erg = d3.scaleLinear() .domain([0.05, 0.1, 0.2, 0.5, 5]) .range(["#267A45", "#66FA5F", "#F8Fc00","#FF0000","#9000FF"]) .clamp(true); return d < -1 ? '#9ECDEA' : d==-1 ? '#7F7F7F' : d==0 ? '#333333' : erg(d); } /****************************************************** * buildMarkers * * fetch data for MArkers from 'mapdata' and create * all the markers, that are visibile within bounds * and plot them on the map. * Use the ClusterGroup-Library to cluster the markers * * params: * bounds find markers within this bounds * return: * all markers plotted on map *******************************************************/ export async function buildMarkers(params, mpp) { const url = mpp.APIURL + `type=radioactivity&box=${mpp.bounds.toBBoxString()}` let sensors = await utils.fetchfromserver(url) if (!sensors.err) { // if (markersAll) { // mpp.map.removeLayer(markersAll); // } let markers = L.markerClusterGroup({ spiderfyOnMaxZoom: true, showCoverageOnHover: false, zoomToBoundsOnClick: true, // disableClusteringAtZoom: 14, iconCreateFunction: function (cluster) { let mymarkers = cluster.getAllChildMarkers(); let color = getMedian(mymarkers); // calc median of markers in cluster and use that color // return L.divIcon({ html: '' + cluster.getChildCount() + '' }); return new L.Icon({ iconUrl: buildIcon(color, cluster.getChildCount()), iconSize: [35, 35] }); } }); for (let x of sensors.values) { if (x.location == undefined) { // if there is no location defined ... continue; // ... skip this sensor } // otherwise create marker if ((x.name != "Radiation Si22G") && showOnlySi22G) { continue; } if ((params.weeks > 0) && (x.weeks > params.weeks)) { continue } let uSvph = x.value < 0 ? -1 : x.value / 60 * sv_factor[x.name.slice(10)]; let curcolor = getColor(uSvph > 0 ? x.indoor ? -2 : uSvph : uSvph); let marker = L.marker([x.location[1], x.location[0]], { name: x.id, icon: new L.Icon({ iconUrl: buildIcon(curcolor), iconSize: [35, 35] }), value: x.value, mSvph: uSvph, url: '/' + x.id, rohr: x.name.slice(10), indoor: x.indoor, lastseen: dt.formatISODate(x.lastseen) }) .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) } } /* let pos = map.latLngToLayerPoint(marker.getLatLng()).round(); marker.setZIndexOffset(100 - pos.y); // if clicked on the marker fill popup with address and click function marker.on('click', async function () { let addr = await holAddress(marker); marker.setPopupContent((getPopUp(marker,addr))); $('#btnshwgrafic').click(() => { map.closePopup(); // if(window.matchMedia("(orientation:portrait").matches) { // showError(5,"goto Landscape") // } else { showGrafik(clickedSensor); // } }); }); marker.bindPopup(`Loading adresse data`); // and bind the popup text if (marker.options.value != -2) { markersAll.addLayer(marker); } else { console.log(`Too old Sensor: ${marker.options.name}`); } } mpp.map.addLayer(markersAll); } */ 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 !== undefined) { icon += '' + n + ''; } icon += ''; return encodeURI("data:image/svg+xml," + icon).replace(new RegExp('#', 'g'), '%23'); } // 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) { markers.sort(function (a, b) { // first sort, the lowest first let y1 = a.options.mSvph; let y2 = b.options.mSvph; if (y1 < y2) { return -1; } if (y2 < y1) { return 1; } return 0; }); // console.log(markers); let i = 0; // now find the 'offlines' (mSvph == -1) for (i = 0; i < markers.length; i++) { if (markers[i].options.mSvph > 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.mSvph); // median is in the middle } else { // evaen -> lang = lang / 2; // median is mean of both middle mSvphs // console.log(lang); let wert = (markers[lang - 1].options.mSvph + markers[lang].options.mSvph) / 2; return getColor(wert); } } else if (lang == 1) { // only one marker -> return its color return getColor(markers[0].options.mSvph); } return getColor(-1); // only offlines } async function bauPopupText(item, txts) { let addr = '' let offlinetext = ` ${txts.offline} ${txts.lastseen}:${item.lastseen}` let normaltext = ` cpm:${item.value} µSvph:${item.mSvph}` 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 let ok = await showChart(params, 'live', 'dlive') if (ok) { let triggerEl = document.querySelector(`#livetab`) bootstrap.Tab.getInstance(triggerEl).show() // Select tab by name utils.setCurrentTab('livetab') params.center = [e.latlng.lat, e.latlng.lng] mpp.map.setView([e.latlng.lat, e.latlng.lng]); ev.preventDefault() await loadAll(params) } }) }