feat: 新增8km范围识别
This commit is contained in:
parent
9604c62f4c
commit
504e39f0a5
@ -121,6 +121,7 @@
|
|||||||
}
|
}
|
||||||
maybeCalcSector();
|
maybeCalcSector();
|
||||||
maybePlotSquare();
|
maybePlotSquare();
|
||||||
|
maybeCalcNearbyRain();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadTileAt(z, y, x, dtStr) {
|
async function loadTileAt(z, y, x, dtStr) {
|
||||||
@ -146,6 +147,7 @@
|
|||||||
}
|
}
|
||||||
maybeCalcSector();
|
maybeCalcSector();
|
||||||
maybePlotSquare();
|
maybePlotSquare();
|
||||||
|
maybeCalcNearbyRain();
|
||||||
}
|
}
|
||||||
|
|
||||||
function fmtDTLocal(dt){
|
function fmtDTLocal(dt){
|
||||||
@ -272,6 +274,12 @@
|
|||||||
xsFan.push(gStLon); ysFan.push(gStLat);
|
xsFan.push(gStLon); ysFan.push(gStLat);
|
||||||
data.push({ type:'scatter', mode:'lines', x:xsFan, y:ysFan, line:{ color:'#FFFFFF', width:2, dash:'dash' }, fill:'toself', fillcolor:'rgba(255,255,255,0.18)', hoverinfo:'skip', showlegend:false });
|
data.push({ type:'scatter', mode:'lines', x:xsFan, y:ysFan, line:{ color:'#FFFFFF', width:2, dash:'dash' }, fill:'toself', fillcolor:'rgba(255,255,255,0.18)', hoverinfo:'skip', showlegend:false });
|
||||||
}
|
}
|
||||||
|
// 叠加附近5km圆
|
||||||
|
if (gStLat !== null && gStLon !== null) {
|
||||||
|
const Rm = 8000; const samples=128; const xsC=[], ysC=[];
|
||||||
|
for(let i=0;i<=samples;i++){ const θ=i*(360/samples); const p=destPoint(gStLat,gStLon,θ,Rm); xsC.push(p.lon); ysC.push(p.lat); }
|
||||||
|
data.push({ type:'scatter', mode:'lines', x:xsC, y:ysC, line:{ color:'#66CC66', width:1, dash:'dot' }, hoverinfo:'skip', showlegend:false });
|
||||||
|
}
|
||||||
Plotly.newPlot('tile_plot', data, {
|
Plotly.newPlot('tile_plot', data, {
|
||||||
margin:{l:36,r:8,t:8,b:90},
|
margin:{l:36,r:8,t:8,b:90},
|
||||||
xaxis:{title:{text:'经度', standoff: 12}, tickformat:'.2f', constrain:'domain', automargin:true},
|
xaxis:{title:{text:'经度', standoff: 12}, tickformat:'.2f', constrain:'domain', automargin:true},
|
||||||
@ -366,6 +374,12 @@
|
|||||||
xsFan.push(gStLon); ysFan.push(gStLat);
|
xsFan.push(gStLon); ysFan.push(gStLat);
|
||||||
data.push({ type:'scatter', mode:'lines', x:xsFan, y:ysFan, line:{color:'#FFFFFF',width:2,dash:'dash'}, fill:'toself', fillcolor:'rgba(255,255,255,0.18)', hoverinfo:'skip', showlegend:false });
|
data.push({ type:'scatter', mode:'lines', x:xsFan, y:ysFan, line:{color:'#FFFFFF',width:2,dash:'dash'}, fill:'toself', fillcolor:'rgba(255,255,255,0.18)', hoverinfo:'skip', showlegend:false });
|
||||||
}
|
}
|
||||||
|
// 叠加附近5km圆
|
||||||
|
{
|
||||||
|
const Rm = 8000; const samples=128; const xsC=[], ysC=[];
|
||||||
|
for(let i=0;i<=samples;i++){ const θ=i*(360/samples); const p=destPoint(gStLat,gStLon,θ,Rm); xsC.push(p.lon); ysC.push(p.lat); }
|
||||||
|
data.push({ type:'scatter', mode:'lines', x:xsC, y:ysC, line:{ color:'#66CC66', width:1, dash:'dot' }, hoverinfo:'skip', showlegend:false });
|
||||||
|
}
|
||||||
const el=document.getElementById('squarePlot');
|
const el=document.getElementById('squarePlot');
|
||||||
const layout={ autosize:true, margin:{l:40,r:8,t:8,b:90},
|
const layout={ autosize:true, margin:{l:40,r:8,t:8,b:90},
|
||||||
xaxis:{title:'经度', tickformat:'.2f', zeroline:false, constrain:'domain', automargin:true, range:[lonMin, lonMax]},
|
xaxis:{title:'经度', tickformat:'.2f', zeroline:false, constrain:'domain', automargin:true, range:[lonMin, lonMax]},
|
||||||
@ -376,6 +390,26 @@
|
|||||||
}catch(e){ document.getElementById('squarePlot').innerHTML=`<div class=\"p-3 text-sm text-red-600 bg-red-50 border border-red-200 rounded\">正方形热力图渲染失败:${e.message}</div>`; }
|
}catch(e){ document.getElementById('squarePlot').innerHTML=`<div class=\"p-3 text-sm text-red-600 bg-red-50 border border-red-200 rounded\">正方形热力图渲染失败:${e.message}</div>`; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function maybeCalcNearbyRain(){
|
||||||
|
try{
|
||||||
|
const el = document.getElementById('nearbyStatus'); if(!el) return;
|
||||||
|
if(!gTileValues || !gXs || !gYs || gStLat===null || gStLon===null){ el.textContent=''; return; }
|
||||||
|
const radiusM = 8000; // 8km
|
||||||
|
const h=gTileValues.length, w=gTileValues[0].length;
|
||||||
|
let hit=false, maxDBZ=null;
|
||||||
|
for(let r=0;r<h && !hit;r++){
|
||||||
|
const lat=gYs[r];
|
||||||
|
for(let c=0;c<w;c++){
|
||||||
|
const val=gTileValues[r][c]; if(val==null) continue; const dbz=Number(val); if(!(dbz>=40)) continue;
|
||||||
|
const lon=gXs[c]; const dist=haversine(gStLat,gStLon,lat,lon);
|
||||||
|
if(dist <= radiusM){ hit=true; maxDBZ = maxDBZ==null?dbz:Math.max(maxDBZ, dbz); break; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(hit){ el.textContent = `附近8km可能有降雨(≥40 dBZ)`; el.classList.remove('text-gray-700'); el.classList.add('text-red-700'); }
|
||||||
|
else { el.textContent = `附近8km未检测到≥40 dBZ 回波`; el.classList.remove('text-red-700'); el.classList.add('text-gray-700'); }
|
||||||
|
}catch(e){ /* ignore */ }
|
||||||
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
await loadStations();
|
await loadStations();
|
||||||
// 初始化时间范围为最近24小时
|
// 初始化时间范围为最近24小时
|
||||||
@ -524,6 +558,7 @@
|
|||||||
最近距离:<span id="sectorDist"></span> km;预计到达时间:<span id="sectorETA"></span><br>
|
最近距离:<span id="sectorDist"></span> km;预计到达时间:<span id="sectorETA"></span><br>
|
||||||
位置:lat=<span id="sectorLat"></span>,lon=<span id="sectorLon"></span> 组合反射率:<span id="sectorDBZ"></span> dBZ
|
位置:lat=<span id="sectorLat"></span>,lon=<span id="sectorLon"></span> 组合反射率:<span id="sectorDBZ"></span> dBZ
|
||||||
</div>
|
</div>
|
||||||
|
<div id="nearbyStatus" class="mt-1 text-gray-700"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user