@caoguo/maplibre 0.0.3 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/styles.ts","../src/crs/gcj02.ts","../src/crs/cgcs2000.ts","../src/crs/transform.ts","../src/sources/tianditu.ts","../src/sources/addTianditu.ts","../src/offline/storage.ts","../src/offline/protocol.ts","../src/offline/packer.ts","../src/offline/serviceWorker.ts","../src/offline/idbStore.ts","../src/controls/ScaleControl.ts","../src/controls/ThemeSwitcher.ts","../src/shaders/glowGeometry.ts","../src/shaders/CustomLineLayer.ts","../src/lod/lodController.ts","../src/index.ts"],"names":["theme","buildStyle","out","maplibregl","Map"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * 草果地图内置样式。\n *\n * - `caoguoStyle()`:官方矢量主题(caoguo-dark / caoguo-light),\n * 由 @caoguo/theme 生成,底层使用 MapLibre 免费 demo 矢量瓦片,无需 token。\n * - `osmRasterStyle()`:OSM 栅格兜底样式,矢量主题加载失败时使用。\n */\n\nimport type { StyleSpecification } from 'maplibre-gl';\nimport { buildStyle, type ThemeName } from '@caoguo/theme';\n\nexport const WUHAN_CENTER: [number, number] = [114.3055, 30.5928];\nexport const WUHAN_ZOOM = 11;\n\n/** 草果官方矢量主题(默认暗色)。 */\nexport function caoguoStyle(theme: ThemeName = 'caoguo-dark'): StyleSpecification {\n return buildStyle(theme);\n}\n\n/** 暗色 OSM 栅格兜底底图(无需 key)。 */\nexport function osmRasterStyle(): StyleSpecification {\n return {\n version: 8,\n glyphs: 'https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf',\n sources: {\n 'osm-raster': {\n type: 'raster',\n tiles: [\n 'https://a.tile.openstreetmap.org/{z}/{x}/{y}.png',\n 'https://b.tile.openstreetmap.org/{z}/{x}/{y}.png',\n 'https://c.tile.openstreetmap.org/{z}/{x}/{y}.png',\n ],\n tileSize: 256,\n attribution: '© OpenStreetMap contributors',\n },\n },\n layers: [\n {\n id: 'background',\n type: 'background',\n paint: { 'background-color': '#0a0f1e' },\n },\n {\n id: 'osm-raster',\n type: 'raster',\n source: 'osm-raster',\n paint: {\n 'raster-opacity': 0.85,\n 'raster-saturation': -0.6,\n 'raster-brightness-max': 0.7,\n 'raster-contrast': 0.1,\n },\n },\n ],\n };\n}\n","/**\n * WGS84 <-> GCJ-02(火星坐标系)转换。\n *\n * 算法:公开的解析偏移模型(Krasovsky 椭球),与 coordtransform 一致。\n * 全国范围单点误差 < 50m(PRD 验收 F-1.1)。\n * 注意:GCJ-02 -> WGS84 采用 3 次迭代反算,进一步收敛残差。\n */\n\nconst PI = Math.PI;\nconst A = 6378245.0; // 长半轴\nconst EE = 0.00669342162296594323; // 第一偏心率平方\n\nfunction outOfChina(lng: number, lat: number): boolean {\n return lng < 72.004 || lng > 137.8347 || lat < 0.8293 || lat > 55.8271;\n}\n\nfunction transformLat(lng: number, lat: number): number {\n let ret =\n -100.0 +\n 2.0 * lng +\n 3.0 * lat +\n 0.2 * lat * lat +\n 0.1 * lng * lat +\n 0.2 * Math.sqrt(Math.abs(lng));\n ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0;\n ret += ((20.0 * Math.sin(lat * PI) + 40.0 * Math.sin((lat / 3.0) * PI)) * 2.0) / 3.0;\n ret += ((160.0 * Math.sin((lat / 12.0) * PI) + 320 * Math.sin((lat * PI) / 30.0)) * 2.0) / 3.0;\n return ret;\n}\n\nfunction transformLng(lng: number, lat: number): number {\n let ret =\n 300.0 +\n lng +\n 2.0 * lat +\n 0.1 * lng * lng +\n 0.1 * lng * lat +\n 0.1 * Math.sqrt(Math.abs(lng));\n ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0;\n ret += ((20.0 * Math.sin(lng * PI) + 40.0 * Math.sin((lng / 3.0) * PI)) * 2.0) / 3.0;\n ret += ((150.0 * Math.sin((lng / 12.0) * PI) + 300.0 * Math.sin((lng / 30.0) * PI)) * 2.0) / 3.0;\n return ret;\n}\n\n/** WGS84 -> GCJ-02 */\nexport function wgs84ToGcj02(lng: number, lat: number): [number, number] {\n if (outOfChina(lng, lat)) return [lng, lat];\n let dLat = transformLat(lng - 105.0, lat - 35.0);\n let dLng = transformLng(lng - 105.0, lat - 35.0);\n const radLat = (lat / 180.0) * PI;\n let magic = Math.sin(radLat);\n magic = 1 - EE * magic * magic;\n const sqrtMagic = Math.sqrt(magic);\n dLat = (dLat * 180.0) / (((A * (1 - EE)) / (magic * sqrtMagic)) * PI);\n dLng = (dLng * 180.0) / ((A / sqrtMagic) * Math.cos(radLat) * PI);\n return [lng + dLng, lat + dLat];\n}\n\n/** GCJ-02 -> WGS84(3 次迭代反算) */\nexport function gcj02ToWgs84(lng: number, lat: number): [number, number] {\n if (outOfChina(lng, lat)) return [lng, lat];\n let [mlng, mlat] = wgs84ToGcj02(lng, lat);\n let dlng = mlng - lng;\n let dlat = mlat - lat;\n // 一次迭代\n [mlng, mlat] = wgs84ToGcj02(lng - dlng, lat - dlat);\n dlng = mlng - lng;\n dlat = mlat - lat;\n // 二次迭代(收敛)\n [mlng, mlat] = wgs84ToGcj02(lng - dlng, lat - dlat);\n dlng = mlng - lng;\n dlat = mlat - lat;\n return [lng - dlng, lat - dlat];\n}\n\n/** 是否在 GCJ-02 偏移覆盖区(中国境内外判定) */\nexport function isInChina(lng: number, lat: number): boolean {\n return !outOfChina(lng, lat);\n}\n","/**\n * WGS84 <-> CGCS2000 转换。\n *\n * 说明:CGCS2000 与 WGS84 采用近似相同的参考椭球(扁率/长半轴差异极小,\n * 历元差异仅导致 cm~dm 级点位偏移),在 Web Mercator 显示尺度下等价于一致。\n * 因此 Phase 0 默认实现为恒等变换(残差 < 0.5m,满足 PRD 验收 F-1.1)。\n *\n * 测绘级高精度需求:可注入 `GridShiftProvider`(区域 7 参数 / 格网平移),\n * 见 types.ts。本文件保留可扩展入口。\n */\n\nimport type { GridShiftProvider, LngLat } from './types';\n\nlet gridShift: GridShiftProvider | null = null;\n\n/** 注册 CGCS2000 偏移提供方(可选,测绘级) */\nexport function setCgcs2000GridShift(provider: GridShiftProvider | null): void {\n gridShift = provider;\n}\n\n/** WGS84 -> CGCS2000 */\nexport function wgs84ToCgcs2000(lng: number, lat: number): LngLat {\n if (!gridShift) return [lng, lat];\n const [dLng, dLat] = gridShift.shift(lng, lat);\n return [lng + dLng, lat + dLat];\n}\n\n/** CGCS2000 -> WGS84 */\nexport function cgcs2000ToWgs84(lng: number, lat: number): LngLat {\n if (!gridShift) return [lng, lat];\n const [dLng, dLat] = gridShift.shift(lng, lat);\n return [lng - dLng, lat - dLat];\n}\n","/**\n * 坐标系变换组合器(以 WGS84 为枢纽)。\n *\n * 用法:\n * const t = createTransformer('GCJ02', 'WGS84');\n * const [lng, lat] = t.forward(114.30, 30.59); // GCJ-02 业务数据 -> 渲染基准\n */\n\nimport type { Bounds, CRS, LngLat, Transformer } from './types';\nimport { cgcs2000ToWgs84, wgs84ToCgcs2000 } from './cgcs2000';\nimport { gcj02ToWgs84, wgs84ToGcj02 } from './gcj02';\n\n/** 把任意 CRS 的坐标转换到 WGS84 */\nexport function toWgs84(crs: CRS, lng: number, lat: number): LngLat {\n switch (crs) {\n case 'WGS84':\n return [lng, lat];\n case 'GCJ02':\n return gcj02ToWgs84(lng, lat);\n case 'CGCS2000':\n return cgcs2000ToWgs84(lng, lat);\n }\n}\n\n/** 把 WGS84 坐标转换到目标 CRS */\nexport function fromWgs84(crs: CRS, lng: number, lat: number): LngLat {\n switch (crs) {\n case 'WGS84':\n return [lng, lat];\n case 'GCJ02':\n return wgs84ToGcj02(lng, lat);\n case 'CGCS2000':\n return wgs84ToCgcs2000(lng, lat);\n }\n}\n\nexport function createTransformer(from: CRS, to: CRS): Transformer {\n if (from === to) {\n const identity = (lng: number, lat: number): LngLat => [lng, lat];\n return { forward: identity, inverse: identity };\n }\n const forward = (lng: number, lat: number): LngLat => {\n const [wLng, wLat] = toWgs84(from, lng, lat);\n return fromWgs84(to, wLng, wLat);\n };\n const inverse = (lng: number, lat: number): LngLat => {\n const [wLng, wLat] = toWgs84(to, lng, lat);\n return fromWgs84(from, wLng, wLat);\n };\n return { forward, inverse };\n}\n\n/** 单点快捷转换 */\nexport function transformPoint(\n lng: number,\n lat: number,\n from: CRS,\n to: CRS\n): LngLat {\n return createTransformer(from, to).forward(lng, lat);\n}\n\n/** 范围 [w, s, e, n] 转换(取四个角点极值) */\nexport function transformBounds(b: Bounds, from: CRS, to: CRS): Bounds {\n const t = createTransformer(from, to);\n const xs: number[] = [];\n const ys: number[] = [];\n for (const [x, y] of [\n [b[0], b[1]],\n [b[2], b[1]],\n [b[0], b[3]],\n [b[2], b[3]],\n ]) {\n const [nx, ny] = t.forward(x, y);\n xs.push(nx);\n ys.push(ny);\n }\n return [Math.min(...xs), Math.min(...ys), Math.max(...xs), Math.max(...ys)];\n}\n","/**\n * 天地图(Tianditu)WMTS 底图源(F-1.2)。\n *\n * 天地图为国内权威底图,坐标系为 CGCS2000 / Web Mercator(显示尺度等价于 WGS84)。\n * token 必须由调用方在运行时注入,**绝不硬编码**;缺失时抛出明确错误。\n *\n * 文档:https://lbs.tianditu.gov.cn/server/MapService.html\n */\n\nexport type TiandituLayer =\n /** 矢量底图(含道路/注记基础) */\n | 'vec'\n /** 影像底图 */\n | 'img'\n /** 地形底图 */\n | 'ter'\n /** 矢量注记(道路/地名) */\n | 'cva'\n /** 影像注记 */\n | 'cia'\n /** 地形注记 */\n | 'cta'\n /** 矢量注记(英文) */\n | 'eva'\n /** 影像注记(英文) */\n | 'eia'\n /** 地形注记(英文) */\n | 'eta';\n\nexport type TiandituType = 'vector' | 'satellite' | 'terrain';\n\nexport interface TiandituOptions {\n /** 天地图授权 token(必填,运行时注入) */\n token: string;\n /** 语言:中文 cva/cia/cta 或英文 eva/eia/eta */\n lang?: 'zh' | 'en';\n /** 瓦片服务子域,默认 0-7 */\n subdomains?: number[];\n /** 瓦片尺寸,默认 256 */\n tileSize?: number;\n /** 最大层级,默认 18 */\n maxzoom?: number;\n}\n\nconst LAYER_MAP: Record<TiandituType, { base: TiandituLayer; label: TiandituLayer }> = {\n vector: { base: 'vec', label: 'cva' },\n satellite: { base: 'img', label: 'cia' },\n terrain: { base: 'ter', label: 'cta' },\n};\n\nconst LAYER_LABEL_EN: Partial<Record<TiandituLayer, TiandituLayer>> = {\n cva: 'eva',\n cia: 'eia',\n cta: 'eta',\n};\n\n/** 构建单张 WMTS 栅格源的 tiles URL 列表(含子域与 token) */\nexport function tiandituTileUrls(\n layer: TiandituLayer,\n opts: TiandituOptions\n): string[] {\n const sub = opts.subdomains ?? [0, 1, 2, 3, 4, 5, 6, 7];\n const labelLayer = opts.lang === 'en' ? LAYER_LABEL_EN[layer] ?? layer : layer;\n return sub.map(\n (s) =>\n `https://t${s}.tianditu.gov.cn/${labelLayer}_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=${labelLayer}&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${encodeURIComponent(opts.token)}`\n );\n}\n\nexport interface TiandituSourceSpec {\n id: string;\n source: {\n type: 'raster';\n tiles: string[];\n tileSize: number;\n maxzoom: number;\n attribution: string;\n };\n /** 是否注记层(绘制于底图之上) */\n isLabel: boolean;\n}\n\n/** 生成一组天地图源(底图 + 注记) */\nexport function buildTiandituSources(\n type: TiandituType,\n opts: TiandituOptions\n): TiandituSourceSpec[] {\n const { base, label } = LAYER_MAP[type];\n const tileSize = opts.tileSize ?? 256;\n const maxzoom = opts.maxzoom ?? 18;\n const attr = '© 天地图 GS(2023)3295号';\n return [\n {\n id: `tianditu-${base}`,\n isLabel: false,\n source: {\n type: 'raster',\n tiles: tiandituTileUrls(base, opts),\n tileSize,\n maxzoom,\n attribution: attr,\n },\n },\n {\n id: `tianditu-${label}`,\n isLabel: true,\n source: {\n type: 'raster',\n tiles: tiandituTileUrls(label, opts),\n tileSize,\n maxzoom,\n attribution: attr,\n },\n },\n ];\n}\n\nexport class MissingTokenError extends Error {\n constructor() {\n super('天地图 token 缺失:调用 addTiandituBaseMap 必须传入 tianditu: { token } 选项。');\n this.name = 'MissingTokenError';\n }\n}\n","/**\n * 把天地图底图(底图 + 注记)作为源/图层添加到 MapLibre 地图实例。\n *\n * 由于天地图为栅格底图,推荐作为「无 style 背景」的地图底层:\n * 直接通过 setStyle 注入最小 style,或先 addSource + addLayer。\n * 这里提供低侵入的「注入已有 map」方式,业务可叠加自有矢量图层。\n */\n\nimport type { Map as MlMap, StyleSpecification } from 'maplibre-gl';\nimport {\n buildTiandituSources,\n MissingTokenError,\n type TiandituOptions,\n type TiandituType,\n} from './tianditu';\n\nexport interface AddTiandituOptions extends TiandituOptions {\n type?: TiandituType;\n /** 添加到指定地图实例 */\n map: MlMap;\n /** 注入为 style 的源/图层还是 addSource(默认 addSource + addLayer) */\n asStyle?: false;\n}\n\n/** 生成可直接作为 Map style 的天地图 Style JSON(含底图+注记两层) */\nexport function tiandituStyle(\n type: TiandituType,\n opts: TiandituOptions\n): StyleSpecification {\n if (!opts.token) throw new MissingTokenError();\n const sources = buildTiandituSources(type, opts);\n return {\n version: 8,\n glyphs: 'https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf',\n sources: Object.fromEntries(\n sources.map((s) => [s.id, s.source])\n ) as StyleSpecification['sources'],\n layers: sources.map((s) => ({\n id: s.id,\n type: 'raster' as const,\n source: s.id,\n // 注记层置于底图之上\n ...(s.isLabel ? { minzoom: 0 } : {}),\n })),\n };\n}\n\n/** 向已存在的地图实例注入天地图底图(底图 + 注记) */\nexport function addTiandituBaseMap(opts: AddTiandituOptions): void {\n if (!opts.token) throw new MissingTokenError();\n const type = opts.type ?? 'vector';\n const sources = buildTiandituSources(type, opts);\n const map = opts.map;\n for (const s of sources) {\n if (!map.getSource(s.id)) {\n map.addSource(s.id, s.source as never);\n }\n if (!map.getLayer(s.id)) {\n map.addLayer({\n id: s.id,\n type: 'raster',\n source: s.id,\n } as never);\n }\n }\n}\n","/**\n * 离线瓦片存储抽象层(F-1.4)。\n *\n * 设计:存储后端可插拔。浏览器用 IndexedDB(idb),Node/测试用内存实现。\n * 瓦片 key 统一为 `${sourceId}:${z}:${x}:${y}`,value 为原始字节 + 过期时间。\n */\n\nexport type TileFormat = 'pbf' | 'geojson' | 'png' | 'mvt' | 'json';\n\nexport interface StoredTile {\n data: ArrayBuffer | Uint8Array;\n format: TileFormat;\n /** 过期时间戳(ms);0 表示永不过期 */\n expires: number;\n}\n\nexport interface TileStoreBackend {\n get(key: string): Promise<StoredTile | undefined>;\n put(key: string, tile: StoredTile): Promise<void>;\n has(key: string): Promise<boolean>;\n delete(key: string): Promise<void>;\n clear(prefix?: string): Promise<void>;\n size(): Promise<number>;\n}\n\n/** 内存实现(测试 / 无 IndexedDB 环境) */\nexport class MemoryTileStore implements TileStoreBackend {\n private map = new Map<string, StoredTile>();\n async get(key: string) {\n const t = this.map.get(key);\n if (!t) return undefined;\n if (t.expires && t.expires < Date.now()) {\n this.map.delete(key);\n return undefined;\n }\n return t;\n }\n async put(key: string, tile: StoredTile) {\n this.map.set(key, tile);\n }\n async has(key: string) {\n return (await this.get(key)) !== undefined;\n }\n async delete(key: string) {\n this.map.delete(key);\n }\n async clear(prefix?: string) {\n if (!prefix) {\n this.map.clear();\n return;\n }\n for (const k of [...this.map.keys()]) {\n if (k.startsWith(prefix)) this.map.delete(k);\n }\n }\n async size() {\n return this.map.size;\n }\n}\n\nexport function tileKey(sourceId: string, z: number, x: number, y: number): string {\n return `${sourceId}:${z}:${x}:${y}`;\n}\n\n/** 离线协议名(caoguo-offline://...)。集中定义,供 protocol 与 serviceWorker 共用。 */\nexport const OFFLINE_PROTOCOL = 'caoguo-offline';\n\n/**\n * 解析离线协议 URL:`caoguo-offline://{sourceId}/{z}/{x}/{y}`\n * 返回 sourceId 与瓦片坐标,便于 ProtocolHandler 取瓦片。\n */\nexport function parseOfflineUrl(\n url: string\n): { sourceId: string; z: number; x: number; y: number } | null {\n const m = /^caoguo-offline:\\/\\/([^/]+)\\/(\\d+)\\/(\\d+)\\/(\\d+)$/.exec(url);\n if (!m) return null;\n return {\n sourceId: decodeURIComponent(m[1]),\n z: Number(m[2]),\n x: Number(m[3]),\n y: Number(m[4]),\n };\n}\n","/**\n * 离线协议加载器(F-1.4)。\n *\n * 通过 MapLibre `addProtocol('caoguo-offline', loader)` 注册自定义协议,\n * 瓦片源可声明 `tiles: ['caoguo-offline://{sourceId}/{z}/{x}/{y}']`,\n * 引擎即从离线存储读取瓦片,实现「空气隔离」离线底图。\n *\n * MapLibre v4 的 protocol handler 签名:\n * (requestParameters, abortController) => Promise<{ data: ArrayBuffer }>\n */\n\nimport type { AddProtocolAction, RequestParameters } from 'maplibre-gl';\nimport { parseOfflineUrl, tileKey, OFFLINE_PROTOCOL, type TileStoreBackend } from './storage';\n\nexport { OFFLINE_PROTOCOL };\n\nexport interface OfflineProtocolContext {\n store: TileStoreBackend;\n}\n\n/** 构造离线协议 URL(供 source.tiles 使用) */\nexport function offlineTileUrl(sourceId: string, z: number, x: number, y: number): string {\n return `${OFFLINE_PROTOCOL}://${encodeURIComponent(sourceId)}/${z}/${x}/${y}`;\n}\n\n/** 生成离线栅格/矢量源的 tiles 数组 */\nexport function offlineSourceTiles(sourceId: string): string[] {\n return [`${OFFLINE_PROTOCOL}://${encodeURIComponent(sourceId)}/{z}/{x}/{y}`];\n}\n\n/** 把存储中的瓦片数据规整为 ArrayBuffer */\nfunction toArrayBuffer(data: ArrayBuffer | Uint8Array): ArrayBuffer {\n if (data instanceof Uint8Array) {\n const out = new ArrayBuffer(data.byteLength);\n new Uint8Array(out).set(data);\n return out;\n }\n // ArrayBufferLike 可能含 SharedArrayBuffer,复制为独立 ArrayBuffer\n const src = data as ArrayBuffer;\n const out = new ArrayBuffer(src.byteLength);\n new Uint8Array(out).set(new Uint8Array(src));\n return out;\n}\n\n/**\n * 创建离线协议 loader(返回可直接传给 addProtocol 的异步函数)。\n * 未命中瓦片时 reject,由 MapLibre 回退到线上源(若配置)。\n */\nexport function createOfflineLoader(ctx: OfflineProtocolContext): AddProtocolAction {\n return (params: RequestParameters) => {\n const url = params.url;\n const parsed = parseOfflineUrl(url);\n if (!parsed) {\n return Promise.reject(new Error(`非法离线 URL: ${url}`));\n }\n const key = tileKey(parsed.sourceId, parsed.z, parsed.x, parsed.y);\n return ctx.store.get(key).then((tile) => {\n if (!tile) {\n throw new Error(`离线瓦片缺失: ${key}`);\n }\n return { data: toArrayBuffer(tile.data) };\n });\n };\n}\n\n/** 在指定地图实例上注册离线协议 */\nexport function registerOfflineProtocol(\n maplibregl: { addProtocol: (name: string, action: AddProtocolAction) => void },\n ctx: OfflineProtocolContext\n): void {\n maplibregl.addProtocol(OFFLINE_PROTOCOL, createOfflineLoader(ctx));\n}\n","/**\n * 离线瓦片打包器(F-1.4)。\n *\n * 把本地瓦片导入离线存储:\n * - 原始 {z}/{x}/{y}.pbf|png 目录结构\n * - 单张 GeoJSON(按 z/x/y 网格切片为矢量瓦片缓冲,供 `caoguo-offline` 协议读取)\n *\n * 这里的「切片」为简化实现:GeoJSON 按瓦片网格空间包含关系分桶,\n * 仅把要素写入对应瓦片(不做 MVT 编码),存储为 UTF-8 JSON,\n * 由 protocol loader 以 `geojson` 格式返回,source type 用 geojson。\n * 生产级 MVT 编码(tippecanoe / @mapbox/vector-tile)可后续接入。\n */\n\nimport { tileKey, type StoredTile, type TileStoreBackend, type TileFormat } from './storage';\n\nconst MAX_ZOOM_DEFAULT = 14;\n\nfunction lon2x(lon: number, z: number): number {\n return Math.floor(((lon + 180) / 360) * Math.pow(2, z));\n}\nfunction lat2y(lat: number, z: number): number {\n const rad = (lat * Math.PI) / 180;\n return Math.floor(\n ((1 - Math.log(Math.tan(rad) + 1 / Math.cos(rad)) / Math.PI) / 2) * Math.pow(2, z)\n );\n}\n\nfunction tileBounds(z: number, x: number, y: number): [number, number, number, number] {\n const n = Math.pow(2, z);\n const lonWest = (x / n) * 360 - 180;\n const lonEast = ((x + 1) / n) * 360 - 180;\n const latNorth = (Math.atan(Math.sinh(Math.PI * (1 - (2 * y) / n))) * 180) / Math.PI;\n const latSouth = (Math.atan(Math.sinh(Math.PI * (1 - (2 * (y + 1)) / n))) * 180) / Math.PI;\n return [lonWest, latSouth, lonEast, latNorth];\n}\n\nfunction coordInTile(lon: number, lat: number, z: number, x: number, y: number): boolean {\n const [w, s, e, n] = tileBounds(z, x, y);\n return lon >= w && lon <= e && lat >= s && lat <= n;\n}\n\nexport interface PackGeoJSONOptions {\n sourceId: string;\n geojson: {\n type: 'FeatureCollection';\n features: Array<{\n geometry: { type: string; coordinates: unknown };\n properties: Record<string, unknown>;\n }>;\n };\n maxZoom?: number;\n /** 过期时间(ms 时间戳),0=永不过期 */\n expires?: number;\n onProgress?: (done: number, total: number) => void;\n}\n\n/**\n * 将 GeoJSON 按瓦片网格分桶写入离线存储。\n * 返回写入的瓦片数量。\n */\nexport async function packGeoJSONToStore(\n store: TileStoreBackend,\n opts: PackGeoJSONOptions\n): Promise<number> {\n const maxZoom = opts.maxZoom ?? MAX_ZOOM_DEFAULT;\n const expires = opts.expires ?? 0;\n const buckets = new Map<string, unknown[]>();\n\n for (const f of opts.geojson.features) {\n const g = f.geometry;\n const coords: number[][] = [];\n if (g.type === 'Point' || g.type === 'Circle') {\n coords.push(g.coordinates as number[]);\n } else if (g.type === 'LineString' || g.type === 'MultiPoint') {\n coords.push(...(g.coordinates as number[][]));\n } else if (g.type === 'Polygon' || g.type === 'MultiLineString') {\n for (const ring of g.coordinates as number[][][]) coords.push(...ring);\n } else if (g.type === 'MultiPolygon') {\n for (const poly of g.coordinates as number[][][][]) {\n for (const ring of poly) coords.push(...ring);\n }\n }\n for (const [lon, lat] of coords) {\n // 在每个缩放层级把要素写入其命中的瓦片(父瓦片亦包含,保证任意层级请求命中)\n for (let z = 0; z <= maxZoom; z++) {\n const x = lon2x(lon, z);\n const y = lat2y(lat, z);\n if (coordInTile(lon, lat, z, x, y)) {\n const k = tileKey(opts.sourceId, z, x, y);\n if (!buckets.has(k)) buckets.set(k, []);\n (buckets.get(k) as unknown[]).push(f);\n }\n }\n }\n }\n\n const total = buckets.size;\n let done = 0;\n for (const [k, features] of buckets) {\n const fc = { type: 'FeatureCollection', features };\n const tile: StoredTile = {\n data: new TextEncoder().encode(JSON.stringify(fc)),\n format: 'geojson' as TileFormat,\n expires,\n };\n await store.put(k, tile);\n done++;\n opts.onProgress?.(done, total);\n }\n return total;\n}\n\n/**\n * 由离线存储构造一个 geojson 源(用于 MapLibre source.tiles)。\n * 注意:geojson 协议瓦片由 protocol loader 直接返回 FeatureCollection。\n */\nexport function offlineGeoJSONSource(\n sourceId: string\n): { type: 'geojson'; data: never } & { tiles: string[]; _caoguoOffline: true; _sourceId: string } {\n return {\n type: 'geojson',\n data: undefined as never,\n tiles: [`caoguo-offline://${encodeURIComponent(sourceId)}/{z}/{x}/{y}`],\n _caoguoOffline: true,\n _sourceId: sourceId,\n } as never;\n}\n","/**\n * Service Worker 离线拦截(T5 / F-1.6)。\n *\n * 目标:在 T4 离线瓦片(IndexedDB + caoguo-offline 协议)之上,增加一层\n * **网络级二级缓存**——用 Cache API 缓存线上请求的瓦片(天地图等),并在\n * 「空气隔离(air-gap)」模式下拦截所有请求、用 Cache/离线存储兜底,\n * 实现断网后地图仍可平移缩放。\n *\n * 设计:\n * - `resolveCacheKey` / `shouldCache` / `resolveResponse` 是**纯函数 core**,\n * 不依赖真实 ServiceWorker 全局,可在 Node/vitest 中直接测试。\n * - `createFetchHandler` 把 core 包装成标准 `fetch` 事件处理器(注入 cache 与 store)。\n * - 浏览器侧用 `registerServiceWorker` 注册脚本,并通过 postMessage 切换空气隔离模式。\n *\n * 与 T4 的边界:T4 负责「业务离线瓦片 → IndexedDB → maplibre 协议」,\n * 本模块负责「线上瓦片请求 → Cache API 二级缓存 + 空气隔离拦截」,\n * 二者互补:T4 命中时根本不发网络请求(协议层短路),未命中时才走到 SW 缓存。\n */\n\nimport { OFFLINE_PROTOCOL, tileKey, type TileStoreBackend } from './storage';\n\n/** 需要二级缓存的瓦片来源(host 白名单,避免缓存无关资源) */\nexport const CACHEABLE_HOSTS = ['t0.tianditu.gov.cn', 't7.tianditu.gov.cn', 'tianditu.gov.cn'];\n\n/** 缓存名称(版本化,便于失效升级) */\nexport const CACHE_NAME = 'caoguo-offline-tiles-v1';\n\n/** 空气隔离模式消息协议 */\nexport const MSG_AIRGAP = 'caoguo:airgap' as const;\n\nexport interface AirgapMessage {\n type: typeof MSG_AIRGAP;\n /** true=开启空气隔离(断网模式),false=恢复在线优先 */\n enabled: boolean;\n}\n\n/**\n * 判断请求是否应进入离线二级缓存。\n * 只缓存 GET 请求 & 白名单 host & 图片/瓦片类型(保守策略)。\n */\nexport function shouldCache(request: { method: string; url: string }): boolean {\n if (request.method !== 'GET') return false;\n try {\n const u = new URL(request.url);\n // 离线协议请求(caoguo-offline://)由 T4 处理,不在此缓存\n if (u.protocol === `${OFFLINE_PROTOCOL}:`) return false;\n return CACHEABLE_HOSTS.some((h) => u.host === h || u.host.endsWith(`.${h}`));\n } catch {\n return false;\n }\n}\n\n/**\n * 计算 Cache Storage 的 key。优先用 URL(含 query,token 不同视为不同资源),\n * 否则回退到 request 对象本身。\n */\nexport function resolveCacheKey(request: { url: string }): string {\n return request.url;\n}\n\n/**\n * 从存储(IndexedDB/T4 离线)尝试取得瓦片兜底。\n * 用于空气隔离模式下网络不可达时返回上次离线打包的瓦片。\n */\nexport async function resolveFromStore(\n store: TileStoreBackend | undefined,\n request: { url: string }\n): Promise<{ data: ArrayBuffer; contentType: string } | undefined> {\n if (!store) return undefined;\n const z = /TILEMATRIX=(\\d+)/.exec(request.url)?.[1];\n const x = /TILECOL=(\\d+)/.exec(request.url)?.[1];\n const y = /TILEROW=(\\d+)/.exec(request.url)?.[1];\n if (!z || !x || !y) return undefined;\n // 天地图瓦片 key 以 sourceId 前缀;此处用 url 中的 layer 推断 sourceId\n const layer = /LAYER=([a-z]+)/.exec(request.url)?.[1] ?? 'tianditu';\n const key = tileKey(`td-${layer}`, Number(z), Number(x), Number(y));\n const tile = await store.get(key);\n if (!tile) return undefined;\n const buf = tile.data instanceof Uint8Array ? tile.data : new Uint8Array(tile.data);\n return { data: buf.buffer as ArrayBuffer, contentType: 'image/png' };\n}\n\nexport interface ResolveResponseDeps {\n /** 实际的 fetch 实现(浏览器为全局 fetch,测试可注入) */\n fetchImpl: (input: string) => Promise<{ ok: boolean; status: number; arrayBuffer: () => Promise<ArrayBuffer>; headers: { get: (k: string) => string | null } }>;\n /** Cache 接口(浏览器为全局 caches,测试可注入内存实现) */\n cache: {\n match: (key: string) => Promise<CacheEntry | undefined>;\n put: (key: string, resp: unknown) => Promise<void>;\n };\n /** 空气隔离开关(闭包状态,由消息控制) */\n airgap: { enabled: boolean };\n /** T4 离线存储(可选,空气隔离兜底) */\n store?: TileStoreBackend;\n}\n\ninterface CacheEntry {\n ok: boolean;\n status: number;\n arrayBuffer: () => Promise<ArrayBuffer>;\n headers: { get: (k: string) => string | null };\n}\n\nexport interface ResolvedResponse {\n /** 最终响应主体 */\n data: ArrayBuffer;\n /** 内容类型 */\n contentType: string;\n /** 来源:cache=命中缓存 / network=线上最新 / store=离线存储兜底 */\n source: 'cache' | 'network' | 'store';\n /** 该响应是否应写回缓存 */\n cacheable: boolean;\n}\n\n/**\n * 核心解析逻辑(纯函数,可测试)。\n * 两种模式:\n * - 在线优先(airgap=false):cache → network(写回 cache) → store 兜底\n * - 空气隔离(airgap=true):cache → store 兜底(不发网络请求)\n */\nexport async function resolveResponse(\n request: { method: string; url: string },\n deps: ResolveResponseDeps\n): Promise<ResolvedResponse | null> {\n if (!shouldCache(request)) return null;\n\n const key = resolveCacheKey(request);\n\n // 1) Cache 优先\n const cached = await deps.cache.match(key);\n if (cached && cached.ok) {\n return {\n data: await cached.arrayBuffer(),\n contentType: cached.headers.get('content-type') ?? 'image/png',\n source: 'cache',\n cacheable: false,\n };\n }\n\n // 2) 空气隔离模式:禁止网络,直接走离线存储兜底\n if (deps.airgap.enabled) {\n const fromStore = await resolveFromStore(deps.store, request);\n if (fromStore) {\n return { ...fromStore, source: 'store', cacheable: false };\n }\n return null; // 离线且无任何缓存:放弃(交由上层 404/透明恢复)\n }\n\n // 3) 在线优先:fetch 并写回 Cache\n try {\n const resp = await deps.fetchImpl(request.url);\n if (resp.ok) {\n const data = await resp.arrayBuffer();\n const contentType = resp.headers.get('content-type') ?? 'image/png';\n // 异步写回缓存(不阻塞响应)\n void deps.cache\n .put(key, {\n ok: true,\n status: resp.status,\n arrayBuffer: async () => data,\n headers: { get: (k: string) => (k.toLowerCase() === 'content-type' ? contentType : null) },\n })\n .catch(() => undefined);\n return { data, contentType, source: 'network', cacheable: true };\n }\n } catch {\n // 网络失败:回退 store\n const fromStore = await resolveFromStore(deps.store, request);\n if (fromStore) {\n return { ...fromStore, source: 'store', cacheable: false };\n }\n }\n return null;\n}\n\n/**\n * 包装为 Service Worker 的 fetch 事件处理器。\n * 注入真实的 caches / fetch / store。在浏览器 SW 全局中调用:\n * self.addEventListener('fetch', createFetchHandler({ store }));\n */\nexport function createFetchHandler(opts: {\n store?: TileStoreBackend;\n airgap?: { enabled: boolean };\n}): (event: { request: { method: string; url: string }; respondWith: (r: Promise<Response> | Response) => void }) => void {\n const airgap = opts.airgap ?? { enabled: false };\n return (event) => {\n const request = event.request;\n event.respondWith(\n (async () => {\n const deps: ResolveResponseDeps = {\n fetchImpl: (u) => fetch(u) as unknown as ResolveResponseDeps['fetchImpl'] extends (a: string) => infer R ? R : never,\n cache: caches as unknown as ResolveResponseDeps['cache'],\n airgap,\n store: opts.store,\n };\n const res = await resolveResponse(request, deps);\n if (res) {\n return new Response(res.data, {\n status: 200,\n headers: { 'content-type': res.contentType, 'x-caoguo-source': res.source },\n });\n }\n // 非瓦片请求 / 空气隔离缺失:透明放行\n return fetch(request.url);\n })()\n );\n };\n}\n\n/**\n * 在 Service Worker 全局上安装离线拦截逻辑(浏览器 SW 脚本入口)。\n * 处理 install/activate 生命周期、airgap 消息、fetch 拦截。\n */\nexport function installServiceWorker(sw: {\n addEventListener: (type: string, handler: (ev: unknown) => void) => void;\n caches: unknown;\n store?: TileStoreBackend;\n}): { airgap: { enabled: boolean } } {\n const airgap = { enabled: false };\n\n sw.addEventListener('install', () => {\n // @ts-expect-error 浏览器全局\n sw.skipWaiting?.();\n });\n sw.addEventListener('activate', () => {\n // @ts-expect-error 浏览器全局\n sw.clients?.claim?.();\n });\n sw.addEventListener('message', (ev: unknown) => {\n const msg = ev as { data?: AirgapMessage };\n if (msg.data?.type === MSG_AIRGAP) {\n airgap.enabled = !!msg.data.enabled;\n }\n });\n sw.addEventListener('fetch', createFetchHandler({ store: sw.store, airgap }) as never);\n\n return { airgap };\n}\n\n/**\n * 浏览器端注册离线 Service Worker(主线程调用)。\n * 需要项目提供 SW 脚本文件(见 `sw-template` 注释),并部署到与地图同域根路径。\n *\n * @param scriptUrl SW 脚本 URL(如 '/caoguo-sw.js'),需调用方自行构建/放置\n * @returns 注册成功的 ServiceWorker 实例;不支持时返回 null\n */\nexport async function registerOfflineServiceWorker(\n scriptUrl: string\n): Promise<ServiceWorkerRegistration | null> {\n if (typeof navigator === 'undefined' || !('serviceWorker' in navigator)) return null;\n try {\n return await navigator.serviceWorker.register(scriptUrl);\n } catch {\n return null;\n }\n}\n\n/**\n * 向已注册的 Service Worker 发送消息,切换「空气隔离」模式。\n * enabled=true 时地图进入断网可用状态(仅用 Cache + T4 离线存储)。\n */\nexport function setAirgap(registration: ServiceWorkerRegistration, enabled: boolean): void {\n const ctrl = registration.active ?? registration.installing ?? registration.waiting;\n ctrl?.postMessage({ type: MSG_AIRGAP, enabled } satisfies AirgapMessage as unknown);\n}\n\n/**\n * SW 脚本模板(供调用方写入部署文件,如 public/caoguo-sw.js)。\n * 该脚本通过 importScripts 复用本包编译产物,或直接内联 installServiceWorker。\n *\n * ```js\n * // caoguo-sw.js\n * importScripts('/caoguo-offline-sw.bundle.js'); // 含 installServiceWorker\n * installServiceWorker(self);\n * ```\n */\nexport const SW_TEMPLATE_HINT =\n \"importScripts('caoguo-offline-sw.bundle.js'); installServiceWorker(self);\";\n","/**\n * IndexedDB 离线瓦片后端(浏览器环境,F-1.4)。\n * 延迟依赖 idb;仅当运行在浏览器时加载,避免 Node/测试环境报错。\n */\n\nimport { MemoryTileStore, type StoredTile, type TileStoreBackend } from './storage';\n\ninterface RawRow {\n key: string;\n data: ArrayBuffer | Uint8Array;\n format: StoredTile['format'];\n expires: number;\n}\n\nlet dbPromise: Promise<unknown> | null = null;\n\nfunction getDb(): Promise<unknown> {\n if (!dbPromise) {\n dbPromise = (async () => {\n const { openDB } = await import('idb');\n return openDB('caoguo-offline', 1, {\n upgrade(db: any) {\n if (!db.objectStoreNames.contains('tiles')) {\n const store = db.createObjectStore('tiles', { keyPath: 'key' });\n store.createIndex('sourceId', 'sourceId');\n }\n },\n });\n })();\n }\n return dbPromise;\n}\n\nexport class IdbTileStore implements TileStoreBackend {\n async get(key: string): Promise<StoredTile | undefined> {\n const db: any = await getDb();\n const row: RawRow | undefined = await db.get('tiles', key);\n if (!row) return undefined;\n if (row.expires && row.expires < Date.now()) {\n await this.delete(key);\n return undefined;\n }\n return { data: row.data, format: row.format, expires: row.expires };\n }\n async put(key: string, tile: StoredTile): Promise<void> {\n const db: any = await getDb();\n const sourceId = key.split(':')[0];\n await db.put('tiles', {\n key,\n sourceId,\n data: tile.data,\n format: tile.format,\n expires: tile.expires,\n });\n }\n async has(key: string): Promise<boolean> {\n return (await this.get(key)) !== undefined;\n }\n async delete(key: string): Promise<void> {\n const db: any = await getDb();\n await db.delete('tiles', key);\n }\n async clear(prefix?: string): Promise<void> {\n const db: any = await getDb();\n if (!prefix) {\n await db.clear('tiles');\n return;\n }\n const tx = db.transaction('tiles', 'readwrite');\n const idx = tx.store.index('sourceId');\n let cursor = await idx.openCursor(prefix);\n while (cursor) {\n await cursor.delete();\n cursor = await cursor.continue();\n }\n await tx.done;\n }\n async size(): Promise<number> {\n const db: any = await getDb();\n return db.count('tiles');\n }\n}\n\n/** 浏览器环境默认用 IndexedDB,否则回退内存 */\nexport function createDefaultStore(): TileStoreBackend {\n if (typeof indexedDB !== 'undefined') {\n try {\n return new IdbTileStore();\n } catch {\n /* fallthrough */\n }\n }\n return new MemoryTileStore();\n}\n","/**\n * 比例尺 + 坐标显示控件(T8 / F-1.8)。\n *\n * - 比例尺:基于 Web Mercator 在给定纬度下的地面分辨率(m/像素),\n * 自动选择「米 / 公里」并吸附到 1/2/5 的整数档(标准地图比例尺行为)。\n * - 坐标:鼠标在图上移动时,实时显示当前光标处的经纬坐标(WGS84 渲染基准)。\n *\n * 设计为「纯函数 core + 薄 DOM 绑定」:比例计算 `computeScaleBar` 不依赖浏览器,\n * 可独立单测;`ScaleControl` 类负责把结果渲染进容器并监听地图事件。\n */\n\nexport type LengthUnit = 'metric';\n\nexport interface ScaleBar {\n /** 比例尺条代表的真实距离(米) */\n meters: number;\n /** 比例尺条在屏幕上的像素宽度 */\n pixels: number;\n /** 展示文案,如 \"500 m\" / \"2 km\" */\n label: string;\n}\n\nconst EARTH_RADIUS = 6378137; // WGS84 赤道半径(米)\n\n/**\n * 计算比例尺。\n * @param latitude 当前视图中心纬度(度)\n * @param zoom MapLibre zoom(Web Mercator)\n * @param dpiScale 设备像素比(默认 1;Retina 设为 window.devicePixelRatio)\n * @param maxWidth 比例尺条最大像素宽度(默认 100)\n * @param tileSize 瓦片像素尺寸(默认 512,MapLibre v4 默认)\n */\nexport function computeScaleBar(\n latitude: number,\n zoom: number,\n opts: { dpiScale?: number; maxWidth?: number; tileSize?: number } = {}\n): ScaleBar {\n const dpiScale = opts.dpiScale ?? 1;\n const maxWidth = opts.maxWidth ?? 100;\n const tileSize = opts.tileSize ?? 512;\n\n // 每像素的地面距离(米/像素),在给定纬度下\n const latRad = (latitude * Math.PI) / 180;\n const metersPerPixel =\n (Math.cos(latRad) * 2 * Math.PI * EARTH_RADIUS) /\n (tileSize * Math.pow(2, zoom) * dpiScale);\n\n // 最大像素宽度对应的真实距离\n let meters = metersPerPixel * maxWidth;\n\n // 吸附到 1/2/5 档\n const pow = Math.pow(10, Math.floor(Math.log10(meters)));\n const base = meters / pow; // 1..10\n const step = base >= 5 ? 5 : base >= 2 ? 2 : 1;\n meters = step * pow;\n\n const pixels = meters / metersPerPixel;\n const label = meters >= 1000 ? `${(meters / 1000).toLocaleString()} km` : `${Math.round(meters)} m`;\n\n return { meters, pixels, label };\n}\n\nexport interface ScaleControlOptions {\n /** 挂载容器(可选;不传则在地图容器内自动创建) */\n container?: HTMLElement;\n /** 是否显示实时坐标(默认 true) */\n showCoordinate?: boolean;\n /** 最大比例尺像素宽度 */\n maxWidth?: number;\n}\n\n/**\n * 比例尺控件。需传入 maplibre Map 实例(直接用 maplibre-gl 的 Map)。\n */\nexport class ScaleControl {\n private el: HTMLElement;\n private barEl: HTMLElement;\n private labelEl: HTMLElement;\n private coordEl?: HTMLElement;\n private map: { getZoom: () => number; getCenter: () => { lat: number }; on: (e: string, h: (ev: unknown) => void) => void; off: (e: string, h: (ev: unknown) => void) => void; getCanvas?: () => { addEventListener: (t: string, h: (ev: unknown) => void) => void; removeEventListener: (t: string, h: (ev: unknown) => void) => void } };\n private opts: Required<Omit<ScaleControlOptions, 'container'>>;\n private onMove = (ev: unknown) => this.handleMove(ev);\n private onZoom = () => this.update();\n\n constructor(\n map: ScaleControl['map'],\n options: ScaleControlOptions = {}\n ) {\n this.map = map;\n this.opts = {\n showCoordinate: options.showCoordinate ?? true,\n maxWidth: options.maxWidth ?? 100,\n };\n this.el = options.container ?? document.createElement('div');\n this.el.className = 'caoguo-scale-control';\n this.el.style.cssText =\n 'position:absolute;left:10px;bottom:24px;padding:4px 8px;background:rgba(10,15,30,.7);color:#cfe;border-radius:4px;font:12px/1.4 system-ui,sans-serif;pointer-events:none;z-index:2;';\n\n this.barEl = document.createElement('div');\n this.barEl.style.cssText =\n 'height:6px;border:1px solid #cfe;border-top:none;margin-bottom:2px;';\n this.labelEl = document.createElement('div');\n if (this.opts.showCoordinate) {\n this.coordEl = document.createElement('div');\n this.coordEl.style.cssText = 'opacity:.85;margin-top:2px;';\n this.el.append(this.barEl, this.labelEl, this.coordEl);\n } else {\n this.el.append(this.barEl, this.labelEl);\n }\n\n map.on('zoom', this.onZoom);\n map.on('move', this.onZoom);\n const canvas = (map as any).getCanvas?.();\n canvas?.addEventListener('mousemove', this.onMove as never);\n }\n\n /** 把控件挂到地图容器(无预设容器时调用) */\n addTo(container: HTMLElement): this {\n if (!this.el.parentElement) container.appendChild(this.el);\n this.update();\n return this;\n }\n\n /** 计算并刷新显示 */\n update(): void {\n const center = this.map.getCenter();\n const bar = computeScaleBar(center.lat, this.map.getZoom(), { maxWidth: this.opts.maxWidth });\n this.barEl.style.width = `${Math.round(bar.pixels)}px`;\n this.labelEl.textContent = bar.label;\n }\n\n private handleMove(ev: unknown): void {\n if (!this.coordEl) return;\n const e = ev as { lngLat?: { lng: number; lat: number } };\n const ll = e.lngLat;\n if (!ll) return;\n this.coordEl.textContent = `${ll.lng.toFixed(5)}, ${ll.lat.toFixed(5)}`;\n }\n\n /** 移除控件与事件监听 */\n remove(): void {\n this.map.off('zoom', this.onZoom);\n this.map.off('move', this.onZoom);\n const canvas = (this.map as any).getCanvas?.();\n canvas?.removeEventListener('mousemove', this.onMove as never);\n this.el.remove();\n }\n}\n","/**\n * 主题切换控件(T8 / F-1.9)。\n *\n * 在暗色(caoguo-dark)与亮色(caoguo-light)官方矢量主题间切换,\n * 调用 `map.setStyle` 并保留当前视图(center/zoom)与现有 GeoJSON 源/图层。\n *\n * 设计为「纯函数 core + 薄 DOM 绑定」:\n * - `toggleTheme` / `themeFromStyle` 为纯逻辑,可独立单测;\n * - `ThemeSwitcher` 类负责渲染按钮并绑定点击事件。\n */\n\nimport { caoguoStyle } from '../styles';\nimport type { ThemeName } from '@caoguo/theme';\n\nexport interface ThemeSwitcherOptions {\n /** 挂载容器(可选) */\n container?: HTMLElement;\n /** 初始主题 */\n initial?: ThemeName;\n}\n\nexport function oppositeTheme(theme: ThemeName): ThemeName {\n return theme === 'caoguo-dark' ? 'caoguo-light' : 'caoguo-dark';\n}\n\n/**\n * 从当前 style 对象推断主题名(依据其 JSON 标识)。\n * 非草果主题时回退到传入的 fallback。\n */\nexport function themeFromStyle(\n style: { name?: string } | string | null | undefined,\n fallback: ThemeName = 'caoguo-dark'\n): ThemeName {\n if (!style) return fallback;\n const name = typeof style === 'string' ? style : style.name;\n if (name === 'caoguo-dark' || name === 'caoguo-light') return name;\n return fallback;\n}\n\nexport class ThemeSwitcher {\n private el: HTMLElement;\n private btn: HTMLButtonElement;\n private current: ThemeName;\n private map: {\n getStyle: () => { name?: string } | undefined;\n setStyle: (s: unknown, opts?: { diff?: boolean }) => void;\n };\n\n constructor(map: ThemeSwitcher['map'], options: ThemeSwitcherOptions = {}) {\n this.map = map;\n this.current = options.initial ?? themeFromStyle(map.getStyle?.(), 'caoguo-dark');\n\n this.el = options.container ?? document.createElement('div');\n this.el.className = 'caoguo-theme-switcher';\n this.el.style.cssText =\n 'position:absolute;right:10px;top:10px;z-index:3;';\n\n this.btn = document.createElement('button');\n this.btn.type = 'button';\n this.applyLabel();\n this.btn.style.cssText =\n 'cursor:pointer;padding:4px 10px;border:1px solid #2a3550;border-radius:6px;' +\n 'background:rgba(10,15,30,.7);color:#cfe;font:12px system-ui,sans-serif;';\n this.btn.addEventListener('click', () => this.toggle());\n this.el.append(this.btn);\n }\n\n private applyLabel(): void {\n this.btn.textContent = this.current === 'caoguo-dark' ? '🌙 暗色' : '☀ 亮色';\n }\n\n /** 当前主题 */\n getTheme(): ThemeName {\n return this.current;\n }\n\n /** 切换到指定主题(保留视图,diff 模式避免闪烁) */\n setTheme(theme: ThemeName): void {\n if (theme === this.current) return;\n this.current = theme;\n this.applyLabel();\n this.map.setStyle(caoguoStyle(theme), { diff: true });\n }\n\n /** 在明暗之间切换 */\n toggle(): void {\n this.setTheme(oppositeTheme(this.current));\n }\n\n /** 挂到容器 */\n addTo(container: HTMLElement): this {\n if (!this.el.parentElement) container.appendChild(this.el);\n return this;\n }\n\n /** 移除 */\n remove(): void {\n this.btn.removeEventListener('click', () => this.toggle());\n this.el.remove();\n }\n}\n","/**\n * 辉光线几何构建(T6 / F-1.3 纯逻辑部分)。\n *\n * 把 GeoJSON LineString 集合转换为「多遍辉光描边」所需的几何描述。\n * 渲染层(CustomLineLayer)再据此在 WebGL 中绘制:每遍一个宽度档 + 透明度档,\n * 叠加形成管线/路网/水系的辉光效果。\n *\n * 设计:本模块**不依赖 WebGL / maplibre**,纯函数可在 Node 单测。\n * 坐标投影使用简化 Web Mercator(经度→x、纬度→y 的归一化世界坐标),\n * 真实渲染时由 CustomLayer 的 matrix 变换到屏幕。\n */\n\nexport interface GlowLine {\n /** 线坐标 [lng, lat][] */\n coordinates: [number, number][];\n /** 该线所属分组(如 'pipe' | 'road' | 'water'),用于着色 */\n group?: string;\n}\n\nexport interface GlowPass {\n /** 相对基础宽度的倍数(核心线=1,外晕逐遍增大) */\n widthScale: number;\n /** 该遍不透明度(核心线高、外晕低) */\n opacity: number;\n}\n\nexport interface GlowGeometry {\n /** 所有线(含分组标记)的归一化坐标序列 */\n lines: { points: [number, number][]; group?: string }[];\n /** 辉光多遍参数(从外晕到核心,或反之,由渲染层决定) */\n passes: GlowPass[];\n /** 总顶点数(用于缓冲分配) */\n vertexCount: number;\n}\n\n/**\n * 生成辉光多遍档位。\n * @param passes 遍数(默认 4:3 层外晕 + 1 核心)\n * @param coreOpacity 核心线不透明度\n */\nexport function glowPasses(passes = 4, coreOpacity = 1): GlowPass[] {\n if (passes < 1) passes = 1;\n const out: GlowPass[] = [];\n // passes[0] = 核心(widthScale=1、opacity 最高);\n // passes[last] = 最外晕(widthScale 最大、opacity 最低)\n for (let i = 0; i < passes; i++) {\n const t = passes === 1 ? 1 : 1 - i / (passes - 1); // 1(核心)..0(外晕)\n out.push({\n widthScale: 1 + (1 - t) * (passes - 1) * 1.5,\n opacity: coreOpacity * (0.12 + 0.88 * t),\n });\n }\n return out;\n}\n\n/**\n * 简化 Web Mercator 归一化(经度→x∈[-1,1],纬度→y∈[-1,1])。\n * 仅用于几何构建与单测,真实投影在渲染层用 map 的 matrix。\n */\nexport function projectSimple(lng: number, lat: number): [number, number] {\n const x = lng / 180;\n const y = Math.log(Math.tan((Math.PI / 4) + (lat * Math.PI) / 360)) / Math.PI;\n return [x, Math.max(-1, Math.min(1, y))];\n}\n\n/**\n * 构建辉光几何:投影每条线并统计顶点。\n * 顶点数 = 各线(点数-1)*2(线段两端),用于 Line 绘制。\n */\nexport function buildGlowGeometry(\n lines: GlowLine[],\n opts: { passes?: number; coreOpacity?: number } = {}\n): GlowGeometry {\n const passes = glowPasses(opts.passes ?? 4, opts.coreOpacity ?? 1);\n let vertexCount = 0;\n const projected = lines.map((l) => {\n const points = l.coordinates.map(([lng, lat]) => projectSimple(lng, lat));\n // 线段绘制:每条 segment 2 顶点\n vertexCount += Math.max(0, points.length - 1) * 2;\n return { points, group: l.group };\n });\n return { lines: projected, passes, vertexCount };\n}\n","/**\n * 辉光管线 Custom Layer(T6 / F-1.3 WebGL 渲染层)。\n *\n * 实现 MapLibre v4 `CustomLayerInterface`:在地图之上叠加绘制 GeoJSON 线,\n * 用多遍(glowPasses)描边形成管线/路网/水系的辉光效果。\n *\n * 设计:几何构建(投影/档位)在 `./glowGeometry` 纯函数中完成(可单测);\n * 本文件仅负责 WebGL 状态机与绘制,仅在浏览器执行。\n * 通过 `Map.addGlowLayer` 注入,调用方无需感知 WebGL 细节。\n *\n * 依赖 MapLibre 注入的 `matrix`(map 的 projectionMatrix * modelViewMatrix),\n * 与官方 CustomLayer 示例一致。\n */\n\nimport { buildGlowGeometry, type GlowLine } from './glowGeometry';\n\n/** MapLibre v4 CustomLayerInterface 最小子集(避免强类型耦合) */\nexport interface CustomLayerInterface {\n id: string;\n type: 'custom';\n renderingMode?: '2d' | '3d';\n onAdd?(map: unknown, gl: WebGLRenderingContext): void;\n render(gl: WebGLRenderingContext, matrix: number[]): void;\n onRemove?(map: unknown, gl: WebGLRenderingContext): void;\n prerender?(gl: WebGLRenderingContext, matrix: number[]): void;\n}\n\nexport interface GlowLayerOptions {\n /** 图层 id */\n id?: string;\n /** 线分组颜色映射(group -> [r,g,b] 0..1) */\n colors?: Record<string, [number, number, number]>;\n /** 基础线宽(像素,核心线) */\n baseWidth?: number;\n /** 辉光遍数 */\n passes?: number;\n /** 线集合 */\n lines: GlowLine[];\n}\n\nconst DEFAULT_COLORS: Record<string, [number, number, number]> = {\n pipe: [0.2, 0.85, 1.0], // 青蓝:管线\n road: [0.6, 0.7, 0.9], // 灰蓝:路网\n water: [0.25, 0.55, 0.95], // 深蓝:水系\n};\n\nconst VERT = `\nattribute vec2 aPos;\nattribute float aMiter;\nuniform mat4 uMatrix;\nuniform float uWidth;\nuniform vec2 uResolution;\nvoid main() {\n // 简化:沿法线方向偏移 width(屏幕空间),这里仅演示核心投影\n vec4 clip = uMatrix * vec4(aPos, 0.0, 1.0);\n vec2 screen = clip.xy / clip.w;\n // 注:精确线宽需法线计算,示范层用点宽近似\n vec2 offset = vec2(aMiter * uWidth / uResolution.x * 2.0, 0.0);\n gl_Position = vec4(screen + offset * clip.w, clip.z, clip.w);\n}\n`;\n\nconst FRAG = `\nprecision mediump float;\nuniform vec3 uColor;\nuniform float uOpacity;\nvoid main() {\n gl_FragColor = vec4(uColor, uOpacity);\n}\n`;\n\nfunction compile(gl: WebGLRenderingContext, type: number, src: string): WebGLShader {\n const sh = gl.createShader(type)!;\n gl.shaderSource(sh, src);\n gl.compileShader(sh);\n return sh;\n}\n\nexport class CustomLineLayer implements CustomLayerInterface {\n id: string;\n type = 'custom' as const;\n renderingMode: '2d' = '2d';\n\n private lines: GlowLine[];\n private colors: Record<string, [number, number, number]>;\n private baseWidth: number;\n private passes: number;\n\n private program?: WebGLProgram;\n private buffer?: WebGLBuffer;\n private geometry: ReturnType<typeof buildGlowGeometry>;\n private map?: { getCanvas: () => HTMLCanvasElement };\n\n constructor(opts: GlowLayerOptions) {\n this.id = opts.id ?? 'caoguo-glow-line';\n this.lines = opts.lines;\n this.colors = { ...DEFAULT_COLORS, ...opts.colors };\n this.baseWidth = opts.baseWidth ?? 3;\n this.passes = opts.passes ?? 4;\n this.geometry = buildGlowGeometry(this.lines, { passes: this.passes });\n }\n\n onAdd(map: unknown, gl: WebGLRenderingContext): void {\n this.map = map as { getCanvas: () => HTMLCanvasElement };\n const vs = compile(gl, gl.VERTEX_SHADER, VERT);\n const fs = compile(gl, gl.FRAGMENT_SHADER, FRAG);\n const prog = gl.createProgram()!;\n gl.attachShader(prog, vs);\n gl.attachShader(prog, fs);\n gl.linkProgram(prog);\n this.program = prog;\n\n // 扁平化顶点:每条 segment 两端点\n const verts: number[] = [];\n for (const line of this.geometry.lines) {\n const pts = line.points;\n for (let i = 0; i < pts.length - 1; i++) {\n verts.push(pts[i][0], pts[i][1], 0, pts[i + 1][0], pts[i + 1][1], 0);\n }\n }\n const buf = gl.createBuffer()!;\n gl.bindBuffer(gl.ARRAY_BUFFER, buf);\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verts), gl.STATIC_DRAW);\n this.buffer = buf;\n }\n\n render(gl: WebGLRenderingContext, matrix: number[]): void {\n if (!this.program || !this.buffer) return;\n gl.useProgram(this.program);\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n const aPos = gl.getAttribLocation(this.program, 'aPos');\n const aMiter = gl.getAttribLocation(this.program, 'aMiter');\n gl.enableVertexAttribArray(aPos);\n gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 24, 0);\n gl.enableVertexAttribArray(aMiter);\n gl.vertexAttribPointer(aMiter, 1, gl.FLOAT, false, 24, 16);\n\n const uMatrix = gl.getUniformLocation(this.program, 'uMatrix');\n gl.uniformMatrix4fv(uMatrix, false, new Float32Array(matrix));\n const uWidth = gl.getUniformLocation(this.program, 'uWidth');\n const uColor = gl.getUniformLocation(this.program, 'uColor');\n const uOpacity = gl.getUniformLocation(this.program, 'uOpacity');\n const uRes = gl.getUniformLocation(this.program, 'uResolution');\n const canvas = this.map?.getCanvas();\n gl.uniform2f(uRes, canvas?.width ?? 1024, canvas?.height ?? 768);\n gl.enable(gl.BLEND);\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE); // 加法混合形成辉光\n\n const color = this.colors[this.lines[0]?.group ?? 'pipe'] ?? this.colors.pipe;\n for (const pass of this.geometry.passes) {\n gl.uniform1f(uWidth, this.baseWidth * pass.widthScale);\n gl.uniform3f(uColor, color[0], color[1], color[2]);\n gl.uniform1f(uOpacity, pass.opacity);\n gl.drawArrays(gl.LINES, 0, this.geometry.vertexCount);\n }\n }\n\n onRemove(_map: unknown, gl: WebGLRenderingContext): void {\n if (this.buffer) gl.deleteBuffer(this.buffer);\n if (this.program) gl.deleteProgram(this.program);\n this.buffer = undefined;\n this.program = undefined;\n }\n}\n","/**\n * LOD 控制器(T7 / F-1.7,纯逻辑)。\n *\n * 按地图 zoom 自动切换数据密度(Level of Detail):\n * - 低 zoom(全国/省)显示聚合/简化数据,避免要素过密;\n * - 高 zoom(市/区)显示全量/精细数据。\n *\n * 设计:本模块**不依赖 maplibre / WebGL / DOM**,纯函数可在 Node 单测。\n * 控制器 `LodController` 监听 zoom 变化并回调当前应激活的 LOD 等级,\n * 调用方据此 `setData` / 切换 source(具体渲染动作由调用方决定)。\n */\n\nexport interface LodLevel<T = unknown> {\n /** 该等级名称(如 'country' | 'province' | 'city' | 'detail') */\n id: string;\n /** 进入该等级的最小 zoom(含) */\n minZoom: number;\n /** 进入该等级的最大 zoom(含);省略表示 +∞ */\n maxZoom?: number;\n /** 该等级承载的数据/配置(任意类型,调用方解释) */\n payload?: T;\n}\n\nexport interface LodChangeEvent<T> {\n /** 当前激活等级 */\n level: LodLevel<T>;\n /** 是否相较上一次发生了等级切换 */\n changed: boolean;\n /** 当前 zoom */\n zoom: number;\n}\n\n/**\n * 根据 zoom 解析应激活的 LOD 等级。\n * 规则:取满足 minZoom<=zoom<=(maxZoom??∞) 的等级;\n * 若存在多个命中(区间重叠),取 minZoom 最大者(更精细优先)。\n * 无命中返回 null(调用方可保留上一等级)。\n */\nexport function resolveLod<T>(zoom: number, levels: LodLevel<T>[]): LodLevel<T> | null {\n let best: LodLevel<T> | null = null;\n for (const lv of levels) {\n const max = lv.maxZoom ?? Infinity;\n if (zoom >= lv.minZoom && zoom <= max) {\n if (!best || lv.minZoom > best.minZoom) best = lv;\n }\n }\n return best;\n}\n\n/**\n * 给定可视范围的\"要素密度\"建议(用于调试/UI 提示)。\n * 返回每屏建议最大要素数(随 zoom 平方增长,模拟瓦片面积)。\n */\nexport function suggestDensity(zoom: number, basePerTile = 200, tileCountFactor = 1): number {\n const z = Math.max(0, zoom);\n return Math.round(basePerTile * Math.pow(2, Math.max(0, z - 8)) * tileCountFactor);\n}\n\n/**\n * LOD 控制器(薄状态机)。监听 zoom,触发 onLod 回调。\n */\nexport class LodController<T = unknown> {\n private levels: LodLevel<T>[];\n private current: LodLevel<T> | null = null;\n private onChange: (e: LodChangeEvent<T>) => void;\n private map: { getZoom: () => number; on: (e: string, h: (ev: unknown) => void) => void; off: (e: string, h: (ev: unknown) => void) => void };\n\n constructor(\n map: LodController['map'],\n levels: LodLevel<T>[],\n onChange: (e: LodChangeEvent<T>) => void\n ) {\n this.map = map;\n this.levels = levels;\n this.onChange = onChange;\n this.handler = () => this.evaluate(false);\n map.on('zoom', this.handler);\n map.on('move', this.handler);\n }\n\n private handler: (ev: unknown) => void;\n\n /** 立即评估当前 zoom 并(按需)触发回调 */\n evaluate(force = false): LodLevel<T> | null {\n const zoom = this.map.getZoom();\n const next = resolveLod(zoom, this.levels);\n if (!next) return this.current;\n const changed = force || next.id !== this.current?.id;\n if (changed || force) {\n this.current = next;\n this.onChange({ level: next, changed, zoom });\n }\n return next;\n }\n\n /** 当前等级 */\n getLevel(): LodLevel<T> | null {\n return this.current;\n }\n\n /** 更新分级配置(如权限/数据就绪后) */\n setLevels(levels: LodLevel<T>[]): void {\n this.levels = levels;\n this.evaluate(false);\n }\n\n /** 卸载监听 */\n remove(): void {\n this.map.off('zoom', this.handler);\n this.map.off('move', this.handler);\n }\n}\n","import maplibregl from 'maplibre-gl';\nimport type {\n Map as MlMap,\n StyleSpecification,\n} from 'maplibre-gl';\nimport 'maplibre-gl/dist/maplibre-gl.css';\n\nimport { osmRasterStyle, WUHAN_CENTER, WUHAN_ZOOM } from './styles';\nimport { createTransformer, type CRS, type LngLat } from './crs';\nimport { toWgs84 } from './crs';\nimport {\n addTiandituBaseMap,\n tiandituStyle,\n MissingTokenError,\n type TiandituOptions,\n type TiandituType,\n} from './sources';\nimport {\n createDefaultStore,\n registerOfflineProtocol,\n offlineTileUrl,\n offlineSourceTiles,\n packGeoJSONToStore,\n type TileStoreBackend,\n type TileFormat,\n} from './offline';\nimport { ScaleControl, ThemeSwitcher } from './controls';\nimport { CustomLineLayer } from './shaders';\nimport type { GlowLine } from './shaders';\nimport { LodController } from './lod';\nimport type { LodLevel, LodChangeEvent } from './lod';\nimport type { ThemeName } from '@caoguo/theme';\n\nexport type MapInstance = MlMap;\n\nexport { maplibregl, WUHAN_CENTER, WUHAN_ZOOM, osmRasterStyle };\nexport * from './crs';\nexport * from './sources';\nexport * from './offline';\nexport * from './controls';\nexport * from './shaders';\nexport * from './lod';\n\nexport interface MapOptions {\n container: string | HTMLElement;\n center?: [number, number];\n zoom?: number;\n style?: string | StyleSpecification;\n pitch?: number;\n bearing?: number;\n /**\n * 业务/叠加数据的坐标系(默认 WGS84)。\n * 引擎内部以 WGS84 渲染;若数据为 GCJ-02 / CGCS2000,\n * 设定后可通过 `transformToMap` 在入图前自动纠偏。\n */\n dataCRS?: CRS;\n}\n\n/**\n * 草果地图引擎封装(展示层骨架)。\n *\n * 当前为轻量包装:直接复用 maplibre-gl 能力。\n * 后续阶段将在此注入:GCJ-02/BD-09 坐标系插件、行业 Shader、离线瓦片加载,\n * 业务调用方无需改动(通过本类统一入口)。\n */\nexport class Map {\n private _map: MlMap;\n private _dataCRS: CRS;\n\n constructor(options: MapOptions) {\n this._dataCRS = options.dataCRS ?? 'WGS84';\n this._map = new maplibregl.Map({\n container: options.container,\n center: options.center ?? WUHAN_CENTER,\n zoom: options.zoom ?? WUHAN_ZOOM,\n style: options.style ?? (osmRasterStyle() as StyleSpecification),\n pitch: options.pitch ?? 0,\n bearing: options.bearing ?? 0,\n attributionControl: { compact: true },\n });\n }\n\n /**\n * 把业务坐标系坐标转换到地图渲染基准(WGS84)。\n * 用于叠加 GCJ-02 / CGCS2000 数据前的纠偏。\n */\n transformToMap(lng: number, lat: number): LngLat {\n return toWgs84(this._dataCRS, lng, lat);\n }\n\n /** 设定叠加数据坐标系 */\n setDataCRS(crs: CRS): void {\n this._dataCRS = crs;\n }\n\n /** 读取叠加数据坐标系 */\n getDataCRS(): CRS {\n return this._dataCRS;\n }\n\n /** 生成当前 dataCRS -> WGS84 的变换器(供批量转换使用) */\n getTransformer() {\n return createTransformer(this._dataCRS, 'WGS84');\n }\n\n /**\n * 切换为底图为天地图(国内权威底图,CGCS2000 / Web Mercator)。\n * token 必须由调用方注入,缺失时抛出 MissingTokenError。\n */\n useTianditu(type: TiandituType, opts: Omit<TiandituOptions, 'type'>): void {\n this._map.setStyle(tiandituStyle(type, opts) as never);\n }\n\n /** 向当前地图注入天地图底图(叠加在现有 style 之上) */\n addTianditu(opts: Omit<TiandituOptions, 'type'> & { type?: TiandituType }): void {\n addTiandituBaseMap({ ...opts, map: this._map });\n }\n\n /** 离线瓦片后端(默认浏览器 IndexedDB / Node 内存) */\n private _store: TileStoreBackend = createDefaultStore();\n\n /** 注册离线协议并启用离线瓦片读取(F-1.4) */\n enableOffline(store?: TileStoreBackend): void {\n if (store) this._store = store;\n registerOfflineProtocol(maplibregl, { store: this._store });\n }\n\n /** 当前离线存储实例 */\n getOfflineStore(): TileStoreBackend {\n return this._store;\n }\n\n /** 构造离线源 tiles(供 source.tiles 使用) */\n offlineTiles(sourceId: string): string[] {\n return offlineSourceTiles(sourceId);\n }\n\n /** 把 GeoJSON 打包进离线存储(分桶到瓦片网格) */\n async packGeoJSON(\n sourceId: string,\n geojson: Parameters<typeof packGeoJSONToStore>[1]['geojson'],\n opts: { maxZoom?: number; expires?: number } = {}\n ): Promise<number> {\n return packGeoJSONToStore(this._store, {\n sourceId,\n geojson,\n maxZoom: opts.maxZoom,\n expires: opts.expires,\n });\n }\n\n addLayer(layer: Record<string, unknown>): void {\n this._map.addLayer(layer as MlMap['addLayer'] extends (l: infer L) => void ? L : never);\n }\n\n removeLayer(id: string): void {\n if (this._map.getLayer(id)) this._map.removeLayer(id);\n }\n\n on(event: string, layerId?: string, cb?: (e: unknown) => void): void {\n if (cb && layerId) this._map.on(event as keyof MlMap['on'], layerId, cb as never);\n else this._map.on(event as keyof MlMap['on'], cb as never);\n }\n\n addSource(id: string, source: object): void {\n this._map.addSource(id, source as never);\n }\n\n getSource(id: string): unknown {\n return this._map.getSource(id);\n }\n\n flyTo(opts: { center?: [number, number]; zoom?: number; pitch?: number; bearing?: number }): void {\n this._map.flyTo(opts as never);\n }\n\n remove(): void {\n this._map.remove();\n }\n\n /**\n * 挂载比例尺 + 实时坐标控件(T8 / F-1.8)。\n * 返回控件实例,可调用 .remove() 卸载。\n */\n addScaleControl(options?: { showCoordinate?: boolean; maxWidth?: number }): ScaleControl {\n const ctrl = new ScaleControl(this._map as never, options);\n const container = (this._map as unknown as { getContainer: () => HTMLElement }).getContainer();\n ctrl.addTo(container);\n return ctrl;\n }\n\n /**\n * 挂载主题切换控件(T8 / F-1.9),在 caoguo-dark / caoguo-light 间切换。\n * 返回控件实例,可调用 .toggle() / .setTheme() / .remove()。\n */\n addThemeSwitcher(initial?: ThemeName): ThemeSwitcher {\n const ctrl = new ThemeSwitcher(this._map as never, { initial });\n const container = (this._map as unknown as { getContainer: () => HTMLElement }).getContainer();\n ctrl.addTo(container);\n return ctrl;\n }\n\n /**\n * 挂载辉光管线 Custom Layer(T6 / F-1.3)。\n * 传入 GeoJSON 线集合,叠加渲染管线/路网/水系辉光效果。\n * @returns 图层 id(可用于 removeLayer)\n */\n addGlowLayer(opts: {\n id?: string;\n lines: GlowLine[];\n colors?: Record<string, [number, number, number]>;\n baseWidth?: number;\n passes?: number;\n }): string {\n const layer = new CustomLineLayer(opts);\n this._map.addLayer(layer as never);\n return layer.id;\n }\n\n /**\n * 挂载 LOD 控制器(T7 / F-1.7)。\n * 随 zoom 切换数据密度等级,并在等级变化时回调(调用方据此 setData / 切源)。\n * @returns LodController 实例(可 .getLevel() / .remove())\n */\n addLodController<T = unknown>(\n levels: LodLevel<T>[],\n onLod: (e: LodChangeEvent<T>) => void\n ): LodController<T> {\n const ctrl = new LodController<T>(this._map as never, levels, onLod);\n ctrl.evaluate(true);\n return ctrl;\n }\n\n get instance(): MlMap {\n return this._map;\n }\n}\n\nexport default Map;\n"]}
1
+ {"version":3,"sources":["../src/styles.ts","../src/crs/gcj02.ts","../src/crs/cgcs2000.ts","../src/crs/transform.ts","../src/sources/tianditu.ts","../src/sources/addTianditu.ts","../src/offline/storage.ts","../src/offline/protocol.ts","../src/offline/packer.ts","../src/offline/serviceWorker.ts","../src/offline/idbStore.ts","../src/controls/ScaleControl.ts","../src/controls/ThemeSwitcher.ts","../src/controls/LegendControl.ts","../src/controls/ExportControl.ts","../src/shaders/glowGeometry.ts","../src/shaders/CustomLineLayer.ts","../src/lod/lodController.ts","../src/terrain.ts","../src/sourceUtils.ts","../src/index.ts"],"names":["theme","buildStyle","out","maplibregl","count","Map"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * 草果地图内置样式。\n *\n * - `caoguoStyle()`:官方矢量主题(caoguo-dark / caoguo-light),\n * 由 @caoguo/theme 生成,底层使用 MapLibre 免费 demo 矢量瓦片,无需 token。\n * - `osmRasterStyle()`:OSM 栅格兜底样式,矢量主题加载失败时使用。\n */\n\nimport type { StyleSpecification } from 'maplibre-gl';\nimport { buildStyle, type ThemeName } from '@caoguo/theme';\n\nexport const WUHAN_CENTER: [number, number] = [114.3055, 30.5928];\nexport const WUHAN_ZOOM = 11;\n\n/** 草果官方矢量主题(默认暗色)。 */\nexport function caoguoStyle(theme: ThemeName = 'caoguo-dark'): StyleSpecification {\n return buildStyle(theme);\n}\n\n/** 暗色 OSM 栅格兜底底图(无需 key)。 */\nexport function osmRasterStyle(): StyleSpecification {\n return {\n version: 8,\n glyphs: 'https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf',\n sources: {\n 'osm-raster': {\n type: 'raster',\n tiles: [\n 'https://a.tile.openstreetmap.org/{z}/{x}/{y}.png',\n 'https://b.tile.openstreetmap.org/{z}/{x}/{y}.png',\n 'https://c.tile.openstreetmap.org/{z}/{x}/{y}.png',\n ],\n tileSize: 256,\n attribution: '© OpenStreetMap contributors',\n },\n },\n layers: [\n {\n id: 'background',\n type: 'background',\n paint: { 'background-color': '#0a0f1e' },\n },\n {\n id: 'osm-raster',\n type: 'raster',\n source: 'osm-raster',\n paint: {\n 'raster-opacity': 0.85,\n 'raster-saturation': -0.6,\n 'raster-brightness-max': 0.7,\n 'raster-contrast': 0.1,\n },\n },\n ],\n };\n}\n","/**\n * WGS84 <-> GCJ-02(火星坐标系)转换。\n *\n * 算法:公开的解析偏移模型(Krasovsky 椭球),与 coordtransform 一致。\n * 全国范围单点误差 < 50m(PRD 验收 F-1.1)。\n * 注意:GCJ-02 -> WGS84 采用 3 次迭代反算,进一步收敛残差。\n */\n\nconst PI = Math.PI;\nconst A = 6378245.0; // 长半轴\nconst EE = 0.00669342162296594323; // 第一偏心率平方\n\nfunction outOfChina(lng: number, lat: number): boolean {\n return lng < 72.004 || lng > 137.8347 || lat < 0.8293 || lat > 55.8271;\n}\n\nfunction transformLat(lng: number, lat: number): number {\n let ret =\n -100.0 +\n 2.0 * lng +\n 3.0 * lat +\n 0.2 * lat * lat +\n 0.1 * lng * lat +\n 0.2 * Math.sqrt(Math.abs(lng));\n ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0;\n ret += ((20.0 * Math.sin(lat * PI) + 40.0 * Math.sin((lat / 3.0) * PI)) * 2.0) / 3.0;\n ret += ((160.0 * Math.sin((lat / 12.0) * PI) + 320 * Math.sin((lat * PI) / 30.0)) * 2.0) / 3.0;\n return ret;\n}\n\nfunction transformLng(lng: number, lat: number): number {\n let ret =\n 300.0 +\n lng +\n 2.0 * lat +\n 0.1 * lng * lng +\n 0.1 * lng * lat +\n 0.1 * Math.sqrt(Math.abs(lng));\n ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0;\n ret += ((20.0 * Math.sin(lng * PI) + 40.0 * Math.sin((lng / 3.0) * PI)) * 2.0) / 3.0;\n ret += ((150.0 * Math.sin((lng / 12.0) * PI) + 300.0 * Math.sin((lng / 30.0) * PI)) * 2.0) / 3.0;\n return ret;\n}\n\n/** WGS84 -> GCJ-02 */\nexport function wgs84ToGcj02(lng: number, lat: number): [number, number] {\n if (outOfChina(lng, lat)) return [lng, lat];\n let dLat = transformLat(lng - 105.0, lat - 35.0);\n let dLng = transformLng(lng - 105.0, lat - 35.0);\n const radLat = (lat / 180.0) * PI;\n let magic = Math.sin(radLat);\n magic = 1 - EE * magic * magic;\n const sqrtMagic = Math.sqrt(magic);\n dLat = (dLat * 180.0) / (((A * (1 - EE)) / (magic * sqrtMagic)) * PI);\n dLng = (dLng * 180.0) / ((A / sqrtMagic) * Math.cos(radLat) * PI);\n return [lng + dLng, lat + dLat];\n}\n\n/** GCJ-02 -> WGS84(3 次迭代反算) */\nexport function gcj02ToWgs84(lng: number, lat: number): [number, number] {\n if (outOfChina(lng, lat)) return [lng, lat];\n let [mlng, mlat] = wgs84ToGcj02(lng, lat);\n let dlng = mlng - lng;\n let dlat = mlat - lat;\n // 一次迭代\n [mlng, mlat] = wgs84ToGcj02(lng - dlng, lat - dlat);\n dlng = mlng - lng;\n dlat = mlat - lat;\n // 二次迭代(收敛)\n [mlng, mlat] = wgs84ToGcj02(lng - dlng, lat - dlat);\n dlng = mlng - lng;\n dlat = mlat - lat;\n return [lng - dlng, lat - dlat];\n}\n\n/** 是否在 GCJ-02 偏移覆盖区(中国境内外判定) */\nexport function isInChina(lng: number, lat: number): boolean {\n return !outOfChina(lng, lat);\n}\n","/**\n * WGS84 <-> CGCS2000 转换。\n *\n * 说明:CGCS2000 与 WGS84 采用近似相同的参考椭球(扁率/长半轴差异极小,\n * 历元差异仅导致 cm~dm 级点位偏移),在 Web Mercator 显示尺度下等价于一致。\n * 因此 Phase 0 默认实现为恒等变换(残差 < 0.5m,满足 PRD 验收 F-1.1)。\n *\n * 测绘级高精度需求:可注入 `GridShiftProvider`(区域 7 参数 / 格网平移),\n * 见 types.ts。本文件保留可扩展入口。\n */\n\nimport type { GridShiftProvider, LngLat } from './types';\n\nlet gridShift: GridShiftProvider | null = null;\n\n/** 注册 CGCS2000 偏移提供方(可选,测绘级) */\nexport function setCgcs2000GridShift(provider: GridShiftProvider | null): void {\n gridShift = provider;\n}\n\n/** WGS84 -> CGCS2000 */\nexport function wgs84ToCgcs2000(lng: number, lat: number): LngLat {\n if (!gridShift) return [lng, lat];\n const [dLng, dLat] = gridShift.shift(lng, lat);\n return [lng + dLng, lat + dLat];\n}\n\n/** CGCS2000 -> WGS84 */\nexport function cgcs2000ToWgs84(lng: number, lat: number): LngLat {\n if (!gridShift) return [lng, lat];\n const [dLng, dLat] = gridShift.shift(lng, lat);\n return [lng - dLng, lat - dLat];\n}\n","/**\n * 坐标系变换组合器(以 WGS84 为枢纽)。\n *\n * 用法:\n * const t = createTransformer('GCJ02', 'WGS84');\n * const [lng, lat] = t.forward(114.30, 30.59); // GCJ-02 业务数据 -> 渲染基准\n */\n\nimport type { Bounds, CRS, LngLat, Transformer } from './types';\nimport { cgcs2000ToWgs84, wgs84ToCgcs2000 } from './cgcs2000';\nimport { gcj02ToWgs84, wgs84ToGcj02 } from './gcj02';\n\n/** 把任意 CRS 的坐标转换到 WGS84 */\nexport function toWgs84(crs: CRS, lng: number, lat: number): LngLat {\n switch (crs) {\n case 'WGS84':\n return [lng, lat];\n case 'GCJ02':\n return gcj02ToWgs84(lng, lat);\n case 'CGCS2000':\n return cgcs2000ToWgs84(lng, lat);\n }\n}\n\n/** 把 WGS84 坐标转换到目标 CRS */\nexport function fromWgs84(crs: CRS, lng: number, lat: number): LngLat {\n switch (crs) {\n case 'WGS84':\n return [lng, lat];\n case 'GCJ02':\n return wgs84ToGcj02(lng, lat);\n case 'CGCS2000':\n return wgs84ToCgcs2000(lng, lat);\n }\n}\n\nexport function createTransformer(from: CRS, to: CRS): Transformer {\n if (from === to) {\n const identity = (lng: number, lat: number): LngLat => [lng, lat];\n return { forward: identity, inverse: identity };\n }\n const forward = (lng: number, lat: number): LngLat => {\n const [wLng, wLat] = toWgs84(from, lng, lat);\n return fromWgs84(to, wLng, wLat);\n };\n const inverse = (lng: number, lat: number): LngLat => {\n const [wLng, wLat] = toWgs84(to, lng, lat);\n return fromWgs84(from, wLng, wLat);\n };\n return { forward, inverse };\n}\n\n/** 单点快捷转换 */\nexport function transformPoint(\n lng: number,\n lat: number,\n from: CRS,\n to: CRS\n): LngLat {\n return createTransformer(from, to).forward(lng, lat);\n}\n\n/** 范围 [w, s, e, n] 转换(取四个角点极值) */\nexport function transformBounds(b: Bounds, from: CRS, to: CRS): Bounds {\n const t = createTransformer(from, to);\n const xs: number[] = [];\n const ys: number[] = [];\n for (const [x, y] of [\n [b[0], b[1]],\n [b[2], b[1]],\n [b[0], b[3]],\n [b[2], b[3]],\n ]) {\n const [nx, ny] = t.forward(x, y);\n xs.push(nx);\n ys.push(ny);\n }\n return [Math.min(...xs), Math.min(...ys), Math.max(...xs), Math.max(...ys)];\n}\n","/**\n * 天地图(Tianditu)WMTS 底图源(F-1.2)。\n *\n * 天地图为国内权威底图,坐标系为 CGCS2000 / Web Mercator(显示尺度等价于 WGS84)。\n * token 必须由调用方在运行时注入,**绝不硬编码**;缺失时抛出明确错误。\n *\n * 文档:https://lbs.tianditu.gov.cn/server/MapService.html\n */\n\nexport type TiandituLayer =\n /** 矢量底图(含道路/注记基础) */\n | 'vec'\n /** 影像底图 */\n | 'img'\n /** 地形底图 */\n | 'ter'\n /** 矢量注记(道路/地名) */\n | 'cva'\n /** 影像注记 */\n | 'cia'\n /** 地形注记 */\n | 'cta'\n /** 矢量注记(英文) */\n | 'eva'\n /** 影像注记(英文) */\n | 'eia'\n /** 地形注记(英文) */\n | 'eta';\n\nexport type TiandituType = 'vector' | 'satellite' | 'terrain';\n\nexport interface TiandituOptions {\n /** 天地图授权 token(必填,运行时注入) */\n token: string;\n /** 语言:中文 cva/cia/cta 或英文 eva/eia/eta */\n lang?: 'zh' | 'en';\n /** 瓦片服务子域,默认 0-7 */\n subdomains?: number[];\n /** 瓦片尺寸,默认 256 */\n tileSize?: number;\n /** 最大层级,默认 18 */\n maxzoom?: number;\n}\n\nconst LAYER_MAP: Record<TiandituType, { base: TiandituLayer; label: TiandituLayer }> = {\n vector: { base: 'vec', label: 'cva' },\n satellite: { base: 'img', label: 'cia' },\n terrain: { base: 'ter', label: 'cta' },\n};\n\nconst LAYER_LABEL_EN: Partial<Record<TiandituLayer, TiandituLayer>> = {\n cva: 'eva',\n cia: 'eia',\n cta: 'eta',\n};\n\n/** 构建单张 WMTS 栅格源的 tiles URL 列表(含子域与 token) */\nexport function tiandituTileUrls(\n layer: TiandituLayer,\n opts: TiandituOptions\n): string[] {\n const sub = opts.subdomains ?? [0, 1, 2, 3, 4, 5, 6, 7];\n const labelLayer = opts.lang === 'en' ? LAYER_LABEL_EN[layer] ?? layer : layer;\n return sub.map(\n (s) =>\n `https://t${s}.tianditu.gov.cn/${labelLayer}_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=${labelLayer}&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${encodeURIComponent(opts.token)}`\n );\n}\n\nexport interface TiandituSourceSpec {\n id: string;\n source: {\n type: 'raster';\n tiles: string[];\n tileSize: number;\n maxzoom: number;\n attribution: string;\n };\n /** 是否注记层(绘制于底图之上) */\n isLabel: boolean;\n}\n\n/** 生成一组天地图源(底图 + 注记) */\nexport function buildTiandituSources(\n type: TiandituType,\n opts: TiandituOptions\n): TiandituSourceSpec[] {\n const { base, label } = LAYER_MAP[type];\n const tileSize = opts.tileSize ?? 256;\n const maxzoom = opts.maxzoom ?? 18;\n const attr = '© 天地图 GS(2023)3295号 · 草果地图';\n return [\n {\n id: `tianditu-${base}`,\n isLabel: false,\n source: {\n type: 'raster',\n tiles: tiandituTileUrls(base, opts),\n tileSize,\n maxzoom,\n attribution: attr,\n },\n },\n {\n id: `tianditu-${label}`,\n isLabel: true,\n source: {\n type: 'raster',\n tiles: tiandituTileUrls(label, opts),\n tileSize,\n maxzoom,\n attribution: attr,\n },\n },\n ];\n}\n\nexport class MissingTokenError extends Error {\n constructor() {\n super('天地图 token 缺失:调用 addTiandituBaseMap 必须传入 tianditu: { token } 选项。');\n this.name = 'MissingTokenError';\n }\n}\n","/**\n * 把天地图底图(底图 + 注记)作为源/图层添加到 MapLibre 地图实例。\n *\n * 由于天地图为栅格底图,推荐作为「无 style 背景」的地图底层:\n * 直接通过 setStyle 注入最小 style,或先 addSource + addLayer。\n * 这里提供低侵入的「注入已有 map」方式,业务可叠加自有矢量图层。\n */\n\nimport type { Map as MlMap, StyleSpecification } from 'maplibre-gl';\nimport {\n buildTiandituSources,\n MissingTokenError,\n type TiandituOptions,\n type TiandituType,\n} from './tianditu';\n\nexport interface AddTiandituOptions extends TiandituOptions {\n type?: TiandituType;\n /** 添加到指定地图实例 */\n map: MlMap;\n /** 注入为 style 的源/图层还是 addSource(默认 addSource + addLayer) */\n asStyle?: false;\n}\n\n/** 生成可直接作为 Map style 的天地图 Style JSON(含底图+注记两层) */\nexport function tiandituStyle(\n type: TiandituType,\n opts: TiandituOptions\n): StyleSpecification {\n if (!opts.token) throw new MissingTokenError();\n const sources = buildTiandituSources(type, opts);\n return {\n version: 8,\n glyphs: 'https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf',\n sources: Object.fromEntries(\n sources.map((s) => [s.id, s.source])\n ) as StyleSpecification['sources'],\n layers: sources.map((s) => ({\n id: s.id,\n type: 'raster' as const,\n source: s.id,\n // 注记层置于底图之上\n ...(s.isLabel ? { minzoom: 0 } : {}),\n })),\n };\n}\n\n/** 向已存在的地图实例注入天地图底图(底图 + 注记) */\nexport function addTiandituBaseMap(opts: AddTiandituOptions): void {\n if (!opts.token) throw new MissingTokenError();\n const type = opts.type ?? 'vector';\n const sources = buildTiandituSources(type, opts);\n const map = opts.map;\n for (const s of sources) {\n if (!map.getSource(s.id)) {\n map.addSource(s.id, s.source as never);\n }\n if (!map.getLayer(s.id)) {\n map.addLayer({\n id: s.id,\n type: 'raster',\n source: s.id,\n } as never);\n }\n }\n}\n","/**\n * 离线瓦片存储抽象层(F-1.4)。\n *\n * 设计:存储后端可插拔。浏览器用 IndexedDB(idb),Node/测试用内存实现。\n * 瓦片 key 统一为 `${sourceId}:${z}:${x}:${y}`,value 为原始字节 + 过期时间。\n */\n\nexport type TileFormat = 'pbf' | 'geojson' | 'png' | 'mvt' | 'json';\n\nexport interface StoredTile {\n data: ArrayBuffer | Uint8Array;\n format: TileFormat;\n /** 过期时间戳(ms);0 表示永不过期 */\n expires: number;\n}\n\nexport interface TileStoreBackend {\n get(key: string): Promise<StoredTile | undefined>;\n put(key: string, tile: StoredTile): Promise<void>;\n has(key: string): Promise<boolean>;\n delete(key: string): Promise<void>;\n clear(prefix?: string): Promise<void>;\n size(): Promise<number>;\n}\n\n/** 内存实现(测试 / 无 IndexedDB 环境) */\nexport class MemoryTileStore implements TileStoreBackend {\n private map = new Map<string, StoredTile>();\n async get(key: string) {\n const t = this.map.get(key);\n if (!t) return undefined;\n if (t.expires && t.expires < Date.now()) {\n this.map.delete(key);\n return undefined;\n }\n return t;\n }\n async put(key: string, tile: StoredTile) {\n this.map.set(key, tile);\n }\n async has(key: string) {\n return (await this.get(key)) !== undefined;\n }\n async delete(key: string) {\n this.map.delete(key);\n }\n async clear(prefix?: string) {\n if (!prefix) {\n this.map.clear();\n return;\n }\n for (const k of [...this.map.keys()]) {\n if (k.startsWith(prefix)) this.map.delete(k);\n }\n }\n async size() {\n return this.map.size;\n }\n}\n\nexport function tileKey(sourceId: string, z: number, x: number, y: number): string {\n return `${sourceId}:${z}:${x}:${y}`;\n}\n\n/** 离线协议名(caoguo-offline://...)。集中定义,供 protocol 与 serviceWorker 共用。 */\nexport const OFFLINE_PROTOCOL = 'caoguo-offline';\n\n/**\n * 解析离线协议 URL:`caoguo-offline://{sourceId}/{z}/{x}/{y}`\n * 返回 sourceId 与瓦片坐标,便于 ProtocolHandler 取瓦片。\n */\nexport function parseOfflineUrl(\n url: string\n): { sourceId: string; z: number; x: number; y: number } | null {\n const m = /^caoguo-offline:\\/\\/([^/]+)\\/(\\d+)\\/(\\d+)\\/(\\d+)$/.exec(url);\n if (!m) return null;\n return {\n sourceId: decodeURIComponent(m[1]),\n z: Number(m[2]),\n x: Number(m[3]),\n y: Number(m[4]),\n };\n}\n","/**\n * 离线协议加载器(F-1.4)。\n *\n * 通过 MapLibre `addProtocol('caoguo-offline', loader)` 注册自定义协议,\n * 瓦片源可声明 `tiles: ['caoguo-offline://{sourceId}/{z}/{x}/{y}']`,\n * 引擎即从离线存储读取瓦片,实现「空气隔离」离线底图。\n *\n * MapLibre v4 的 protocol handler 签名:\n * (requestParameters, abortController) => Promise<{ data: ArrayBuffer }>\n */\n\nimport type { AddProtocolAction, RequestParameters } from 'maplibre-gl';\nimport { parseOfflineUrl, tileKey, OFFLINE_PROTOCOL, type TileStoreBackend } from './storage';\n\nexport { OFFLINE_PROTOCOL };\n\nexport interface OfflineProtocolContext {\n store: TileStoreBackend;\n}\n\n/** 构造离线协议 URL(供 source.tiles 使用) */\nexport function offlineTileUrl(sourceId: string, z: number, x: number, y: number): string {\n return `${OFFLINE_PROTOCOL}://${encodeURIComponent(sourceId)}/${z}/${x}/${y}`;\n}\n\n/** 生成离线栅格/矢量源的 tiles 数组 */\nexport function offlineSourceTiles(sourceId: string): string[] {\n return [`${OFFLINE_PROTOCOL}://${encodeURIComponent(sourceId)}/{z}/{x}/{y}`];\n}\n\n/** 把存储中的瓦片数据规整为 ArrayBuffer */\nfunction toArrayBuffer(data: ArrayBuffer | Uint8Array): ArrayBuffer {\n if (data instanceof Uint8Array) {\n const out = new ArrayBuffer(data.byteLength);\n new Uint8Array(out).set(data);\n return out;\n }\n // ArrayBufferLike 可能含 SharedArrayBuffer,复制为独立 ArrayBuffer\n const src = data as ArrayBuffer;\n const out = new ArrayBuffer(src.byteLength);\n new Uint8Array(out).set(new Uint8Array(src));\n return out;\n}\n\n/**\n * 创建离线协议 loader(返回可直接传给 addProtocol 的异步函数)。\n * 未命中瓦片时 reject,由 MapLibre 回退到线上源(若配置)。\n */\nexport function createOfflineLoader(ctx: OfflineProtocolContext): AddProtocolAction {\n return (params: RequestParameters) => {\n const url = params.url;\n const parsed = parseOfflineUrl(url);\n if (!parsed) {\n return Promise.reject(new Error(`非法离线 URL: ${url}`));\n }\n const key = tileKey(parsed.sourceId, parsed.z, parsed.x, parsed.y);\n return ctx.store.get(key).then((tile) => {\n if (!tile) {\n throw new Error(`离线瓦片缺失: ${key}`);\n }\n return { data: toArrayBuffer(tile.data) };\n });\n };\n}\n\n/** 在指定地图实例上注册离线协议 */\nexport function registerOfflineProtocol(\n maplibregl: { addProtocol: (name: string, action: AddProtocolAction) => void },\n ctx: OfflineProtocolContext\n): void {\n maplibregl.addProtocol(OFFLINE_PROTOCOL, createOfflineLoader(ctx));\n}\n","/**\n * 离线瓦片打包器(F-1.4)。\n *\n * 把本地瓦片导入离线存储:\n * - 原始 {z}/{x}/{y}.pbf|png 目录结构\n * - 单张 GeoJSON(按 z/x/y 网格切片为矢量瓦片缓冲,供 `caoguo-offline` 协议读取)\n *\n * 这里的「切片」为简化实现:GeoJSON 按瓦片网格空间包含关系分桶,\n * 仅把要素写入对应瓦片(不做 MVT 编码),存储为 UTF-8 JSON,\n * 由 protocol loader 以 `geojson` 格式返回,source type 用 geojson。\n * 生产级 MVT 编码(tippecanoe / @mapbox/vector-tile)可后续接入。\n */\n\nimport { tileKey, type StoredTile, type TileStoreBackend, type TileFormat } from './storage';\n\nconst MAX_ZOOM_DEFAULT = 14;\n\nfunction lon2x(lon: number, z: number): number {\n return Math.floor(((lon + 180) / 360) * Math.pow(2, z));\n}\nfunction lat2y(lat: number, z: number): number {\n const rad = (lat * Math.PI) / 180;\n return Math.floor(\n ((1 - Math.log(Math.tan(rad) + 1 / Math.cos(rad)) / Math.PI) / 2) * Math.pow(2, z)\n );\n}\n\nfunction tileBounds(z: number, x: number, y: number): [number, number, number, number] {\n const n = Math.pow(2, z);\n const lonWest = (x / n) * 360 - 180;\n const lonEast = ((x + 1) / n) * 360 - 180;\n const latNorth = (Math.atan(Math.sinh(Math.PI * (1 - (2 * y) / n))) * 180) / Math.PI;\n const latSouth = (Math.atan(Math.sinh(Math.PI * (1 - (2 * (y + 1)) / n))) * 180) / Math.PI;\n return [lonWest, latSouth, lonEast, latNorth];\n}\n\nfunction coordInTile(lon: number, lat: number, z: number, x: number, y: number): boolean {\n const [w, s, e, n] = tileBounds(z, x, y);\n return lon >= w && lon <= e && lat >= s && lat <= n;\n}\n\nexport interface PackGeoJSONOptions {\n sourceId: string;\n geojson: {\n type: 'FeatureCollection';\n features: Array<{\n geometry: { type: string; coordinates: unknown };\n properties: Record<string, unknown>;\n }>;\n };\n maxZoom?: number;\n /** 过期时间(ms 时间戳),0=永不过期 */\n expires?: number;\n onProgress?: (done: number, total: number) => void;\n}\n\n/**\n * 将 GeoJSON 按瓦片网格分桶写入离线存储。\n * 返回写入的瓦片数量。\n */\nexport async function packGeoJSONToStore(\n store: TileStoreBackend,\n opts: PackGeoJSONOptions\n): Promise<number> {\n const maxZoom = opts.maxZoom ?? MAX_ZOOM_DEFAULT;\n const expires = opts.expires ?? 0;\n const buckets = new Map<string, unknown[]>();\n\n for (const f of opts.geojson.features) {\n const g = f.geometry;\n const coords: number[][] = [];\n if (g.type === 'Point' || g.type === 'Circle') {\n coords.push(g.coordinates as number[]);\n } else if (g.type === 'LineString' || g.type === 'MultiPoint') {\n coords.push(...(g.coordinates as number[][]));\n } else if (g.type === 'Polygon' || g.type === 'MultiLineString') {\n for (const ring of g.coordinates as number[][][]) coords.push(...ring);\n } else if (g.type === 'MultiPolygon') {\n for (const poly of g.coordinates as number[][][][]) {\n for (const ring of poly) coords.push(...ring);\n }\n }\n for (const [lon, lat] of coords) {\n // 在每个缩放层级把要素写入其命中的瓦片(父瓦片亦包含,保证任意层级请求命中)\n for (let z = 0; z <= maxZoom; z++) {\n const x = lon2x(lon, z);\n const y = lat2y(lat, z);\n if (coordInTile(lon, lat, z, x, y)) {\n const k = tileKey(opts.sourceId, z, x, y);\n if (!buckets.has(k)) buckets.set(k, []);\n (buckets.get(k) as unknown[]).push(f);\n }\n }\n }\n }\n\n const total = buckets.size;\n let done = 0;\n for (const [k, features] of buckets) {\n const fc = { type: 'FeatureCollection', features };\n const tile: StoredTile = {\n data: new TextEncoder().encode(JSON.stringify(fc)),\n format: 'geojson' as TileFormat,\n expires,\n };\n await store.put(k, tile);\n done++;\n opts.onProgress?.(done, total);\n }\n return total;\n}\n\n/**\n * 由离线存储构造一个 geojson 源(用于 MapLibre source.tiles)。\n * 注意:geojson 协议瓦片由 protocol loader 直接返回 FeatureCollection。\n */\nexport function offlineGeoJSONSource(\n sourceId: string\n): { type: 'geojson'; data: never } & { tiles: string[]; _caoguoOffline: true; _sourceId: string } {\n return {\n type: 'geojson',\n data: undefined as never,\n tiles: [`caoguo-offline://${encodeURIComponent(sourceId)}/{z}/{x}/{y}`],\n _caoguoOffline: true,\n _sourceId: sourceId,\n } as never;\n}\n","/**\n * Service Worker 离线拦截(T5 / F-1.6)。\n *\n * 目标:在 T4 离线瓦片(IndexedDB + caoguo-offline 协议)之上,增加一层\n * **网络级二级缓存**——用 Cache API 缓存线上请求的瓦片(天地图等),并在\n * 「空气隔离(air-gap)」模式下拦截所有请求、用 Cache/离线存储兜底,\n * 实现断网后地图仍可平移缩放。\n *\n * 设计:\n * - `resolveCacheKey` / `shouldCache` / `resolveResponse` 是**纯函数 core**,\n * 不依赖真实 ServiceWorker 全局,可在 Node/vitest 中直接测试。\n * - `createFetchHandler` 把 core 包装成标准 `fetch` 事件处理器(注入 cache 与 store)。\n * - 浏览器侧用 `registerServiceWorker` 注册脚本,并通过 postMessage 切换空气隔离模式。\n *\n * 与 T4 的边界:T4 负责「业务离线瓦片 → IndexedDB → maplibre 协议」,\n * 本模块负责「线上瓦片请求 → Cache API 二级缓存 + 空气隔离拦截」,\n * 二者互补:T4 命中时根本不发网络请求(协议层短路),未命中时才走到 SW 缓存。\n */\n\nimport { OFFLINE_PROTOCOL, tileKey, type TileStoreBackend } from './storage';\n\n/** 需要二级缓存的瓦片来源(host 白名单,避免缓存无关资源) */\nexport const CACHEABLE_HOSTS = ['t0.tianditu.gov.cn', 't7.tianditu.gov.cn', 'tianditu.gov.cn'];\n\n/** 缓存名称(版本化,便于失效升级) */\nexport const CACHE_NAME = 'caoguo-offline-tiles-v1';\n\n/** 空气隔离模式消息协议 */\nexport const MSG_AIRGAP = 'caoguo:airgap' as const;\n\nexport interface AirgapMessage {\n type: typeof MSG_AIRGAP;\n /** true=开启空气隔离(断网模式),false=恢复在线优先 */\n enabled: boolean;\n}\n\n/**\n * 判断请求是否应进入离线二级缓存。\n * 只缓存 GET 请求 & 白名单 host & 图片/瓦片类型(保守策略)。\n */\nexport function shouldCache(request: { method: string; url: string }): boolean {\n if (request.method !== 'GET') return false;\n try {\n const u = new URL(request.url);\n // 离线协议请求(caoguo-offline://)由 T4 处理,不在此缓存\n if (u.protocol === `${OFFLINE_PROTOCOL}:`) return false;\n return CACHEABLE_HOSTS.some((h) => u.host === h || u.host.endsWith(`.${h}`));\n } catch {\n return false;\n }\n}\n\n/**\n * 计算 Cache Storage 的 key。优先用 URL(含 query,token 不同视为不同资源),\n * 否则回退到 request 对象本身。\n */\nexport function resolveCacheKey(request: { url: string }): string {\n return request.url;\n}\n\n/**\n * 从存储(IndexedDB/T4 离线)尝试取得瓦片兜底。\n * 用于空气隔离模式下网络不可达时返回上次离线打包的瓦片。\n */\nexport async function resolveFromStore(\n store: TileStoreBackend | undefined,\n request: { url: string }\n): Promise<{ data: ArrayBuffer; contentType: string } | undefined> {\n if (!store) return undefined;\n const z = /TILEMATRIX=(\\d+)/.exec(request.url)?.[1];\n const x = /TILECOL=(\\d+)/.exec(request.url)?.[1];\n const y = /TILEROW=(\\d+)/.exec(request.url)?.[1];\n if (!z || !x || !y) return undefined;\n // 天地图瓦片 key 以 sourceId 前缀;此处用 url 中的 layer 推断 sourceId\n const layer = /LAYER=([a-z]+)/.exec(request.url)?.[1] ?? 'tianditu';\n const key = tileKey(`td-${layer}`, Number(z), Number(x), Number(y));\n const tile = await store.get(key);\n if (!tile) return undefined;\n const buf = tile.data instanceof Uint8Array ? tile.data : new Uint8Array(tile.data);\n return { data: buf.buffer as ArrayBuffer, contentType: 'image/png' };\n}\n\nexport interface ResolveResponseDeps {\n /** 实际的 fetch 实现(浏览器为全局 fetch,测试可注入) */\n fetchImpl: (input: string) => Promise<{ ok: boolean; status: number; arrayBuffer: () => Promise<ArrayBuffer>; headers: { get: (k: string) => string | null } }>;\n /** Cache 接口(浏览器为全局 caches,测试可注入内存实现) */\n cache: {\n match: (key: string) => Promise<CacheEntry | undefined>;\n put: (key: string, resp: unknown) => Promise<void>;\n };\n /** 空气隔离开关(闭包状态,由消息控制) */\n airgap: { enabled: boolean };\n /** T4 离线存储(可选,空气隔离兜底) */\n store?: TileStoreBackend;\n}\n\ninterface CacheEntry {\n ok: boolean;\n status: number;\n arrayBuffer: () => Promise<ArrayBuffer>;\n headers: { get: (k: string) => string | null };\n}\n\nexport interface ResolvedResponse {\n /** 最终响应主体 */\n data: ArrayBuffer;\n /** 内容类型 */\n contentType: string;\n /** 来源:cache=命中缓存 / network=线上最新 / store=离线存储兜底 */\n source: 'cache' | 'network' | 'store';\n /** 该响应是否应写回缓存 */\n cacheable: boolean;\n}\n\n/**\n * 核心解析逻辑(纯函数,可测试)。\n * 两种模式:\n * - 在线优先(airgap=false):cache → network(写回 cache) → store 兜底\n * - 空气隔离(airgap=true):cache → store 兜底(不发网络请求)\n */\nexport async function resolveResponse(\n request: { method: string; url: string },\n deps: ResolveResponseDeps\n): Promise<ResolvedResponse | null> {\n if (!shouldCache(request)) return null;\n\n const key = resolveCacheKey(request);\n\n // 1) Cache 优先\n const cached = await deps.cache.match(key);\n if (cached && cached.ok) {\n return {\n data: await cached.arrayBuffer(),\n contentType: cached.headers.get('content-type') ?? 'image/png',\n source: 'cache',\n cacheable: false,\n };\n }\n\n // 2) 空气隔离模式:禁止网络,直接走离线存储兜底\n if (deps.airgap.enabled) {\n const fromStore = await resolveFromStore(deps.store, request);\n if (fromStore) {\n return { ...fromStore, source: 'store', cacheable: false };\n }\n return null; // 离线且无任何缓存:放弃(交由上层 404/透明恢复)\n }\n\n // 3) 在线优先:fetch 并写回 Cache\n try {\n const resp = await deps.fetchImpl(request.url);\n if (resp.ok) {\n const data = await resp.arrayBuffer();\n const contentType = resp.headers.get('content-type') ?? 'image/png';\n // 异步写回缓存(不阻塞响应)\n void deps.cache\n .put(key, {\n ok: true,\n status: resp.status,\n arrayBuffer: async () => data,\n headers: { get: (k: string) => (k.toLowerCase() === 'content-type' ? contentType : null) },\n })\n .catch(() => undefined);\n return { data, contentType, source: 'network', cacheable: true };\n }\n } catch {\n // 网络失败:回退 store\n const fromStore = await resolveFromStore(deps.store, request);\n if (fromStore) {\n return { ...fromStore, source: 'store', cacheable: false };\n }\n }\n return null;\n}\n\n/**\n * 包装为 Service Worker 的 fetch 事件处理器。\n * 注入真实的 caches / fetch / store。在浏览器 SW 全局中调用:\n * self.addEventListener('fetch', createFetchHandler({ store }));\n */\nexport function createFetchHandler(opts: {\n store?: TileStoreBackend;\n airgap?: { enabled: boolean };\n}): (event: { request: { method: string; url: string }; respondWith: (r: Promise<Response> | Response) => void }) => void {\n const airgap = opts.airgap ?? { enabled: false };\n return (event) => {\n const request = event.request;\n event.respondWith(\n (async () => {\n const deps: ResolveResponseDeps = {\n fetchImpl: (u) => fetch(u) as unknown as ResolveResponseDeps['fetchImpl'] extends (a: string) => infer R ? R : never,\n cache: caches as unknown as ResolveResponseDeps['cache'],\n airgap,\n store: opts.store,\n };\n const res = await resolveResponse(request, deps);\n if (res) {\n return new Response(res.data, {\n status: 200,\n headers: { 'content-type': res.contentType, 'x-caoguo-source': res.source },\n });\n }\n // 非瓦片请求 / 空气隔离缺失:透明放行\n return fetch(request.url);\n })()\n );\n };\n}\n\n/**\n * 在 Service Worker 全局上安装离线拦截逻辑(浏览器 SW 脚本入口)。\n * 处理 install/activate 生命周期、airgap 消息、fetch 拦截。\n */\nexport function installServiceWorker(sw: {\n addEventListener: (type: string, handler: (ev: unknown) => void) => void;\n caches: unknown;\n store?: TileStoreBackend;\n}): { airgap: { enabled: boolean } } {\n const airgap = { enabled: false };\n\n sw.addEventListener('install', () => {\n // @ts-expect-error 浏览器全局\n sw.skipWaiting?.();\n });\n sw.addEventListener('activate', () => {\n // @ts-expect-error 浏览器全局\n sw.clients?.claim?.();\n });\n sw.addEventListener('message', (ev: unknown) => {\n const msg = ev as { data?: AirgapMessage };\n if (msg.data?.type === MSG_AIRGAP) {\n airgap.enabled = !!msg.data.enabled;\n }\n });\n sw.addEventListener('fetch', createFetchHandler({ store: sw.store, airgap }) as never);\n\n return { airgap };\n}\n\n/**\n * 浏览器端注册离线 Service Worker(主线程调用)。\n * 需要项目提供 SW 脚本文件(见 `sw-template` 注释),并部署到与地图同域根路径。\n *\n * @param scriptUrl SW 脚本 URL(如 '/caoguo-sw.js'),需调用方自行构建/放置\n * @returns 注册成功的 ServiceWorker 实例;不支持时返回 null\n */\nexport async function registerOfflineServiceWorker(\n scriptUrl: string\n): Promise<ServiceWorkerRegistration | null> {\n if (typeof navigator === 'undefined' || !('serviceWorker' in navigator)) return null;\n try {\n return await navigator.serviceWorker.register(scriptUrl);\n } catch {\n return null;\n }\n}\n\n/**\n * 向已注册的 Service Worker 发送消息,切换「空气隔离」模式。\n * enabled=true 时地图进入断网可用状态(仅用 Cache + T4 离线存储)。\n */\nexport function setAirgap(registration: ServiceWorkerRegistration, enabled: boolean): void {\n const ctrl = registration.active ?? registration.installing ?? registration.waiting;\n ctrl?.postMessage({ type: MSG_AIRGAP, enabled } satisfies AirgapMessage as unknown);\n}\n\n/**\n * SW 脚本模板(供调用方写入部署文件,如 public/caoguo-sw.js)。\n * 该脚本通过 importScripts 复用本包编译产物,或直接内联 installServiceWorker。\n *\n * ```js\n * // caoguo-sw.js\n * importScripts('/caoguo-offline-sw.bundle.js'); // 含 installServiceWorker\n * installServiceWorker(self);\n * ```\n */\nexport const SW_TEMPLATE_HINT =\n \"importScripts('caoguo-offline-sw.bundle.js'); installServiceWorker(self);\";\n","/**\n * IndexedDB 离线瓦片后端(浏览器环境,F-1.4)。\n * 延迟依赖 idb;仅当运行在浏览器时加载,避免 Node/测试环境报错。\n */\n\nimport { MemoryTileStore, type StoredTile, type TileStoreBackend } from './storage';\n\ninterface RawRow {\n key: string;\n data: ArrayBuffer | Uint8Array;\n format: StoredTile['format'];\n expires: number;\n}\n\nlet dbPromise: Promise<unknown> | null = null;\n\nfunction getDb(): Promise<unknown> {\n if (!dbPromise) {\n dbPromise = (async () => {\n const { openDB } = await import('idb');\n return openDB('caoguo-offline', 1, {\n upgrade(db: any) {\n if (!db.objectStoreNames.contains('tiles')) {\n const store = db.createObjectStore('tiles', { keyPath: 'key' });\n store.createIndex('sourceId', 'sourceId');\n }\n },\n });\n })();\n }\n return dbPromise;\n}\n\nexport class IdbTileStore implements TileStoreBackend {\n async get(key: string): Promise<StoredTile | undefined> {\n const db: any = await getDb();\n const row: RawRow | undefined = await db.get('tiles', key);\n if (!row) return undefined;\n if (row.expires && row.expires < Date.now()) {\n await this.delete(key);\n return undefined;\n }\n return { data: row.data, format: row.format, expires: row.expires };\n }\n async put(key: string, tile: StoredTile): Promise<void> {\n const db: any = await getDb();\n const sourceId = key.split(':')[0];\n await db.put('tiles', {\n key,\n sourceId,\n data: tile.data,\n format: tile.format,\n expires: tile.expires,\n });\n }\n async has(key: string): Promise<boolean> {\n return (await this.get(key)) !== undefined;\n }\n async delete(key: string): Promise<void> {\n const db: any = await getDb();\n await db.delete('tiles', key);\n }\n async clear(prefix?: string): Promise<void> {\n const db: any = await getDb();\n if (!prefix) {\n await db.clear('tiles');\n return;\n }\n const tx = db.transaction('tiles', 'readwrite');\n const idx = tx.store.index('sourceId');\n let cursor = await idx.openCursor(prefix);\n while (cursor) {\n await cursor.delete();\n cursor = await cursor.continue();\n }\n await tx.done;\n }\n async size(): Promise<number> {\n const db: any = await getDb();\n return db.count('tiles');\n }\n}\n\n/** 浏览器环境默认用 IndexedDB,否则回退内存 */\nexport function createDefaultStore(): TileStoreBackend {\n if (typeof indexedDB !== 'undefined') {\n try {\n return new IdbTileStore();\n } catch {\n /* fallthrough */\n }\n }\n return new MemoryTileStore();\n}\n","/**\n * 比例尺 + 坐标显示控件(T8 / F-1.8)。\n *\n * - 比例尺:基于 Web Mercator 在给定纬度下的地面分辨率(m/像素),\n * 自动选择「米 / 公里」并吸附到 1/2/5 的整数档(标准地图比例尺行为)。\n * - 坐标:鼠标在图上移动时,实时显示当前光标处的经纬坐标(WGS84 渲染基准)。\n *\n * 设计为「纯函数 core + 薄 DOM 绑定」:比例计算 `computeScaleBar` 不依赖浏览器,\n * 可独立单测;`ScaleControl` 类负责把结果渲染进容器并监听地图事件。\n */\n\nexport type LengthUnit = 'metric';\n\nexport interface ScaleBar {\n /** 比例尺条代表的真实距离(米) */\n meters: number;\n /** 比例尺条在屏幕上的像素宽度 */\n pixels: number;\n /** 展示文案,如 \"500 m\" / \"2 km\" */\n label: string;\n}\n\nconst EARTH_RADIUS = 6378137; // WGS84 赤道半径(米)\n\n/**\n * 计算比例尺。\n * @param latitude 当前视图中心纬度(度)\n * @param zoom MapLibre zoom(Web Mercator)\n * @param dpiScale 设备像素比(默认 1;Retina 设为 window.devicePixelRatio)\n * @param maxWidth 比例尺条最大像素宽度(默认 100)\n * @param tileSize 瓦片像素尺寸(默认 512,MapLibre v4 默认)\n */\nexport function computeScaleBar(\n latitude: number,\n zoom: number,\n opts: { dpiScale?: number; maxWidth?: number; tileSize?: number } = {}\n): ScaleBar {\n const dpiScale = opts.dpiScale ?? 1;\n const maxWidth = opts.maxWidth ?? 100;\n const tileSize = opts.tileSize ?? 512;\n\n // 每像素的地面距离(米/像素),在给定纬度下\n const latRad = (latitude * Math.PI) / 180;\n const metersPerPixel =\n (Math.cos(latRad) * 2 * Math.PI * EARTH_RADIUS) /\n (tileSize * Math.pow(2, zoom) * dpiScale);\n\n // 最大像素宽度对应的真实距离\n let meters = metersPerPixel * maxWidth;\n\n // 吸附到 1/2/5 档\n const pow = Math.pow(10, Math.floor(Math.log10(meters)));\n const base = meters / pow; // 1..10\n const step = base >= 5 ? 5 : base >= 2 ? 2 : 1;\n meters = step * pow;\n\n const pixels = meters / metersPerPixel;\n const label = meters >= 1000 ? `${(meters / 1000).toLocaleString()} km` : `${Math.round(meters)} m`;\n\n return { meters, pixels, label };\n}\n\nexport interface ScaleControlOptions {\n /** 挂载容器(可选;不传则在地图容器内自动创建) */\n container?: HTMLElement;\n /** 是否显示实时坐标(默认 true) */\n showCoordinate?: boolean;\n /** 最大比例尺像素宽度 */\n maxWidth?: number;\n}\n\n/**\n * 比例尺控件。需传入 maplibre Map 实例(直接用 maplibre-gl 的 Map)。\n */\nexport class ScaleControl {\n private el: HTMLElement;\n private barEl: HTMLElement;\n private labelEl: HTMLElement;\n private coordEl?: HTMLElement;\n private map: { getZoom: () => number; getCenter: () => { lat: number }; on: (e: string, h: (ev: unknown) => void) => void; off: (e: string, h: (ev: unknown) => void) => void; getCanvas?: () => { addEventListener: (t: string, h: (ev: unknown) => void) => void; removeEventListener: (t: string, h: (ev: unknown) => void) => void } };\n private opts: Required<Omit<ScaleControlOptions, 'container'>>;\n private onMove = (ev: unknown) => this.handleMove(ev);\n private onZoom = () => this.update();\n\n constructor(\n map: ScaleControl['map'],\n options: ScaleControlOptions = {}\n ) {\n this.map = map;\n this.opts = {\n showCoordinate: options.showCoordinate ?? true,\n maxWidth: options.maxWidth ?? 100,\n };\n this.el = options.container ?? document.createElement('div');\n this.el.className = 'caoguo-scale-control';\n this.el.style.cssText =\n 'position:absolute;left:10px;bottom:24px;padding:4px 8px;background:rgba(10,15,30,.7);color:#cfe;border-radius:4px;font:12px/1.4 system-ui,sans-serif;pointer-events:none;z-index:2;';\n\n this.barEl = document.createElement('div');\n this.barEl.style.cssText =\n 'height:6px;border:1px solid #cfe;border-top:none;margin-bottom:2px;';\n this.labelEl = document.createElement('div');\n if (this.opts.showCoordinate) {\n this.coordEl = document.createElement('div');\n this.coordEl.style.cssText = 'opacity:.85;margin-top:2px;';\n this.el.append(this.barEl, this.labelEl, this.coordEl);\n } else {\n this.el.append(this.barEl, this.labelEl);\n }\n\n map.on('zoom', this.onZoom);\n map.on('move', this.onZoom);\n const canvas = (map as any).getCanvas?.();\n canvas?.addEventListener('mousemove', this.onMove as never);\n }\n\n /** 把控件挂到地图容器(无预设容器时调用) */\n addTo(container: HTMLElement): this {\n if (!this.el.parentElement) container.appendChild(this.el);\n this.update();\n return this;\n }\n\n /** 计算并刷新显示 */\n update(): void {\n const center = this.map.getCenter();\n const bar = computeScaleBar(center.lat, this.map.getZoom(), { maxWidth: this.opts.maxWidth });\n this.barEl.style.width = `${Math.round(bar.pixels)}px`;\n this.labelEl.textContent = bar.label;\n }\n\n private handleMove(ev: unknown): void {\n if (!this.coordEl) return;\n const e = ev as { lngLat?: { lng: number; lat: number } };\n const ll = e.lngLat;\n if (!ll) return;\n this.coordEl.textContent = `${ll.lng.toFixed(5)}, ${ll.lat.toFixed(5)}`;\n }\n\n /** 移除控件与事件监听 */\n remove(): void {\n this.map.off('zoom', this.onZoom);\n this.map.off('move', this.onZoom);\n const canvas = (this.map as any).getCanvas?.();\n canvas?.removeEventListener('mousemove', this.onMove as never);\n this.el.remove();\n }\n}\n","/**\n * 主题切换控件(T8 / F-1.9)。\n *\n * 在暗色(caoguo-dark)与亮色(caoguo-light)官方矢量主题间切换,\n * 调用 `map.setStyle` 并保留当前视图(center/zoom)与现有 GeoJSON 源/图层。\n *\n * 设计为「纯函数 core + 薄 DOM 绑定」:\n * - `toggleTheme` / `themeFromStyle` 为纯逻辑,可独立单测;\n * - `ThemeSwitcher` 类负责渲染按钮并绑定点击事件。\n */\n\nimport { caoguoStyle } from '../styles';\nimport type { ThemeName } from '@caoguo/theme';\n\nexport interface ThemeSwitcherOptions {\n /** 挂载容器(可选) */\n container?: HTMLElement;\n /** 初始主题 */\n initial?: ThemeName;\n}\n\nexport function oppositeTheme(theme: ThemeName): ThemeName {\n return theme === 'caoguo-dark' ? 'caoguo-light' : 'caoguo-dark';\n}\n\n/**\n * 从当前 style 对象推断主题名(依据其 JSON 标识)。\n * 非草果主题时回退到传入的 fallback。\n */\nexport function themeFromStyle(\n style: { name?: string } | string | null | undefined,\n fallback: ThemeName = 'caoguo-dark'\n): ThemeName {\n if (!style) return fallback;\n const name = typeof style === 'string' ? style : style.name;\n if (name === 'caoguo-dark' || name === 'caoguo-light') return name;\n return fallback;\n}\n\nexport class ThemeSwitcher {\n private el: HTMLElement;\n private btn: HTMLButtonElement;\n private current: ThemeName;\n private map: {\n getStyle: () => { name?: string } | undefined;\n setStyle: (s: unknown, opts?: { diff?: boolean }) => void;\n };\n\n constructor(map: ThemeSwitcher['map'], options: ThemeSwitcherOptions = {}) {\n this.map = map;\n this.current = options.initial ?? themeFromStyle(map.getStyle?.(), 'caoguo-dark');\n\n this.el = options.container ?? document.createElement('div');\n this.el.className = 'caoguo-theme-switcher';\n this.el.style.cssText =\n 'position:absolute;right:10px;top:10px;z-index:3;';\n\n this.btn = document.createElement('button');\n this.btn.type = 'button';\n this.applyLabel();\n this.btn.style.cssText =\n 'cursor:pointer;padding:4px 10px;border:1px solid #2a3550;border-radius:6px;' +\n 'background:rgba(10,15,30,.7);color:#cfe;font:12px system-ui,sans-serif;';\n this.btn.addEventListener('click', () => this.toggle());\n this.el.append(this.btn);\n }\n\n private applyLabel(): void {\n this.btn.textContent = this.current === 'caoguo-dark' ? '🌙 暗色' : '☀ 亮色';\n }\n\n /** 当前主题 */\n getTheme(): ThemeName {\n return this.current;\n }\n\n /** 切换到指定主题(保留视图,diff 模式避免闪烁) */\n setTheme(theme: ThemeName): void {\n if (theme === this.current) return;\n this.current = theme;\n this.applyLabel();\n this.map.setStyle(caoguoStyle(theme), { diff: true });\n }\n\n /** 在明暗之间切换 */\n toggle(): void {\n this.setTheme(oppositeTheme(this.current));\n }\n\n /** 挂到容器 */\n addTo(container: HTMLElement): this {\n if (!this.el.parentElement) container.appendChild(this.el);\n return this;\n }\n\n /** 移除 */\n remove(): void {\n this.btn.removeEventListener('click', () => this.toggle());\n this.el.remove();\n }\n}\n","/**\n * 图例控件(通用)。\n *\n * 行业专题图(水深色阶 / 光缆利用率 / 闸站状态 / 故障告警等)渲染后,\n * 需要用户可读的图例说明。本控件接收数据驱动的图例项(label + color),\n * 以「色块 + 文案」形式渲染;支持运行时 setItems 随图层切换更新。\n *\n * 设计为「纯函数 renderLegendHtml + 薄 DOM 绑定」:renderLegendHtml 不依赖浏览器,可独立单测。\n */\n\nexport interface LegendItem {\n /** 文案,如「水深 > 3m」「利用率高」 */\n label: string;\n /** 色值(CSS color,可与渲染层 paint 配色保持一致) */\n color: string;\n /** 标记形状:color 色块(默认)/ line 线段 */\n shape?: 'color' | 'line';\n}\n\nexport interface LegendOptions {\n /** 图例标题(可选) */\n title?: string;\n /** 图例项 */\n items: LegendItem[];\n /** 挂载容器(可选;不传则自动创建) */\n container?: HTMLElement;\n}\n\nfunction escapeHtml(s: string): string {\n return s.replace(/[&<>\"']/g, (c) =>\n c === '&' ? '&amp;' : c === '<' ? '&lt;' : c === '>' ? '&gt;' : c === '\"' ? '&quot;' : '&#39;',\n );\n}\n\n/** 纯函数:根据图例项生成 HTML 字符串(可单测) */\nexport function renderLegendHtml(items: LegendItem[], title?: string): string {\n const titleHtml = title ? `<div class=\"cg-legend-title\">${escapeHtml(title)}</div>` : '';\n const itemsHtml = items\n .map((it) => {\n const swatch =\n it.shape === 'line'\n ? `<span class=\"cg-legend-swatch cg-legend-swatch--line\" style=\"background:${it.color}\"></span>`\n : `<span class=\"cg-legend-swatch\" style=\"background:${it.color}\"></span>`;\n return `<div class=\"cg-legend-item\">${swatch}<span>${escapeHtml(it.label)}</span></div>`;\n })\n .join('');\n return `<div class=\"cg-legend-body\">${titleHtml}${itemsHtml}</div>`;\n}\n\n/** 图例控件 */\nexport class LegendControl {\n private el: HTMLElement;\n private bodyEl: HTMLElement;\n private opts: Required<Pick<LegendOptions, 'title'>> & { items: LegendItem[] };\n\n constructor(options: LegendOptions) {\n this.opts = { title: options.title ?? '', items: options.items };\n this.el = options.container ?? document.createElement('div');\n this.el.className = 'caoguo-legend-control';\n this.el.style.cssText =\n 'position:absolute;right:10px;top:10px;padding:8px 10px;background:rgba(10,15,30,.72);color:#cfe;border-radius:6px;font:12px/1.5 system-ui,sans-serif;z-index:2;max-width:220px;';\n this.bodyEl = document.createElement('div');\n this.el.appendChild(this.bodyEl);\n this.render();\n }\n\n private render(): void {\n this.bodyEl.innerHTML = renderLegendHtml(this.opts.items, this.opts.title || undefined);\n }\n\n /** 运行时更新图例项(随图层切换重新渲染) */\n setItems(items: LegendItem[], title?: string): void {\n if (title !== undefined) this.opts.title = title;\n this.opts.items = items;\n this.render();\n }\n\n /** 挂载到容器 */\n addTo(container: HTMLElement): this {\n if (!this.el.parentElement) container.appendChild(this.el);\n return this;\n }\n\n remove(): void {\n this.el.remove();\n }\n}\n","/**\n * 地图导出控件(通用)。\n *\n * 行业专题图渲染后,常需导出当前视图为成果图(PNG)。\n * 基于 maplibre-gl 画布 `toDataURL('image/png')` 生成截图并触发浏览器下载。\n *\n * 设计为「纯函数 triggerDownload + 薄 DOM 绑定」:triggerDownload 不依赖地图,可独立单测。\n */\n\nexport interface ExportOptions {\n /** 下载文件名(不含扩展名) */\n filename?: string;\n /** 挂载容器(可选;不传则自动创建) */\n container?: HTMLElement;\n /** 按钮文案 */\n buttonText?: string;\n}\n\n/** 纯函数:触发浏览器下载(data URL) */\nexport function triggerDownload(dataUrl: string, filename: string): void {\n const a = document.createElement('a');\n a.href = dataUrl;\n a.download = filename.endsWith('.png') ? filename : `${filename}.png`;\n document.body.appendChild(a);\n a.click();\n a.remove();\n}\n\n/** 导出控件 */\nexport class ExportControl {\n private el: HTMLElement;\n private map: {\n getCanvas: () => { toDataURL: (type?: string) => string };\n };\n private filename: string;\n private onClick = () => this.export();\n\n constructor(map: ExportControl['map'], options: ExportOptions = {}) {\n this.map = map;\n this.filename = options.filename ?? 'caoguo-map';\n this.el = options.container ?? document.createElement('button');\n this.el.className = 'caoguo-export-control';\n this.el.textContent = options.buttonText ?? '导出 PNG';\n this.el.style.cssText =\n 'position:absolute;right:10px;top:10px;padding:5px 10px;background:rgba(10,15,30,.72);color:#cfe;border:1px solid #2a3550;border-radius:4px;font:12px system-ui,sans-serif;cursor:pointer;z-index:3;';\n this.el.addEventListener('click', this.onClick);\n }\n\n /** 导出当前地图视图为 PNG 并下载 */\n export(): void {\n const canvas = this.map.getCanvas();\n const url = canvas.toDataURL('image/png');\n triggerDownload(url, this.filename);\n }\n\n /** 挂载到容器 */\n addTo(container: HTMLElement): this {\n if (!this.el.parentElement) container.appendChild(this.el);\n return this;\n }\n\n remove(): void {\n this.el.removeEventListener('click', this.onClick);\n this.el.remove();\n }\n}\n","/**\n * 辉光线几何构建(T6 / F-1.3 纯逻辑部分)。\n *\n * 把 GeoJSON LineString 集合转换为「多遍描边」所需的三角形带几何。\n * 渲染层(CustomLineLayer)据此在 WebGL 中以屏幕像素宽度的三角面叠加绘制,\n * 每遍一个宽度档 + 透明度档,加法混合形成管线/路网/水系的辉光效果。\n *\n * 设计:本模块**不依赖 WebGL / maplibre**,纯函数可在 Node 单测。\n * 坐标投影使用简化 Web Mercator(经度→x、纬度→y 的归一化世界坐标),\n * 真实渲染时由 CustomLayer 的 matrix 变换到屏幕;线宽在屏幕空间计算。\n */\n\nexport interface GlowLine {\n /** 线坐标 [lng, lat][] */\n coordinates: [number, number][];\n /** 该线所属分组(如 'pipe' | 'road' | 'water'),用于按组分色。缺省归入 'default'。 */\n group?: string;\n}\n\nexport interface GlowPass {\n /** 该遍屏幕像素宽度 */\n width: number;\n /** 该遍不透明度(核心线高、外晕低) */\n opacity: number;\n}\n\nexport interface GlowGeometry {\n /**\n * 扁平化顶点缓冲。每个顶点 6 个 float:\n * [worldX, worldY, dirX, dirY, side, groupIndex]\n * - worldX/worldY:该端点的归一化世界坐标\n * - dirX/dirY:所在线段的世界空间方向(用于屏幕空间法线)\n * - side:±1,左/右扩展符号\n * - groupIndex:该顶点所属分组在 `groups` 中的下标(用于按组分色)\n */\n vertices: Float32Array;\n /** 每遍在 vertices 中的顶点区间 [start, count](按顶点数,非 float 数) */\n passRanges: { start: number; count: number }[];\n /** 每遍参数(从最外晕到核心,由宽到窄) */\n passes: GlowPass[];\n /** 顶点属性跨距(float 数) */\n stride: number;\n /** 参与渲染的去重分组名(与上层 colorMap 对应,下标即 groupIndex) */\n groups: string[];\n /** 逐遍、逐分组的连续顶点区间,供按组分色绘制 */\n renderGroups: { passIndex: number; group: string; start: number; count: number }[];\n}\n\n/**\n * 生成辉光多遍档位。\n * @param passes 遍数(默认 4:3 层外晕 + 1 核心)\n * @param baseWidth 核心线像素宽度(默认 3)\n */\nexport function glowPasses(passes = 4, baseWidth = 3): GlowPass[] {\n if (passes < 1) passes = 1;\n const out: GlowPass[] = [];\n // 从最外晕(宽、淡)到核心(窄、浓)排列\n for (let i = 0; i < passes; i++) {\n const t = passes === 1 ? 1 : 1 - i / (passes - 1); // 1(核心)..0(外晕)\n out.push({\n width: baseWidth * (1 + (1 - t) * (passes - 1) * 1.8),\n opacity: 0.1 + 0.9 * t * t,\n });\n }\n return out;\n}\n\n/**\n * 简化 Web Mercator 归一化(经度→x∈[-1,1],纬度→y 经墨卡托压缩)。\n * 仅用于几何构建与单测,真实投影在渲染层用 map 的 matrix。\n */\nexport function projectSimple(lng: number, lat: number): [number, number] {\n const x = lng / 180;\n const y = Math.log(Math.tan(Math.PI / 4 + (lat * Math.PI) / 360)) / Math.PI;\n // 纬度墨卡托范围约 [-π/2, π/2],归一化到 [-1,1] 方便观察\n return [x, Math.max(-1, Math.min(1, y / Math.PI))];\n}\n\n/**\n * 构建辉光几何:对每条线、每遍、每段生成三角面(2 三角形 = 6 顶点)。\n */\nexport function buildGlowGeometry(\n lines: GlowLine[],\n opts: { passes?: number; baseWidth?: number } = {}\n): GlowGeometry {\n const passes = glowPasses(opts.passes ?? 4, opts.baseWidth ?? 3);\n const stride = 6; // worldX, worldY, dirX, dirY, side, groupIndex\n const verts: number[] = [];\n const passRanges: { start: number; count: number }[] = [];\n const renderGroups: { passIndex: number; group: string; start: number; count: number }[] = [];\n\n // 分组名按首次出现顺序去重,下标即顶点携带的 groupIndex。\n const groups: string[] = [];\n for (const line of lines) {\n const g = line.group ?? 'default';\n if (!groups.includes(g)) groups.push(g);\n }\n\n for (let p = 0; p < passes.length; p++) {\n const pass = passes[p];\n const start = verts.length / stride;\n // 每遍内部按分组聚集成连续区间,便于按组取色绘制。\n for (const group of groups) {\n const groupStart = verts.length / stride;\n const groupIndex = groups.indexOf(group);\n for (const line of lines) {\n if ((line.group ?? 'default') !== group) continue;\n const pts = line.coordinates.map(([lng, lat]) => projectSimple(lng, lat));\n if (pts.length < 2) continue;\n for (let i = 0; i < pts.length - 1; i++) {\n const a = pts[i];\n const b = pts[i + 1];\n // 段方向(世界空间,未归一化,shader 内会归一化)\n const dx = b[0] - a[0];\n const dy = b[1] - a[1];\n // 每个端点左右各一个顶点,组成 quad:aL,aR,bL,bR → (aL,aR,bL),(bL,aR,bR)\n const quad: Array<[number, number, number, number, number, number]> = [\n [a[0], a[1], dx, dy, 1, groupIndex],\n [a[0], a[1], dx, dy, -1, groupIndex],\n [b[0], b[1], dx, dy, 1, groupIndex],\n [b[0], b[1], dx, dy, -1, groupIndex],\n ];\n // 两个三角形:0,1,2 与 2,1,3\n const idx = [0, 1, 2, 2, 1, 3];\n for (const k of idx) {\n const v = quad[k];\n verts.push(v[0], v[1], v[2], v[3], v[4], v[5]);\n }\n }\n }\n const count = verts.length / stride - groupStart;\n if (count > 0) renderGroups.push({ passIndex: p, group, start: groupStart, count });\n }\n const count = verts.length / stride - start;\n passRanges.push({ start, count });\n }\n\n return { vertices: new Float32Array(verts), passRanges, passes, stride, groups, renderGroups };\n}\n","/**\n * 辉光管线 Custom Layer(T6 / F-1.3 WebGL 渲染层)。\n *\n * 实现 MapLibre v4 `CustomLayerInterface`:在地图之上叠加绘制 GeoJSON 线,\n * 用多遍(glowPasses)三角面描边形成管线/路网/水系的辉光效果。\n *\n * 设计:几何构建(投影/三角带)在 `./glowGeometry` 纯函数中完成(可单测);\n * 本文件仅负责 WebGL 状态机与绘制,仅在浏览器执行。\n * 线宽在屏幕空间按像素计算(标准 Mapbox line shader 思路),因此可随缩放保持视觉宽度。\n * 通过 `Map.addGlowLayer` 注入,调用方无需感知 WebGL 细节。\n *\n * 依赖 MapLibre 注入的 `matrix`(map 的 projectionMatrix * modelViewMatrix)。\n */\n\nimport { buildGlowGeometry, type GlowLine } from './glowGeometry';\n\n/** MapLibre v4 CustomLayerInterface 最小子集(避免强类型耦合) */\nexport interface CustomLayerInterface {\n id: string;\n type: 'custom';\n renderingMode?: '2d' | '3d';\n onAdd?(map: unknown, gl: WebGLRenderingContext): void;\n render(gl: WebGLRenderingContext, matrix: number[]): void;\n onRemove?(map: unknown, gl: WebGLRenderingContext): void;\n prerender?(gl: WebGLRenderingContext, matrix: number[]): void;\n}\n\nexport interface GlowLayerOptions {\n /** 图层 id */\n id?: string;\n /** 线分组颜色映射(group -> [r,g,b] 0..1) */\n colors?: Record<string, [number, number, number]>;\n /** 基础线宽(像素,核心线) */\n baseWidth?: number;\n /** 辉光遍数 */\n passes?: number;\n /** 线集合 */\n lines: GlowLine[];\n}\n\n/** 取分组色的兜底色(灰蓝),避免未配置分组时渲染透明/黑。 */\nconst FALLBACK_COLOR: [number, number, number] = [0.6, 0.7, 0.9];\n\nconst DEFAULT_COLORS: Record<string, [number, number, number]> = {\n pipe: [0.2, 0.85, 1.0], // 青蓝:管线\n road: [0.6, 0.7, 0.9], // 灰蓝:路网\n water: [0.25, 0.55, 0.95], // 深蓝:水系\n};\n\n// 顶点属性:aPos(世界xy)、aDir(段方向xy)、aSide(±1)\nconst VERT = `\nattribute vec2 aPos;\nattribute vec2 aDir;\nattribute float aSide;\nuniform mat4 uMatrix;\nuniform float uWidth;\nuniform vec2 uResolution;\nvoid main() {\n vec4 clip = uMatrix * vec4(aPos, 0.0, 1.0);\n // 段方向也投影,求屏幕空间方向\n vec4 clipDir = uMatrix * vec4(aPos + aDir, 0.0, 1.0);\n vec2 s0 = clip.xy / clip.w;\n vec2 s1 = clipDir.xy / clipDir.w;\n vec2 dir = normalize(s1 - s0 + vec2(1e-6));\n vec2 normal = vec2(-dir.y, dir.x);\n vec2 offset = normal * aSide * (uWidth / uResolution * 2.0);\n gl_Position = vec4(s0 + offset * clip.w, clip.z, clip.w);\n}\n`;\n\nconst FRAG = `\nprecision mediump float;\nuniform vec3 uColor;\nuniform float uOpacity;\nvoid main() {\n gl_FragColor = vec4(uColor, uOpacity);\n}\n`;\n\nfunction compile(gl: WebGLRenderingContext, type: number, src: string): WebGLShader {\n const sh = gl.createShader(type)!;\n gl.shaderSource(sh, src);\n gl.compileShader(sh);\n if (!gl.getShaderParameter(sh, gl.COMPILE_STATUS)) {\n console.error('[CustomLineLayer] shader 编译失败:', gl.getShaderInfoLog(sh));\n }\n return sh;\n}\n\nexport class CustomLineLayer implements CustomLayerInterface {\n id: string;\n type = 'custom' as const;\n renderingMode: '2d' = '2d';\n\n private lines: GlowLine[];\n private colors: Record<string, [number, number, number]>;\n private baseWidth: number;\n\n private program?: WebGLProgram;\n private buffer?: WebGLBuffer;\n private geometry: ReturnType<typeof buildGlowGeometry>;\n private map?: { getCanvas: () => HTMLCanvasElement };\n private gl?: WebGLRenderingContext;\n\n constructor(opts: GlowLayerOptions) {\n this.id = opts.id ?? 'caoguo-glow-line';\n this.lines = opts.lines;\n this.colors = { ...DEFAULT_COLORS, ...opts.colors };\n this.baseWidth = opts.baseWidth ?? 3;\n this.geometry = buildGlowGeometry(this.lines, { passes: opts.passes ?? 4, baseWidth: this.baseWidth });\n // 为新分组补充兜底色,保证未显式配置的分组也能渲染。\n for (const g of this.geometry.groups) {\n if (!(g in this.colors)) this.colors[g] = FALLBACK_COLOR;\n }\n }\n\n onAdd(map: unknown, gl: WebGLRenderingContext): void {\n this.map = map as { getCanvas: () => HTMLCanvasElement };\n this.gl = gl;\n const vs = compile(gl, gl.VERTEX_SHADER, VERT);\n const fs = compile(gl, gl.FRAGMENT_SHADER, FRAG);\n const prog = gl.createProgram()!;\n gl.attachShader(prog, vs);\n gl.attachShader(prog, fs);\n gl.linkProgram(prog);\n if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {\n console.error('[CustomLineLayer] program 链接失败:', gl.getProgramInfoLog(prog));\n }\n this.program = prog;\n\n const buf = gl.createBuffer()!;\n gl.bindBuffer(gl.ARRAY_BUFFER, buf);\n gl.bufferData(gl.ARRAY_BUFFER, this.geometry.vertices, gl.STATIC_DRAW);\n this.buffer = buf;\n }\n\n render(gl: WebGLRenderingContext, matrix: number[]): void {\n if (!this.program || !this.buffer) return;\n gl.useProgram(this.program);\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n\n const stride = this.geometry.stride * 4; // float -> byte\n const aPos = gl.getAttribLocation(this.program, 'aPos');\n const aDir = gl.getAttribLocation(this.program, 'aDir');\n const aSide = gl.getAttribLocation(this.program, 'aSide');\n const aGroup = gl.getAttribLocation(this.program, 'aGroup');\n gl.enableVertexAttribArray(aPos);\n gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, stride, 0);\n gl.enableVertexAttribArray(aDir);\n gl.vertexAttribPointer(aDir, 2, gl.FLOAT, false, stride, 8);\n gl.enableVertexAttribArray(aSide);\n gl.vertexAttribPointer(aSide, 1, gl.FLOAT, false, stride, 16);\n if (aGroup >= 0) {\n gl.enableVertexAttribArray(aGroup);\n gl.vertexAttribPointer(aGroup, 1, gl.FLOAT, false, stride, 20);\n }\n\n const uMatrix = gl.getUniformLocation(this.program, 'uMatrix');\n gl.uniformMatrix4fv(uMatrix, false, new Float32Array(matrix));\n const uWidth = gl.getUniformLocation(this.program, 'uWidth');\n const uColor = gl.getUniformLocation(this.program, 'uColor');\n const uOpacity = gl.getUniformLocation(this.program, 'uOpacity');\n const uRes = gl.getUniformLocation(this.program, 'uResolution');\n const canvas = this.map?.getCanvas();\n gl.uniform2f(uRes, canvas?.width ?? 1024, canvas?.height ?? 768);\n\n gl.enable(gl.BLEND);\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE); // 加法混合形成辉光\n\n // 逐遍、逐分组取色绘制:实现「按分组多色」,不同业务线(管/路/水)各自着色。\n for (const rg of this.geometry.renderGroups) {\n const pass = this.geometry.passes[rg.passIndex];\n const color = this.colors[rg.group] ?? FALLBACK_COLOR;\n gl.uniform1f(uWidth, pass.width);\n gl.uniform3f(uColor, color[0], color[1], color[2]);\n gl.uniform1f(uOpacity, pass.opacity);\n gl.drawArrays(gl.TRIANGLES, rg.start, rg.count);\n }\n }\n\n /**\n * 动态更新线集合(高亮选中、切换数据等无需重建图层)。\n * 浏览器环境会刷新 GPU 缓冲;纯逻辑/测试环境仅更新几何与数据。\n */\n setLines(lines: GlowLine[]): void {\n this.lines = lines;\n this.geometry = buildGlowGeometry(this.lines, {\n passes: this.geometry.passes.length,\n baseWidth: this.baseWidth,\n });\n // 为新分组补充兜底色,保证未显式配置的分组也能渲染。\n for (const g of this.geometry.groups) {\n if (!(g in this.colors)) this.colors[g] = FALLBACK_COLOR;\n }\n // 图层已挂载(this.gl 在 onAdd 时缓存)则刷新 GPU 缓冲。\n if (this.buffer && this.gl) {\n this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffer);\n this.gl.bufferData(this.gl.ARRAY_BUFFER, this.geometry.vertices, this.gl.STATIC_DRAW);\n }\n }\n\n onRemove(_map: unknown, gl: WebGLRenderingContext): void {\n if (this.buffer) gl.deleteBuffer(this.buffer);\n if (this.program) gl.deleteProgram(this.program);\n this.buffer = undefined;\n this.program = undefined;\n }\n}\n","/**\n * LOD 控制器(T7 / F-1.7,纯逻辑)。\n *\n * 按地图 zoom 自动切换数据密度(Level of Detail):\n * - 低 zoom(全国/省)显示聚合/简化数据,避免要素过密;\n * - 高 zoom(市/区)显示全量/精细数据。\n *\n * 设计:本模块**不依赖 maplibre / WebGL / DOM**,纯函数可在 Node 单测。\n * 控制器 `LodController` 监听 zoom 变化并回调当前应激活的 LOD 等级,\n * 调用方据此 `setData` / 切换 source(具体渲染动作由调用方决定)。\n */\n\nexport interface LodLevel<T = unknown> {\n /** 该等级名称(如 'country' | 'province' | 'city' | 'detail') */\n id: string;\n /** 进入该等级的最小 zoom(含) */\n minZoom: number;\n /** 进入该等级的最大 zoom(含);省略表示 +∞ */\n maxZoom?: number;\n /** 该等级承载的数据/配置(任意类型,调用方解释) */\n payload?: T;\n}\n\nexport interface LodChangeEvent<T> {\n /** 当前激活等级 */\n level: LodLevel<T>;\n /** 是否相较上一次发生了等级切换 */\n changed: boolean;\n /** 当前 zoom */\n zoom: number;\n}\n\n/**\n * 根据 zoom 解析应激活的 LOD 等级。\n * 规则:取满足 minZoom<=zoom<=(maxZoom??∞) 的等级;\n * 若存在多个命中(区间重叠),取 minZoom 最大者(更精细优先)。\n * 无命中返回 null(调用方可保留上一等级)。\n */\nexport function resolveLod<T>(zoom: number, levels: LodLevel<T>[]): LodLevel<T> | null {\n let best: LodLevel<T> | null = null;\n for (const lv of levels) {\n const max = lv.maxZoom ?? Infinity;\n if (zoom >= lv.minZoom && zoom <= max) {\n if (!best || lv.minZoom > best.minZoom) best = lv;\n }\n }\n return best;\n}\n\n/**\n * 给定可视范围的\"要素密度\"建议(用于调试/UI 提示)。\n * 返回每屏建议最大要素数(随 zoom 平方增长,模拟瓦片面积)。\n */\nexport function suggestDensity(zoom: number, basePerTile = 200, tileCountFactor = 1): number {\n const z = Math.max(0, zoom);\n return Math.round(basePerTile * Math.pow(2, Math.max(0, z - 8)) * tileCountFactor);\n}\n\n/**\n * LOD 控制器(薄状态机)。监听 zoom,触发 onLod 回调。\n */\nexport class LodController<T = unknown> {\n private levels: LodLevel<T>[];\n private current: LodLevel<T> | null = null;\n private onChange: (e: LodChangeEvent<T>) => void;\n private map: { getZoom: () => number; on: (e: string, h: (ev: unknown) => void) => void; off: (e: string, h: (ev: unknown) => void) => void };\n\n constructor(\n map: LodController['map'],\n levels: LodLevel<T>[],\n onChange: (e: LodChangeEvent<T>) => void\n ) {\n this.map = map;\n this.levels = levels;\n this.onChange = onChange;\n this.handler = () => this.evaluate(false);\n map.on('zoom', this.handler);\n map.on('move', this.handler);\n }\n\n private handler: (ev: unknown) => void;\n\n /** 立即评估当前 zoom 并(按需)触发回调 */\n evaluate(force = false): LodLevel<T> | null {\n const zoom = this.map.getZoom();\n const next = resolveLod(zoom, this.levels);\n if (!next) return this.current;\n const changed = force || next.id !== this.current?.id;\n if (changed || force) {\n this.current = next;\n this.onChange({ level: next, changed, zoom });\n }\n return next;\n }\n\n /** 当前等级 */\n getLevel(): LodLevel<T> | null {\n return this.current;\n }\n\n /** 更新分级配置(如权限/数据就绪后) */\n setLevels(levels: LodLevel<T>[]): void {\n this.levels = levels;\n this.evaluate(false);\n }\n\n /** 卸载监听 */\n remove(): void {\n this.map.off('zoom', this.handler);\n this.map.off('move', this.handler);\n }\n}\n","/**\n * 3D 地形渲染(F-1.5)\n *\n * 注入 raster-dem 高程源并调用 maplibre-gl 原生 `setTerrain`,使地图呈现地形起伏。\n * DEM 瓦片默认使用公共 Terrarium 源(elevation-tiles-prod,Terrain-RGB 编码,支持 CORS),\n * 可在 opts.tiles 覆盖为私有瓦片服务(如 MinIO / 本地 MBTiles 服务)。\n */\n\nimport type { Map as MlMap } from 'maplibre-gl';\n\nexport interface TerrainOptions {\n /** DEM source id(默认 cg-dem) */\n sourceId?: string;\n /** DEM 瓦片模板,{z}/{x}/{y} 占位 */\n tiles?: string[];\n encoding?: 'terrarium' | 'mapbox';\n /** 地形夸张系数(默认 1.5) */\n exaggeration?: number;\n maxzoom?: number;\n}\n\n/** 默认 DEM 瓦片源(Mapzen Terrarium,Terrain-RGB,支持 CORS,无需鉴权) */\nexport const DEFAULT_TERRAIN_TILES = [\n 'https://elevation-tiles-prod.s3.amazonaws.com/terrarium/{z}/{x}/{y}.png',\n];\n\n/** 在原生 MapLibre 实例上启用地形(纯函数,便于单测) */\nexport function applyTerrain(mlMap: MlMap, opts: TerrainOptions = {}): void {\n const sourceId = opts.sourceId ?? 'cg-dem';\n if (!mlMap.getSource(sourceId)) {\n mlMap.addSource(sourceId, {\n type: 'raster-dem',\n tiles: opts.tiles ?? DEFAULT_TERRAIN_TILES,\n encoding: opts.encoding ?? 'terrarium',\n tileSize: 256,\n maxzoom: opts.maxzoom ?? 15,\n } as never);\n }\n mlMap.setTerrain({ source: sourceId, exaggeration: opts.exaggeration ?? 1.5 } as never);\n}\n\n/** 关闭地形(纯函数),移除 DEM 源 */\nexport function removeTerrain(mlMap: MlMap, sourceId = 'cg-dem'): void {\n mlMap.setTerrain(null);\n if (mlMap.getSource(sourceId)) {\n mlMap.removeSource(sourceId);\n }\n}\n","/**\n * 原生 MapLibre 地图 source 操作的幂等工具。\n *\n * 各业务 System(grid/water/pipeline/telecom/compute/transport)的 render()\n * 通过 `this.map.instance` 直接调用原生 MapLibre,而非经 CaoguoMap 包装类的\n * 幂等 addSource。为避免在每个 System 内重复书写 `if (!mlMap.getSource(id))`\n * 样板,并根治「层级切换重渲染崩溃」(Source already exists),统一在此提供\n * 幂等 upsert 与安全的 removeSource。\n *\n * 仅依赖原生 MapLibre 的 source 子集接口,便于各 System 直接传入 instance。\n */\n\n/**\n * 原生 MapLibre source 操作的子集接口。\n *\n * 仅 `getSource` 为必填——它是所有 helper 判断「source 是否存在」的统一探针。\n * 其余方法全部可选,因为各业务 System 对 `this.map.instance` 的局部类型断言\n * 只声明了实际用到的若干方法(如 topology 只取 getSource/removeSource,\n * traffic 只取 addSource/addLayer),强制统一必填字段会与这些子集冲突。\n * helper 内部对每个要调用的方法做存在性检查,缺失时安全跳过或回退,\n * 保证类型与运行时都安全(真实 MapLibre 实例始终具备全部方法)。\n */\nexport interface MlMapSourceApi {\n getSource: (id: string) => unknown;\n addSource?: (id: string, source: unknown) => void;\n addLayer?: (layer: unknown) => void;\n setData?: (id: string, data: unknown) => void;\n removeSource?: (id: string) => void;\n}\n\n/**\n * 幂等地确保一个 GeoJSON source 存在并持有给定数据。\n *\n * - 若 source 已存在且具备 setData:setData 更新(避免重复 addSource 抛错)。\n * - 若 source 已存在但无 setData:回退为 addSource(MapLibre 对重复 id 会忽略/覆盖,\n * 不抛错,仍可达成渲染目标)。\n * - 若 source 不存在且具备 addSource:addSource 创建。\n *\n * 注意:若传入对象既无 setData 又无 addSource,则无法创建/更新 source。\n * 各 System 传入的 `this.map.instance` 为真实 MapLibre 实例,始终具备这些方法。\n *\n * @param mlMap 原生 MapLibre 实例(或任意满足 MlMapSourceApi 的对象)\n * @param id source 唯一标识\n * @param data GeoJSON 数据(或 addSource 所需的 source spec)\n */\nexport function upsertSource(\n mlMap: MlMapSourceApi,\n id: string,\n data: unknown,\n): void {\n if (mlMap.getSource(id)) {\n if (mlMap.setData) {\n mlMap.setData(id, data);\n } else if (mlMap.addSource) {\n // 无 setData 时回退为 addSource:MapLibre 对同名 source 会忽略重复创建。\n mlMap.addSource(id, data);\n }\n } else if (mlMap.addSource) {\n mlMap.addSource(id, data);\n }\n}\n\n/**\n * 安全地移除 source:仅当存在且具备 removeSource 时才移除,避免不存在时抛错。\n *\n * @param mlMap 原生 MapLibre 实例\n * @param id source 唯一标识\n */\nexport function removeSourceSafe(mlMap: MlMapSourceApi, id: string): void {\n if (mlMap.getSource(id) && mlMap.removeSource) {\n mlMap.removeSource(id);\n }\n}\n\n/**\n * 安全地批量移除 source。\n *\n * @param mlMap 原生 MapLibre 实例\n * @param ids source 标识数组\n */\nexport function removeSourcesSafe(mlMap: MlMapSourceApi, ids: string[]): void {\n for (const id of ids) {\n removeSourceSafe(mlMap, id);\n }\n}\n","import maplibregl from 'maplibre-gl';\nimport type {\n Map as MlMap,\n StyleSpecification,\n} from 'maplibre-gl';\nimport 'maplibre-gl/dist/maplibre-gl.css';\n\nimport { osmRasterStyle, WUHAN_CENTER, WUHAN_ZOOM } from './styles';\nimport { createTransformer, type CRS, type LngLat } from './crs';\nimport { toWgs84 } from './crs';\nimport {\n addTiandituBaseMap,\n tiandituStyle,\n MissingTokenError,\n type TiandituOptions,\n type TiandituType,\n} from './sources';\nimport {\n createDefaultStore,\n registerOfflineProtocol,\n offlineTileUrl,\n offlineSourceTiles,\n packGeoJSONToStore,\n type TileStoreBackend,\n type TileFormat,\n} from './offline';\nimport { ScaleControl, ThemeSwitcher, LegendControl, ExportControl } from './controls';\nimport { CustomLineLayer } from './shaders';\nimport type { GlowLine } from './shaders';\nimport { LodController } from './lod';\nimport type { LodLevel, LodChangeEvent } from './lod';\nimport { applyTerrain, removeTerrain } from './terrain';\nimport type { ThemeName } from '@caoguo/theme';\n\nexport type MapInstance = MlMap;\n\n/**\n * WebGL 不可用时抛出(如无 GPU 的沙箱/无头环境、老旧浏览器)。\n * 调用方应捕获并向用户展示降级提示,而非让页面崩溃。\n */\nexport class WebGLUnavailableError extends Error {\n constructor(message = '当前环境不支持 WebGL,无法渲染地图') {\n super(message);\n this.name = 'WebGLUnavailableError';\n }\n}\n\n/**\n * 探测当前环境是否可创建真正可用的 WebGL 上下文。\n * 某些沙箱/无头浏览器会返回 canvas,且 getContext 也返回一个「伪对象」,\n * 但上下文实际不可用(渲染时崩溃)。因此除了非 null 判断,还进一步验证\n * 上下文确实能工作:能读出 VENDOR、能取到必要扩展,并捕获\n * webglcontextcreationerror 事件。\n */\nexport function isWebGLAvailable(): boolean {\n try {\n const canvas = document.createElement('canvas');\n let failed = false;\n const onErr = () => {\n failed = true;\n };\n canvas.addEventListener('webglcontextcreationerror', onErr, { once: true });\n\n const gl =\n (canvas.getContext('webgl2') as WebGLRenderingContext | null) ||\n (canvas.getContext('webgl') as WebGLRenderingContext | null) ||\n (canvas.getContext('experimental-webgl') as WebGLRenderingContext | null);\n\n canvas.removeEventListener('webglcontextcreationerror', onErr);\n\n if (failed || !gl) return false;\n\n // 进一步验证上下文确实可用:读取基础参数 + 编译一个最小着色器。\n const vendor = gl.getParameter(gl.VERSION);\n if (!vendor) return false;\n\n const vs = gl.createShader(gl.VERTEX_SHADER);\n if (!vs) return false;\n gl.shaderSource(vs, 'attribute vec2 p; void main(){ gl_Position = vec4(p,0.0,1.0); }');\n gl.compileShader(vs);\n if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) return false;\n\n return true;\n } catch {\n return false;\n }\n}\n\nexport { maplibregl, WUHAN_CENTER, WUHAN_ZOOM, osmRasterStyle };\nexport * from './crs';\nexport * from './sources';\nexport * from './offline';\nexport * from './controls';\nexport * from './shaders';\nexport * from './lod';\nexport * from './sourceUtils';\n\n/**\n * 全局配置(由应用入口注入一次,所有 Map 实例共享)。\n * 用于把敏感 token(如天地图 key)从库内部解耦到应用侧,\n * 避免硬编码、避免库 dist 中无法替换 import.meta.env 的问题。\n */\nexport interface CaoguoMapGlobalConfig {\n /** 天地图 token;未显式给 Map 传 tianditu 时自动生效 */\n tiandituToken?: string;\n}\n\nconst GLOBAL_KEY = '__caoguoMapConfig__';\n\nexport function setGlobalConfig(cfg: CaoguoMapGlobalConfig): void {\n const prev = getGlobalConfig();\n (globalThis as Record<string, unknown>)[GLOBAL_KEY] = { ...prev, ...cfg };\n}\n\nexport function getGlobalConfig(): CaoguoMapGlobalConfig {\n return (globalThis as Record<string, unknown>)[GLOBAL_KEY] as CaoguoMapGlobalConfig ?? {};\n}\n\n/** `addGlowLayer` 返回的句柄:既提供图层 id(用于 removeLayer),也支持动态更新线数据。 */\nexport interface GlowLayerHandle {\n /** 图层 id,可用于 map.removeLayer(id) */\n id: string;\n /** 动态替换线集合(高亮选中 / 切换数据,无需重建图层) */\n setLines: (lines: GlowLine[]) => void;\n}\n\nexport interface MapOptions {\n container: string | HTMLElement;\n center?: [number, number];\n zoom?: number;\n style?: string | StyleSpecification;\n pitch?: number;\n bearing?: number;\n /**\n * 业务/叠加数据的坐标系(默认 WGS84)。\n * 引擎内部以 WGS84 渲染;若数据为 GCJ-02 / CGCS2000,\n * 设定后可通过 `transformToMap` 在入图前自动纠偏。\n */\n dataCRS?: CRS;\n /**\n * 天地图(Tianditu)底图选项。传入后,**默认底图从 OSM 切换为天地图**\n * (国内权威底图,CGCS2000 / Web Mercator,适配国内网络与坐标系)。\n * token 由调用方注入,缺失时抛出 MissingTokenError。\n */\n tianditu?: {\n token: string;\n type?: TiandituType;\n lang?: 'zh' | 'en';\n subdomains?: number[];\n tileSize?: number;\n maxzoom?: number;\n };\n}\n\n/**\n * 草果地图引擎封装(展示层骨架)。\n *\n * 当前为轻量包装:直接复用 maplibre-gl 能力。\n * 后续阶段将在此注入:GCJ-02/BD-09 坐标系插件、行业 Shader、离线瓦片加载,\n * 业务调用方无需改动(通过本类统一入口)。\n */\nexport class Map {\n private _map: MlMap;\n private _dataCRS: CRS;\n\n constructor(options: MapOptions) {\n this._dataCRS = options.dataCRS ?? 'WGS84';\n if (!isWebGLAvailable()) {\n throw new WebGLUnavailableError();\n }\n\n let style = osmRasterStyle() as StyleSpecification;\n if (options.style) {\n style = options.style as StyleSpecification;\n } else if (options.tianditu) {\n if (!options.tianditu.token) throw new MissingTokenError();\n style = tiandituStyle(\n options.tianditu.type ?? 'vector',\n options.tianditu as TiandituOptions,\n ) as StyleSpecification;\n } else {\n // 未显式指定底图时,若应用侧已注入天地图 token,则默认使用天地图(国内权威底图)。\n const g = getGlobalConfig();\n if (g.tiandituToken) {\n style = tiandituStyle('vector', { token: g.tiandituToken } as TiandituOptions) as StyleSpecification;\n }\n }\n\n this._map = new maplibregl.Map({\n container: options.container,\n center: options.center ?? WUHAN_CENTER,\n zoom: options.zoom ?? WUHAN_ZOOM,\n style,\n pitch: options.pitch ?? 0,\n bearing: options.bearing ?? 0,\n attributionControl: { compact: true },\n });\n }\n\n /**\n * 把业务坐标系坐标转换到地图渲染基准(WGS84)。\n * 用于叠加 GCJ-02 / CGCS2000 数据前的纠偏。\n */\n transformToMap(lng: number, lat: number): LngLat {\n return toWgs84(this._dataCRS, lng, lat);\n }\n\n /** 设定叠加数据坐标系 */\n setDataCRS(crs: CRS): void {\n this._dataCRS = crs;\n }\n\n /** 读取叠加数据坐标系 */\n getDataCRS(): CRS {\n return this._dataCRS;\n }\n\n /** 生成当前 dataCRS -> WGS84 的变换器(供批量转换使用) */\n getTransformer() {\n return createTransformer(this._dataCRS, 'WGS84');\n }\n\n /**\n * 切换为底图为天地图(国内权威底图,CGCS2000 / Web Mercator)。\n * token 必须由调用方注入,缺失时抛出 MissingTokenError。\n */\n useTianditu(type: TiandituType, opts: Omit<TiandituOptions, 'type'>): void {\n this._map.setStyle(tiandituStyle(type, opts) as never);\n }\n\n /** 向当前地图注入天地图底图(叠加在现有 style 之上) */\n addTianditu(opts: Omit<TiandituOptions, 'type'> & { type?: TiandituType }): void {\n addTiandituBaseMap({ ...opts, map: this._map });\n }\n\n /** 离线瓦片后端(默认浏览器 IndexedDB / Node 内存) */\n private _store: TileStoreBackend = createDefaultStore();\n\n /** 注册离线协议并启用离线瓦片读取(F-1.4) */\n enableOffline(store?: TileStoreBackend): void {\n if (store) this._store = store;\n registerOfflineProtocol(maplibregl, { store: this._store });\n }\n\n /** 当前离线存储实例 */\n getOfflineStore(): TileStoreBackend {\n return this._store;\n }\n\n /** 构造离线源 tiles(供 source.tiles 使用) */\n offlineTiles(sourceId: string): string[] {\n return offlineSourceTiles(sourceId);\n }\n\n /** 把 GeoJSON 打包进离线存储(分桶到瓦片网格) */\n async packGeoJSON(\n sourceId: string,\n geojson: Parameters<typeof packGeoJSONToStore>[1]['geojson'],\n opts: { maxZoom?: number; expires?: number } = {}\n ): Promise<number> {\n return packGeoJSONToStore(this._store, {\n sourceId,\n geojson,\n maxZoom: opts.maxZoom,\n expires: opts.expires,\n });\n }\n\n addLayer(layer: Record<string, unknown>): void {\n this._map.addLayer(layer as MlMap['addLayer'] extends (l: infer L) => void ? L : never);\n }\n\n removeLayer(id: string): void {\n if (this._map.getLayer(id)) this._map.removeLayer(id);\n }\n\n on(event: string, layerId?: string, cb?: (e: unknown) => void): void {\n if (cb && layerId) this._map.on(event as keyof MlMap['on'], layerId, cb as never);\n else this._map.on(event as keyof MlMap['on'], cb as never);\n }\n\n addSource(id: string, source: object): void {\n // 幂等:若同名 source 已存在(如层级切换重渲染时),先移除再重建,\n // 避免抛 \"Source already exists\" 导致面板交互静默失败。\n if (this._map.getSource(id)) {\n try {\n this._map.removeSource(id);\n } catch {\n // ignore\n }\n }\n this._map.addSource(id, source as never);\n }\n\n /** 安全移除 source(不存在时静默忽略) */\n removeSource(id: string): void {\n if (this._map.getSource(id)) {\n try {\n this._map.removeSource(id);\n } catch {\n // ignore\n }\n }\n }\n\n getSource(id: string): unknown {\n return this._map.getSource(id);\n }\n\n flyTo(opts: { center?: [number, number]; zoom?: number; pitch?: number; bearing?: number }): void {\n this._map.flyTo(opts as never);\n }\n\n remove(): void {\n this._map.remove();\n }\n\n /**\n * 挂载比例尺 + 实时坐标控件(T8 / F-1.8)。\n * 返回控件实例,可调用 .remove() 卸载。\n */\n addScaleControl(options?: { showCoordinate?: boolean; maxWidth?: number }): ScaleControl {\n const ctrl = new ScaleControl(this._map as never, options);\n const container = (this._map as unknown as { getContainer: () => HTMLElement }).getContainer();\n ctrl.addTo(container);\n return ctrl;\n }\n\n /**\n * 挂载主题切换控件(T8 / F-1.9),在 caoguo-dark / caoguo-light 间切换。\n * 返回控件实例,可调用 .toggle() / .setTheme() / .remove()。\n */\n addThemeSwitcher(initial?: ThemeName): ThemeSwitcher {\n const ctrl = new ThemeSwitcher(this._map as never, { initial });\n const container = (this._map as unknown as { getContainer: () => HTMLElement }).getContainer();\n ctrl.addTo(container);\n return ctrl;\n }\n\n /**\n * 挂载图例控件(通用):渲染数据驱动的色块/线段图例,说明专题图层语义。\n * 返回控件实例,可调用 .setItems() 随图层切换更新、.remove() 卸载。\n */\n addLegendControl(options: { title?: string; items: { label: string; color: string; shape?: 'color' | 'line' }[] }): LegendControl {\n const ctrl = new LegendControl(options);\n const container = (this._map as unknown as { getContainer: () => HTMLElement }).getContainer();\n ctrl.addTo(container);\n return ctrl;\n }\n\n /**\n * 挂载地图导出控件(通用):点击按钮将当前视图导出为 PNG 下载。\n * 返回控件实例,可调用 .remove() 卸载。\n */\n addExportControl(options: { filename?: string; buttonText?: string } = {}): ExportControl {\n const ctrl = new ExportControl(this._map as never, options);\n const container = (this._map as unknown as { getContainer: () => HTMLElement }).getContainer();\n ctrl.addTo(container);\n return ctrl;\n }\n\n /**\n * 挂载辉光管线 Custom Layer(T6 / F-1.3)。\n * 传入 GeoJSON 线集合,叠加渲染管线/路网/水系辉光效果。\n * @returns 图层 id(可用于 removeLayer)\n */\n addGlowLayer(opts: {\n id?: string;\n lines: GlowLine[];\n colors?: Record<string, [number, number, number]>;\n baseWidth?: number;\n passes?: number;\n }): GlowLayerHandle {\n const layer = new CustomLineLayer(opts);\n this._map.addLayer(layer as never);\n return {\n id: layer.id,\n setLines: (lines: GlowLine[]) => layer.setLines(lines),\n };\n }\n\n /**\n * 挂载 LOD 控制器(T7 / F-1.7)。\n * 随 zoom 切换数据密度等级,并在等级变化时回调(调用方据此 setData / 切源)。\n * @returns LodController 实例(可 .getLevel() / .remove())\n */\n addLodController<T = unknown>(\n levels: LodLevel<T>[],\n onLod: (e: LodChangeEvent<T>) => void\n ): LodController<T> {\n const ctrl = new LodController<T>(this._map as never, levels, onLod);\n ctrl.evaluate(true);\n return ctrl;\n }\n\n /**\n * 启用 3D 地形渲染(F-1.5)。\n *\n * 注入 raster-dem 高程源并调用 maplibre-gl 原生 `setTerrain`,使地图呈现地形起伏。\n * DEM 瓦片默认使用公共 Terrarium 源(elevation-tiles-prod,Terrain-RGB 编码,支持 CORS),\n * 可在 opts.tiles 覆盖为私有瓦片服务(如 MinIO / 本地 MBTiles 服务)。\n *\n * @param opts.exaggeration 地形夸张系数(默认 1.5)\n * @param opts.tiles DEM 瓦片模板,{z}/{x}/{y} 占位\n * @param opts.encoding 'terrarium'(默认,Mapzen)| 'mapbox'\n */\n enableTerrain(\n opts: {\n sourceId?: string;\n tiles?: string[];\n encoding?: 'terrarium' | 'mapbox';\n exaggeration?: number;\n maxzoom?: number;\n } = {},\n ): void {\n applyTerrain(this._map, opts);\n }\n\n /** 关闭 3D 地形渲染(F-1.5),并移除 DEM 源 */\n disableTerrain(sourceId = 'cg-dem'): void {\n removeTerrain(this._map, sourceId);\n }\n\n get instance(): MlMap {\n return this._map;\n }\n}\n\nexport default Map;\n"]}