cesium-mars-op-cog 0.1.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/workers/workerPool.ts","../src/utils/cache.ts","../src/utils/crs.ts","../src/core/provider.ts","../src/utils/geo.ts","../src/cog.ts","../src/adapters/openlayers.ts","../src/hooks/useCogTif.ts","../src/hooks/useCogManager.ts"],"sourcesContent":["interface TaskEntry {\n resolve: (value: any) => void\n reject: (reason?: any) => void\n}\n\ninterface QueueItem {\n type: string\n payload: any\n resolve: (value: any) => void\n reject: (reason?: any) => void\n}\n\nexport default class WorkerPool {\n private poolSize: number\n private maxLoadPerWorker: number\n private workers: Worker[] = []\n private queue: QueueItem[] = []\n private taskMap: Map<number, TaskEntry> = new Map()\n private taskIdCounter = 0\n private workerLoad: Map<number, number> = new Map()\n private workerInitialized: Set<number> = new Set()\n private workerInitializing: Set<number> = new Set()\n private initPayload: any = null\n private _initPromise: Promise<void> | null = null\n\n constructor(\n workerFactory: () => Worker,\n poolSize: number = navigator.hardwareConcurrency || 4,\n maxLoadPerWorker: number = 4,\n ) {\n this.poolSize = poolSize\n this.maxLoadPerWorker = maxLoadPerWorker\n\n for (let i = 0; i < poolSize; i++) {\n const worker = workerFactory()\n worker.onmessage = (e: MessageEvent) => this._handleMessage(e, i)\n worker.onerror = (err: ErrorEvent) => console.error('Worker error:', err)\n this.workers.push(worker)\n this.workerLoad.set(i, 0)\n }\n }\n\n async initOne(payload: any): Promise<any> {\n this.initPayload = payload\n this.workerInitialized.clear()\n this.workerInitializing.clear()\n\n // 优化: 在等待 worker[0] 初始化的同时,并行启动其他 Worker 的初始化\n const firstWorkerInit = new Promise<any>((resolve, reject) => {\n const taskId = ++this.taskIdCounter\n this.taskMap.set(taskId, { resolve, reject })\n this.workerLoad.set(0, (this.workerLoad.get(0) || 0) + 1)\n this.workerInitializing.add(0)\n this.workers[0]!.postMessage({ type: 'INIT', payload, taskId })\n })\n\n const result = await firstWorkerInit\n\n // Worker[0] 初始化完成后,并行初始化其余 Worker(不阻塞返回)\n this._initPromise = this._initRemainingWorkers()\n\n return result\n }\n\n private async _initRemainingWorkers(): Promise<void> {\n const initPromises: Promise<void>[] = []\n for (let i = 1; i < this.poolSize; i++) {\n if (!this.workerInitialized.has(i) && !this.workerInitializing.has(i)) {\n initPromises.push(\n new Promise<void>((resolve) => {\n this.workerInitializing.add(i)\n const initTaskId = ++this.taskIdCounter\n this.taskMap.set(initTaskId, {\n resolve: () => resolve(),\n reject: () => resolve(), // 单个 Worker 初始化失败不阻塞其他\n })\n this.workerLoad.set(i, (this.workerLoad.get(i) || 0) + 1)\n // 发送 LAZY_INIT 而非 INIT,避免每个 Worker 都解析 COG 元数据\n this.workers[i]!.postMessage({\n type: 'LAZY_INIT',\n payload: this.initPayload,\n taskId: initTaskId,\n })\n }),\n )\n }\n }\n await Promise.allSettled(initPromises)\n }\n\n private _getLeastLoadedWorker(): number {\n let minIdx = -1\n let minLoad = Infinity\n // 优先在已初始化的 Worker 中选择\n for (const idx of this.workerInitialized) {\n const load = this.workerLoad.get(idx) ?? 0\n if (load < minLoad) {\n minLoad = load\n minIdx = idx\n }\n }\n // 如果所有已初始化的 Worker 都满载,再考虑未初始化的\n if (minIdx === -1) {\n for (const [idx, load] of this.workerLoad.entries()) {\n if (load < minLoad) {\n minLoad = load\n minIdx = idx\n }\n }\n }\n return minIdx >= 0 ? minIdx : 0\n }\n\n private _handleMessage(e: MessageEvent, workerIdx: number): void {\n const { type, taskId, payload } = e.data\n const task = this.taskMap.get(taskId)\n if (!task) return\n\n const currentLoad = this.workerLoad.get(workerIdx) || 1\n this.workerLoad.set(workerIdx, Math.max(0, currentLoad - 1))\n\n if (type === 'INIT_DONE') {\n this.workerInitialized.add(workerIdx)\n this.workerInitializing.delete(workerIdx)\n task.resolve(payload)\n } else if (type === 'TILE_DONE') {\n task.resolve(payload)\n } else if (type === 'ERROR') {\n // 初始化失败时仍标记为已初始化(避免阻塞队列)\n if (this.workerInitializing.has(workerIdx)) {\n this.workerInitialized.add(workerIdx)\n this.workerInitializing.delete(workerIdx)\n }\n task.reject(new Error(payload?.error || 'Worker error'))\n }\n\n this.taskMap.delete(taskId)\n this._processQueue()\n }\n\n private _processQueue(): void {\n if (this.queue.length === 0) return\n\n // 优化: 每次处理多个任务,充分利用所有可用 Worker\n let dispatched = 0\n const maxDispatch = Math.min(this.queue.length, this.poolSize)\n\n for (let attempt = 0; attempt < maxDispatch; attempt++) {\n // 找到最空闲的已初始化 Worker\n let bestIdx = -1\n let bestLoad = Infinity\n\n for (const idx of this.workerInitialized) {\n const load = this.workerLoad.get(idx) ?? 0\n if (load < this.maxLoadPerWorker && load < bestLoad) {\n bestLoad = load\n bestIdx = idx\n }\n }\n\n if (bestIdx === -1) {\n // 无可用已初始化 Worker,尝试初始化一个未初始化的\n for (let i = 0; i < this.poolSize; i++) {\n if (!this.workerInitialized.has(i) && !this.workerInitializing.has(i)) {\n this.workerInitializing.add(i)\n const initTaskId = ++this.taskIdCounter\n this.taskMap.set(initTaskId, { resolve: () => {}, reject: () => {} })\n this.workerLoad.set(i, (this.workerLoad.get(i) || 0) + 1)\n this.workers[i]!.postMessage({\n type: 'LAZY_INIT',\n payload: this.initPayload,\n taskId: initTaskId,\n })\n break\n }\n }\n break // 初始化一个 Worker 后停止本轮调度,等 onmessage 触发后再继续\n }\n\n const item = this.queue.shift()!\n dispatched++\n const taskId = ++this.taskIdCounter\n this.taskMap.set(taskId, {\n resolve: item.resolve,\n reject: item.reject,\n })\n this.workerLoad.set(bestIdx, (this.workerLoad.get(bestIdx) || 0) + 1)\n this.workers[bestIdx]!.postMessage({ type: item.type, payload: item.payload, taskId })\n }\n }\n\n execute(type: string, payload: any): Promise<any> {\n return new Promise((resolve, reject) => {\n this.queue.push({ type, payload, resolve, reject })\n this._processQueue()\n })\n }\n\n terminate(): void {\n for (const task of this.queue) {\n task.reject?.(new Error('WorkerPool 已终止'))\n }\n for (const [, task] of this.taskMap) {\n task.reject?.(new Error('WorkerPool 已终止'))\n }\n for (const w of this.workers) {\n w.terminate()\n }\n this.workers = []\n this.queue = []\n this.taskMap.clear()\n this.workerInitialized.clear()\n this.workerInitializing.clear()\n }\n}\n","/**\n * LRU 缓存\n */\nexport class LRUCache<T> {\n private max: number\n private map: Map<string, T>\n private onEvict: ((key: string, value: T) => void) | null\n\n constructor(max = 256, onEvict?: (key: string, value: T) => void) {\n this.max = max\n this.map = new Map()\n this.onEvict = onEvict ?? null\n }\n\n get(key: string): T | undefined {\n if (!this.map.has(key)) return undefined\n const val = this.map.get(key)!\n this.map.delete(key)\n this.map.set(key, val)\n return val\n }\n\n set(key: string, val: T): void {\n if (this.map.has(key)) this.map.delete(key)\n this.map.set(key, val)\n if (this.map.size > this.max) {\n const oldestKey = this.map.keys().next().value!\n const oldestVal = this.map.get(oldestKey)!\n this.map.delete(oldestKey)\n this.onEvict?.(oldestKey, oldestVal)\n }\n }\n\n delete(key: string): boolean {\n return this.map.delete(key)\n }\n\n clear(): void {\n this.map.clear()\n }\n\n get size(): number {\n return this.map.size\n }\n}\n","import proj4 from 'proj4'\n\n/**\n * 注册项目中所有需要的 CRS 定义\n * 主线程和 Worker 共享此函数,避免两端重复维护\n */\nexport function registerCrsDefs(): void {\n proj4.defs(\n 'EPSG:3857',\n '+proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs',\n )\n proj4.defs('EPSG:4326', '+proj=longlat +datum=WGS84 +no_defs')\n // EPSG:4548 = CGCS2000 / 3-degree Gauss-Kruger zone 40 (CM 120°E)\n proj4.defs(\n 'EPSG:4548',\n '+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs',\n )\n // CGCS2000 / 3-degree Gauss-Kruger 带 (EPSG:4524 ~ EPSG:4553)\n for (let cm = 75; cm <= 135; cm += 3) {\n const epsg = 4524 + Math.floor((cm - 75) / 3)\n proj4.defs(\n `EPSG:${epsg}`,\n `+proj=tmerc +lat_0=0 +lon_0=${cm} +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs`,\n )\n }\n}\n","/**\n * CogImageryProvider — Cesium/Mars3D 可用的 COG 影像提供者\n *\n * 实现 Cesium.ImageryProvider 接口,可直接传入 viewer.imageryLayers.addImageryProvider()。\n * Mars3D 基于 Cesium,同样适用。\n *\n * 用法:\n * const provider = new CogImageryProvider(url)\n * await provider.init()\n * const layer = viewer.imageryLayers.addImageryProvider(provider)\n * layer.alpha = 0.5 // 原生 API 操控\n */\n\nimport { Rectangle, GeographicTilingScheme, Event } from 'cesium'\nimport WorkerPool from '../workers/workerPool'\nimport CogWorker from '../workers/cogTile.worker.ts?worker'\nimport proj4 from 'proj4'\nimport { LRUCache } from '../utils/cache'\nimport { registerCrsDefs } from '../utils/crs'\n\n// 注册 CRS(只执行一次)\nregisterCrsDefs()\n\nexport interface CogProviderOptions {\n /** Worker 池大小,默认 max(2, min(6, CPU 核心数/2)) */\n poolSize?: number\n /** 每个 Worker 最大并发任务数(默认 8) */\n maxLoadPerWorker?: number\n /** 初始化超时毫秒(默认 30000) */\n timeout?: number\n /** 瓦片缓存数量(默认 512) */\n tileCacheSize?: number\n /** 影像透明度 0-1(默认 1.0,在 Worker 中与像素混合) */\n alpha?: number\n}\n\nconst DEFAULTS: Required<CogProviderOptions> = {\n poolSize: Math.max(2, Math.min(6, Math.floor((navigator.hardwareConcurrency || 4) / 2))),\n maxLoadPerWorker: 8,\n timeout: 30000,\n tileCacheSize: 512,\n alpha: 1.0,\n}\n\nexport class CogImageryProvider {\n // ===== ImageryProvider 接口属性 =====\n readonly tileWidth = 256\n readonly tileHeight = 256\n readonly tilingScheme = new GeographicTilingScheme()\n readonly hasAlphaChannel = true\n readonly ready = true\n\n maximumLevel!: number\n minimumLevel!: number\n rectangle!: ReturnType<typeof Rectangle.fromDegrees>\n _errorEvent!: any\n\n get errorEvent() {\n return this._errorEvent\n }\n\n /** 影像的度坐标 bbox [west, south, east, north],用于 flyTo 等场景 */\n get bboxDegrees(): readonly [number, number, number, number] {\n return this._bbox\n }\n\n // ===== 内部状态 =====\n private _url: string\n private _options: Required<CogProviderOptions>\n private _workerPool!: WorkerPool\n private _tileCache: LRUCache<ImageBitmap>\n private _inflightRequests = new Map<string, Promise<ImageBitmap | null>>()\n private _emptyTile: HTMLCanvasElement\n private _destroyed = false\n private _bbox: [number, number, number, number] = [0, 0, 0, 0]\n private _initialized = false\n\n constructor(url: string, options?: CogProviderOptions) {\n this._url = url\n this._options = { ...DEFAULTS, ...options }\n this._tileCache = new LRUCache<ImageBitmap>(this._options.tileCacheSize, (_key, bitmap) => {\n bitmap.close()\n })\n this._emptyTile = document.createElement('canvas')\n this._emptyTile.width = 256\n this._emptyTile.height = 256\n }\n\n // ===== 初始化 =====\n\n async init(): Promise<void> {\n if (this._initialized) return\n if (this._destroyed) throw new Error('CogImageryProvider 已销毁')\n\n this._workerPool = new WorkerPool(\n () => new CogWorker(),\n this._options.poolSize,\n this._options.maxLoadPerWorker,\n )\n\n const raw = await Promise.race([\n this._workerPool.initOne({ url: this._url }),\n new Promise<never>((_, reject) =>\n setTimeout(() => reject(new Error('COG 初始化超时')), this._options.timeout),\n ),\n ])\n\n if (!raw || !Array.isArray(raw.bbox) || raw.bbox.length !== 4) {\n throw new Error('COG 元数据无效: bbox 格式错误')\n }\n\n const ib = raw.bbox as number[]\n const cogW = ib[0]!\n const cogS = ib[1]!\n const cogE = ib[2]!\n const cogN = ib[3]!\n\n if (!isFinite(cogW) || !isFinite(cogS) || !isFinite(cogE) || !isFinite(cogN)) {\n throw new Error('COG 元数据无效: bbox 包含非数值')\n }\n\n const maxLevel = raw.maxLevel ?? 17\n const minLevel = raw.minLevel ?? Math.max(0, maxLevel - 8)\n const crsType: string = raw.crsType ?? '4326'\n\n // bbox 度坐标修正\n this._bbox = this._normalizeBbox(cogW, cogS, cogE, cogN, crsType)\n\n this.maximumLevel = maxLevel\n this.minimumLevel = minLevel\n this.rectangle = Rectangle.fromDegrees(\n this._bbox[0],\n this._bbox[1],\n this._bbox[2],\n this._bbox[3],\n )\n this._errorEvent = new Event() as any\n this._initialized = true\n\n console.log(`[COG] 初始化完成, 级别 ${minLevel}-${maxLevel}, bbox: [${this._bbox.join(', ')}]`)\n }\n\n /** 将 COG 原始 bbox 转换为度坐标 */\n private _normalizeBbox(\n w: number,\n s: number,\n e: number,\n n: number,\n crsType: string,\n ): [number, number, number, number] {\n if (Math.abs(w) <= 360 && Math.abs(e) <= 360 && Math.abs(s) <= 90 && Math.abs(n) <= 90) {\n return [w, s, e, n]\n }\n try {\n const fromProj = proj4(`EPSG:${crsType}`, 'EPSG:4326')\n const sw = fromProj.forward([w, s]) as number[]\n const ne = fromProj.forward([e, n]) as number[]\n if (\n isFinite(sw[0]!) &&\n isFinite(sw[1]!) &&\n isFinite(ne[0]!) &&\n isFinite(ne[1]!) &&\n Math.abs(sw[0]!) <= 180 &&\n Math.abs(ne[0]!) <= 180 &&\n Math.abs(sw[1]!) <= 90 &&\n Math.abs(ne[1]!) <= 90\n ) {\n return [sw[0]!, sw[1]!, ne[0]!, ne[1]!]\n }\n } catch {\n /* fall through */\n }\n throw new Error(`bbox 超出度坐标范围 [${w}, ${s}, ${e}, ${n}],CRS=${crsType},转换失败`)\n }\n\n // ===== ImageryProvider 接口方法 =====\n\n isDestroyed(): boolean {\n return this._destroyed\n }\n\n async requestImage(x: number, y: number, level: number): Promise<HTMLCanvasElement | undefined> {\n if (this._destroyed || !this._initialized) return undefined\n\n const [finalW, finalS, finalE, finalN] = this._bbox\n\n // 计算瓦片地理范围\n const xTiles = Math.pow(2, level + 1)\n const yTiles = Math.pow(2, level)\n const tileWidth = 360 / xTiles\n const tileHeight = 180 / yTiles\n const west = x * tileWidth - 180\n const east = west + tileWidth\n const north = 90 - y * tileHeight\n const south = north - tileHeight\n\n // 瓦片与 COG 无交集 → 返回空\n if (east <= finalW || west >= finalE || north <= finalS || south >= finalN) {\n return this._emptyTile\n }\n\n const cacheKey = `${this._url}_${x}_${y}_${level}`\n\n // 缓存命中\n const cached = this._tileCache.get(cacheKey)\n if (cached) {\n const canvas = document.createElement('canvas')\n canvas.width = cached.width\n canvas.height = cached.height\n canvas.getContext('2d')!.drawImage(cached, 0, 0)\n return canvas\n }\n\n // 请求去重\n let inflight = this._inflightRequests.get(cacheKey)\n if (!inflight) {\n inflight = this._fetchTile(cacheKey, x, y, level, { west, south, east, north })\n this._inflightRequests.set(cacheKey, inflight)\n }\n\n const bitmap = await inflight\n if (!bitmap) return this._emptyTile\n\n const canvas = document.createElement('canvas')\n canvas.width = bitmap.width\n canvas.height = bitmap.height\n canvas.getContext('2d')!.drawImage(bitmap, 0, 0)\n return canvas\n }\n\n private async _fetchTile(\n cacheKey: string,\n x: number,\n y: number,\n level: number,\n tileRect: { west: number; south: number; east: number; north: number },\n ): Promise<ImageBitmap | null> {\n try {\n const raw = await this._workerPool.execute('PROCESS_TILE', {\n x,\n y,\n level,\n tileRect,\n alpha: this._options.alpha,\n })\n if (!raw || raw.empty || !raw.bitmap) return null\n this._tileCache.set(cacheKey, raw.bitmap)\n return raw.bitmap\n } finally {\n this._inflightRequests.delete(cacheKey)\n }\n }\n\n destroy(): void {\n this._destroyed = true\n this._workerPool?.terminate()\n this._tileCache.clear()\n this._inflightRequests.clear()\n this._initialized = false\n }\n}\n","/** 矩形区域(度坐标) */\nexport interface BBox {\n west: number\n south: number\n east: number\n north: number\n}\n\n/**\n * 将矩形向外扩展指定比例\n * @param rect 原始矩形(度坐标)\n * @param padding 扩展比例,如 0.3 表示每边扩展 30%\n * @returns 扩展后的矩形\n */\nexport function expandRectangle(rect: BBox, padding = 0.3): BBox {\n const width = rect.east - rect.west\n const height = rect.north - rect.south\n const padX = width * padding\n const padY = height * padding\n return {\n west: rect.west - padX,\n south: rect.south - padY,\n east: rect.east + padX,\n north: rect.north + padY,\n }\n}\n","/**\n * @cog/cesium 公共 API 入口\n *\n * 提供简洁的工厂函数,返回 Cesium/Mars3D 可用的图层对象。\n *\n * 用法:\n * // Cesium\n * import { createCogProvider } from '@cog/cesium'\n * const provider = await createCogProvider('http://.../image.tif')\n * const layer = viewer.imageryLayers.addImageryProvider(provider)\n * layer.alpha = 0.5\n *\n * // Mars3D (Mars3D = Cesium,用法完全一致)\n * const provider = await createCogProvider('http://.../image.tif')\n * const layer = map.imageryLayers.addImageryProvider(provider)\n *\n * // 或一步到位\n * import { addCogLayerToMap } from '@cog/cesium'\n * const layer = await addCogLayerToMap(map, 'http://.../image.tif')\n * layer.alpha = 0.5\n */\n\nimport { CogImageryProvider } from './core/provider'\nimport type { CogProviderOptions } from './core/provider'\nimport { expandRectangle } from './utils/geo'\n\n/** addCogLayerToMap 额外选项 */\nexport interface AddLayerOptions extends CogProviderOptions {\n /** 透明度(默认 1.0) */\n alpha?: number\n /** 是否飞向图层(默认 true) */\n flyTo?: boolean\n}\n\n/**\n * 创建并初始化一个 COG ImageryProvider\n *\n * @param url COG 文件地址\n * @param options 配置选项\n * @returns 已初始化的 CogImageryProvider,可直接传入 viewer.imageryLayers.addImageryProvider()\n */\nexport async function createCogProvider(\n url: string,\n options?: CogProviderOptions,\n): Promise<CogImageryProvider> {\n const provider = new CogImageryProvider(url, options)\n await provider.init()\n return provider\n}\n\n/**\n * 将 COG 影像直接添加到 Cesium/Mars3D 地图\n *\n * @param map Cesium.Viewer 或 Mars3D 地图实例(需有 imageryLayers.addImageryProvider)\n * @param url COG 文件地址\n * @param options 配置选项\n * @returns 影像图层对象,可通过原生 API 操控(alpha、show、remove 等)\n */\nexport async function addCogLayerToMap(\n map: {\n imageryLayers: {\n addImageryProvider: (provider: any) => any\n remove: (layer: any, destroy: boolean) => void\n }\n camera?: { flyTo: (opts: any) => void }\n scene?: { requestRender: () => void }\n },\n url: string,\n options?: AddLayerOptions,\n): Promise<any> {\n const provider = new CogImageryProvider(url, options)\n await provider.init()\n\n const layer = map.imageryLayers.addImageryProvider(provider as any)\n layer.alpha = options?.alpha ?? 1.0\n\n if (options?.flyTo !== false && map.camera) {\n const bbox = provider.bboxDegrees\n const expanded = expandRectangle(\n { west: bbox[0]!, south: bbox[1]!, east: bbox[2]!, north: bbox[3]! },\n 0.3,\n )\n map.camera.flyTo({\n destination: {\n west: expanded.west,\n south: expanded.south,\n east: expanded.east,\n north: expanded.north,\n } as any,\n duration: 1.5,\n })\n }\n\n return layer\n}\n","/**\n * OpenLayers 适配器 — 将 COG 影像加载为 OpenLayers TileLayer\n *\n * 用法:\n * import { addCogLayerToOpenLayers } from '@cog/cesium'\n * const layer = await addCogLayerToOpenLayers(olMap, 'http://.../image.tif')\n * layer.setOpacity(0.5) // 原生 API\n * olMap.removeLayer(layer)\n */\n\nimport { CogImageryProvider } from '../core/provider'\nimport type { CogProviderOptions } from '../core/provider'\n\n/** OpenLayers 地图最小接口 */\ninterface OpenLayersMap {\n addLayer(layer: any): void\n removeLayer(layer: any): void\n getView(): any\n}\n\n/** addCogLayerToOpenLayers 选项 */\nexport interface OpenLayersLayerOptions extends CogProviderOptions {\n /** 图层透明度 0-1(默认 1.0) */\n opacity?: number\n}\n\n/**\n * 将 COG 影像添加到 OpenLayers 地图\n *\n * @param map OpenLayers 地图实例\n * @param url COG 文件地址\n * @param options 配置选项\n * @returns OpenLayers TileLayer,可通过原生 API 操控\n */\nexport async function addCogLayerToOpenLayers(\n map: OpenLayersMap,\n url: string,\n options?: OpenLayersLayerOptions,\n): Promise<any> {\n const provider = new CogImageryProvider(url, options)\n await provider.init()\n\n const bbox = provider.bboxDegrees\n const maxLevel = provider.maximumLevel\n const minLevel = provider.minimumLevel\n\n // 动态导入 OpenLayers(不强制依赖)\n const ol = await importOpenLayers()\n const { TileGrid } = ol.tilegrid\n\n // ===== 构建与 Cesium GeographicTilingScheme 一致的 TileGrid =====\n const tileSize = 256\n const resolutions: number[] = []\n for (let z = 0; z <= maxLevel; z++) {\n resolutions.push(360 / (tileSize * Math.pow(2, z + 1)))\n }\n\n const tileGrid = new TileGrid({\n extent: [-180, -90, 180, 90],\n origin: [-180, 90], // 左上角原点\n resolutions,\n tileSize: [tileSize, tileSize],\n })\n\n // ===== 创建 TileImage Source =====\n const source = new ol.source.TileImage({\n projection: 'EPSG:4326',\n tileGrid,\n tileUrlFunction: (tileCoord: number[]) => {\n // 将坐标编码为 fake URL,tileLoadFunction 中解析\n return `cog://${tileCoord[0]}/${tileCoord[1]}/${tileCoord[2]}`\n },\n tileLoadFunction: (imgTile: any, src: string) => {\n const parts = src.replace('cog://', '').split('/')\n const z = Number(parts[0])\n const x = Number(parts[1])\n const y = Number(parts[2])\n\n provider\n .requestImage(x, y, z)\n .then((canvas: HTMLCanvasElement | undefined) => {\n if (canvas) {\n canvas.toBlob((blob: Blob | null) => {\n if (blob) {\n const img = imgTile.getImage() as HTMLImageElement\n img.src = URL.createObjectURL(blob)\n }\n })\n }\n })\n .catch(() => {\n // 瓦片加载失败,OpenLayers 会标记为 error 并重试\n })\n },\n })\n\n // ===== 创建 TileLayer =====\n const layer = new ol.layer.Tile({\n source,\n opacity: options?.opacity ?? 1.0,\n extent: [bbox[0]!, bbox[1]!, bbox[2]!, bbox[3]!],\n minResolution: resolutions[Math.min(maxLevel, resolutions.length - 1)],\n maxResolution: resolutions[Math.min(minLevel, resolutions.length - 1)],\n })\n\n map.addLayer(layer)\n\n // 飞到影像范围\n const view = map.getView()\n if (view) {\n view.fit([bbox[0]!, bbox[1]!, bbox[2]!, bbox[3]!], {\n padding: [50, 50, 50, 50],\n duration: 1500,\n })\n }\n\n return layer\n}\n\n/** 动态加载 OpenLayers 核心模块 */\nasync function importOpenLayers(): Promise<{\n tilegrid: { TileGrid: new (...args: any[]) => any }\n source: { TileImage: new (...args: any[]) => any }\n layer: { Tile: new (...args: any[]) => any }\n}> {\n try {\n const TileGrid = (await import('ol/tilegrid/TileGrid')).default\n const TileImage = (await import('ol/source/TileImage')).default\n const TileLayer = (await import('ol/layer/Tile')).default\n return {\n tilegrid: { TileGrid },\n source: { TileImage },\n layer: { Tile: TileLayer },\n }\n } catch {\n throw new Error('OpenLayers 依赖未找到,请安装: npm install ol')\n }\n}\n","import { Rectangle } from 'cesium'\r\nimport { CogImageryProvider } from '../core/provider'\r\nimport type { CogProviderOptions } from '../core/provider'\r\n\r\ninterface CogLayerInfo {\r\n imageryLayer: any\r\n layerId: string\r\n provider: CogImageryProvider\r\n bbox: [number, number, number, number]\r\n}\r\n\r\n/**\r\n * [Vue Composable] COG 影像图层管理\r\n *\r\n * 基于 CogImageryProvider 的 Vue 封装,管理图层生命周期。\r\n * 非 Vue 项目请直接使用 createCogProvider / addCogLayerToMap。\r\n */\r\nexport function useCogTif(getViewer: () => any) {\r\n const layers = new Map<string, CogLayerInfo>()\r\n\r\n return {\r\n async addCogLayer(\r\n id: string,\r\n url: string,\r\n options: CogProviderOptions & {\r\n alpha?: number\r\n flyTo?: boolean\r\n } = {},\r\n ) {\r\n const viewer = getViewer()\r\n if (!viewer) throw new Error('Cesium Viewer 未初始化')\r\n\r\n const opts = { alpha: 1.0, flyTo: true, ...options }\r\n let provider: CogImageryProvider | null = null\r\n let layer: any = null\r\n\r\n try {\r\n provider = new CogImageryProvider(url, opts)\r\n await provider.init()\r\n\r\n layer = viewer.imageryLayers.addImageryProvider(provider as any)\r\n layer.alpha = opts.alpha\r\n\r\n const bbox = provider.bboxDegrees\r\n\r\n const info: CogLayerInfo = { imageryLayer: layer, layerId: id, provider, bbox: [...bbox] }\r\n layers.set(id, info)\r\n\r\n if (opts.flyTo !== false) {\r\n const [w, s, e, n] = bbox\r\n const width = e - w\r\n const height = n - s\r\n const padX = width * 0.3\r\n const padY = height * 0.3\r\n const rect = Rectangle.fromDegrees(w - padX, s - padY, e + padX, n + padY)\r\n viewer.camera.flyTo({ destination: rect, duration: 1.5 })\r\n }\r\n\r\n console.log('[COG] 加载成功:', id)\r\n return info\r\n } catch (err) {\r\n provider?.destroy()\r\n if (layer) {\r\n try {\r\n viewer.imageryLayers.remove(layer, true)\r\n } catch (_) {}\r\n }\r\n throw err\r\n }\r\n },\r\n\r\n removeCogLayer(id: string) {\r\n const info = layers.get(id)\r\n if (!info) {\r\n console.warn('[COG] 图层不存在:', id)\r\n return\r\n }\r\n\r\n try {\r\n info.provider.destroy()\r\n const viewer = getViewer()\r\n if (viewer) {\r\n info.imageryLayer.show = false\r\n viewer.scene.requestRender()\r\n requestAnimationFrame(() => {\r\n try {\r\n viewer.imageryLayers.remove(info.imageryLayer, true)\r\n viewer.scene.requestRender()\r\n } catch (_) {}\r\n })\r\n }\r\n } catch (e) {\r\n console.warn('[COG] 移除图层时出错:', e)\r\n }\r\n layers.delete(id)\r\n },\r\n\r\n flyToCogLayer(id: string) {\r\n const info = layers.get(id)\r\n if (!info) {\r\n console.warn('[COG] 图层不存在:', id)\r\n return\r\n }\r\n const viewer = getViewer()\r\n if (!viewer) return\r\n const [w, s, e, n] = info.bbox\r\n const padX = (e - w) * 0.3\r\n const padY = (n - s) * 0.3\r\n const rect = Rectangle.fromDegrees(w - padX, s - padY, e + padX, n + padY)\r\n viewer.camera.flyTo({ destination: rect, duration: 1.5 })\r\n },\r\n\r\n destroyCogTools() {\r\n for (const [id] of layers) {\r\n this.removeCogLayer(id)\r\n }\r\n layers.clear()\r\n },\r\n }\r\n}\r\n","import { ref, shallowRef, onUnmounted } from 'vue'\r\nimport * as Cesium from 'cesium'\r\nimport { useCogTif } from './useCogTif'\r\n\r\ninterface CogItem {\r\n name: string\r\n url: string\r\n}\r\n\r\ninterface CogManagerOptions {\r\n baseUrl?: string\r\n cogApiUrl?: string\r\n cogStaticBaseUrl?: string\r\n viewerOptions?: Record<string, any>\r\n}\r\n\r\n/**\r\n * COG 图层管理器\r\n */\r\nexport function useCogManager(options: CogManagerOptions = {}) {\r\n const {\r\n baseUrl = '/Cesium/',\r\n cogApiUrl = 'http://localhost:5158/api/cog/list',\r\n cogStaticBaseUrl = 'http://localhost:5158',\r\n viewerOptions = {},\r\n } = options\r\n\r\n const viewer = shallowRef<any>(null)\r\n const cogList = ref<CogItem[]>([])\r\n const selectedCog = ref('')\r\n const isLoading = ref(false)\r\n const error = ref<string | null>(null)\r\n\r\n let cogTools: ReturnType<typeof useCogTif> | null = null\r\n let currentLayerId: string | null = null\r\n\r\n const initViewer = async (containerId = 'cesiumContainer') => {\r\n try {\r\n ;(window as any).CESIUM_BASE_URL = baseUrl\r\n\r\n Cesium.RequestScheduler.maximumRequests = 100\r\n Cesium.RequestScheduler.maximumRequestsPerServer = 24\r\n\r\n viewer.value = new (Cesium.Viewer as any)(containerId, {\r\n geocoder: false,\r\n animation: false,\r\n timeline: false,\r\n baseLayerPicker: false,\r\n terrainProvider: new (Cesium.EllipsoidTerrainProvider as any)(),\r\n imagery: false,\r\n sun: false,\r\n moon: false,\r\n ...viewerOptions,\r\n })\r\n\r\n const layers = viewer.value.imageryLayers\r\n if (layers.length > 0) {\r\n console.log('[CogManager] 当前已有底图,不再重复清理')\r\n } else {\r\n viewer.value.imageryLayers.addImageryProvider(\r\n new (Cesium.UrlTemplateImageryProvider as any)({\r\n url: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',\r\n tilingScheme: new (Cesium.WebMercatorTilingScheme as any)(),\r\n maximumLevel: 18,\r\n }),\r\n )\r\n }\r\n\r\n const scene = viewer.value.scene\r\n scene.fog.enabled = false\r\n scene.highDynamicRange = false\r\n scene.globe.depthTestAgainstTerrain = false\r\n scene.globe.baseColor = (Cesium.Color as any).fromCssColorString('#1a1a2e')\r\n scene.backgroundColor = (Cesium.Color as any).fromCssColorString('#1a1a2e')\r\n if (scene.skyAtmosphere) scene.skyAtmosphere.show = false\r\n scene.light.enabled = false\r\n if (viewer.value.cesiumWidget.creditContainer) {\r\n viewer.value.cesiumWidget.creditContainer.style.display = 'none'\r\n }\r\n\r\n await new Promise<void>((resolve) => requestAnimationFrame(() => resolve()))\r\n\r\n cogTools = useCogTif(() => viewer.value)\r\n error.value = null\r\n } catch (err: any) {\r\n error.value = err.message || 'Viewer 初始化失败'\r\n console.error('[CogManager] 初始化失败:', err)\r\n throw err\r\n }\r\n }\r\n\r\n const fetchCogList = async () => {\r\n try {\r\n const controller = new AbortController()\r\n const timeout = setTimeout(() => controller.abort(), 10000)\r\n const res = await fetch(cogApiUrl, { signal: controller.signal })\r\n clearTimeout(timeout)\r\n const data = await res.json()\r\n cogList.value = data.map((item: any) => ({\r\n name: item.name,\r\n url: item.staticUrl.startsWith('http')\r\n ? item.staticUrl\r\n : `${cogStaticBaseUrl}${item.staticUrl}`,\r\n }))\r\n if (cogList.value.length > 0) {\r\n selectedCog.value = cogList.value[0]!.url\r\n }\r\n error.value = null\r\n } catch (err: any) {\r\n console.error('[CogManager] 获取 COG 列表失败:', err)\r\n cogList.value = []\r\n error.value = '获取 COG 列表失败: ' + (err.name === 'AbortError' ? '请求超时' : err.message)\r\n }\r\n }\r\n\r\n const loadCOG = async () => {\r\n if (!selectedCog.value || isLoading.value) return\r\n\r\n isLoading.value = true\r\n error.value = null\r\n try {\r\n if (currentLayerId) {\r\n try {\r\n cogTools?.removeCogLayer(currentLayerId)\r\n } catch (e) {\r\n console.warn('[CogManager] 移除旧图层时出错(继续加载):', e)\r\n }\r\n currentLayerId = null\r\n await new Promise<void>((r) =>\r\n requestAnimationFrame(() => requestAnimationFrame(() => r())),\r\n )\r\n }\r\n\r\n const newLayerId = 'cog-layer-' + Date.now()\r\n await cogTools!.addCogLayer(newLayerId, selectedCog.value, {\r\n alpha: 1,\r\n flyTo: true,\r\n })\r\n currentLayerId = newLayerId\r\n console.log('[CogManager] 加载成功:', newLayerId)\r\n } catch (err: any) {\r\n console.error('[CogManager] 加载失败:', err)\r\n error.value = err.message\r\n throw err\r\n } finally {\r\n isLoading.value = false\r\n }\r\n }\r\n\r\n const removeCOG = () => {\r\n if (!currentLayerId) {\r\n error.value = '没有可移除的图层'\r\n return\r\n }\r\n if (!cogTools) {\r\n error.value = '系统未初始化'\r\n return\r\n }\r\n console.log('[CogManager] 移除图层:', currentLayerId)\r\n cogTools.removeCogLayer(currentLayerId)\r\n currentLayerId = null\r\n error.value = null\r\n }\r\n\r\n const flyTo = () => {\r\n if (!currentLayerId) {\r\n error.value = '没有可飞行的图层'\r\n return\r\n }\r\n if (!cogTools) {\r\n error.value = '系统未初始化'\r\n return\r\n }\r\n cogTools.flyToCogLayer(currentLayerId)\r\n error.value = null\r\n }\r\n\r\n const switchCog = async (url: string) => {\r\n selectedCog.value = url\r\n try {\r\n await loadCOG()\r\n } catch (err: any) {\r\n console.error('[CogManager] 切换 COG 失败:', err)\r\n }\r\n }\r\n\r\n const destroy = () => {\r\n cogTools?.destroyCogTools()\r\n viewer.value?.destroy()\r\n viewer.value = null\r\n cogTools = null\r\n currentLayerId = null\r\n }\r\n\r\n onUnmounted(destroy)\r\n\r\n return {\r\n viewer,\r\n cogList,\r\n selectedCog,\r\n isLoading,\r\n error,\r\n initViewer,\r\n fetchCogList,\r\n loadCOG,\r\n removeCOG,\r\n flyTo,\r\n switchCog,\r\n destroy,\r\n }\r\n}\r\n"],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * LRU 缓存
3
+ */
4
+ export declare class LRUCache<T> {
5
+ private max;
6
+ private map;
7
+ private onEvict;
8
+ constructor(max?: number, onEvict?: (key: string, value: T) => void);
9
+ get(key: string): T | undefined;
10
+ set(key: string, val: T): void;
11
+ delete(key: string): boolean;
12
+ clear(): void;
13
+ get size(): number;
14
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * 注册项目中所有需要的 CRS 定义
3
+ * 主线程和 Worker 共享此函数,避免两端重复维护
4
+ */
5
+ export declare function registerCrsDefs(): void;
@@ -0,0 +1,14 @@
1
+ /** 矩形区域(度坐标) */
2
+ export interface BBox {
3
+ west: number;
4
+ south: number;
5
+ east: number;
6
+ north: number;
7
+ }
8
+ /**
9
+ * 将矩形向外扩展指定比例
10
+ * @param rect 原始矩形(度坐标)
11
+ * @param padding 扩展比例,如 0.3 表示每边扩展 30%
12
+ * @returns 扩展后的矩形
13
+ */
14
+ export declare function expandRectangle(rect: BBox, padding?: number): BBox;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,21 @@
1
+ export default class WorkerPool {
2
+ private poolSize;
3
+ private maxLoadPerWorker;
4
+ private workers;
5
+ private queue;
6
+ private taskMap;
7
+ private taskIdCounter;
8
+ private workerLoad;
9
+ private workerInitialized;
10
+ private workerInitializing;
11
+ private initPayload;
12
+ private _initPromise;
13
+ constructor(workerFactory: () => Worker, poolSize?: number, maxLoadPerWorker?: number);
14
+ initOne(payload: any): Promise<any>;
15
+ private _initRemainingWorkers;
16
+ private _getLeastLoadedWorker;
17
+ private _handleMessage;
18
+ private _processQueue;
19
+ execute(type: string, payload: any): Promise<any>;
20
+ terminate(): void;
21
+ }
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "cesium-mars-op-cog",
3
+ "version": "0.1.0",
4
+ "description": "COG (Cloud Optimized GeoTIFF) image layer for CesiumJS with Vue 3",
5
+ "private": false,
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "module": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js",
14
+ "default": "./dist/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "README.md"
20
+ ],
21
+ "scripts": {
22
+ "dev": "vite",
23
+ "build": "run-p type-check \"build-only {@}\" --",
24
+ "build:lib": "vite build --config vite.lib.config.ts && vue-tsc --declaration --emitDeclarationOnly --project tsconfig.lib.json",
25
+ "preview": "vite preview",
26
+ "build-only": "vite build",
27
+ "type-check": "vue-tsc --build",
28
+ "format": "prettier --write --experimental-cli src/"
29
+ },
30
+ "dependencies": {
31
+ "geotiff": "^3.0.5",
32
+ "proj4": "^2.20.8",
33
+ "zstddec": "^0.2.0"
34
+ },
35
+ "devDependencies": {
36
+ "@originjs/vite-plugin-commonjs": "^1.0.3",
37
+ "@tsconfig/node24": "^24.0.4",
38
+ "@types/node": "^24.12.2",
39
+ "@vitejs/plugin-vue": "^6.0.7",
40
+ "@vue/tsconfig": "^0.9.1",
41
+ "cesium": "^1.141.0",
42
+ "esbuild": "^0.28.0",
43
+ "npm-run-all2": "^8.0.4",
44
+ "ol": "^10.9.0",
45
+ "prettier": "3.8.3",
46
+ "typescript": "~6.0.0",
47
+ "vite": "^8.0.15",
48
+ "vite-plugin-cesium": "^1.2.23",
49
+ "vite-plugin-vue-devtools": "^8.1.1",
50
+ "vue": "^3.5.32",
51
+ "vue-tsc": "^3.3.3"
52
+ },
53
+ "peerDependencies": {
54
+ "cesium": "^1.0.0",
55
+ "vue": "^3.0.0",
56
+ "ol": ">=9.0.0",
57
+ "geotiff": "^3.0.0",
58
+ "proj4": "^2.0.0",
59
+ "zstddec": "^0.2.0"
60
+ },
61
+ "engines": {
62
+ "node": "^20.19.0 || >=22.12.0"
63
+ }
64
+ }