grid-webgl-openlayers 1.0.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":"layerControlHelpers-BSZqa4fP.js","sources":["../src/data/gridDataCore.ts","../src/data/GridDataWorkerClient.ts","../src/data/ArrayDataLoader.ts","../src/webgl/shaders.ts","../src/webgl/ChoroplethRenderer.ts","../src/webgl/ColorRamp.ts","../src/utils/projBridge.ts","../src/layers/ChoroplethLayer.ts","../src/utils/canvasCoords.ts","../src/layers/GridValueLayer.ts","../src/core/GridMapView.ts","../src/ui/LegendRangeSlider.ts","../src/ui/legendPanelTypes.ts","../src/ui/layerControlHelpers.ts"],"sourcesContent":["/** 纯函数:Worker 与主线程共享的网格数据处理 */\r\n\r\nexport interface ArrayDataMeta {\r\n startLat: number\r\n endLat: number\r\n startLon: number\r\n endLon: number\r\n latStep: number\r\n lonStep: number\r\n latCount: number\r\n lonCount: number\r\n}\r\n\r\nexport interface GridTile {\r\n data: Float32Array\r\n width: number\r\n height: number\r\n bbox: [number, number, number, number]\r\n resolution: [number, number]\r\n lodLevel: number\r\n lodStep: number\r\n}\r\n\r\nexport interface GridLabel {\r\n lon: number\r\n lat: number\r\n text: string\r\n}\r\n\r\nexport type ColorRampItem = [number, [number, number, number, number]]\r\n\r\n/** 与 arrayData.json 一致的网格数据格式 */\r\nexport interface ArrayDataJson {\r\n startLat: number\r\n endLat: number\r\n startLon: number\r\n endLon: number\r\n latStep: number\r\n lonStep: number\r\n latCount: number\r\n lonCount: number\r\n ds: number[][]\r\n}\r\n\r\nconst NODATA = -9999\r\n\r\nexport function getLodStep(zoom: number): number {\r\n const level = Math.max(0, Math.min(3, Math.floor((11 - zoom) / 2)))\r\n return 2 ** level\r\n}\r\n\r\n/** LOD 块在屏幕上的宽度(像素),兼容 4326(度/px)与 3857(米/px) */\r\nfunction lodCellPixelWidth(\r\n meta: ArrayDataMeta,\r\n lodStep: number,\r\n mapResolution: number,\r\n projCode: string,\r\n): number {\r\n const latMid = (meta.startLat + meta.endLat) * 0.5\r\n const lodCellLonDeg = meta.lonStep * lodStep\r\n if (projCode === \"EPSG:3857\") {\r\n const metersPerDegLon = 111320 * Math.cos((latMid * Math.PI) / 180)\r\n return (lodCellLonDeg * metersPerDegLon) / Math.max(mapResolution, 1e-12)\r\n }\r\n return lodCellLonDeg / Math.max(mapResolution, 1e-12)\r\n}\r\n\r\n/** 标注步长(原生格索引),与色斑图 LOD 对齐:lodStep × 像素稀疏倍数 */\r\nexport function getLabelStep(\r\n meta: ArrayDataMeta,\r\n zoom: number,\r\n mapResolution: number,\r\n distancePx: number,\r\n projCode = \"EPSG:4326\",\r\n): number {\r\n const lodStep = getLodStep(zoom)\r\n const lodCellPx = lodCellPixelWidth(meta, lodStep, mapResolution, projCode)\r\n const blockSkip = Math.max(1, Math.round(distancePx / Math.max(lodCellPx, 1)))\r\n return lodStep * blockSkip\r\n}\r\n\r\nfunction sampleBlock(\r\n flat: Float32Array,\r\n meta: ArrayDataMeta,\r\n row0: number,\r\n col0: number,\r\n step: number,\r\n): number {\r\n let sum = 0\r\n let count = 0\r\n const { latCount, lonCount } = meta\r\n for (let dr = 0; dr < step; dr++) {\r\n for (let dc = 0; dc < step; dc++) {\r\n const r = row0 + dr\r\n const c = col0 + dc\r\n if (r >= latCount || c >= lonCount) continue\r\n const v = flat[r * lonCount + c]\r\n if (v == null || Number.isNaN(v)) continue\r\n sum += v\r\n count++\r\n }\r\n }\r\n return count > 0 ? sum / count : NODATA\r\n}\r\n\r\nexport function readWindow(\r\n flat: Float32Array,\r\n meta: ArrayDataMeta,\r\n extent4326: number[],\r\n zoom: number,\r\n): GridTile | null {\r\n const dataBbox: [number, number, number, number] = [\r\n meta.startLon,\r\n meta.startLat,\r\n meta.endLon,\r\n meta.endLat,\r\n ]\r\n const [vMinLon, vMinLat, vMaxLon, vMaxLat] = extent4326\r\n const [dMinLon, dMinLat, dMaxLon, dMaxLat] = dataBbox\r\n\r\n const minLon = Math.max(vMinLon, dMinLon)\r\n const minLat = Math.max(vMinLat, dMinLat)\r\n const maxLon = Math.min(vMaxLon, dMaxLon)\r\n const maxLat = Math.min(vMaxLat, dMaxLat)\r\n\r\n if (minLon >= maxLon || minLat >= maxLat) return null\r\n\r\n const { startLon, startLat, lonStep, latStep, lonCount, latCount } = meta\r\n const lodStep = getLodStep(zoom)\r\n\r\n const col0 = Math.max(0, Math.floor((minLon - startLon) / lonStep / lodStep) * lodStep)\r\n const col1 = Math.min(lonCount, Math.ceil((maxLon - startLon) / lonStep))\r\n const row0 = Math.max(0, Math.floor((minLat - startLat) / latStep / lodStep) * lodStep)\r\n const row1 = Math.min(latCount, Math.ceil((maxLat - startLat) / latStep))\r\n\r\n if (col0 >= col1 || row0 >= row1) return null\r\n\r\n const outCols = Math.ceil((col1 - col0) / lodStep)\r\n const outRows = Math.ceil((row1 - row0) / lodStep)\r\n const data = new Float32Array(outCols * outRows)\r\n\r\n let idx = 0\r\n for (let r = row1 - lodStep; r >= row0; r -= lodStep) {\r\n for (let c = col0; c < col1; c += lodStep) {\r\n data[idx++] = sampleBlock(flat, meta, r, c, lodStep)\r\n }\r\n }\r\n\r\n return {\r\n data,\r\n width: outCols,\r\n height: outRows,\r\n bbox: [startLon + col0 * lonStep, startLat + row0 * latStep, startLon + col1 * lonStep, startLat + row1 * latStep],\r\n resolution: [lonStep * lodStep, latStep * lodStep],\r\n lodLevel: Math.log2(lodStep),\r\n lodStep,\r\n }\r\n}\r\n\r\n/**\r\n * 与 readWindow 相同 LOD 聚合 + 相同格网原点对齐;\r\n * 位置取 LOD 块中心,数值取 sampleBlock(与色斑图一致)。\r\n */\r\nexport function computeLabels(\r\n flat: Float32Array,\r\n meta: ArrayDataMeta,\r\n extent4326: number[],\r\n zoom: number,\r\n resolution: number,\r\n distancePx: number,\r\n precision: number,\r\n projCode = \"EPSG:4326\",\r\n): GridLabel[] {\r\n const { startLon, startLat, lonStep, latStep, lonCount, latCount } = meta\r\n const lodStep = getLodStep(zoom)\r\n const labelStep = getLabelStep(meta, zoom, resolution, distancePx, projCode)\r\n\r\n const [minLon, minLat, maxLon, maxLat] = extent4326\r\n const col0 = Math.max(0, Math.floor((minLon - startLon) / lonStep / labelStep) * labelStep)\r\n const col1 = Math.min(lonCount, Math.ceil((maxLon - startLon) / lonStep))\r\n const row0 = Math.max(0, Math.floor((minLat - startLat) / latStep / labelStep) * labelStep)\r\n const row1 = Math.min(latCount, Math.ceil((maxLat - startLat) / latStep))\r\n\r\n if (col0 >= col1 || row0 >= row1) return []\r\n\r\n const labels: GridLabel[] = []\r\n for (let row = row0; row < row1; row += labelStep) {\r\n for (let col = col0; col < col1; col += labelStep) {\r\n const v = sampleBlock(flat, meta, row, col, lodStep)\r\n if (v === NODATA || Number.isNaN(v)) continue\r\n const lon = startLon + (col + lodStep * 0.5) * lonStep\r\n const lat = startLat + (row + lodStep * 0.5) * latStep\r\n if (lon < startLon || lon >= meta.endLon || lat < startLat || lat >= meta.endLat) continue\r\n labels.push({ lon, lat, text: v.toFixed(precision) })\r\n }\r\n }\r\n return labels\r\n}\r\n\r\nexport function flattenGrid(ds: number[][], latCount: number, lonCount: number): Float32Array {\r\n const flat = new Float32Array(latCount * lonCount)\r\n for (let r = 0; r < latCount; r++) {\r\n for (let c = 0; c < lonCount; c++) {\r\n flat[r * lonCount + c] = ds[r][c]\r\n }\r\n }\r\n return flat\r\n}\r\n\r\nexport function computeStats(flat: Float32Array): { min: number; max: number } {\r\n let min = Infinity\r\n let max = -Infinity\r\n for (const v of flat) {\r\n if (v == null || Number.isNaN(v)) continue\r\n if (v < min) min = v\r\n if (v > max) max = v\r\n }\r\n return { min, max }\r\n}\r\n\r\nexport function getNativeValue(\r\n flat: Float32Array,\r\n meta: ArrayDataMeta,\r\n lon: number,\r\n lat: number,\r\n): number | null {\r\n const { startLon, startLat, lonStep, latStep, lonCount, latCount } = meta\r\n const col = Math.floor((lon - startLon) / lonStep)\r\n const row = Math.floor((lat - startLat) / latStep)\r\n if (col < 0 || row < 0 || col >= lonCount || row >= latCount) return null\r\n const v = flat[row * lonCount + col]\r\n if (v == null || Number.isNaN(v)) return null\r\n return v\r\n}\r\n\r\nexport { NODATA }\r\n","import type { ArrayDataMeta, GridLabel, GridTile } from \"./gridDataCore\"\r\nimport type { WorkerRequest, WorkerResponse } from \"../worker/gridDataWorkerTypes\"\r\n\r\nexport class GridDataWorkerClient {\r\n private worker: Worker\r\n private seq = 0\r\n private pending = new Map<number, { resolve: (v: unknown) => void; reject: (e: Error) => void }>()\r\n\r\n constructor() {\r\n this.worker = new Worker(new URL(\"../worker/gridData.worker.ts\", import.meta.url), { type: \"module\" })\r\n this.worker.onmessage = (ev: MessageEvent<WorkerResponse>) => {\r\n const msg = ev.data\r\n const p = this.pending.get(msg.id)\r\n if (!p) return\r\n this.pending.delete(msg.id)\r\n if (!msg.ok) {\r\n p.reject(new Error(msg.error))\r\n return\r\n }\r\n p.resolve(msg)\r\n }\r\n this.worker.onerror = () => {\r\n this.pending.forEach(({ reject }) => reject(new Error(\"worker error\")))\r\n this.pending.clear()\r\n }\r\n }\r\n\r\n init(meta: ArrayDataMeta, flat: Float32Array): Promise<void> {\r\n const id = ++this.seq\r\n return new Promise((resolve, reject) => {\r\n this.pending.set(id, { resolve: resolve as (v: unknown) => void, reject })\r\n this.worker.postMessage({ type: \"init\", meta, flat, id } as WorkerRequest, [flat.buffer])\r\n }).then(() => {})\r\n }\r\n\r\n private call<T>(req: Omit<WorkerRequest, \"id\">): Promise<T> {\r\n const id = ++this.seq\r\n return new Promise((resolve, reject) => {\r\n this.pending.set(id, { resolve: resolve as (v: unknown) => void, reject })\r\n this.worker.postMessage({ ...req, id } as WorkerRequest)\r\n })\r\n }\r\n\r\n readWindow(extent4326: number[], zoom: number): Promise<GridTile | null> {\r\n return this.call<{ type: \"readWindow\"; tile: GridTile }>({\r\n type: \"readWindow\",\r\n extent4326,\r\n zoom,\r\n } as Omit<WorkerRequest, \"id\">)\r\n .then((r) => r.tile)\r\n .catch(() => null)\r\n }\r\n\r\n computeLabels(\r\n extent4326: number[],\r\n zoom: number,\r\n resolution: number,\r\n distancePx: number,\r\n precision: number,\r\n projCode = \"EPSG:4326\",\r\n ): Promise<GridLabel[]> {\r\n return this.call<{ type: \"computeLabels\"; labels: GridLabel[] }>({\r\n type: \"computeLabels\",\r\n extent4326,\r\n zoom,\r\n resolution,\r\n distancePx,\r\n precision,\r\n projCode,\r\n } as Omit<WorkerRequest, \"id\">)\r\n .then((r) => r.labels)\r\n .catch(() => [])\r\n }\r\n\r\n terminate(): void {\r\n this.worker.terminate()\r\n }\r\n}\r\n","import {\r\n type ArrayDataMeta,\r\n type ArrayDataJson,\r\n type GridLabel,\r\n type GridTile,\r\n type ColorRampItem,\r\n NODATA,\r\n computeLabels,\r\n computeStats,\r\n flattenGrid,\r\n getLabelStep,\r\n getLodStep,\r\n getNativeValue,\r\n readWindow as readWindowSync,\r\n} from \"./gridDataCore\"\r\nimport { GridDataWorkerClient } from \"./GridDataWorkerClient\"\r\n\r\nexport type { ArrayDataMeta, ArrayDataJson, GridTile, GridLabel, ColorRampItem } from \"./gridDataCore\"\r\n\r\n/**\r\n * 网格数据加载器:主线程保留 flat 副本供同步拾取,LOD/标注计算走 Worker。\r\n */\r\nexport class ArrayDataLoader {\r\n private meta!: ArrayDataMeta\r\n private flat!: Float32Array\r\n private loaded = false\r\n private worker = new GridDataWorkerClient()\r\n private lastExtent: number[] | null = null\r\n private lastZoom = -1\r\n private cachedTile: GridTile | null = null\r\n private tileRequestId = 0\r\n\r\n get bbox(): [number, number, number, number] {\r\n return [this.meta.startLon, this.meta.startLat, this.meta.endLon, this.meta.endLat]\r\n }\r\n\r\n get metadata() {\r\n return { ...this.meta, nodata: NODATA, bbox: this.bbox }\r\n }\r\n\r\n get isLoaded() {\r\n return this.loaded\r\n }\r\n\r\n async load(url: string): Promise<void> {\r\n const json = (await fetch(url).then((r) => r.json())) as ArrayDataJson\r\n await this.loadData(json)\r\n }\r\n\r\n /** 直接加载 JSON 对象(Vue / Node 传入内存数据时使用) */\r\n async loadData(json: ArrayDataJson): Promise<void> {\r\n this.meta = {\r\n startLat: json.startLat,\r\n endLat: json.endLat,\r\n startLon: json.startLon,\r\n endLon: json.endLon,\r\n latStep: json.latStep,\r\n lonStep: json.lonStep,\r\n latCount: json.latCount,\r\n lonCount: json.lonCount,\r\n }\r\n this.flat = flattenGrid(json.ds, this.meta.latCount, this.meta.lonCount)\r\n await this.worker.init(this.meta, this.flat.slice())\r\n this.loaded = true\r\n }\r\n\r\n getLodStep(zoom: number): number {\r\n return getLodStep(zoom)\r\n }\r\n\r\n getLabelStep(zoom: number, resolution: number, distancePx: number, projCode = \"EPSG:4326\"): number {\r\n return getLabelStep(this.meta, zoom, resolution, distancePx, projCode)\r\n }\r\n\r\n /** 异步 readWindow(Worker) */\r\n async readWindowAsync(extent4326: number[], zoom: number): Promise<GridTile | null> {\r\n if (!this.loaded) return null\r\n\r\n if (\r\n this.cachedTile &&\r\n this.lastZoom === zoom &&\r\n this.lastExtent &&\r\n extentEqual(this.lastExtent, extent4326)\r\n ) {\r\n return this.cachedTile\r\n }\r\n\r\n const reqId = ++this.tileRequestId\r\n const tile = await this.worker.readWindow(extent4326, zoom)\r\n if (reqId !== this.tileRequestId) return this.cachedTile\r\n\r\n if (tile) {\r\n this.lastExtent = [...extent4326]\r\n this.lastZoom = zoom\r\n this.cachedTile = tile\r\n }\r\n return tile\r\n }\r\n\r\n /** 同步 readWindow(Worker 未就绪时 fallback) */\r\n readWindow(extent4326: number[], zoom: number): GridTile | null {\r\n if (!this.loaded) return null\r\n if (\r\n this.cachedTile &&\r\n this.lastZoom === zoom &&\r\n this.lastExtent &&\r\n extentEqual(this.lastExtent, extent4326)\r\n ) {\r\n return this.cachedTile\r\n }\r\n const tile = readWindowSync(this.flat, this.meta, extent4326, zoom)\r\n if (tile) {\r\n this.lastExtent = [...extent4326]\r\n this.lastZoom = zoom\r\n this.cachedTile = tile\r\n }\r\n return tile\r\n }\r\n\r\n async computeLabelsAsync(\r\n extent4326: number[],\r\n zoom: number,\r\n resolution: number,\r\n distancePx: number,\r\n precision: number,\r\n projCode = \"EPSG:4326\",\r\n ): Promise<GridLabel[]> {\r\n if (!this.loaded) return []\r\n try {\r\n const labels = await this.worker.computeLabels(\r\n extent4326,\r\n zoom,\r\n resolution,\r\n distancePx,\r\n precision,\r\n projCode,\r\n )\r\n if (labels.length > 0) return labels\r\n } catch {\r\n /* Worker 失败时降级主线程 */\r\n }\r\n return computeLabels(this.flat, this.meta, extent4326, zoom, resolution, distancePx, precision, projCode)\r\n }\r\n\r\n computeLabelsSync(\r\n extent4326: number[],\r\n zoom: number,\r\n resolution: number,\r\n distancePx: number,\r\n precision: number,\r\n projCode = \"EPSG:4326\",\r\n ): GridLabel[] {\r\n if (!this.loaded) return []\r\n return computeLabels(this.flat, this.meta, extent4326, zoom, resolution, distancePx, precision, projCode)\r\n }\r\n\r\n getValueAt(lon: number, lat: number, tile?: GridTile | null): number | null {\r\n const t = tile ?? this.cachedTile\r\n if (!t) return null\r\n const [minLon, minLat, maxLon, maxLat] = t.bbox\r\n if (lon < minLon || lon > maxLon || lat < minLat || lat > maxLat) return null\r\n const [resLon, resLat] = t.resolution\r\n const col = Math.floor((lon - minLon) / resLon)\r\n const row = Math.floor((maxLat - lat) / resLat)\r\n if (col < 0 || row < 0 || col >= t.width || row >= t.height) return null\r\n const v = t.data[row * t.width + col]\r\n if (v === NODATA || Number.isNaN(v)) return null\r\n return v\r\n }\r\n\r\n getNativeValueAt(lon: number, lat: number): number | null {\r\n return getNativeValue(this.flat, this.meta, lon, lat)\r\n }\r\n\r\n computeStats() {\r\n return computeStats(this.flat)\r\n }\r\n\r\n get nativeResolution(): [number, number] {\r\n return [this.meta.lonStep, this.meta.latStep]\r\n }\r\n\r\n get gridOrigin(): [number, number] {\r\n return [this.meta.startLon, this.meta.startLat]\r\n }\r\n\r\n invalidateCache(): void {\r\n this.cachedTile = null\r\n this.lastExtent = null\r\n this.tileRequestId++\r\n }\r\n\r\n dispose(): void {\r\n this.worker.terminate()\r\n }\r\n}\r\n\r\nfunction extentEqual(a: number[], b: number[], eps = 1e-6): boolean {\r\n return a.length === b.length && a.every((v, i) => Math.abs(v - b[i]) < eps)\r\n}\r\n","export const CHOROPLETH_VS = `#version 300 es\r\nin vec2 a_position;\r\nout vec2 v_uv;\r\nvoid main() {\r\n v_uv = a_position * 0.5 + 0.5;\r\n gl_Position = vec4(a_position, 0.0, 1.0);\r\n}\r\n`\r\n\r\nexport const CHOROPLETH_FS = `#version 300 es\r\nprecision highp float;\r\n\r\nin vec2 v_uv;\r\nout vec4 fragColor;\r\n\r\nuniform sampler2D u_data;\r\nuniform sampler2D u_legend;\r\nuniform mat3 u_transform;\r\nuniform vec2 u_size;\r\nuniform vec2 u_delta;\r\nuniform float u_pixel_ratio;\r\nuniform vec4 u_data_bbox; // minLon, minLat, maxLon, maxLat\r\nuniform vec2 u_cell_size; // LOD lonStep, latStep(数据采样)\r\nuniform vec2 u_native_cell_size; // 原始格距\r\nuniform vec2 u_grid_origin; // startLon, startLat\r\nuniform vec2 u_data_size; // cols, rows\r\nuniform vec2 u_legend_meta; // min, max\r\nuniform vec2 u_display_range; // 显示区间 [min, max],区间外格点隐藏\r\nuniform float u_nodata;\r\nuniform float u_opacity;\r\nuniform float u_show_grid;\r\nuniform float u_grid_lod;\r\nuniform float u_proj_mercator; // 1 = EPSG:3857\r\n\r\nvec2 mapCoordToLonLat(vec2 mapCoord) {\r\n if (u_proj_mercator < 0.5) return mapCoord;\r\n const float MAX_EXT = 20037508.342789244;\r\n float lon = mapCoord.x / MAX_EXT * 180.0;\r\n float lat = atan(exp(mapCoord.y / MAX_EXT * 3.141592653589793)) * 360.0 / 3.141592653589793 - 90.0;\r\n return vec2(lon, lat);\r\n}\r\n\r\nvec2 getLonLat(vec2 uv) {\r\n vec2 xy = (vec2(uv.x, 1.0 - uv.y) * u_size) / u_pixel_ratio - u_delta;\r\n float projX = u_transform[0][0] * xy.x + u_transform[1][0] * xy.y + u_transform[2][0];\r\n float projY = u_transform[0][1] * xy.x + u_transform[1][1] * xy.y + u_transform[2][1];\r\n return mapCoordToLonLat(vec2(projX, projY));\r\n}\r\n\r\nvec4 lookupLegend(float value) {\r\n float t = clamp((value - u_legend_meta.x) / (u_legend_meta.y - u_legend_meta.x), 0.0, 1.0);\r\n return texture(u_legend, vec2(t, 0.5));\r\n}\r\n\r\nfloat gridLineFactor(vec2 lonlat, vec2 cellSize, vec4 dataBbox) {\r\n if (u_show_grid < 0.5) return 0.0;\r\n float fx = fract((lonlat.x - dataBbox.x) / cellSize.x);\r\n float fy = fract((lonlat.y - dataBbox.y) / cellSize.y);\r\n float edge = min(min(fx, 1.0 - fx), min(fy, 1.0 - fy));\r\n float pxLon = cellSize.x / (u_data_bbox.z - u_data_bbox.x) * u_size.x / u_pixel_ratio;\r\n float pxLat = cellSize.y / (u_data_bbox.w - u_data_bbox.y) * u_size.y / u_pixel_ratio;\r\n float threshold = 1.0 / min(pxLon, pxLat);\r\n return 1.0 - smoothstep(0.0, threshold, edge);\r\n}\r\n\r\nvoid main() {\r\n vec2 lonlat = getLonLat(v_uv);\r\n\r\n if (lonlat.x < u_data_bbox.x || lonlat.x > u_data_bbox.z ||\r\n lonlat.y < u_data_bbox.y || lonlat.y > u_data_bbox.w) {\r\n discard;\r\n }\r\n\r\n float col = floor((lonlat.x - u_data_bbox.x) / u_cell_size.x);\r\n float row = floor((u_data_bbox.w - lonlat.y) / u_cell_size.y);\r\n col = clamp(col, 0.0, u_data_size.x - 1.0);\r\n row = clamp(row, 0.0, u_data_size.y - 1.0);\r\n\r\n vec2 texCoord = (vec2(col + 0.5, row + 0.5)) / u_data_size;\r\n float v = texture(u_data, texCoord).r;\r\n\r\n if (isnan(v) || abs(v - u_nodata) < 0.001) {\r\n discard;\r\n }\r\n\r\n if (v < u_display_range.x || v > u_display_range.y) {\r\n discard;\r\n }\r\n\r\n vec4 color = lookupLegend(v);\r\n if (color.a < 0.02) {\r\n discard;\r\n }\r\n\r\n float grid = gridLineFactor(lonlat, u_cell_size, u_data_bbox);\r\n vec3 rgb = mix(color.rgb, vec3(0.15, 0.15, 0.15), grid * 0.55);\r\n fragColor = vec4(rgb, color.a * u_opacity);\r\n}\r\n`\r\n","import { CHOROPLETH_FS, CHOROPLETH_VS } from \"./shaders\"\r\nimport type { LegendTexture } from \"./ColorRamp\"\r\nimport type { GridTile } from \"../data/gridDataCore\"\r\n\r\nexport interface RenderUniforms {\r\n transform: number[]\r\n size: [number, number]\r\n delta: [number, number]\r\n pixelRatio: number\r\n dataBbox: [number, number, number, number]\r\n nativeCellSize: [number, number]\r\n gridOrigin: [number, number]\r\n gridLod: number\r\n opacity: number\r\n showGrid: boolean\r\n projMercator: boolean\r\n displayRange: [number, number]\r\n}\r\n\r\nfunction compileShader(gl: WebGL2RenderingContext, type: number, source: string): WebGLShader {\r\n const shader = gl.createShader(type)!\r\n gl.shaderSource(shader, source)\r\n gl.compileShader(shader)\r\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\r\n throw new Error(gl.getShaderInfoLog(shader) ?? \"shader compile error\")\r\n }\r\n return shader\r\n}\r\n\r\nfunction createProgram(gl: WebGL2RenderingContext, vs: string, fs: string): WebGLProgram {\r\n const program = gl.createProgram()!\r\n gl.attachShader(program, compileShader(gl, gl.VERTEX_SHADER, vs))\r\n gl.attachShader(program, compileShader(gl, gl.FRAGMENT_SHADER, fs))\r\n gl.linkProgram(program)\r\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\r\n throw new Error(gl.getProgramInfoLog(program) ?? \"program link error\")\r\n }\r\n return program\r\n}\r\n\r\nexport class ChoroplethRenderer {\r\n readonly gl: WebGL2RenderingContext\r\n private program: WebGLProgram\r\n private vao: WebGLVertexArrayObject\r\n private dataTexture: WebGLTexture | null = null\r\n private legend: LegendTexture | null = null\r\n private lastTileKey = \"\"\r\n private loc: Record<string, WebGLUniformLocation | null> = {}\r\n\r\n constructor(canvas: HTMLCanvasElement) {\r\n const gl = canvas.getContext(\"webgl2\", {\r\n alpha: true,\r\n antialias: false,\r\n preserveDrawingBuffer: false,\r\n })\r\n if (!gl) throw new Error(\"WebGL2 not supported\")\r\n this.gl = gl\r\n this.program = createProgram(gl, CHOROPLETH_VS, CHOROPLETH_FS)\r\n this.vao = this.initQuad()\r\n for (const n of [\r\n \"u_data\", \"u_legend\", \"u_transform\", \"u_size\", \"u_delta\", \"u_pixel_ratio\",\r\n \"u_data_bbox\", \"u_cell_size\", \"u_native_cell_size\", \"u_grid_origin\", \"u_data_size\",\r\n \"u_legend_meta\", \"u_display_range\", \"u_nodata\", \"u_opacity\", \"u_show_grid\", \"u_grid_lod\", \"u_proj_mercator\",\r\n ]) {\r\n this.loc[n] = gl.getUniformLocation(this.program, n)\r\n }\r\n }\r\n\r\n private initQuad(): WebGLVertexArrayObject {\r\n const gl = this.gl\r\n const vao = gl.createVertexArray()!\r\n gl.bindVertexArray(vao)\r\n const buf = gl.createBuffer()!\r\n gl.bindBuffer(gl.ARRAY_BUFFER, buf)\r\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, 1, -1, -1, 1, 1, 1, -1]), gl.STATIC_DRAW)\r\n const loc = gl.getAttribLocation(this.program, \"a_position\")\r\n gl.enableVertexAttribArray(loc)\r\n gl.vertexAttribPointer(loc, 2, gl.FLOAT, false, 0, 0)\r\n gl.bindVertexArray(null)\r\n return vao\r\n }\r\n\r\n resize(w: number, h: number): void {\r\n const gl = this.gl\r\n gl.canvas.width = Math.max(1, Math.floor(w))\r\n gl.canvas.height = Math.max(1, Math.floor(h))\r\n gl.viewport(0, 0, gl.canvas.width, gl.canvas.height)\r\n }\r\n\r\n setLegend(legend: LegendTexture): void {\r\n this.legend = legend\r\n }\r\n\r\n uploadTile(tile: GridTile): void {\r\n const key = `${tile.width}x${tile.height}-${tile.lodStep}-${tile.bbox.join(\",\")}`\r\n if (key === this.lastTileKey && this.dataTexture) return\r\n\r\n const gl = this.gl\r\n if (!this.dataTexture) {\r\n this.dataTexture = gl.createTexture()\r\n }\r\n gl.bindTexture(gl.TEXTURE_2D, this.dataTexture)\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.R32F, tile.width, tile.height, 0, gl.RED, gl.FLOAT, tile.data)\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)\r\n this.lastTileKey = key\r\n }\r\n\r\n render(tile: GridTile, uniforms: RenderUniforms): void {\r\n if (!this.dataTexture || !this.legend) return\r\n\r\n const gl = this.gl\r\n gl.clearColor(0, 0, 0, 0)\r\n gl.clear(gl.COLOR_BUFFER_BIT)\r\n gl.enable(gl.BLEND)\r\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)\r\n\r\n gl.useProgram(this.program)\r\n gl.bindVertexArray(this.vao)\r\n\r\n gl.activeTexture(gl.TEXTURE0)\r\n gl.bindTexture(gl.TEXTURE_2D, this.dataTexture)\r\n gl.uniform1i(this.loc.u_data!, 0)\r\n\r\n gl.activeTexture(gl.TEXTURE1)\r\n gl.bindTexture(gl.TEXTURE_2D, this.legend.texture)\r\n gl.uniform1i(this.loc.u_legend!, 1)\r\n\r\n const [minLon, minLat, maxLon, maxLat] = tile.bbox\r\n const [resLon, resLat] = tile.resolution\r\n\r\n gl.uniformMatrix3fv(this.loc.u_transform!, false, uniforms.transform)\r\n gl.uniform2f(this.loc.u_size!, uniforms.size[0], uniforms.size[1])\r\n gl.uniform2f(this.loc.u_delta!, uniforms.delta[0], uniforms.delta[1])\r\n gl.uniform1f(this.loc.u_pixel_ratio!, uniforms.pixelRatio)\r\n gl.uniform4f(this.loc.u_data_bbox!, minLon, minLat, maxLon, maxLat)\r\n gl.uniform2f(this.loc.u_cell_size!, resLon, resLat)\r\n gl.uniform2f(this.loc.u_native_cell_size!, uniforms.nativeCellSize[0], uniforms.nativeCellSize[1])\r\n gl.uniform2f(this.loc.u_grid_origin!, uniforms.gridOrigin[0], uniforms.gridOrigin[1])\r\n gl.uniform2f(this.loc.u_data_size!, tile.width, tile.height)\r\n gl.uniform2f(this.loc.u_legend_meta!, this.legend.min, this.legend.max)\r\n gl.uniform2f(this.loc.u_display_range!, uniforms.displayRange[0], uniforms.displayRange[1])\r\n gl.uniform1f(this.loc.u_nodata!, -9999)\r\n gl.uniform1f(this.loc.u_opacity!, uniforms.opacity)\r\n gl.uniform1f(this.loc.u_show_grid!, uniforms.showGrid ? 1 : 0)\r\n gl.uniform1f(this.loc.u_grid_lod!, uniforms.gridLod)\r\n gl.uniform1f(this.loc.u_proj_mercator!, uniforms.projMercator ? 1 : 0)\r\n\r\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4)\r\n gl.bindVertexArray(null)\r\n }\r\n\r\n dispose(): void {\r\n const gl = this.gl\r\n if (this.dataTexture) gl.deleteTexture(this.dataTexture)\r\n if (this.legend) gl.deleteTexture(this.legend.texture)\r\n gl.deleteProgram(this.program)\r\n gl.deleteVertexArray(this.vao)\r\n }\r\n}\r\n\r\nexport function affineToMat3(affine: number[]): Float32Array {\r\n return new Float32Array([affine[0], affine[1], 0, affine[2], affine[3], 0, affine[4], affine[5], 1])\r\n}\r\n\r\nexport function computeDelta(viewExtent: number[], frameExtent: number[], resolution: number): [number, number] {\r\n return [\r\n (viewExtent[0] - frameExtent[0]) / resolution,\r\n (frameExtent[3] - viewExtent[3]) / resolution,\r\n ]\r\n}\r\n","import type { ColorRampItem } from \"../data/gridDataCore\"\r\n\r\nexport interface LegendTexture {\r\n texture: WebGLTexture\r\n min: number\r\n max: number\r\n width: number\r\n}\r\n\r\nconst LEGEND_WIDTH = 256\r\n\r\nfunction hexToRgba(hex: string): [number, number, number, number] {\r\n if (hex.length === 9) {\r\n const n = parseInt(hex.slice(1, 7), 16)\r\n const a = parseInt(hex.slice(7, 9), 16)\r\n return [(n >> 16) & 255, (n >> 8) & 255, n & 255, a]\r\n }\r\n const n = parseInt(hex.slice(1), 16)\r\n return [(n >> 16) & 255, (n >> 8) & 255, n & 255, 255]\r\n}\r\n\r\nfunction lerpRgba(\r\n a: [number, number, number, number],\r\n b: [number, number, number, number],\r\n t: number,\r\n): [number, number, number, number] {\r\n return [\r\n Math.round(a[0] + (b[0] - a[0]) * t),\r\n Math.round(a[1] + (b[1] - a[1]) * t),\r\n Math.round(a[2] + (b[2] - a[2]) * t),\r\n Math.round(a[3] + (b[3] - a[3]) * t),\r\n ]\r\n}\r\n\r\nfunction sampleRamp(stops: ColorRampItem[], value: number): [number, number, number, number] {\r\n if (value <= stops[0][0]) return stops[0][1]\r\n if (value >= stops[stops.length - 1][0]) return stops[stops.length - 1][1]\r\n for (let i = 0; i < stops.length - 1; i++) {\r\n const [v0, c0] = stops[i]\r\n const [v1, c1] = stops[i + 1]\r\n if (value >= v0 && value <= v1) {\r\n const t = v1 === v0 ? 0 : (value - v0) / (v1 - v0)\r\n return lerpRgba(c0, c1, t)\r\n }\r\n }\r\n return stops[stops.length - 1][1]\r\n}\r\n\r\n/** 256×1 连续色带(LINEAR),避免低值 NEAREST 采到透明 */\r\nexport function buildLegendTexture(\r\n gl: WebGL2RenderingContext,\r\n colorRamp: ColorRampItem[],\r\n): LegendTexture {\r\n const inner = colorRamp.filter(([v]) => v > -9000 && v < 9000)\r\n const min = inner[0][0]\r\n const max = inner[inner.length - 1][0]\r\n const span = Math.max(max - min, 0.01)\r\n\r\n const pixels = new Uint8Array(LEGEND_WIDTH * 4)\r\n for (let i = 0; i < LEGEND_WIDTH; i++) {\r\n const value = min + (span * i) / (LEGEND_WIDTH - 1)\r\n pixels.set(sampleRamp(inner, value), i * 4)\r\n }\r\n\r\n const texture = gl.createTexture()!\r\n gl.bindTexture(gl.TEXTURE_2D, texture)\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, LEGEND_WIDTH, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, pixels)\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)\r\n\r\n return { texture, min, max, width: LEGEND_WIDTH }\r\n}\r\n\r\n/** 标准色斑色带:min 起可见浅绿,低值(0~3)也能渲染 */\r\nexport function defaultGridColorRamp(min: number, max: number): ColorRampItem[] {\r\n const span = Math.max(max - min, 0.01)\r\n const v = (t: number) => min + span * t\r\n const stops: [number, string][] = [\r\n [min, \"#e8f5e9\"],\r\n [v(0.08), \"#c8e6c9\"],\r\n [v(0.2), \"#a5d6a7\"],\r\n [v(0.35), \"#66bb6a\"],\r\n [v(0.55), \"#43a047\"],\r\n [v(0.75), \"#2e7d32\"],\r\n [max, \"#1b5e20\"],\r\n ]\r\n return [\r\n [-9999, [0, 0, 0, 0]],\r\n ...stops.map(([val, hex]) => [val, hexToRgba(hex)] as ColorRampItem),\r\n [9999, [0, 0, 0, 0]],\r\n ]\r\n}\r\n\r\nexport function defaultTemperatureRamp(min: number, max: number): ColorRampItem[] {\r\n const stops: [number, string][] = [\r\n [min, \"#313695\"],\r\n [min + (max - min) * 0.15, \"#4575b4\"],\r\n [min + (max - min) * 0.3, \"#74add1\"],\r\n [min + (max - min) * 0.45, \"#abd9e9\"],\r\n [min + (max - min) * 0.55, \"#fee090\"],\r\n [min + (max - min) * 0.7, \"#fdae61\"],\r\n [min + (max - min) * 0.85, \"#f46d43\"],\r\n [max, \"#a50026\"],\r\n ]\r\n return [\r\n [-9999, [0, 0, 0, 0]],\r\n ...stops.map(([val, hex]) => [val, hexToRgba(hex)] as ColorRampItem),\r\n [9999, [0, 0, 0, 0]],\r\n ]\r\n}\r\n\r\n/** 按新 min/max 重采样色带(保留各 stop 相对位置) */\r\nexport function colorRampWithRange(\r\n min: number,\r\n max: number,\r\n template?: ColorRampItem[],\r\n): ColorRampItem[] {\r\n const base = template ?? defaultGridColorRamp(min, max)\r\n const inner = base.filter(([v]) => v > -9000 && v < 9000)\r\n if (inner.length < 2) return defaultGridColorRamp(min, max)\r\n\r\n const oldMin = inner[0][0]\r\n const oldMax = inner[inner.length - 1][0]\r\n const oldSpan = Math.max(oldMax - oldMin, 0.01)\r\n const newSpan = Math.max(max - min, 0.01)\r\n\r\n const remapped = inner.map(([v, c]) => {\r\n const t = (v - oldMin) / oldSpan\r\n return [min + t * newSpan, c] as ColorRampItem\r\n })\r\n\r\n return [\r\n [-9999, [0, 0, 0, 0]],\r\n ...remapped,\r\n [9999, [0, 0, 0, 0]],\r\n ]\r\n}\r\n\r\nexport function legendRangeFromRamp(colorRamp: ColorRampItem[]): { min: number; max: number } {\r\n const inner = colorRamp.filter(([v]) => v > -9000 && v < 9000)\r\n return { min: inner[0][0], max: inner[inner.length - 1][0] }\r\n}\r\n\r\n/** 从色带提取图例刻度(支持不规则间隔) */\r\nexport function extractLegendTicks(colorRamp: ColorRampItem[]): number[] {\r\n return colorRamp.filter(([v]) => v > -9000 && v < 9000).map(([v]) => v)\r\n}\r\n\r\n/** 数值在图例条上的位置比例 [0,1](按实际数值线性映射) */\r\nexport function valueToLegendPercent(value: number, colorRamp: ColorRampItem[]): number {\r\n const { min, max } = legendRangeFromRamp(colorRamp)\r\n const span = Math.max(max - min, 0.01)\r\n return Math.max(0, Math.min(1, (value - min) / span))\r\n}\r\n\r\n/** 刻度序号 → 均匀位置 [0,1] */\r\nexport function tickIndexToEvenPercent(index: number, tickCount: number): number {\r\n if (tickCount <= 1) return 0\r\n return index / (tickCount - 1)\r\n}\r\n\r\n/** 数值 → 均匀图例位置(段内按数值插值,段宽相等) */\r\nexport function valueToEvenLegendPercent(value: number, ticks: number[]): number {\r\n if (ticks.length <= 1) return 0\r\n if (value <= ticks[0]) return 0\r\n if (value >= ticks[ticks.length - 1]) return 1\r\n for (let i = 0; i < ticks.length - 1; i++) {\r\n const v0 = ticks[i]\r\n const v1 = ticks[i + 1]\r\n if (value >= v0 && value <= v1) {\r\n const t = v1 === v0 ? 0 : (value - v0) / (v1 - v0)\r\n const p0 = tickIndexToEvenPercent(i, ticks.length)\r\n const p1 = tickIndexToEvenPercent(i + 1, ticks.length)\r\n return p0 + t * (p1 - p0)\r\n }\r\n }\r\n return 1\r\n}\r\n\r\n/** 均匀图例位置 → 数值 */\r\nexport function evenLegendPercentToValue(p: number, ticks: number[]): number {\r\n if (ticks.length <= 1) return ticks[0] ?? 0\r\n const clamped = Math.max(0, Math.min(1, p))\r\n const segCount = ticks.length - 1\r\n const idx = Math.min(segCount - 1, Math.floor(clamped * segCount))\r\n const localP = clamped * segCount - idx\r\n const v0 = ticks[idx]\r\n const v1 = ticks[idx + 1]\r\n return v0 + localP * (v1 - v0)\r\n}\r\n\r\n/** 均匀分布的 CSS 渐变色带 */\r\nexport function rampToEvenCssGradient(colorRamp: ColorRampItem[]): string {\r\n const inner = getInnerRampStops(colorRamp)\r\n const n = inner.length\r\n const stops = inner.map(([_, rgba], i) => {\r\n const pct = n <= 1 ? 0 : (i / (n - 1)) * 100\r\n return `${rgbaToCss(rgba)} ${pct}%`\r\n })\r\n return `linear-gradient(to right, ${stops.join(\", \")})`\r\n}\r\n\r\nexport type LegendDisplayMode = \"gradient\" | \"blocks\"\r\n\r\nexport function getInnerRampStops(colorRamp: ColorRampItem[]): ColorRampItem[] {\r\n return colorRamp.filter(([v]) => v > -9000 && v < 9000)\r\n}\r\n\r\nexport function rgbaToCss(rgba: [number, number, number, number]): string {\r\n return `rgba(${rgba[0]},${rgba[1]},${rgba[2]},${rgba[3] / 255})`\r\n}\r\n\r\nexport function rampToCssGradient(colorRamp: ColorRampItem[]): string {\r\n const inner = colorRamp.filter(([v]) => v > -9000 && v < 9000)\r\n const min = inner[0][0]\r\n const max = inner[inner.length - 1][0]\r\n const stops = inner.map(([v, rgba]) => {\r\n const pct = ((v - min) / (max - min)) * 100\r\n return `rgba(${rgba[0]},${rgba[1]},${rgba[2]},${rgba[3] / 255}) ${pct}%`\r\n })\r\n return `linear-gradient(to right, ${stops.join(\", \")})`\r\n}\r\n","import { fromLonLat, toLonLat, transformExtent } from \"ol/proj\"\r\n\r\nexport type ProjCode = \"EPSG:4326\" | \"EPSG:3857\"\r\n\r\nexport function isMercator(code: string): boolean {\r\n return code === \"EPSG:3857\"\r\n}\r\n\r\n/** 经纬度 → 地图视图投影坐标 */\r\nexport function lonLatToMapCoord(lon: number, lat: number, projCode: string): [number, number] {\r\n if (projCode === \"EPSG:4326\") return [lon, lat]\r\n return fromLonLat([lon, lat]) as [number, number]\r\n}\r\n\r\n/** 地图视图投影坐标 → 经纬度 */\r\nexport function mapCoordToLonLat(x: number, y: number, projCode: string): [number, number] {\r\n if (projCode === \"EPSG:4326\") return [x, y]\r\n return toLonLat([x, y]) as [number, number]\r\n}\r\n\r\n/** 4326 数据 bbox → 视图投影 extent */\r\nexport function dataBboxToViewExtent(\r\n bbox4326: [number, number, number, number],\r\n projCode: string,\r\n): [number, number, number, number] {\r\n if (projCode === \"EPSG:4326\") return bbox4326\r\n return transformExtent(bbox4326, \"EPSG:4326\", projCode) as [number, number, number, number]\r\n}\r\n\r\n/** 视图 extent → 4326(供 Worker / 数据查询) */\r\nexport function viewExtentTo4326(\r\n extent: number[],\r\n projCode: string,\r\n): [number, number, number, number] {\r\n if (projCode === \"EPSG:4326\") return extent as [number, number, number, number]\r\n return transformExtent(extent, projCode, \"EPSG:4326\") as [number, number, number, number]\r\n}\r\n","import ImageLayer from \"ol/layer/Image\"\r\nimport ImageCanvas from \"ol/source/ImageCanvas\"\r\nimport type { Projection } from \"ol/proj\"\r\nimport type Map from \"ol/Map\"\r\nimport type View from \"ol/View\"\r\nimport type { ColorRampItem, GridTile } from \"../data/gridDataCore\"\r\nimport type { ArrayDataLoader } from \"../data/ArrayDataLoader\"\r\nimport { ChoroplethRenderer, affineToMat3, computeDelta } from \"../webgl/ChoroplethRenderer\"\r\nimport { buildLegendTexture, colorRampWithRange, defaultGridColorRamp, legendRangeFromRamp, type LegendTexture } from \"../webgl/ColorRamp\"\r\nimport { isMercator, viewExtentTo4326 } from \"../utils/projBridge\"\r\n\r\nexport interface ChoroplethLayerOptions {\r\n loader: ArrayDataLoader\r\n colorRamp?: ColorRampItem[]\r\n opacity?: number\r\n showGrid?: boolean\r\n zIndex?: number\r\n}\r\n\r\nexport class ChoroplethLayer extends ImageLayer<ImageCanvas> {\r\n private loader: ArrayDataLoader\r\n private glCanvas: HTMLCanvasElement\r\n private displayCanvas: HTMLCanvasElement\r\n private renderer: ChoroplethRenderer\r\n private legend: LegendTexture | null = null\r\n private currentTile: GridTile | null = null\r\n private showGridLines: boolean\r\n private colorRamp: ColorRampItem[]\r\n private displayMin: number\r\n private displayMax: number\r\n private mapRef: Map | null = null\r\n private fetchVersion = 0\r\n private viewUnbind: (() => void) | null = null\r\n private readonly onMapChange = () => this.scheduleFetch()\r\n\r\n constructor(options: ChoroplethLayerOptions) {\r\n const glCanvas = document.createElement(\"canvas\")\r\n const displayCanvas = document.createElement(\"canvas\")\r\n const renderer = new ChoroplethRenderer(glCanvas)\r\n\r\n const renderHolder: {\r\n fn?: (\r\n extent: number[],\r\n resolution: number,\r\n pixelRatio: number,\r\n size: number[],\r\n projection: Projection,\r\n ) => HTMLCanvasElement\r\n } = {}\r\n\r\n super({\r\n opacity: options.opacity ?? 0.85,\r\n zIndex: options.zIndex ?? 2,\r\n source: new ImageCanvas({\r\n canvasFunction: (extent, resolution, pixelRatio, size, projection) =>\r\n renderHolder.fn!(extent, resolution, pixelRatio, size, projection),\r\n ratio: 1,\r\n }),\r\n })\r\n\r\n this.loader = options.loader\r\n this.glCanvas = glCanvas\r\n this.displayCanvas = displayCanvas\r\n this.renderer = renderer\r\n this.showGridLines = options.showGrid ?? false\r\n\r\n const stats = this.loader.computeStats()\r\n const ramp = options.colorRamp ?? defaultGridColorRamp(stats.min, stats.max)\r\n this.colorRamp = ramp\r\n const { min, max } = legendRangeFromRamp(ramp)\r\n this.displayMin = min\r\n this.displayMax = max\r\n this.legend = buildLegendTexture(renderer.gl, ramp)\r\n renderer.setLegend(this.legend)\r\n\r\n renderHolder.fn = this.renderFrame.bind(this)\r\n }\r\n\r\n /** 当前图例数值范围 */\r\n getLegendRange(): { min: number; max: number } {\r\n return legendRangeFromRamp(this.colorRamp)\r\n }\r\n\r\n getColorRamp(): ColorRampItem[] {\r\n return this.colorRamp\r\n }\r\n\r\n /** 设置完整色带并刷新渲染 */\r\n setColorRamp(colorRamp: ColorRampItem[]): void {\r\n this.colorRamp = colorRamp\r\n this.rebuildLegend()\r\n }\r\n\r\n /** 仅调整图例 min/max(保留当前色带样式) */\r\n setLegendRange(min: number, max: number): void {\r\n this.setColorRamp(colorRampWithRange(min, max, this.colorRamp))\r\n }\r\n\r\n /** 色斑图实际显示的数值区间(滑块控制) */\r\n getDisplayRange(): { min: number; max: number } {\r\n return { min: this.displayMin, max: this.displayMax }\r\n }\r\n\r\n setDisplayRange(min: number, max: number): void {\r\n const { min: lmin, max: lmax } = this.getLegendRange()\r\n const span = Math.max(lmax - lmin, 0.01)\r\n const gap = span * 0.001\r\n let dmin = Math.max(lmin, Math.min(min, lmax))\r\n let dmax = Math.min(lmax, Math.max(max, lmin))\r\n if (dmax - dmin < gap) {\r\n dmax = Math.min(lmax, dmin + gap)\r\n }\r\n this.displayMin = dmin\r\n this.displayMax = dmax\r\n this.refreshRender()\r\n }\r\n\r\n private clampDisplayRange(): void {\r\n const { min: lmin, max: lmax } = this.getLegendRange()\r\n this.setDisplayRange(\r\n Math.max(lmin, Math.min(this.displayMin, lmax)),\r\n Math.min(lmax, Math.max(this.displayMax, lmin)),\r\n )\r\n }\r\n\r\n private refreshRender(): void {\r\n this.getSource()?.changed()\r\n this.changed()\r\n }\r\n\r\n getShowGrid(): boolean {\r\n return this.showGridLines\r\n }\r\n\r\n private rebuildLegend(): void {\r\n if (this.legend) {\r\n this.renderer.gl.deleteTexture(this.legend.texture)\r\n }\r\n this.legend = buildLegendTexture(this.renderer.gl, this.colorRamp)\r\n this.renderer.setLegend(this.legend)\r\n this.clampDisplayRange()\r\n }\r\n\r\n setShowGrid(show: boolean): void {\r\n this.showGridLines = show\r\n this.refreshRender()\r\n }\r\n\r\n refreshData(): void {\r\n this.loader.invalidateCache()\r\n this.scheduleFetch()\r\n }\r\n\r\n private scheduleFetch(): void {\r\n const map = this.mapRef\r\n if (!map || !this.loader.isLoaded) return\r\n\r\n const view = map.getView()\r\n const projCode = view.getProjection().getCode()\r\n const size = map.getSize()\r\n if (!size) return\r\n\r\n const extent4326 = viewExtentTo4326(view.calculateExtent(size), projCode)\r\n const zoom = view.getZoom() ?? 6\r\n const ver = ++this.fetchVersion\r\n\r\n this.loader.readWindowAsync(extent4326, zoom).then((tile) => {\r\n if (ver !== this.fetchVersion) return\r\n if (tile) this.currentTile = tile\r\n this.getSource()?.changed()\r\n })\r\n }\r\n\r\n private renderFrame(\r\n extent: number[],\r\n resolution: number,\r\n pixelRatio: number,\r\n size: number[],\r\n ): HTMLCanvasElement {\r\n const [w, h] = size\r\n const canvasW = Math.floor(w * pixelRatio)\r\n const canvasH = Math.floor(h * pixelRatio)\r\n\r\n this.displayCanvas.width = canvasW\r\n this.displayCanvas.height = canvasH\r\n this.renderer.resize(canvasW, canvasH)\r\n\r\n const map = this.mapRef\r\n if (!map || !this.loader.isLoaded) {\r\n return this.displayCanvas\r\n }\r\n\r\n const view = map.getView()\r\n const projCode = view.getProjection().getCode()\r\n const zoom = view.getZoom() ?? 6\r\n const mapSize = map.getSize()\r\n const extent4326 = mapSize\r\n ? viewExtentTo4326(view.calculateExtent(mapSize), projCode)\r\n : (extent as [number, number, number, number])\r\n\r\n const tile = this.currentTile ?? this.loader.readWindow(extent4326, zoom)\r\n\r\n if (!tile) {\r\n const ctx = this.displayCanvas.getContext(\"2d\")!\r\n ctx.clearRect(0, 0, canvasW, canvasH)\r\n return this.displayCanvas\r\n }\r\n\r\n this.currentTile = tile\r\n this.renderer.uploadTile(tile)\r\n\r\n // @ts-expect-error OL 私有 frameState\r\n const frameState = map.frameState_\r\n const pixelToCoord = frameState?.pixelToCoordinateTransform as number[] | undefined\r\n const transform = pixelToCoord\r\n ? affineToMat3(pixelToCoord)\r\n : new Float32Array([1, 0, 0, 0, -1, 0, 0, 0, 1])\r\n\r\n const viewExtent = view.calculateExtent(mapSize ?? size) as number[]\r\n const delta = computeDelta(viewExtent, extent, resolution)\r\n\r\n this.renderer.render(tile, {\r\n transform: Array.from(transform),\r\n size: [canvasW, canvasH],\r\n delta,\r\n pixelRatio,\r\n dataBbox: tile.bbox,\r\n nativeCellSize: this.loader.nativeResolution,\r\n gridOrigin: this.loader.gridOrigin,\r\n gridLod: this.loader.getLodStep(zoom),\r\n opacity: this.getOpacity(),\r\n showGrid: this.showGridLines,\r\n projMercator: isMercator(projCode),\r\n displayRange: [this.displayMin, this.displayMax],\r\n })\r\n\r\n const ctx = this.displayCanvas.getContext(\"2d\")!\r\n ctx.clearRect(0, 0, canvasW, canvasH)\r\n ctx.drawImage(this.glCanvas, 0, 0)\r\n\r\n return this.displayCanvas\r\n }\r\n\r\n attachMap(map: Map): void {\r\n this.mapRef = map\r\n map.on(\"moveend\", this.onMapChange)\r\n this.bindView(map.getView())\r\n this.scheduleFetch()\r\n }\r\n\r\n reattachView(map: Map): void {\r\n this.mapRef = map\r\n this.bindView(map.getView())\r\n this.scheduleFetch()\r\n }\r\n\r\n private bindView(view: View): void {\r\n this.viewUnbind?.()\r\n view.on(\"change:resolution\", this.onMapChange)\r\n this.viewUnbind = () => view.un(\"change:resolution\", this.onMapChange)\r\n }\r\n\r\n getDataValue(lon: number, lat: number): number | null {\r\n return this.loader.getValueAt(lon, lat, this.currentTile)\r\n }\r\n\r\n dispose(): void {\r\n this.renderer.dispose()\r\n }\r\n}\r\n","import type Map from \"ol/Map\"\r\nimport type { Coordinate } from \"ol/coordinate\"\r\n\r\n/**\r\n * 地图坐标 → ImageCanvas 设备像素(与色斑图 frameState 变换一致)\r\n */\r\nexport function mapCoordToCanvasPixel(\r\n map: Map,\r\n coordinate: Coordinate,\r\n pixelRatio: number,\r\n): [number, number] | null {\r\n const css = map.getPixelFromCoordinate(coordinate)\r\n if (!css) return null\r\n return [css[0] * pixelRatio, css[1] * pixelRatio]\r\n}\r\n\r\n/** @deprecated 线性 extent 映射与 OL 变换不一致,勿用于标注 */\r\nexport function mapCoordToFramePixel(\r\n mapX: number,\r\n mapY: number,\r\n frameExtent: number[],\r\n size: number[],\r\n pixelRatio: number,\r\n): [number, number] {\r\n const [minX, minY, maxX, maxY] = frameExtent\r\n const [w, h] = size\r\n const spanX = maxX - minX || 1\r\n const spanY = maxY - minY || 1\r\n const x = ((mapX - minX) / spanX) * w * pixelRatio\r\n const y = ((maxY - mapY) / spanY) * h * pixelRatio\r\n return [x, y]\r\n}\r\n","import ImageLayer from \"ol/layer/Image\"\r\nimport ImageCanvas from \"ol/source/ImageCanvas\"\r\nimport type { Projection } from \"ol/proj\"\r\nimport type Map from \"ol/Map\"\r\nimport type View from \"ol/View\"\r\nimport type { ArrayDataLoader } from \"../data/ArrayDataLoader\"\r\nimport type { GridLabel } from \"../data/gridDataCore\"\r\nimport { lonLatToMapCoord, viewExtentTo4326 } from \"../utils/projBridge\"\r\nimport { mapCoordToCanvasPixel } from \"../utils/canvasCoords\"\r\n\r\nexport interface GridValueLayerOptions {\r\n loader: ArrayDataLoader\r\n distance?: number\r\n precision?: number\r\n fontSize?: number\r\n color?: string\r\n zIndex?: number\r\n}\r\n\r\n/**\r\n * Canvas2D 格点数值标注\r\n * computeLabels → extent 转屏幕像素 → fillText(稳定可读)\r\n */\r\nexport class GridValueLayer extends ImageLayer<ImageCanvas> {\r\n private loader: ArrayDataLoader\r\n private mapRef: Map | null = null\r\n private canvas: HTMLCanvasElement\r\n private labels: GridLabel[] = []\r\n private fetchVersion = 0\r\n private viewUnbind: (() => void) | null = null\r\n private readonly onMapChange = () => this.scheduleFetch()\r\n private opts: Required<Pick<GridValueLayerOptions, \"distance\" | \"precision\" | \"fontSize\" | \"color\">>\r\n\r\n constructor(options: GridValueLayerOptions) {\r\n const canvas = document.createElement(\"canvas\")\r\n const renderHolder: {\r\n fn?: (\r\n extent: number[],\r\n resolution: number,\r\n pixelRatio: number,\r\n size: number[],\r\n projection: Projection,\r\n ) => HTMLCanvasElement\r\n } = {}\r\n\r\n super({\r\n zIndex: options.zIndex ?? 3,\r\n source: new ImageCanvas({\r\n canvasFunction: (extent, resolution, pixelRatio, size, projection) =>\r\n renderHolder.fn!(extent, resolution, pixelRatio, size, projection),\r\n ratio: 1,\r\n }),\r\n })\r\n\r\n this.loader = options.loader\r\n this.canvas = canvas\r\n this.opts = {\r\n distance: options.distance ?? 80,\r\n precision: options.precision ?? 1,\r\n fontSize: options.fontSize ?? 11,\r\n color: options.color ?? \"rgba(20, 20, 20, 0.92)\",\r\n }\r\n\r\n renderHolder.fn = this.renderFrame.bind(this)\r\n }\r\n\r\n attachMap(map: Map): void {\r\n this.mapRef = map\r\n map.on(\"moveend\", this.onMapChange)\r\n this.bindView(map.getView())\r\n this.scheduleFetch()\r\n }\r\n\r\n /** 切换投影后重新绑定 View 监听 */\r\n reattachView(map: Map): void {\r\n this.mapRef = map\r\n this.bindView(map.getView())\r\n this.scheduleFetch()\r\n }\r\n\r\n private bindView(view: View): void {\r\n this.viewUnbind?.()\r\n view.on(\"change:resolution\", this.onMapChange)\r\n this.viewUnbind = () => view.un(\"change:resolution\", this.onMapChange)\r\n }\r\n\r\n refreshData(): void {\r\n this.labels = []\r\n this.scheduleFetch()\r\n }\r\n\r\n private scheduleFetch(): void {\r\n const map = this.mapRef\r\n if (!map || !this.loader.isLoaded) return\r\n\r\n const view = map.getView()\r\n const projCode = view.getProjection().getCode()\r\n const size = map.getSize()\r\n const center = view.getCenter()\r\n if (!size || !center) return\r\n\r\n const extent4326 = viewExtentTo4326(view.calculateExtent(size), projCode)\r\n const zoom = view.getZoom() ?? 6\r\n const resolution = view.getResolution() ?? 1\r\n const ver = ++this.fetchVersion\r\n\r\n this.labels = this.loader.computeLabelsSync(\r\n extent4326,\r\n zoom,\r\n resolution,\r\n this.opts.distance,\r\n this.opts.precision,\r\n projCode,\r\n )\r\n this.getSource()?.changed()\r\n\r\n this.loader\r\n .computeLabelsAsync(\r\n extent4326,\r\n zoom,\r\n resolution,\r\n this.opts.distance,\r\n this.opts.precision,\r\n projCode,\r\n )\r\n .then((labels) => {\r\n if (ver !== this.fetchVersion) return\r\n this.labels = labels\r\n this.getSource()?.changed()\r\n })\r\n }\r\n\r\n private renderFrame(\r\n _extent: number[],\r\n _resolution: number,\r\n pixelRatio: number,\r\n size: number[],\r\n ): HTMLCanvasElement {\r\n const [w, h] = size\r\n const canvasW = Math.max(1, Math.floor(w * pixelRatio))\r\n const canvasH = Math.max(1, Math.floor(h * pixelRatio))\r\n\r\n this.canvas.width = canvasW\r\n this.canvas.height = canvasH\r\n\r\n const ctx = this.canvas.getContext(\"2d\")!\r\n ctx.clearRect(0, 0, canvasW, canvasH)\r\n\r\n const map = this.mapRef\r\n if (!map || this.labels.length === 0) {\r\n return this.canvas\r\n }\r\n\r\n const fontPx = this.opts.fontSize * pixelRatio\r\n ctx.font = `${fontPx}px system-ui, -apple-system, sans-serif`\r\n ctx.textAlign = \"center\"\r\n ctx.textBaseline = \"middle\"\r\n ctx.lineWidth = Math.max(2, 2 * pixelRatio)\r\n ctx.lineJoin = \"round\"\r\n ctx.strokeStyle = \"rgba(255, 255, 255, 0.9)\"\r\n ctx.fillStyle = this.opts.color\r\n\r\n const projCode = map.getView().getProjection().getCode()\r\n for (const label of this.labels) {\r\n const coord = lonLatToMapCoord(label.lon, label.lat, projCode)\r\n const pixel = mapCoordToCanvasPixel(map, coord, pixelRatio)\r\n if (!pixel) continue\r\n const [px, py] = pixel\r\n if (px < -fontPx || px > canvasW + fontPx || py < -fontPx || py > canvasH + fontPx) continue\r\n ctx.strokeText(label.text, px, py)\r\n ctx.fillText(label.text, px, py)\r\n }\r\n\r\n return this.canvas\r\n }\r\n}\r\n","import type Map from \"ol/Map\"\r\nimport { ArrayDataLoader } from \"../data/ArrayDataLoader\"\r\nimport { ChoroplethLayer } from \"../layers/ChoroplethLayer\"\r\nimport { GridValueLayer } from \"../layers/GridValueLayer\"\r\nimport { dataBboxToViewExtent, mapCoordToLonLat } from \"../utils/projBridge\"\r\nimport type { GridMapOptions, GridMapPointerEvent, GridMapViewApi, GridLayerVisibility, LegendRange, DisplayRange } from \"./types\"\r\nimport type { ColorRampItem } from \"../data/gridDataCore\"\r\nimport { colorRampWithRange, defaultGridColorRamp } from \"../webgl/ColorRamp\"\r\nimport type { ProjCode } from \"../utils/projBridge\"\r\n\r\nfunction normalizePadding(padding: number | [number, number, number, number]): [number, number, number, number] {\r\n if (typeof padding === \"number\") return [padding, padding, padding, padding]\r\n return padding\r\n}\r\n\r\n/**\r\n * 网格图层控制器:叠加在外部 ol/Map 上,不创建 Map / 底图。\r\n */\r\nexport class GridMapView implements GridMapViewApi {\r\n readonly map: Map\r\n readonly loader: ArrayDataLoader\r\n readonly choroplethLayer: ChoroplethLayer\r\n readonly gridValueLayer: GridValueLayer\r\n readonly stats: { min: number; max: number }\r\n\r\n private pointerHandler: ((ev: GridMapPointerEvent) => void) | null = null\r\n private pointerUnbind: (() => void) | null = null\r\n private destroyed = false\r\n\r\n private constructor(\r\n map: Map,\r\n loader: ArrayDataLoader,\r\n choroplethLayer: ChoroplethLayer,\r\n gridValueLayer: GridValueLayer,\r\n stats: { min: number; max: number },\r\n private fitOpts: { padding: [number, number, number, number]; maxZoom: number },\r\n ) {\r\n this.map = map\r\n this.loader = loader\r\n this.choroplethLayer = choroplethLayer\r\n this.gridValueLayer = gridValueLayer\r\n this.stats = stats\r\n }\r\n\r\n get projection(): ProjCode {\r\n return this.map.getView().getProjection().getCode() as ProjCode\r\n }\r\n\r\n static async create(options: GridMapOptions): Promise<GridMapView> {\r\n if (!options.map) {\r\n throw new Error(\"GridMapView: map is required\")\r\n }\r\n if (!options.dataUrl && !options.data) {\r\n throw new Error(\"GridMapView: dataUrl or data is required\")\r\n }\r\n\r\n const loader = new ArrayDataLoader()\r\n if (options.data) {\r\n await loader.loadData(options.data)\r\n } else {\r\n await loader.load(options.dataUrl!)\r\n }\r\n\r\n const stats = loader.computeStats()\r\n const legendMin = options.legendMin ?? stats.min\r\n const legendMax = options.legendMax ?? stats.max\r\n const initialRamp = options.colorRamp\r\n ? options.colorRamp\r\n : colorRampWithRange(legendMin, legendMax, defaultGridColorRamp(legendMin, legendMax))\r\n\r\n const choroplethLayer = new ChoroplethLayer({\r\n loader,\r\n colorRamp: initialRamp,\r\n opacity: options.choroplethOpacity ?? 0.75,\r\n showGrid: options.showGrid ?? false,\r\n zIndex: options.choroplethZIndex ?? 2,\r\n })\r\n choroplethLayer.setVisible(options.showChoropleth ?? true)\r\n\r\n const gridValueLayer = new GridValueLayer({\r\n loader,\r\n distance: options.labelDistance ?? 80,\r\n precision: options.labelPrecision ?? 1,\r\n fontSize: options.labelFontSize ?? 11,\r\n zIndex: options.labelsZIndex ?? 3,\r\n })\r\n gridValueLayer.setVisible(options.showLabels ?? true)\r\n\r\n const map = options.map\r\n choroplethLayer.attachMap(map)\r\n gridValueLayer.attachMap(map)\r\n map.addLayer(choroplethLayer)\r\n map.addLayer(gridValueLayer)\r\n\r\n const fitPadding = normalizePadding(options.fitPadding ?? 40)\r\n const fitMaxZoom = options.fitMaxZoom ?? 10\r\n\r\n const view = new GridMapView(map, loader, choroplethLayer, gridValueLayer, stats, {\r\n padding: fitPadding,\r\n maxZoom: fitMaxZoom,\r\n })\r\n\r\n if (options.autoFit !== false) {\r\n view.fitToData()\r\n }\r\n\r\n if (options.displayMin != null || options.displayMax != null) {\r\n const { min: lmin, max: lmax } = view.getLegendRange()\r\n view.setDisplayRange(options.displayMin ?? lmin, options.displayMax ?? lmax)\r\n }\r\n\r\n if (options.onPointerMove) {\r\n view.onPointerMove(options.onPointerMove)\r\n }\r\n\r\n return view\r\n }\r\n\r\n /** 拾取 lon/lat 处格点值;超出数据范围或 displayRange 时返回 null */\r\n getValueAt(lon: number, lat: number): number | null {\r\n return this.pickValue(lon, lat)\r\n }\r\n\r\n private pickValue(lon: number, lat: number): number | null {\r\n const [minLon, minLat, maxLon, maxLat] = this.loader.bbox\r\n if (lon < minLon || lon > maxLon || lat < minLat || lat > maxLat) return null\r\n\r\n const raw =\r\n this.choroplethLayer.getDataValue(lon, lat) ?? this.loader.getNativeValueAt(lon, lat)\r\n if (raw == null) return null\r\n\r\n if (this.choroplethLayer.getVisible()) {\r\n const { min, max } = this.getDisplayRange()\r\n if (raw < min || raw > max) return null\r\n }\r\n\r\n return raw\r\n }\r\n\r\n onPointerMove(handler: (ev: GridMapPointerEvent) => void): () => void {\r\n this.pointerUnbind?.()\r\n this.pointerHandler = handler\r\n\r\n const listener = (evt: { coordinate: number[]; dragging?: boolean; originalEvent?: MouseEvent }) => {\r\n if (evt.dragging) return\r\n const projCode = this.projection\r\n const [lon, lat] = mapCoordToLonLat(evt.coordinate[0], evt.coordinate[1], projCode)\r\n const zoom = this.map.getView().getZoom() ?? 6\r\n const value = this.pickValue(lon, lat)\r\n handler({\r\n lon,\r\n lat,\r\n value,\r\n zoom,\r\n lod: this.loader.getLodStep(zoom),\r\n })\r\n }\r\n\r\n this.map.on(\"pointermove\", listener as (e: { coordinate: number[] }) => void)\r\n this.pointerUnbind = () => {\r\n this.map.un(\"pointermove\", listener as (e: { coordinate: number[] }) => void)\r\n if (this.pointerHandler === handler) this.pointerHandler = null\r\n }\r\n\r\n return this.pointerUnbind\r\n }\r\n\r\n refreshView(): void {\r\n if (this.destroyed) return\r\n this.loader.invalidateCache()\r\n this.choroplethLayer.reattachView(this.map)\r\n this.gridValueLayer.reattachView(this.map)\r\n }\r\n\r\n getLayerVisibility(): GridLayerVisibility {\r\n return {\r\n choropleth: this.choroplethLayer.getVisible(),\r\n grid: this.choroplethLayer.getShowGrid(),\r\n labels: this.gridValueLayer.getVisible(),\r\n }\r\n }\r\n\r\n setLayerVisibility(visibility: Partial<GridLayerVisibility>): void {\r\n if (visibility.choropleth !== undefined) this.setShowChoropleth(visibility.choropleth)\r\n if (visibility.grid !== undefined) this.setShowGrid(visibility.grid)\r\n if (visibility.labels !== undefined) this.setShowLabels(visibility.labels)\r\n }\r\n\r\n setShowChoropleth(visible: boolean): void {\r\n this.choroplethLayer.setVisible(visible)\r\n }\r\n\r\n setShowGrid(visible: boolean): void {\r\n this.choroplethLayer.setShowGrid(visible)\r\n }\r\n\r\n setShowLabels(visible: boolean): void {\r\n this.gridValueLayer.setVisible(visible)\r\n }\r\n\r\n getLegendRange(): LegendRange {\r\n return this.choroplethLayer.getLegendRange()\r\n }\r\n\r\n setLegendRange(min: number, max: number): void {\r\n this.choroplethLayer.setLegendRange(min, max)\r\n }\r\n\r\n setColorRamp(colorRamp: ColorRampItem[]): void {\r\n this.choroplethLayer.setColorRamp(colorRamp)\r\n }\r\n\r\n getColorRamp(): ColorRampItem[] {\r\n return this.choroplethLayer.getColorRamp()\r\n }\r\n\r\n getDisplayRange(): DisplayRange {\r\n return this.choroplethLayer.getDisplayRange()\r\n }\r\n\r\n setDisplayRange(min: number, max: number): void {\r\n this.choroplethLayer.setDisplayRange(min, max)\r\n }\r\n\r\n fitToData(): void {\r\n const ext = dataBboxToViewExtent(this.loader.bbox, this.projection)\r\n this.map.getView().fit(ext, { padding: this.fitOpts.padding, maxZoom: this.fitOpts.maxZoom })\r\n }\r\n\r\n getLodStep(): number {\r\n return this.loader.getLodStep(this.map.getView().getZoom() ?? 6)\r\n }\r\n\r\n destroy(): void {\r\n if (this.destroyed) return\r\n this.destroyed = true\r\n this.pointerUnbind?.()\r\n this.pointerUnbind = null\r\n this.map.removeLayer(this.choroplethLayer)\r\n this.map.removeLayer(this.gridValueLayer)\r\n this.choroplethLayer.dispose()\r\n this.loader.dispose()\r\n }\r\n}\r\n\r\nexport async function createGridMap(options: GridMapOptions): Promise<GridMapView> {\r\n return GridMapView.create(options)\r\n}\r\n\r\nexport const createGridOverlay = createGridMap\r\n","import type { ColorRampItem } from \"../data/gridDataCore\"\r\nimport {\r\n evenLegendPercentToValue,\r\n extractLegendTicks,\r\n getInnerRampStops,\r\n legendRangeFromRamp,\r\n rampToEvenCssGradient,\r\n rgbaToCss,\r\n tickIndexToEvenPercent,\r\n valueToEvenLegendPercent,\r\n type LegendDisplayMode,\r\n} from \"../webgl/ColorRamp\"\r\n\r\nexport type { LegendDisplayMode }\r\n\r\nexport interface LegendRangeSliderOptions {\r\n container: HTMLElement\r\n colorRamp: ColorRampItem[]\r\n legendTicks?: number[]\r\n legendMode?: LegendDisplayMode\r\n displayMin?: number\r\n displayMax?: number\r\n precision?: number\r\n /** 是否显示内置标题(面板模式下由外部控制) */\r\n showTitle?: boolean\r\n onChange?: (range: { displayMin: number; displayMax: number }) => void\r\n}\r\n\r\nconst SLIDER_STYLES = `\r\n.gred-legend-slider { user-select: none; font: 11px/1.4 system-ui, sans-serif; }\r\n.gred-legend-slider__title { margin-bottom: 6px; color: #333; }\r\n.gred-legend-slider__body { overflow: visible; }\r\n.gred-legend-slider__track {\r\n position: relative; height: 18px; border: 1px solid #ccc; border-radius: 4px; cursor: pointer;\r\n}\r\n.gred-legend-slider__bar {\r\n position: absolute; inset: 0; border-radius: 3px;\r\n}\r\n.gred-legend-slider__blocks {\r\n position: absolute; inset: 0; border-radius: 3px; overflow: hidden;\r\n}\r\n.gred-legend-slider__block {\r\n position: absolute; top: 0; bottom: 0;\r\n}\r\n.gred-legend-slider__mask {\r\n position: absolute; top: 0; bottom: 0; background: rgba(255,255,255,0.72); pointer-events: none;\r\n}\r\n.gred-legend-slider__mask--left { left: 0; }\r\n.gred-legend-slider__mask--right { right: 0; }\r\n.gred-legend-slider__thumb {\r\n position: absolute; top: 50%; width: 12px; height: 22px; margin-left: -6px;\r\n transform: translateY(-50%); background: #fff; border: 2px solid #333; border-radius: 3px;\r\n box-shadow: 0 1px 4px rgba(0,0,0,0.25); cursor: grab; z-index: 2;\r\n}\r\n.gred-legend-slider__thumb:active { cursor: grabbing; }\r\n.gred-legend-slider__labels {\r\n position: relative; height: 18px; margin: 3px 0 0; padding: 0;\r\n}\r\n.gred-legend-slider__label {\r\n position: absolute; top: 0; transform: translateX(-50%);\r\n color: #333; font-size: 10px; white-space: nowrap; line-height: 1.2;\r\n}\r\n.gred-legend-slider__label--edge-left { transform: translateX(0); }\r\n.gred-legend-slider__label--edge-right { transform: translateX(-100%); }\r\n`\r\n\r\nlet stylesInjected = false\r\n\r\nfunction injectStyles(): void {\r\n if (stylesInjected) return\r\n stylesInjected = true\r\n const el = document.createElement(\"style\")\r\n el.textContent = SLIDER_STYLES\r\n document.head.appendChild(el)\r\n}\r\n\r\n/**\r\n * 图例双滑块:色带/色块均匀分布,数值标注紧贴色带下方。\r\n */\r\nexport class LegendRangeSlider {\r\n private root: HTMLElement\r\n private body: HTMLElement\r\n private track: HTMLElement\r\n private bar: HTMLElement\r\n private blocks: HTMLElement\r\n private labelsRow: HTMLElement\r\n private maskLeft: HTMLElement\r\n private maskRight: HTMLElement\r\n private thumbMin: HTMLElement\r\n private thumbMax: HTMLElement\r\n private legendMin: number\r\n private legendMax: number\r\n private displayMin: number\r\n private displayMax: number\r\n private colorRamp: ColorRampItem[]\r\n private legendTicks: number[]\r\n private legendMode: LegendDisplayMode\r\n private precision: number\r\n private showTitle: boolean\r\n private onChange?: (range: { displayMin: number; displayMax: number }) => void\r\n private dragging: \"min\" | \"max\" | null = null\r\n\r\n private onPointerMove = (e: PointerEvent) => {\r\n if (!this.dragging) return\r\n const rect = this.track.getBoundingClientRect()\r\n const p = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width))\r\n const value = evenLegendPercentToValue(p, this.legendTicks)\r\n if (this.dragging === \"min\") {\r\n this.displayMin = Math.min(value, this.displayMax)\r\n } else {\r\n this.displayMax = Math.max(value, this.displayMin)\r\n }\r\n this.applyDisplayRange(this.displayMin, this.displayMax, false)\r\n }\r\n\r\n private onPointerUp = () => {\r\n this.dragging = null\r\n }\r\n\r\n constructor(options: LegendRangeSliderOptions) {\r\n injectStyles()\r\n this.colorRamp = options.colorRamp\r\n this.legendTicks = options.legendTicks ?? extractLegendTicks(options.colorRamp)\r\n this.legendMode = options.legendMode ?? \"blocks\"\r\n const { min, max } = legendRangeFromRamp(this.colorRamp)\r\n this.legendMin = min\r\n this.legendMax = max\r\n this.displayMin = options.displayMin ?? min\r\n this.displayMax = options.displayMax ?? max\r\n this.precision = options.precision ?? 1\r\n this.showTitle = options.showTitle !== false\r\n this.onChange = options.onChange\r\n\r\n this.root = document.createElement(\"div\")\r\n this.root.className = \"gred-legend-slider\"\r\n\r\n if (this.showTitle) {\r\n const title = document.createElement(\"div\")\r\n title.className = \"gred-legend-slider__title\"\r\n title.textContent = \"格点值\"\r\n this.root.appendChild(title)\r\n }\r\n\r\n this.body = document.createElement(\"div\")\r\n this.body.className = \"gred-legend-slider__body\"\r\n\r\n this.track = document.createElement(\"div\")\r\n this.track.className = \"gred-legend-slider__track\"\r\n\r\n this.bar = document.createElement(\"div\")\r\n this.bar.className = \"gred-legend-slider__bar\"\r\n this.blocks = document.createElement(\"div\")\r\n this.blocks.className = \"gred-legend-slider__blocks\"\r\n this.track.appendChild(this.bar)\r\n this.track.appendChild(this.blocks)\r\n\r\n this.maskLeft = document.createElement(\"div\")\r\n this.maskLeft.className = \"gred-legend-slider__mask gred-legend-slider__mask--left\"\r\n this.maskRight = document.createElement(\"div\")\r\n this.maskRight.className = \"gred-legend-slider__mask gred-legend-slider__mask--right\"\r\n this.track.appendChild(this.maskLeft)\r\n this.track.appendChild(this.maskRight)\r\n\r\n this.thumbMin = this.createThumb(\"min\")\r\n this.thumbMax = this.createThumb(\"max\")\r\n this.track.appendChild(this.thumbMin)\r\n this.track.appendChild(this.thumbMax)\r\n\r\n this.labelsRow = document.createElement(\"div\")\r\n this.labelsRow.className = \"gred-legend-slider__labels\"\r\n\r\n this.body.appendChild(this.track)\r\n this.body.appendChild(this.labelsRow)\r\n this.root.appendChild(this.body)\r\n\r\n options.container.appendChild(this.root)\r\n\r\n document.addEventListener(\"pointermove\", this.onPointerMove)\r\n document.addEventListener(\"pointerup\", this.onPointerUp)\r\n\r\n this.updateBar()\r\n this.rebuildLabels()\r\n this.applyDisplayRange(this.displayMin, this.displayMax, true)\r\n }\r\n\r\n private createThumb(which: \"min\" | \"max\"): HTMLElement {\r\n const thumb = document.createElement(\"div\")\r\n thumb.className = \"gred-legend-slider__thumb\"\r\n thumb.addEventListener(\"pointerdown\", (e) => {\r\n e.preventDefault()\r\n this.dragging = which\r\n thumb.setPointerCapture(e.pointerId)\r\n })\r\n return thumb\r\n }\r\n\r\n /** 均匀布局位置 */\r\n private evenPct(value: number): number {\r\n return valueToEvenLegendPercent(value, this.legendTicks)\r\n }\r\n\r\n private evenPctByIndex(index: number): number {\r\n return tickIndexToEvenPercent(index, this.legendTicks.length)\r\n }\r\n\r\n private fmt(value: number): string {\r\n return value.toFixed(this.precision)\r\n }\r\n\r\n private updateBar(): void {\r\n const { min, max } = legendRangeFromRamp(this.colorRamp)\r\n this.legendMin = min\r\n this.legendMax = max\r\n\r\n if (this.legendMode === \"gradient\") {\r\n this.bar.style.display = \"block\"\r\n this.blocks.style.display = \"none\"\r\n this.bar.style.background = rampToEvenCssGradient(this.colorRamp)\r\n } else {\r\n this.bar.style.display = \"none\"\r\n this.blocks.style.display = \"block\"\r\n this.blocks.replaceChildren()\r\n const stops = getInnerRampStops(this.colorRamp)\r\n const segCount = stops.length - 1\r\n for (let i = 0; i < segCount; i++) {\r\n const [, c0] = stops[i]\r\n const left = this.evenPctByIndex(i) * 100\r\n const width = (this.evenPctByIndex(i + 1) - this.evenPctByIndex(i)) * 100\r\n const seg = document.createElement(\"div\")\r\n seg.className = \"gred-legend-slider__block\"\r\n seg.style.left = `${left}%`\r\n seg.style.width = `${width}%`\r\n seg.style.background = rgbaToCss(c0)\r\n this.blocks.appendChild(seg)\r\n }\r\n }\r\n }\r\n\r\n private rebuildLabels(): void {\r\n this.labelsRow.replaceChildren()\r\n const n = this.legendTicks.length\r\n this.legendTicks.forEach((tick, i) => {\r\n const el = document.createElement(\"span\")\r\n el.className = \"gred-legend-slider__label\"\r\n if (i === 0) el.classList.add(\"gred-legend-slider__label--edge-left\")\r\n if (i === n - 1) el.classList.add(\"gred-legend-slider__label--edge-right\")\r\n el.textContent = this.fmt(tick)\r\n el.style.left = `${this.evenPctByIndex(i) * 100}%`\r\n this.labelsRow.appendChild(el)\r\n })\r\n }\r\n\r\n private applyDisplayRange(min: number, max: number, silent: boolean): void {\r\n const span = Math.max(this.legendMax - this.legendMin, 0.01)\r\n const gap = span * 0.001\r\n let dmin = Math.max(this.legendMin, Math.min(min, this.legendMax))\r\n let dmax = Math.min(this.legendMax, Math.max(max, this.legendMin))\r\n if (dmax - dmin < gap) dmax = Math.min(this.legendMax, dmin + gap)\r\n\r\n this.displayMin = dmin\r\n this.displayMax = dmax\r\n\r\n const pMin = this.evenPct(dmin)\r\n const pMax = this.evenPct(dmax)\r\n\r\n this.thumbMin.style.left = `${pMin * 100}%`\r\n this.thumbMax.style.left = `${pMax * 100}%`\r\n this.maskLeft.style.width = `${pMin * 100}%`\r\n this.maskRight.style.width = `${(1 - pMax) * 100}%`\r\n\r\n if (!silent) {\r\n this.onChange?.({ displayMin: dmin, displayMax: dmax })\r\n }\r\n }\r\n\r\n setLegendMode(mode: LegendDisplayMode): void {\r\n if (this.legendMode === mode) return\r\n this.legendMode = mode\r\n this.updateBar()\r\n }\r\n\r\n getLegendMode(): LegendDisplayMode {\r\n return this.legendMode\r\n }\r\n\r\n setColorRamp(colorRamp: ColorRampItem[], legendTicks?: number[]): void {\r\n this.colorRamp = colorRamp\r\n this.legendTicks = legendTicks ?? extractLegendTicks(colorRamp)\r\n this.updateBar()\r\n this.rebuildLabels()\r\n this.applyDisplayRange(this.displayMin, this.displayMax, true)\r\n }\r\n\r\n setLegendTicks(ticks: number[]): void {\r\n this.legendTicks = ticks\r\n this.rebuildLabels()\r\n this.updateBar()\r\n this.applyDisplayRange(this.displayMin, this.displayMax, true)\r\n }\r\n\r\n getLegendTicks(): number[] {\r\n return [...this.legendTicks]\r\n }\r\n\r\n setDisplayRange(min: number, max: number, silent = false): void {\r\n this.applyDisplayRange(min, max, silent)\r\n }\r\n\r\n getDisplayRange(): { displayMin: number; displayMax: number } {\r\n return { displayMin: this.displayMin, displayMax: this.displayMax }\r\n }\r\n\r\n getLegendRange(): { min: number; max: number } {\r\n return { min: this.legendMin, max: this.legendMax }\r\n }\r\n\r\n destroy(): void {\r\n document.removeEventListener(\"pointermove\", this.onPointerMove)\r\n document.removeEventListener(\"pointerup\", this.onPointerUp)\r\n this.root.remove()\r\n }\r\n}\r\n\r\nexport function createLegendRangeSlider(options: LegendRangeSliderOptions): LegendRangeSlider {\r\n return new LegendRangeSlider(options)\r\n}\r\n","import type { LegendDisplayMode } from \"../webgl/ColorRamp\"\r\n\r\nexport type LegendPanelPlacement = \"bottom-right\" | \"bottom-left\" | \"top-right\" | \"top-left\" | \"custom\"\r\n\r\nexport interface LegendPanelStyle {\r\n background?: string\r\n width?: string | number\r\n padding?: string\r\n borderRadius?: string\r\n boxShadow?: string\r\n zIndex?: number\r\n bottom?: string | number\r\n right?: string | number\r\n left?: string | number\r\n top?: string | number\r\n font?: string\r\n}\r\n\r\nexport const DEFAULT_LEGEND_PANEL_STYLE: Required<\r\n Pick<LegendPanelStyle, \"background\" | \"width\" | \"padding\" | \"borderRadius\" | \"boxShadow\" | \"zIndex\">\r\n> = {\r\n background: \"rgba(255, 255, 255, 0.92)\",\r\n width: \"280px\",\r\n padding: \"10px 14px 12px\",\r\n borderRadius: \"8px\",\r\n boxShadow: \"0 2px 8px rgba(0, 0, 0, 0.15)\",\r\n zIndex: 10,\r\n}\r\n\r\nexport const LEGEND_PANEL_PLACEMENT_STYLE: Record<\r\n Exclude<LegendPanelPlacement, \"custom\">,\r\n Pick<LegendPanelStyle, \"bottom\" | \"right\" | \"left\" | \"top\">\r\n> = {\r\n \"bottom-right\": { bottom: 24, right: 12 },\r\n \"bottom-left\": { bottom: 24, left: 12 },\r\n \"top-right\": { top: 12, right: 12 },\r\n \"top-left\": { top: 12, left: 12 },\r\n}\r\n\r\nexport function resolveLegendPanelStyle(\r\n placement: LegendPanelPlacement = \"bottom-right\",\r\n style: LegendPanelStyle = {},\r\n): Record<string, string | number> {\r\n const base = { ...DEFAULT_LEGEND_PANEL_STYLE, ...style }\r\n const pos =\r\n placement === \"custom\" ? {} : LEGEND_PANEL_PLACEMENT_STYLE[placement]\r\n\r\n const css: Record<string, string | number> = {\r\n position: \"absolute\",\r\n background: base.background,\r\n width: typeof base.width === \"number\" ? `${base.width}px` : base.width,\r\n padding: base.padding,\r\n borderRadius: base.borderRadius,\r\n boxShadow: base.boxShadow,\r\n zIndex: style.zIndex ?? base.zIndex,\r\n font: style.font ?? \"11px system-ui, sans-serif\",\r\n boxSizing: \"border-box\",\r\n }\r\n\r\n const edges = { ...pos, ...style }\r\n for (const key of [\"bottom\", \"right\", \"left\", \"top\"] as const) {\r\n const v = edges[key]\r\n if (v != null) css[key] = typeof v === \"number\" ? `${v}px` : v\r\n }\r\n return css\r\n}\r\n\r\nexport interface LegendPanelDisplayMode {\r\n legendMode: LegendDisplayMode\r\n}\r\n","import type { GridMapView } from \"../core/GridMapView\"\r\nimport type { GridLayerVisibility } from \"../core/types\"\r\n\r\n/** 插槽内控制色斑 / 网格 / 标注显隐的 API */\r\nexport interface LayerControlApi {\r\n getVisibility: () => GridLayerVisibility | null\r\n setLayerVisibility: (visibility: Partial<GridLayerVisibility>) => void\r\n setShowChoropleth: (visible: boolean) => void\r\n setShowGrid: (visible: boolean) => void\r\n setShowLabels: (visible: boolean) => void\r\n toggleChoropleth: () => void\r\n toggleGrid: () => void\r\n toggleLabels: () => void\r\n}\r\n\r\nexport function createLayerControlApi(overlay: GridMapView | null | undefined): LayerControlApi {\r\n return {\r\n getVisibility: () => overlay?.getLayerVisibility() ?? null,\r\n setLayerVisibility: (v) => overlay?.setLayerVisibility(v),\r\n setShowChoropleth: (visible) => overlay?.setShowChoropleth(visible),\r\n setShowGrid: (visible) => overlay?.setShowGrid(visible),\r\n setShowLabels: (visible) => overlay?.setShowLabels(visible),\r\n toggleChoropleth: () => {\r\n if (!overlay) return\r\n const v = overlay.getLayerVisibility()\r\n overlay.setShowChoropleth(!v.choropleth)\r\n },\r\n toggleGrid: () => {\r\n if (!overlay) return\r\n const v = overlay.getLayerVisibility()\r\n overlay.setShowGrid(!v.grid)\r\n },\r\n toggleLabels: () => {\r\n if (!overlay) return\r\n const v = overlay.getLayerVisibility()\r\n overlay.setShowLabels(!v.labels)\r\n },\r\n }\r\n}\r\n"],"names":["NODATA","getLodStep","zoom","lodCellPixelWidth","meta","lodStep","mapResolution","projCode","latMid","lodCellLonDeg","metersPerDegLon","getLabelStep","distancePx","lodCellPx","blockSkip","sampleBlock","flat","row0","col0","step","sum","count","latCount","lonCount","dr","dc","r","c","v","readWindow","extent4326","dataBbox","vMinLon","vMinLat","vMaxLon","vMaxLat","dMinLon","dMinLat","dMaxLon","dMaxLat","minLon","minLat","maxLon","maxLat","startLon","startLat","lonStep","latStep","col1","row1","outCols","outRows","data","idx","computeLabels","resolution","precision","labelStep","labels","row","col","lon","lat","flattenGrid","ds","computeStats","min","max","getNativeValue","GridDataWorkerClient","__publicField","ev","msg","p","reject","id","resolve","req","ArrayDataLoader","url","json","extentEqual","reqId","tile","readWindowSync","t","resLon","resLat","a","b","eps","i","CHOROPLETH_VS","CHOROPLETH_FS","compileShader","gl","type","source","shader","createProgram","vs","fs","program","ChoroplethRenderer","canvas","vao","buf","loc","w","h","legend","key","uniforms","affineToMat3","affine","computeDelta","viewExtent","frameExtent","LEGEND_WIDTH","hexToRgba","hex","n","lerpRgba","sampleRamp","stops","value","v0","c0","v1","c1","buildLegendTexture","colorRamp","inner","span","pixels","texture","defaultGridColorRamp","val","defaultTemperatureRamp","colorRampWithRange","template","oldMin","oldMax","oldSpan","newSpan","remapped","legendRangeFromRamp","extractLegendTicks","valueToLegendPercent","tickIndexToEvenPercent","index","tickCount","valueToEvenLegendPercent","ticks","p0","p1","evenLegendPercentToValue","clamped","segCount","localP","rampToEvenCssGradient","getInnerRampStops","_","rgba","pct","rgbaToCss","rampToCssGradient","isMercator","code","lonLatToMapCoord","fromLonLat","mapCoordToLonLat","x","y","toLonLat","dataBboxToViewExtent","bbox4326","transformExtent","viewExtentTo4326","extent","ChoroplethLayer","ImageLayer","options","glCanvas","displayCanvas","renderer","renderHolder","ImageCanvas","pixelRatio","size","projection","stats","ramp","lmin","lmax","gap","dmin","dmax","_a","show","map","view","ver","canvasW","canvasH","mapSize","ctx","frameState","pixelToCoord","transform","delta","mapCoordToCanvasPixel","coordinate","css","GridValueLayer","center","_extent","_resolution","fontPx","label","coord","pixel","px","py","normalizePadding","padding","GridMapView","loader","choroplethLayer","gridValueLayer","fitOpts","legendMin","legendMax","initialRamp","fitPadding","fitMaxZoom","raw","handler","listener","evt","visibility","visible","ext","createGridMap","createGridOverlay","SLIDER_STYLES","stylesInjected","injectStyles","el","LegendRangeSlider","e","rect","title","which","thumb","left","width","seg","tick","silent","pMin","pMax","mode","legendTicks","createLegendRangeSlider","DEFAULT_LEGEND_PANEL_STYLE","LEGEND_PANEL_PLACEMENT_STYLE","resolveLegendPanelStyle","placement","style","base","pos","edges","createLayerControlApi","overlay"],"mappings":"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"}