mirror of
https://github.com/Roslund/sthlm-mesh.git
synced 2026-03-28 17:43:02 +01:00
147 lines
5.1 KiB
JavaScript
147 lines
5.1 KiB
JavaScript
function getPositionPrecisionInMeters(positionPrecision) {
|
|
switch(positionPrecision){
|
|
case 2: return 5976446;
|
|
case 3: return 2988223;
|
|
case 4: return 1494111;
|
|
case 5: return 747055;
|
|
case 6: return 373527;
|
|
case 7: return 186763;
|
|
case 8: return 93381;
|
|
case 9: return 46690;
|
|
case 10: return 23345;
|
|
case 11: return 11672; // Android LOW_PRECISION
|
|
case 12: return 5836;
|
|
case 13: return 2918;
|
|
case 14: return 1459;
|
|
case 15: return 729;
|
|
case 16: return 364; // Android MED_PRECISION
|
|
case 17: return 182;
|
|
case 18: return 91;
|
|
case 19: return 45;
|
|
case 20: return 22;
|
|
case 21: return 11;
|
|
case 22: return 5;
|
|
case 23: return 2;
|
|
case 24: return 1;
|
|
case 32: return 0; // Android HIGH_PRECISION
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function getPositionColor(positionPrecision) {
|
|
switch(positionPrecision){
|
|
case 2: return 'rgb(196, 36, 18)';
|
|
case 3: return 'rgb(196, 36, 18)';
|
|
case 4: return 'rgb(196, 36, 18)';
|
|
case 5: return 'rgb(196, 36, 18)';
|
|
case 6: return 'rgb(196, 36, 18)';
|
|
case 7: return 'rgb(196, 36, 18)';
|
|
case 8: return 'rgb(196, 36, 18)';
|
|
case 9: return 'rgb(196, 36, 18)';
|
|
case 10: return 'rgb(196, 36, 18)';
|
|
case 11: return 'rgb(196, 36, 18)'; // Android LOW_PRECISION
|
|
case 12: return 'rgb(196, 36, 18)';
|
|
case 13: return 'rgb(212, 74, 58)'; // Default +/- 3km
|
|
case 14: return 'rgb(242, 161, 67)';
|
|
case 15: return 'rgb(229, 189, 82)';
|
|
case 16: return 'rgb(195, 208, 98)'; // Android MED_PRECISION
|
|
case 17: return 'rgb(157, 195, 91)'; //182
|
|
case 18: return 'rgb(118, 182, 84)';
|
|
case 19: return 'rgb(79, 170, 77)'; //45
|
|
case 20: return 'rgb(41, 156, 70)';
|
|
case 21: return 'rgb(41, 156, 70)';
|
|
case 22: return 'rgb(41, 156, 70)';
|
|
case 23: return 'rgb(41, 156, 70)';
|
|
case 24: return 'rgb(41, 156, 70)';
|
|
case 32: return 'rgb(41, 156, 70)'; // Android HIGH_PRECISION
|
|
}
|
|
return 'rgb(200, 200, 200)';
|
|
}
|
|
|
|
function formatPositionPrecision(positionPrecision) {
|
|
|
|
// get position precision in meters
|
|
const positionPrecisionInMeters = getPositionPrecisionInMeters(positionPrecision);
|
|
if(positionPrecisionInMeters == null){
|
|
return "?";
|
|
}
|
|
|
|
// format kilometers
|
|
if(positionPrecisionInMeters > 1000){
|
|
const positionPrecisionInKilometers = Math.ceil(positionPrecisionInMeters / 1000);
|
|
return `±${positionPrecisionInKilometers}km`;
|
|
}
|
|
|
|
// format meters
|
|
return `±${positionPrecisionInMeters}m`;
|
|
|
|
}
|
|
|
|
async function positionPrecisionGraph() {
|
|
const canvas = document.getElementById('positionPrecisionChart');
|
|
const ctx = canvas.getContext('2d');
|
|
|
|
// Show "Loading..." message
|
|
ctx.font = '16px Arial';
|
|
ctx.fillStyle = 'gray';
|
|
ctx.textAlign = 'center';
|
|
ctx.fillText('Loading data...', canvas.width / 2, canvas.height / 2);
|
|
|
|
|
|
try {
|
|
await fetchNodes();
|
|
const countsByPrecision = {};
|
|
|
|
// Filter out nodes without position_precision
|
|
const nodesWithPoistion = nodes.filter(node => node.position_precision != null);
|
|
|
|
// Count how many nodes fall into each precision value
|
|
for (const node of nodesWithPoistion) {
|
|
const precision = node.position_precision
|
|
countsByPrecision[precision] = (countsByPrecision[precision] || 0) + 1;
|
|
}
|
|
|
|
// Convert to array of { precision, count }
|
|
const statsArray = Object.entries(countsByPrecision).map(([precision, count]) => ({
|
|
precision: parseInt(precision, 10),
|
|
count
|
|
}));
|
|
|
|
// Sort by precision descending
|
|
const sorted = statsArray.sort((a, b) => b.precision - a.precision);
|
|
const labels = sorted.map(entry => formatPositionPrecision(entry.precision));
|
|
const counts = sorted.map(entry => entry.count);
|
|
const backgroundColors = sorted.map(entry => getPositionColor(entry.precision));
|
|
|
|
const chartContainer = document.getElementById('positionPrecisionContainer');
|
|
chartContainer.style.height = `${labels.length * 35 + 50}px`;
|
|
|
|
new Chart(ctx, {
|
|
type: 'bar',
|
|
data: {
|
|
labels: labels,
|
|
datasets: [{
|
|
label: 'Position Precision',
|
|
data: counts,
|
|
backgroundColor: backgroundColors,
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
barPercentage: 0.8,
|
|
indexAxis: 'y',
|
|
y: { ticks: { autoSkip: false, font: { size: 12 } } },
|
|
plugins: { legend: { display: false } }
|
|
}
|
|
});
|
|
} catch(error) {
|
|
console.error('Error fetching data:', error);
|
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
ctx.fillStyle = 'red';
|
|
ctx.fillText('Error loading data', canvas.width / 2, canvas.height / 2);
|
|
}
|
|
}
|
|
|
|
|
|
positionPrecisionGraph(); |