Spaces:
Sleeping
Sleeping
Update script.js
Browse files
script.js
CHANGED
|
@@ -547,51 +547,6 @@ function setupPredictionMode(map) {
|
|
| 547 |
}
|
| 548 |
}
|
| 549 |
|
| 550 |
-
// === 新增:绘制 AI 模型的 3x3 空间感知网格 ===
|
| 551 |
-
// function updatePredictionGrid(map, centerLng, centerLat) {
|
| 552 |
-
// const features = [];
|
| 553 |
-
// const step = 0.002; // 与后端 Python 的 offset = 0.002 对齐
|
| 554 |
-
// const gridSize = 3;
|
| 555 |
-
// const offset = Math.floor(gridSize / 2);
|
| 556 |
-
|
| 557 |
-
// for (let i = 0; i < gridSize; i++) {
|
| 558 |
-
// for (let j = 0; j < gridSize; j++) {
|
| 559 |
-
// // 精确还原 Python 中切片的中心坐标
|
| 560 |
-
// const cLng = centerLng + (j - offset) * step;
|
| 561 |
-
// const cLat = centerLat - (i - offset) * step;
|
| 562 |
-
// const w = step / 2;
|
| 563 |
-
|
| 564 |
-
// features.push({
|
| 565 |
-
// 'type': 'Feature',
|
| 566 |
-
// 'geometry': {
|
| 567 |
-
// 'type': 'Polygon',
|
| 568 |
-
// 'coordinates': [[
|
| 569 |
-
// [cLng - w, cLat - w], [cLng + w, cLat - w],
|
| 570 |
-
// [cLng + w, cLat + w], [cLng - w, cLat + w],
|
| 571 |
-
// [cLng - w, cLat - w]
|
| 572 |
-
// ]]
|
| 573 |
-
// }
|
| 574 |
-
// });
|
| 575 |
-
// }
|
| 576 |
-
// }
|
| 577 |
-
|
| 578 |
-
// const geojson = { 'type': 'FeatureCollection', 'features': features };
|
| 579 |
-
|
| 580 |
-
// if (map.getSource('pred-grid-source')) {
|
| 581 |
-
// map.getSource('pred-grid-source').setData(geojson);
|
| 582 |
-
// } else {
|
| 583 |
-
// map.addSource('pred-grid-source', { type: 'geojson', data: geojson });
|
| 584 |
-
// map.addLayer({
|
| 585 |
-
// 'id': 'pred-grid-fill', 'type': 'fill', 'source': 'pred-grid-source',
|
| 586 |
-
// 'paint': { 'fill-color': '#f39c12', 'fill-opacity': 0.1 }
|
| 587 |
-
// });
|
| 588 |
-
// map.addLayer({
|
| 589 |
-
// 'id': 'pred-grid-line', 'type': 'line', 'source': 'pred-grid-source',
|
| 590 |
-
// 'paint': { 'line-color': '#f39c12', 'line-width': 2, 'line-dasharray': [2, 2] }
|
| 591 |
-
// });
|
| 592 |
-
// }
|
| 593 |
-
// }
|
| 594 |
-
|
| 595 |
// Dynamic 3x3 grid matching the 256px satellite patch bounds
|
| 596 |
function updatePredictionGrid(map, centerLng, centerLat) {
|
| 597 |
const features = [];
|
|
@@ -765,7 +720,6 @@ function setupFilterMenu(map, statsColor) {
|
|
| 765 |
const menu = document.getElementById('filter-menu');
|
| 766 |
if (!btn || !menu) return;
|
| 767 |
|
| 768 |
-
// Define stability levels based on Standard Deviation thresholds
|
| 769 |
const levels = [
|
| 770 |
{ label: "Level 5: Highly Unstable", color: "#e84393", filter: ['>=', 'load_std', statsColor.t4] },
|
| 771 |
{ label: "Level 4: Volatile", color: "#fd79a8", filter: ['all', ['>=', 'load_std', statsColor.t3], ['<', 'load_std', statsColor.t4]] },
|
|
@@ -775,24 +729,38 @@ function setupFilterMenu(map, statsColor) {
|
|
| 775 |
];
|
| 776 |
|
| 777 |
menu.innerHTML = '';
|
| 778 |
-
levels.forEach((lvl) => {
|
| 779 |
const item = document.createElement('div');
|
| 780 |
item.className = 'filter-item';
|
| 781 |
item.innerHTML = `<div class="color-box" style="background:${lvl.color}; box-shadow: 0 0 5px ${lvl.color};"></div><span>${lvl.label}</span>`;
|
|
|
|
|
|
|
| 782 |
item.onclick = (e) => {
|
| 783 |
e.stopPropagation();
|
| 784 |
-
|
| 785 |
-
|
| 786 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 787 |
} else {
|
| 788 |
-
|
| 789 |
-
|
| 790 |
-
applyFilter(map, lvl.filter);
|
| 791 |
}
|
| 792 |
};
|
| 793 |
menu.appendChild(item);
|
| 794 |
});
|
| 795 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 796 |
// Toggle menu visibility
|
| 797 |
btn.onclick = (e) => { e.stopPropagation(); menu.classList.toggle('active'); };
|
| 798 |
document.addEventListener('click', (e) => { if (!menu.contains(e.target) && !btn.contains(e.target)) menu.classList.remove('active'); });
|
|
|
|
| 547 |
}
|
| 548 |
}
|
| 549 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 550 |
// Dynamic 3x3 grid matching the 256px satellite patch bounds
|
| 551 |
function updatePredictionGrid(map, centerLng, centerLat) {
|
| 552 |
const features = [];
|
|
|
|
| 720 |
const menu = document.getElementById('filter-menu');
|
| 721 |
if (!btn || !menu) return;
|
| 722 |
|
|
|
|
| 723 |
const levels = [
|
| 724 |
{ label: "Level 5: Highly Unstable", color: "#e84393", filter: ['>=', 'load_std', statsColor.t4] },
|
| 725 |
{ label: "Level 4: Volatile", color: "#fd79a8", filter: ['all', ['>=', 'load_std', statsColor.t3], ['<', 'load_std', statsColor.t4]] },
|
|
|
|
| 729 |
];
|
| 730 |
|
| 731 |
menu.innerHTML = '';
|
| 732 |
+
levels.forEach((lvl, index) => {
|
| 733 |
const item = document.createElement('div');
|
| 734 |
item.className = 'filter-item';
|
| 735 |
item.innerHTML = `<div class="color-box" style="background:${lvl.color}; box-shadow: 0 0 5px ${lvl.color};"></div><span>${lvl.label}</span>`;
|
| 736 |
+
|
| 737 |
+
// Muti Select
|
| 738 |
item.onclick = (e) => {
|
| 739 |
e.stopPropagation();
|
| 740 |
+
item.classList.toggle('selected');
|
| 741 |
+
const activeFilters = [];
|
| 742 |
+
const allItems = menu.querySelectorAll('.filter-item');
|
| 743 |
+
allItems.forEach((el, i) => {
|
| 744 |
+
if (el.classList.contains('selected')) {
|
| 745 |
+
activeFilters.push(levels[i].filter);
|
| 746 |
+
}
|
| 747 |
+
});
|
| 748 |
+
if (activeFilters.length === 0) {
|
| 749 |
+
applyFilter(map, null);
|
| 750 |
} else {
|
| 751 |
+
const combinedFilter = ['any', ...activeFilters];
|
| 752 |
+
applyFilter(map, combinedFilter);
|
|
|
|
| 753 |
}
|
| 754 |
};
|
| 755 |
menu.appendChild(item);
|
| 756 |
});
|
| 757 |
|
| 758 |
+
btn.onclick = (e) => { e.stopPropagation(); menu.classList.toggle('active'); };
|
| 759 |
+
document.addEventListener('click', (e) => {
|
| 760 |
+
if (!menu.contains(e.target) && !btn.contains(e.target)) menu.classList.remove('active');
|
| 761 |
+
});
|
| 762 |
+
}
|
| 763 |
+
|
| 764 |
// Toggle menu visibility
|
| 765 |
btn.onclick = (e) => { e.stopPropagation(); menu.classList.toggle('active'); };
|
| 766 |
document.addEventListener('click', (e) => { if (!menu.contains(e.target) && !btn.contains(e.target)) menu.classList.remove('active'); });
|