080a5dad1c
Fehlermeldungen pro TAB getrennt
236 lines
9.1 KiB
JavaScript
236 lines
9.1 KiB
JavaScript
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: '<b>' + cluster.getChildCount() + '</b>' });
|
|
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 = '<svg xmlns="http://www.w3.org/2000/svg" width="600" height="600">' +
|
|
'<circle cx="300" cy="300" r="300" fill="' + color + '"/>' +
|
|
'<circle cx="300" cy="300" r="50"/>' +
|
|
'<path stroke="#000" stroke-width="175" fill="none" stroke-dasharray="171.74" d="M382,158a164,164 0 1,1-164,0"/>';
|
|
if (n !== undefined) {
|
|
icon +=
|
|
'<text id="marker_text" x="' + x + '" y="400" font-size="1500%" font-family="Verdana,Lucida Sans Unicode,sans-serif" fill="white">' + n + '</text>';
|
|
}
|
|
icon += '</svg>';
|
|
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 = `
|
|
<tr><td colspan="2"><span style="color:red;">${txts.offline}</span></td></tr>
|
|
<tr><td>${txts.lastseen}:</td><td>${item.lastseen}</td></tr>`
|
|
|
|
let normaltext = `
|
|
<tr></tr><tr><td>cpm:</td><td>${item.value}</td></tr>
|
|
<tr></tr><tr><td>µSvph:</td><td>${item.mSvph}</td></tr>`
|
|
let popuptext = `
|
|
<div id="infoTitle">
|
|
<h4>${txts.sensor}: ${item.name}</h4>
|
|
<div class="addr">${addr}</div>
|
|
<div id="infoTable">
|
|
<table>
|
|
<tr><td colspan="2"><span style="color:limegreen;">${item.indoor==1 ? "indoor" : ""}</span></td></tr>
|
|
${item.value < 0 ? offlinetext : normaltext}
|
|
</table>
|
|
<div id="infoBtn">
|
|
<a href="#" class="speciallink">${txts.showchart}</a>
|
|
</div>
|
|
</div>
|
|
</div>`
|
|
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}<br />${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, utils.ttIndex.live)
|
|
if (ok) {
|
|
let triggerEl = document.querySelector(`#livetab`)
|
|
bootstrap.Tab.getInstance(triggerEl).show() // Select tab by name
|
|
utils.setCurrentTab('livetab')
|
|
params.center.coords = [e.latlng.lat, e.latlng.lng]
|
|
mpp.map.setView([e.latlng.lat, e.latlng.lng]);
|
|
ev.preventDefault()
|
|
await loadAll(params)
|
|
}
|
|
})
|
|
}
|