|
@@ -61,15 +61,31 @@ async function groupsFor(viewer, plan, heights, alive) {
|
|
|
if(!heights.has(key)) needed.set(key,point)
|
|
if(!heights.has(key)) needed.set(key,point)
|
|
|
}
|
|
}
|
|
|
const entries=[...needed]
|
|
const entries=[...needed]
|
|
|
- for(let i=0;i<entries.length;i+=512) {
|
|
|
|
|
- if(!alive()) return []
|
|
|
|
|
- const chunk=entries.slice(i,i+512)
|
|
|
|
|
- try {
|
|
|
|
|
- const values=await sampleTerrainMostDetailed(viewer.terrainProvider,chunk.map(([,p])=>Cartographic.fromDegrees(p[0],p[1])))
|
|
|
|
|
- if(!alive()) return []
|
|
|
|
|
- for(let j=0;j<chunk.length;j+=1) if(Number.isFinite(values[j]?.height)) heights.set(chunk[j][0],values[j].height)
|
|
|
|
|
- } catch { /* No invented ground elevation: retain fallback. */ }
|
|
|
|
|
|
|
+ const chunks=[]
|
|
|
|
|
+ for(let i=0;i<entries.length;i+=512) chunks.push(entries.slice(i,i+512))
|
|
|
|
|
+ // 有限并发(最多 3 批在飞)。批大小仍是 512 点 —— 单批请求规模不变,只是把批与批之间
|
|
|
|
|
+ // 从"串行等待"改成"最多 3 批并行",所以峰值由 Cesium 的 RequestScheduler 兜底、不会翻倍。
|
|
|
|
|
+ //
|
|
|
|
|
+ // 为什么需要:票 60 之后地面视图不再预先采样地形(那本是被否掉的浪费),于是这一轮采样
|
|
|
|
|
+ // 落在**切到管线视图的关键路径**上 —— 串行等待表现为"切过去要等很久才出现模型"。
|
|
|
|
|
+ // 落地顺序与结果都没变(heights 只是缓存,谁先写谁后写不影响取值),只是等待时间变短。
|
|
|
|
|
+ const TERRAIN_CHUNK_CONCURRENCY=3
|
|
|
|
|
+ let cursor=0
|
|
|
|
|
+ const sampleChunk=async()=>{
|
|
|
|
|
+ while(alive()) {
|
|
|
|
|
+ const index=cursor
|
|
|
|
|
+ cursor+=1
|
|
|
|
|
+ if(index>=chunks.length) return
|
|
|
|
|
+ const chunk=chunks[index]
|
|
|
|
|
+ try {
|
|
|
|
|
+ const values=await sampleTerrainMostDetailed(viewer.terrainProvider,chunk.map(([,p])=>Cartographic.fromDegrees(p[0],p[1])))
|
|
|
|
|
+ if(!alive()) return
|
|
|
|
|
+ for(let j=0;j<chunk.length;j+=1) if(Number.isFinite(values[j]?.height)) heights.set(chunk[j][0],values[j].height)
|
|
|
|
|
+ } catch { /* No invented ground elevation: retain fallback. */ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
+ await Promise.all(Array.from({length:Math.min(TERRAIN_CHUNK_CONCURRENCY,chunks.length)},sampleChunk))
|
|
|
|
|
+ if(!alive()) return []
|
|
|
const world=(p,depthM=2)=>{
|
|
const world=(p,depthM=2)=>{
|
|
|
const height=heights.get(keyOf(p))
|
|
const height=heights.get(keyOf(p))
|
|
|
return Number.isFinite(height)?Cartesian3.fromDegrees(p[0],p[1],height-depthM):null
|
|
return Number.isFinite(height)?Cartesian3.fromDegrees(p[0],p[1],height-depthM):null
|
|
@@ -107,6 +123,10 @@ export function createCesiumPipeModels(viewer, { source, onChange=()=>{}, base=i
|
|
|
let lastGroups=[], signatures=new Map(), terrainFailed=false, lastTerrainAttempt=0
|
|
let lastGroups=[], signatures=new Map(), terrainFailed=false, lastTerrainAttempt=0
|
|
|
let diameterSummary={reported:0,interpolated:0,missing:0}, visualDefaultCount=0
|
|
let diameterSummary={reported:0,interpolated:0,missing:0}, visualDefaultCount=0
|
|
|
let pipelineView=viewMode==='pipeline'
|
|
let pipelineView=viewMode==='pipeline'
|
|
|
|
|
+ // 最近一次拿到的管网数据。地面视图虽然不建模型,但必须**记住数据**:
|
|
|
|
|
+ // 计划同步(`syncPipeLayerForPlan`)只由计划数组变化触发,切视图模式不会叫它,
|
|
|
|
|
+ // 所以切回管线时只有这里能立刻重建(详见 setViewMode 的说明)。
|
|
|
|
|
+ let lastNetwork=null
|
|
|
const publish=(state)=>{
|
|
const publish=(state)=>{
|
|
|
if(!active) return
|
|
if(!active) return
|
|
|
const covered=new Set(state.covered.filter((id)=>!missing.has(id)))
|
|
const covered=new Set(state.covered.filter((id)=>!missing.has(id)))
|
|
@@ -159,6 +179,7 @@ export function createCesiumPipeModels(viewer, { source, onChange=()=>{}, base=i
|
|
|
})
|
|
})
|
|
|
function sync(network) {
|
|
function sync(network) {
|
|
|
if (!active || viewer.isDestroyed()) return Promise.resolve()
|
|
if (!active || viewer.isDestroyed()) return Promise.resolve()
|
|
|
|
|
+ lastNetwork = network
|
|
|
// 维护者要求(第 352 轮):**地面视图不建任何管线 3D 模型**,只保留地图上的走向线。
|
|
// 维护者要求(第 352 轮):**地面视图不建任何管线 3D 模型**,只保留地图上的走向线。
|
|
|
// 原实现即使 `ground` 也照样采样地形、拼 GLTF、上传 GPU 模型 —— 那是纯浪费:
|
|
// 原实现即使 `ground` 也照样采样地形、拼 GLTF、上传 GPU 模型 —— 那是纯浪费:
|
|
|
// 地面视图下这些模型本来就被 `show=false` 隐藏,等于白花 CPU/GPU/内存。
|
|
// 地面视图下这些模型本来就被 `show=false` 隐藏,等于白花 CPU/GPU/内存。
|
|
@@ -229,6 +250,14 @@ export function createCesiumPipeModels(viewer, { source, onChange=()=>{}, base=i
|
|
|
batches.clear()
|
|
batches.clear()
|
|
|
}
|
|
}
|
|
|
publish(batches.state())
|
|
publish(batches.state())
|
|
|
|
|
+ // 切回管线视图必须**自己重建**,不能等下一次计划同步。
|
|
|
|
|
+ // 缺陷复盘(维护者 2026-10-27 现场反馈):地面期已把批次清空,而计划同步只由
|
|
|
|
|
+ // MapCanvas 的 watch(依赖 markers/byStatus/pipelines/facilities,**不看 viewMode**)
|
|
|
|
|
+ // 触发 —— 切视图模式根本叫不动它。旧实现里地面视图"顺手"把模型建好了,
|
|
|
|
|
+ // 所以切过去立刻能看见;票 60 把地面建模去掉后这条顺带路径消失,现象变成:
|
|
|
|
|
+ // 切到管线视图仍只显示地面视图的 2D 走向线,3D 模型要等下一次翻页/30s tick
|
|
|
|
|
+ // 才可能出现,甚至一直不出现。
|
|
|
|
|
+ if (pipelineView && lastNetwork) void sync(lastNetwork)
|
|
|
}
|
|
}
|
|
|
return {sync,setViewMode,destroy,state:batches.state}
|
|
return {sync,setViewMode,destroy,state:batches.state}
|
|
|
}
|
|
}
|