pipeVisual.js 3.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /** Display semantics; original industry, diameter, networkLevel and remark remain unchanged. */
  2. export const PIPE_PALETTE = Object.freeze({
  3. GAS: { color:'#ff3b52', label:'燃气' },
  4. WATER_SUPPLY: { color:'#168bff', label:'供水' },
  5. SEWAGE: { color:'#29e36c', label:'污水' },
  6. RAINWATER: { color:'#00e5ff', label:'雨水' },
  7. MANHOLE: { color:'#b36bff', label:'窨井' },
  8. DRAINAGE_UNKNOWN: { color:'#aab7c4', label:'排水(雨污等级未识别)' },
  9. UNKNOWN: { color:'#aab7c4', label:'未分类' },
  10. })
  11. export const PIPE_DISPLAY = Object.freeze({ diameterScale:8, minDiameterM:0, maxDiameterM:Infinity, guideFromM:600, guideWidthPx:4 })
  12. export const PIPE_VIRTUAL_DEPTH_M = Object.freeze({ GAS:1.5, WATER_SUPPLY:4, SEWAGE:8, RAINWATER:10, DRAINAGE_UNKNOWN:8 })
  13. /**
  14. * 管线颜色图例(票 48):地图实际会画出的**全部**颜色桶的展示顺序。
  15. *
  16. * 维护者点名五个(GAS/WATER_SUPPLY/SEWAGE/RAINWATER/MANHOLE);`pipeColorKey()` 对
  17. * 雨污等级未识别的排水管与脏行业码还会给出 DRAINAGE_UNKNOWN / UNKNOWN 两桶,
  18. * 地图上真的会画出这两种灰(见 `pipeColorKey` 的兜底分支)——按「图例必须覆盖
  19. * 地图实际会画出的颜色」判据一并列出,用户看到灰线时含义可直接查到,不静默丢桶。
  20. * 顺序表必须与 `PIPE_PALETTE` 的键集合一致(闸门 t48 锁定):调色板加桶而这里没跟上是缺陷。
  21. */
  22. export const PIPE_LEGEND_ORDER = Object.freeze(['GAS','WATER_SUPPLY','SEWAGE','RAINWATER','MANHOLE','DRAINAGE_UNKNOWN','UNKNOWN'])
  23. /** 图例行:色值与词条**引用 `PIPE_PALETTE` 本体**(同一对象),图例与地图逐字节同源,不另抄十六进制。 */
  24. export function pipeLegendEntries() {
  25. return PIPE_LEGEND_ORDER.map((key) => ({ key, color: PIPE_PALETTE[key].color, label: PIPE_PALETTE[key].label }))
  26. }
  27. /**
  28. * 按颜色桶计数(票 48 图例的计数来源)。
  29. *
  30. * `network` 形状不完整(还没取数 / 取数失败)→ `{ available:false }`,调用方**不得画 0**——
  31. * 「后端没给」与「确实是 0」是两件事(票 05 的纪律);计数 0 是真实值(该桶确实没有对象),照常显示。
  32. * @param {{pipes?:Array, components?:Array}} [network] `domain/pipeNetwork.js` 的图层形状
  33. * @returns {{available: boolean, byKey: object}} `byKey` 只含 `PIPE_LEGEND_ORDER` 的键
  34. */
  35. export function pipeColorCounts(network) {
  36. const pipes = network && Array.isArray(network.pipes) ? network.pipes : null
  37. const components = network && Array.isArray(network.components) ? network.components : null
  38. if (!pipes || !components) return { available: false, byKey: {} }
  39. const byKey = {}
  40. for (const key of PIPE_LEGEND_ORDER) byKey[key] = 0
  41. for (const row of pipes) {
  42. const key = pipeColorKey(row)
  43. if (Object.prototype.hasOwnProperty.call(byKey, key)) byKey[key] += 1
  44. }
  45. for (const row of components) {
  46. const key = pipeColorKey(row)
  47. if (Object.prototype.hasOwnProperty.call(byKey, key)) byKey[key] += 1
  48. }
  49. return { available: true, byKey }
  50. }
  51. export function pipeVirtualDepthM(colorKey) {
  52. return PIPE_VIRTUAL_DEPTH_M[colorKey] ?? 2
  53. }
  54. export function pipeColorKey(row) {
  55. if (row.industry !== 'DRAINAGE') return ['GAS','WATER_SUPPLY','MANHOLE'].includes(row.industry) ? row.industry : 'UNKNOWN'
  56. const raw = row.networkLevel
  57. const level = raw == null || (typeof raw === 'string' && raw.trim() === '') ? '0'
  58. : typeof raw === 'number' || typeof raw === 'string' ? String(raw).trim() : ''
  59. if (level === '0') return 'SEWAGE'
  60. if (level === '1') return 'RAINWATER'
  61. return 'DRAINAGE_UNKNOWN'
  62. }
  63. /** Source metres stay unchanged; 8x transverse display makes underground pipes readable. */
  64. export function displayPipeDiameter(diameterM) {
  65. return Number.isFinite(diameterM) && diameterM > 0 ? diameterM * PIPE_DISPLAY.diameterScale : null
  66. }