| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- /**
- * 视角预设与进入引导(票 30):纯函数、不 import cesium、不读 DOM。
- *
- * 目的:维护者「完全找不到目标位置,无法判断 DEM 与精细影像是否部署成功」。
- * 给出一个**命名视角**(home)与进入引导,让系统一进来就把镜头带到沅陵县城。
- *
- * 坐标口径:维护者给的 `110.39028164, 28.44367870` 是 **CGCS2000 · 天地图**坐标;
- * CGCS2000 与 WGS-84 在本项目的精度要求下视为一致,直接喂 `Cartesian3.fromDegrees`。
- */
- /** 进入引导的默认文案与时长。 */
- export const INTRO_DEFAULTS = {
- enabled: true,
- title: '点击进入系统',
- subtitle: '',
- /** 星球自转一圈的秒数(0 = 不自转)。 */
- spinSeconds: 48,
- }
- /**
- * 默认「家」视角:沅陵县城上空,俯角 -55°、距离 12 km —— 这个距离下能同时看到
- * 县城轮廓与周边地形起伏(实测 4.6 km 是街区级、12 km 是县域级)。
- */
- export const HOME_DEFAULTS = {
- lon: 110.39028164,
- lat: 28.4436787,
- height: 0,
- heading: 0,
- pitch: -55,
- range: 12000,
- }
- function readCoord(value, fallback) {
- const num = Number(value)
- return Number.isFinite(num) ? num : fallback
- }
- /**
- * 取「家」视角(配置优先,缺项用默认)。
- * @param {object} mapConfig 归一化后的 `config.map`
- */
- export function planHome(mapConfig = {}) {
- const home = (mapConfig && mapConfig.home) || {}
- return {
- lon: readCoord(home.lon, HOME_DEFAULTS.lon),
- lat: readCoord(home.lat, HOME_DEFAULTS.lat),
- height: readCoord(home.height, HOME_DEFAULTS.height),
- heading: readCoord(home.heading, HOME_DEFAULTS.heading),
- pitch: readCoord(home.pitch, HOME_DEFAULTS.pitch),
- range: readCoord(home.range, HOME_DEFAULTS.range),
- label: typeof home.label === 'string' && home.label ? home.label : '目标区域',
- }
- }
- /**
- * 取进入引导配置。
- * @param {object} mapConfig 归一化后的 `config.map`
- */
- export function planIntro(mapConfig = {}) {
- const intro = (mapConfig && mapConfig.intro) || {}
- return {
- enabled: intro.enabled !== false,
- title: typeof intro.title === 'string' && intro.title ? intro.title : INTRO_DEFAULTS.title,
- subtitle: typeof intro.subtitle === 'string' ? intro.subtitle : INTRO_DEFAULTS.subtitle,
- spinSeconds: Math.max(0, readCoord(intro.spinSeconds, INTRO_DEFAULTS.spinSeconds)),
- }
- }
- /** 「归位」按钮与引导文案里用的短标签。 */
- export function homeLabel(home) {
- const current = home || HOME_DEFAULTS
- const lon = Number(current.lon).toFixed(4)
- const lat = Number(current.lat).toFixed(4)
- return `${current.label || '目标区域'}(${lon}, ${lat})`
- }
- /**
- * 视角是否已经落在预设上(容差内)—— 归位按钮据此决定是否禁用/高亮,
- * 走查也用它断言「点一下真的回去了」。
- * @param {object} state `cameraControl.getState()`
- * @param {object} home `planHome()` 的结果
- * @param {object} [tolerance] 各分量容差
- */
- export function isAtHome(state, home, tolerance = { lon: 1e-4, lat: 1e-4, range: 0.02, angle: 0.5 }) {
- if (!state || !state.pivot || !state.hpr) return false
- return (
- Math.abs(state.pivot.lon - home.lon) <= tolerance.lon &&
- Math.abs(state.pivot.lat - home.lat) <= tolerance.lat &&
- // 距离用相对容差(2%):弹簧臂是连续量,绝对容差在不同量级下没意义。
- Math.abs(state.hpr.range - home.range) <= Math.max(1, home.range * tolerance.range) &&
- Math.abs(((state.hpr.heading - home.heading + 540) % 360) - 180) <= tolerance.angle &&
- Math.abs(state.hpr.pitch - home.pitch) <= tolerance.angle
- )
- }
|