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.
- package/LICENSE +201 -0
- package/README.md +127 -0
- package/dist/assets/gridData.worker-z5TRvtQ2.js +2 -0
- package/dist/assets/gridData.worker-z5TRvtQ2.js.map +1 -0
- package/dist/grid-webgl-openlayers.css +1 -0
- package/dist/index.d.ts +525 -0
- package/dist/index.js +99 -0
- package/dist/index.js.map +1 -0
- package/dist/layerControlHelpers-BSZqa4fP.js +1208 -0
- package/dist/layerControlHelpers-BSZqa4fP.js.map +1 -0
- package/dist/vue.d.ts +602 -0
- package/dist/vue.js +321 -0
- package/dist/vue.js.map +1 -0
- package/package.json +63 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,525 @@
|
|
|
1
|
+
import { default as default_2 } from 'ol/layer/Image';
|
|
2
|
+
import { default as default_3 } from 'ol/source/ImageCanvas';
|
|
3
|
+
import { default as default_4 } from 'ol/Map';
|
|
4
|
+
|
|
5
|
+
/** 与 arrayData.json 一致的网格数据格式 */
|
|
6
|
+
export declare interface ArrayDataJson {
|
|
7
|
+
startLat: number;
|
|
8
|
+
endLat: number;
|
|
9
|
+
startLon: number;
|
|
10
|
+
endLon: number;
|
|
11
|
+
latStep: number;
|
|
12
|
+
lonStep: number;
|
|
13
|
+
latCount: number;
|
|
14
|
+
lonCount: number;
|
|
15
|
+
ds: number[][];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* 网格数据加载器:主线程保留 flat 副本供同步拾取,LOD/标注计算走 Worker。
|
|
20
|
+
*/
|
|
21
|
+
export declare class ArrayDataLoader {
|
|
22
|
+
private meta;
|
|
23
|
+
private flat;
|
|
24
|
+
private loaded;
|
|
25
|
+
private worker;
|
|
26
|
+
private lastExtent;
|
|
27
|
+
private lastZoom;
|
|
28
|
+
private cachedTile;
|
|
29
|
+
private tileRequestId;
|
|
30
|
+
get bbox(): [number, number, number, number];
|
|
31
|
+
get metadata(): {
|
|
32
|
+
nodata: number;
|
|
33
|
+
bbox: [number, number, number, number];
|
|
34
|
+
startLat: number;
|
|
35
|
+
endLat: number;
|
|
36
|
+
startLon: number;
|
|
37
|
+
endLon: number;
|
|
38
|
+
latStep: number;
|
|
39
|
+
lonStep: number;
|
|
40
|
+
latCount: number;
|
|
41
|
+
lonCount: number;
|
|
42
|
+
};
|
|
43
|
+
get isLoaded(): boolean;
|
|
44
|
+
load(url: string): Promise<void>;
|
|
45
|
+
/** 直接加载 JSON 对象(Vue / Node 传入内存数据时使用) */
|
|
46
|
+
loadData(json: ArrayDataJson): Promise<void>;
|
|
47
|
+
getLodStep(zoom: number): number;
|
|
48
|
+
getLabelStep(zoom: number, resolution: number, distancePx: number, projCode?: string): number;
|
|
49
|
+
/** 异步 readWindow(Worker) */
|
|
50
|
+
readWindowAsync(extent4326: number[], zoom: number): Promise<GridTile | null>;
|
|
51
|
+
/** 同步 readWindow(Worker 未就绪时 fallback) */
|
|
52
|
+
readWindow(extent4326: number[], zoom: number): GridTile | null;
|
|
53
|
+
computeLabelsAsync(extent4326: number[], zoom: number, resolution: number, distancePx: number, precision: number, projCode?: string): Promise<GridLabel[]>;
|
|
54
|
+
computeLabelsSync(extent4326: number[], zoom: number, resolution: number, distancePx: number, precision: number, projCode?: string): GridLabel[];
|
|
55
|
+
getValueAt(lon: number, lat: number, tile?: GridTile | null): number | null;
|
|
56
|
+
getNativeValueAt(lon: number, lat: number): number | null;
|
|
57
|
+
computeStats(): {
|
|
58
|
+
min: number;
|
|
59
|
+
max: number;
|
|
60
|
+
};
|
|
61
|
+
get nativeResolution(): [number, number];
|
|
62
|
+
get gridOrigin(): [number, number];
|
|
63
|
+
invalidateCache(): void;
|
|
64
|
+
dispose(): void;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** 纯函数:Worker 与主线程共享的网格数据处理 */
|
|
68
|
+
export declare interface ArrayDataMeta {
|
|
69
|
+
startLat: number;
|
|
70
|
+
endLat: number;
|
|
71
|
+
startLon: number;
|
|
72
|
+
endLon: number;
|
|
73
|
+
latStep: number;
|
|
74
|
+
lonStep: number;
|
|
75
|
+
latCount: number;
|
|
76
|
+
lonCount: number;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** 256×1 连续色带(LINEAR),避免低值 NEAREST 采到透明 */
|
|
80
|
+
export declare function buildLegendTexture(gl: WebGL2RenderingContext, colorRamp: ColorRampItem[]): LegendTexture;
|
|
81
|
+
|
|
82
|
+
export declare class ChoroplethLayer extends default_2<default_3> {
|
|
83
|
+
private loader;
|
|
84
|
+
private glCanvas;
|
|
85
|
+
private displayCanvas;
|
|
86
|
+
private renderer;
|
|
87
|
+
private legend;
|
|
88
|
+
private currentTile;
|
|
89
|
+
private showGridLines;
|
|
90
|
+
private colorRamp;
|
|
91
|
+
private displayMin;
|
|
92
|
+
private displayMax;
|
|
93
|
+
private mapRef;
|
|
94
|
+
private fetchVersion;
|
|
95
|
+
private viewUnbind;
|
|
96
|
+
private readonly onMapChange;
|
|
97
|
+
constructor(options: ChoroplethLayerOptions);
|
|
98
|
+
/** 当前图例数值范围 */
|
|
99
|
+
getLegendRange(): {
|
|
100
|
+
min: number;
|
|
101
|
+
max: number;
|
|
102
|
+
};
|
|
103
|
+
getColorRamp(): ColorRampItem[];
|
|
104
|
+
/** 设置完整色带并刷新渲染 */
|
|
105
|
+
setColorRamp(colorRamp: ColorRampItem[]): void;
|
|
106
|
+
/** 仅调整图例 min/max(保留当前色带样式) */
|
|
107
|
+
setLegendRange(min: number, max: number): void;
|
|
108
|
+
/** 色斑图实际显示的数值区间(滑块控制) */
|
|
109
|
+
getDisplayRange(): {
|
|
110
|
+
min: number;
|
|
111
|
+
max: number;
|
|
112
|
+
};
|
|
113
|
+
setDisplayRange(min: number, max: number): void;
|
|
114
|
+
private clampDisplayRange;
|
|
115
|
+
private refreshRender;
|
|
116
|
+
getShowGrid(): boolean;
|
|
117
|
+
private rebuildLegend;
|
|
118
|
+
setShowGrid(show: boolean): void;
|
|
119
|
+
refreshData(): void;
|
|
120
|
+
private scheduleFetch;
|
|
121
|
+
private renderFrame;
|
|
122
|
+
attachMap(map: default_4): void;
|
|
123
|
+
reattachView(map: default_4): void;
|
|
124
|
+
private bindView;
|
|
125
|
+
getDataValue(lon: number, lat: number): number | null;
|
|
126
|
+
dispose(): void;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export declare interface ChoroplethLayerOptions {
|
|
130
|
+
loader: ArrayDataLoader;
|
|
131
|
+
colorRamp?: ColorRampItem[];
|
|
132
|
+
opacity?: number;
|
|
133
|
+
showGrid?: boolean;
|
|
134
|
+
zIndex?: number;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export declare type ColorRampItem = [number, [number, number, number, number]];
|
|
138
|
+
|
|
139
|
+
/** 按新 min/max 重采样色带(保留各 stop 相对位置) */
|
|
140
|
+
export declare function colorRampWithRange(min: number, max: number, template?: ColorRampItem[]): ColorRampItem[];
|
|
141
|
+
|
|
142
|
+
export declare function createGridMap(options: GridMapOptions): Promise<GridMapView>;
|
|
143
|
+
|
|
144
|
+
export declare const createGridOverlay: typeof createGridMap;
|
|
145
|
+
|
|
146
|
+
export declare function createLayerControlApi(overlay: GridMapView | null | undefined): LayerControlApi;
|
|
147
|
+
|
|
148
|
+
export declare function createLegendPanel(options: LegendPanelOptions): LegendPanel;
|
|
149
|
+
|
|
150
|
+
export declare function createLegendRangeSlider(options: LegendRangeSliderOptions): LegendRangeSlider;
|
|
151
|
+
|
|
152
|
+
/** 4326 数据 bbox → 视图投影 extent */
|
|
153
|
+
export declare function dataBboxToViewExtent(bbox4326: [number, number, number, number], projCode: string): [number, number, number, number];
|
|
154
|
+
|
|
155
|
+
export declare const DEFAULT_LEGEND_PANEL_STYLE: Required<Pick<LegendPanelStyle, "background" | "width" | "padding" | "borderRadius" | "boxShadow" | "zIndex">>;
|
|
156
|
+
|
|
157
|
+
/** 标准色斑色带:min 起可见浅绿,低值(0~3)也能渲染 */
|
|
158
|
+
export declare function defaultGridColorRamp(min: number, max: number): ColorRampItem[];
|
|
159
|
+
|
|
160
|
+
export declare function defaultTemperatureRamp(min: number, max: number): ColorRampItem[];
|
|
161
|
+
|
|
162
|
+
export declare interface DisplayRange {
|
|
163
|
+
min: number;
|
|
164
|
+
max: number;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/** 均匀图例位置 → 数值 */
|
|
168
|
+
export declare function evenLegendPercentToValue(p: number, ticks: number[]): number;
|
|
169
|
+
|
|
170
|
+
/** 从色带提取图例刻度(支持不规则间隔) */
|
|
171
|
+
export declare function extractLegendTicks(colorRamp: ColorRampItem[]): number[];
|
|
172
|
+
|
|
173
|
+
export declare function getInnerRampStops(colorRamp: ColorRampItem[]): ColorRampItem[];
|
|
174
|
+
|
|
175
|
+
export declare interface GridLabel {
|
|
176
|
+
lon: number;
|
|
177
|
+
lat: number;
|
|
178
|
+
text: string;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export declare interface GridLayerVisibility {
|
|
182
|
+
choropleth: boolean;
|
|
183
|
+
grid: boolean;
|
|
184
|
+
labels: boolean;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export declare interface GridMapOptions {
|
|
188
|
+
/** 外部 OpenLayers Map,色斑图与标注图层叠加其上 */
|
|
189
|
+
map: default_4;
|
|
190
|
+
/** 网格 JSON 地址(与 data 二选一) */
|
|
191
|
+
dataUrl?: string;
|
|
192
|
+
/** 内存中的网格 JSON(与 dataUrl 二选一) */
|
|
193
|
+
data?: ArrayDataJson;
|
|
194
|
+
showChoropleth?: boolean;
|
|
195
|
+
showGrid?: boolean;
|
|
196
|
+
showLabels?: boolean;
|
|
197
|
+
choroplethOpacity?: number;
|
|
198
|
+
choroplethZIndex?: number;
|
|
199
|
+
labelsZIndex?: number;
|
|
200
|
+
labelDistance?: number;
|
|
201
|
+
labelPrecision?: number;
|
|
202
|
+
labelFontSize?: number;
|
|
203
|
+
colorRamp?: ColorRampItem[];
|
|
204
|
+
/** 图例刻度数值(不规则间隔);不传则从 colorRamp 提取 */
|
|
205
|
+
legendTicks?: number[];
|
|
206
|
+
/** 图例 min(默认取数据统计 min) */
|
|
207
|
+
legendMin?: number;
|
|
208
|
+
/** 图例 max(默认取数据统计 max) */
|
|
209
|
+
legendMax?: number;
|
|
210
|
+
/** 色斑显示区间 min(默认等于 legendMin) */
|
|
211
|
+
displayMin?: number;
|
|
212
|
+
/** 色斑显示区间 max(默认等于 legendMax) */
|
|
213
|
+
displayMax?: number;
|
|
214
|
+
/** 挂载后自动 fit 到数据范围,默认 true */
|
|
215
|
+
autoFit?: boolean;
|
|
216
|
+
fitPadding?: number | [number, number, number, number];
|
|
217
|
+
fitMaxZoom?: number;
|
|
218
|
+
/** 鼠标移动拾取回调;传入则在 create 时自动绑定 pointermove */
|
|
219
|
+
onPointerMove?: (event: GridMapPointerEvent) => void;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export declare interface GridMapPointerEvent {
|
|
223
|
+
lon: number;
|
|
224
|
+
lat: number;
|
|
225
|
+
value: number | null;
|
|
226
|
+
zoom: number;
|
|
227
|
+
lod: number;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export declare interface GridMapStats {
|
|
231
|
+
min: number;
|
|
232
|
+
max: number;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* 网格图层控制器:叠加在外部 ol/Map 上,不创建 Map / 底图。
|
|
237
|
+
*/
|
|
238
|
+
export declare class GridMapView implements GridMapViewApi {
|
|
239
|
+
private fitOpts;
|
|
240
|
+
readonly map: default_4;
|
|
241
|
+
readonly loader: ArrayDataLoader;
|
|
242
|
+
readonly choroplethLayer: ChoroplethLayer;
|
|
243
|
+
readonly gridValueLayer: GridValueLayer;
|
|
244
|
+
readonly stats: {
|
|
245
|
+
min: number;
|
|
246
|
+
max: number;
|
|
247
|
+
};
|
|
248
|
+
private pointerHandler;
|
|
249
|
+
private pointerUnbind;
|
|
250
|
+
private destroyed;
|
|
251
|
+
private constructor();
|
|
252
|
+
get projection(): ProjCode;
|
|
253
|
+
static create(options: GridMapOptions): Promise<GridMapView>;
|
|
254
|
+
/** 拾取 lon/lat 处格点值;超出数据范围或 displayRange 时返回 null */
|
|
255
|
+
getValueAt(lon: number, lat: number): number | null;
|
|
256
|
+
private pickValue;
|
|
257
|
+
onPointerMove(handler: (ev: GridMapPointerEvent) => void): () => void;
|
|
258
|
+
refreshView(): void;
|
|
259
|
+
getLayerVisibility(): GridLayerVisibility;
|
|
260
|
+
setLayerVisibility(visibility: Partial<GridLayerVisibility>): void;
|
|
261
|
+
setShowChoropleth(visible: boolean): void;
|
|
262
|
+
setShowGrid(visible: boolean): void;
|
|
263
|
+
setShowLabels(visible: boolean): void;
|
|
264
|
+
getLegendRange(): LegendRange;
|
|
265
|
+
setLegendRange(min: number, max: number): void;
|
|
266
|
+
setColorRamp(colorRamp: ColorRampItem[]): void;
|
|
267
|
+
getColorRamp(): ColorRampItem[];
|
|
268
|
+
getDisplayRange(): DisplayRange;
|
|
269
|
+
setDisplayRange(min: number, max: number): void;
|
|
270
|
+
fitToData(): void;
|
|
271
|
+
getLodStep(): number;
|
|
272
|
+
destroy(): void;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
export declare interface GridMapViewApi {
|
|
276
|
+
readonly map: default_4;
|
|
277
|
+
readonly loader: ArrayDataLoader;
|
|
278
|
+
readonly choroplethLayer: ChoroplethLayer;
|
|
279
|
+
readonly gridValueLayer: GridValueLayer;
|
|
280
|
+
readonly projection: ProjCode;
|
|
281
|
+
readonly stats: GridMapStats;
|
|
282
|
+
getLayerVisibility(): GridLayerVisibility;
|
|
283
|
+
setLayerVisibility(visibility: Partial<GridLayerVisibility>): void;
|
|
284
|
+
setShowChoropleth(visible: boolean): void;
|
|
285
|
+
setShowGrid(visible: boolean): void;
|
|
286
|
+
setShowLabels(visible: boolean): void;
|
|
287
|
+
getLegendRange(): LegendRange;
|
|
288
|
+
setLegendRange(min: number, max: number): void;
|
|
289
|
+
setColorRamp(colorRamp: ColorRampItem[]): void;
|
|
290
|
+
getColorRamp(): ColorRampItem[];
|
|
291
|
+
getDisplayRange(): DisplayRange;
|
|
292
|
+
setDisplayRange(min: number, max: number): void;
|
|
293
|
+
refreshView(): void;
|
|
294
|
+
fitToData(): void;
|
|
295
|
+
getValueAt(lon: number, lat: number): number | null;
|
|
296
|
+
getLodStep(): number;
|
|
297
|
+
/** 绑定 map pointermove,返回当前鼠标位置格点值 */
|
|
298
|
+
onPointerMove(handler: (ev: GridMapPointerEvent) => void): () => void;
|
|
299
|
+
destroy(): void;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
export declare interface GridTile {
|
|
303
|
+
data: Float32Array;
|
|
304
|
+
width: number;
|
|
305
|
+
height: number;
|
|
306
|
+
bbox: [number, number, number, number];
|
|
307
|
+
resolution: [number, number];
|
|
308
|
+
lodLevel: number;
|
|
309
|
+
lodStep: number;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Canvas2D 格点数值标注
|
|
314
|
+
* computeLabels → extent 转屏幕像素 → fillText(稳定可读)
|
|
315
|
+
*/
|
|
316
|
+
export declare class GridValueLayer extends default_2<default_3> {
|
|
317
|
+
private loader;
|
|
318
|
+
private mapRef;
|
|
319
|
+
private canvas;
|
|
320
|
+
private labels;
|
|
321
|
+
private fetchVersion;
|
|
322
|
+
private viewUnbind;
|
|
323
|
+
private readonly onMapChange;
|
|
324
|
+
private opts;
|
|
325
|
+
constructor(options: GridValueLayerOptions);
|
|
326
|
+
attachMap(map: default_4): void;
|
|
327
|
+
/** 切换投影后重新绑定 View 监听 */
|
|
328
|
+
reattachView(map: default_4): void;
|
|
329
|
+
private bindView;
|
|
330
|
+
refreshData(): void;
|
|
331
|
+
private scheduleFetch;
|
|
332
|
+
private renderFrame;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
export declare interface GridValueLayerOptions {
|
|
336
|
+
loader: ArrayDataLoader;
|
|
337
|
+
distance?: number;
|
|
338
|
+
precision?: number;
|
|
339
|
+
fontSize?: number;
|
|
340
|
+
color?: string;
|
|
341
|
+
zIndex?: number;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/** 插槽内控制色斑 / 网格 / 标注显隐的 API */
|
|
345
|
+
export declare interface LayerControlApi {
|
|
346
|
+
getVisibility: () => GridLayerVisibility | null;
|
|
347
|
+
setLayerVisibility: (visibility: Partial<GridLayerVisibility>) => void;
|
|
348
|
+
setShowChoropleth: (visible: boolean) => void;
|
|
349
|
+
setShowGrid: (visible: boolean) => void;
|
|
350
|
+
setShowLabels: (visible: boolean) => void;
|
|
351
|
+
toggleChoropleth: () => void;
|
|
352
|
+
toggleGrid: () => void;
|
|
353
|
+
toggleLabels: () => void;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
export declare const LEGEND_PANEL_PLACEMENT_STYLE: Record<Exclude<LegendPanelPlacement, "custom">, Pick<LegendPanelStyle, "bottom" | "right" | "left" | "top">>;
|
|
357
|
+
|
|
358
|
+
export declare type LegendDisplayMode = "gradient" | "blocks";
|
|
359
|
+
|
|
360
|
+
export declare class LegendPanel {
|
|
361
|
+
readonly element: HTMLElement;
|
|
362
|
+
readonly sliderHost: HTMLElement;
|
|
363
|
+
readonly controlsSlot: HTMLElement;
|
|
364
|
+
readonly slider: LegendRangeSlider;
|
|
365
|
+
private titleEl;
|
|
366
|
+
private overlayOnChange?;
|
|
367
|
+
constructor(options: LegendPanelOptions);
|
|
368
|
+
bindOverlay(overlay: GridMapView): void;
|
|
369
|
+
setTitle(title: string): void;
|
|
370
|
+
applyStyle(style: LegendPanelStyle, placement?: LegendPanelPlacement): void;
|
|
371
|
+
setLegendMode(mode: LegendDisplayMode): void;
|
|
372
|
+
destroy(): void;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
export declare interface LegendPanelOptions {
|
|
376
|
+
parent?: HTMLElement | string;
|
|
377
|
+
placement?: LegendPanelPlacement;
|
|
378
|
+
style?: LegendPanelStyle;
|
|
379
|
+
title?: string;
|
|
380
|
+
showTitle?: boolean;
|
|
381
|
+
colorRamp: ColorRampItem[];
|
|
382
|
+
legendTicks?: number[];
|
|
383
|
+
legendMode?: LegendDisplayMode;
|
|
384
|
+
displayMin?: number;
|
|
385
|
+
displayMax?: number;
|
|
386
|
+
precision?: number;
|
|
387
|
+
onChange?: (range: {
|
|
388
|
+
displayMin: number;
|
|
389
|
+
displayMax: number;
|
|
390
|
+
}) => void;
|
|
391
|
+
controlsSlot?: HTMLElement;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
export declare type LegendPanelPlacement = "bottom-right" | "bottom-left" | "top-right" | "top-left" | "custom";
|
|
395
|
+
|
|
396
|
+
export declare interface LegendPanelStyle {
|
|
397
|
+
background?: string;
|
|
398
|
+
width?: string | number;
|
|
399
|
+
padding?: string;
|
|
400
|
+
borderRadius?: string;
|
|
401
|
+
boxShadow?: string;
|
|
402
|
+
zIndex?: number;
|
|
403
|
+
bottom?: string | number;
|
|
404
|
+
right?: string | number;
|
|
405
|
+
left?: string | number;
|
|
406
|
+
top?: string | number;
|
|
407
|
+
font?: string;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
export declare interface LegendRange {
|
|
411
|
+
min: number;
|
|
412
|
+
max: number;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
export declare function legendRangeFromRamp(colorRamp: ColorRampItem[]): {
|
|
416
|
+
min: number;
|
|
417
|
+
max: number;
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* 图例双滑块:色带/色块均匀分布,数值标注紧贴色带下方。
|
|
422
|
+
*/
|
|
423
|
+
export declare class LegendRangeSlider {
|
|
424
|
+
private root;
|
|
425
|
+
private body;
|
|
426
|
+
private track;
|
|
427
|
+
private bar;
|
|
428
|
+
private blocks;
|
|
429
|
+
private labelsRow;
|
|
430
|
+
private maskLeft;
|
|
431
|
+
private maskRight;
|
|
432
|
+
private thumbMin;
|
|
433
|
+
private thumbMax;
|
|
434
|
+
private legendMin;
|
|
435
|
+
private legendMax;
|
|
436
|
+
private displayMin;
|
|
437
|
+
private displayMax;
|
|
438
|
+
private colorRamp;
|
|
439
|
+
private legendTicks;
|
|
440
|
+
private legendMode;
|
|
441
|
+
private precision;
|
|
442
|
+
private showTitle;
|
|
443
|
+
private onChange?;
|
|
444
|
+
private dragging;
|
|
445
|
+
private onPointerMove;
|
|
446
|
+
private onPointerUp;
|
|
447
|
+
constructor(options: LegendRangeSliderOptions);
|
|
448
|
+
private createThumb;
|
|
449
|
+
/** 均匀布局位置 */
|
|
450
|
+
private evenPct;
|
|
451
|
+
private evenPctByIndex;
|
|
452
|
+
private fmt;
|
|
453
|
+
private updateBar;
|
|
454
|
+
private rebuildLabels;
|
|
455
|
+
private applyDisplayRange;
|
|
456
|
+
setLegendMode(mode: LegendDisplayMode): void;
|
|
457
|
+
getLegendMode(): LegendDisplayMode;
|
|
458
|
+
setColorRamp(colorRamp: ColorRampItem[], legendTicks?: number[]): void;
|
|
459
|
+
setLegendTicks(ticks: number[]): void;
|
|
460
|
+
getLegendTicks(): number[];
|
|
461
|
+
setDisplayRange(min: number, max: number, silent?: boolean): void;
|
|
462
|
+
getDisplayRange(): {
|
|
463
|
+
displayMin: number;
|
|
464
|
+
displayMax: number;
|
|
465
|
+
};
|
|
466
|
+
getLegendRange(): {
|
|
467
|
+
min: number;
|
|
468
|
+
max: number;
|
|
469
|
+
};
|
|
470
|
+
destroy(): void;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
export declare interface LegendRangeSliderOptions {
|
|
474
|
+
container: HTMLElement;
|
|
475
|
+
colorRamp: ColorRampItem[];
|
|
476
|
+
legendTicks?: number[];
|
|
477
|
+
legendMode?: LegendDisplayMode;
|
|
478
|
+
displayMin?: number;
|
|
479
|
+
displayMax?: number;
|
|
480
|
+
precision?: number;
|
|
481
|
+
/** 是否显示内置标题(面板模式下由外部控制) */
|
|
482
|
+
showTitle?: boolean;
|
|
483
|
+
onChange?: (range: {
|
|
484
|
+
displayMin: number;
|
|
485
|
+
displayMax: number;
|
|
486
|
+
}) => void;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
declare interface LegendTexture {
|
|
490
|
+
texture: WebGLTexture;
|
|
491
|
+
min: number;
|
|
492
|
+
max: number;
|
|
493
|
+
width: number;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/** 经纬度 → 地图视图投影坐标 */
|
|
497
|
+
export declare function lonLatToMapCoord(lon: number, lat: number, projCode: string): [number, number];
|
|
498
|
+
|
|
499
|
+
/** 地图视图投影坐标 → 经纬度 */
|
|
500
|
+
export declare function mapCoordToLonLat(x: number, y: number, projCode: string): [number, number];
|
|
501
|
+
|
|
502
|
+
export declare type ProjCode = "EPSG:4326" | "EPSG:3857";
|
|
503
|
+
|
|
504
|
+
export declare function rampToCssGradient(colorRamp: ColorRampItem[]): string;
|
|
505
|
+
|
|
506
|
+
/** 均匀分布的 CSS 渐变色带 */
|
|
507
|
+
export declare function rampToEvenCssGradient(colorRamp: ColorRampItem[]): string;
|
|
508
|
+
|
|
509
|
+
export declare function resolveLegendPanelStyle(placement?: LegendPanelPlacement, style?: LegendPanelStyle): Record<string, string | number>;
|
|
510
|
+
|
|
511
|
+
export declare function rgbaToCss(rgba: [number, number, number, number]): string;
|
|
512
|
+
|
|
513
|
+
/** 刻度序号 → 均匀位置 [0,1] */
|
|
514
|
+
export declare function tickIndexToEvenPercent(index: number, tickCount: number): number;
|
|
515
|
+
|
|
516
|
+
/** 数值 → 均匀图例位置(段内按数值插值,段宽相等) */
|
|
517
|
+
export declare function valueToEvenLegendPercent(value: number, ticks: number[]): number;
|
|
518
|
+
|
|
519
|
+
/** 数值在图例条上的位置比例 [0,1](按实际数值线性映射) */
|
|
520
|
+
export declare function valueToLegendPercent(value: number, colorRamp: ColorRampItem[]): number;
|
|
521
|
+
|
|
522
|
+
/** 视图 extent → 4326(供 Worker / 数据查询) */
|
|
523
|
+
export declare function viewExtentTo4326(extent: number[], projCode: string): [number, number, number, number];
|
|
524
|
+
|
|
525
|
+
export { }
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
var o = Object.defineProperty;
|
|
2
|
+
var d = (t, e, l) => e in t ? o(t, e, { enumerable: !0, configurable: !0, writable: !0, value: l }) : t[e] = l;
|
|
3
|
+
var s = (t, e, l) => d(t, typeof e != "symbol" ? e + "" : e, l);
|
|
4
|
+
import { r as i, L as c } from "./layerControlHelpers-BSZqa4fP.js";
|
|
5
|
+
import { A as u, C, D as T, G as f, a as S, b as x, c as v, d as R, e as w, f as M, g as P, h as _, i as G, j as b, k as N, l as D, m as A, n as O, o as k, p as H, q as V, s as j, t as q, u as B, v as F, w as I, x as W, y as Y } from "./layerControlHelpers-BSZqa4fP.js";
|
|
6
|
+
class h {
|
|
7
|
+
constructor(e) {
|
|
8
|
+
s(this, "element");
|
|
9
|
+
s(this, "sliderHost");
|
|
10
|
+
s(this, "controlsSlot");
|
|
11
|
+
s(this, "slider");
|
|
12
|
+
s(this, "titleEl", null);
|
|
13
|
+
s(this, "overlayOnChange");
|
|
14
|
+
const l = g(e.parent);
|
|
15
|
+
if (this.element = document.createElement("div"), this.element.className = "gred-legend-panel", Object.assign(this.element.style, i(e.placement, e.style)), e.showTitle !== !1 && e.title && (this.titleEl = document.createElement("div"), this.titleEl.className = "gred-legend-panel__title", this.titleEl.textContent = e.title, this.titleEl.style.marginBottom = "6px", this.titleEl.style.color = "#333", this.titleEl.style.fontSize = "12px", this.element.appendChild(this.titleEl)), this.sliderHost = document.createElement("div"), this.sliderHost.className = "gred-legend-panel__slider", this.element.appendChild(this.sliderHost), this.controlsSlot = document.createElement("div"), this.controlsSlot.className = "gred-legend-panel__controls", this.controlsSlot.style.marginTop = "8px", this.controlsSlot.style.display = "flex", this.controlsSlot.style.flexWrap = "wrap", this.controlsSlot.style.gap = "6px", e.controlsSlot)
|
|
16
|
+
for (; e.controlsSlot.firstChild; )
|
|
17
|
+
this.controlsSlot.appendChild(e.controlsSlot.firstChild);
|
|
18
|
+
this.element.appendChild(this.controlsSlot), l.appendChild(this.element), this.slider = new c({
|
|
19
|
+
container: this.sliderHost,
|
|
20
|
+
colorRamp: e.colorRamp,
|
|
21
|
+
legendTicks: e.legendTicks,
|
|
22
|
+
legendMode: e.legendMode ?? "blocks",
|
|
23
|
+
displayMin: e.displayMin,
|
|
24
|
+
displayMax: e.displayMax,
|
|
25
|
+
precision: e.precision,
|
|
26
|
+
showTitle: !1,
|
|
27
|
+
onChange: (a) => {
|
|
28
|
+
var n, r;
|
|
29
|
+
(n = this.overlayOnChange) == null || n.call(this, a), (r = e.onChange) == null || r.call(e, a);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
bindOverlay(e) {
|
|
34
|
+
this.overlayOnChange = ({ displayMin: a, displayMax: n }) => {
|
|
35
|
+
e.setDisplayRange(a, n);
|
|
36
|
+
}, this.slider.setColorRamp(e.getColorRamp());
|
|
37
|
+
const l = e.getDisplayRange();
|
|
38
|
+
this.slider.setDisplayRange(l.min, l.max, !0);
|
|
39
|
+
}
|
|
40
|
+
setTitle(e) {
|
|
41
|
+
this.titleEl && (this.titleEl.textContent = e);
|
|
42
|
+
}
|
|
43
|
+
applyStyle(e, l) {
|
|
44
|
+
Object.assign(this.element.style, i(l, e));
|
|
45
|
+
}
|
|
46
|
+
setLegendMode(e) {
|
|
47
|
+
this.slider.setLegendMode(e);
|
|
48
|
+
}
|
|
49
|
+
destroy() {
|
|
50
|
+
this.slider.destroy(), this.element.remove();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function y(t) {
|
|
54
|
+
return new h(t);
|
|
55
|
+
}
|
|
56
|
+
function g(t) {
|
|
57
|
+
if (!t) return document.body;
|
|
58
|
+
if (typeof t == "string") {
|
|
59
|
+
const e = document.querySelector(t);
|
|
60
|
+
if (!e) throw new Error(`LegendPanel: parent "${t}" not found`);
|
|
61
|
+
return e;
|
|
62
|
+
}
|
|
63
|
+
return t;
|
|
64
|
+
}
|
|
65
|
+
export {
|
|
66
|
+
u as ArrayDataLoader,
|
|
67
|
+
C as ChoroplethLayer,
|
|
68
|
+
T as DEFAULT_LEGEND_PANEL_STYLE,
|
|
69
|
+
f as GridMapView,
|
|
70
|
+
S as GridValueLayer,
|
|
71
|
+
x as LEGEND_PANEL_PLACEMENT_STYLE,
|
|
72
|
+
h as LegendPanel,
|
|
73
|
+
c as LegendRangeSlider,
|
|
74
|
+
v as buildLegendTexture,
|
|
75
|
+
R as colorRampWithRange,
|
|
76
|
+
w as createGridMap,
|
|
77
|
+
M as createGridOverlay,
|
|
78
|
+
P as createLayerControlApi,
|
|
79
|
+
y as createLegendPanel,
|
|
80
|
+
_ as createLegendRangeSlider,
|
|
81
|
+
G as dataBboxToViewExtent,
|
|
82
|
+
b as defaultGridColorRamp,
|
|
83
|
+
N as defaultTemperatureRamp,
|
|
84
|
+
D as evenLegendPercentToValue,
|
|
85
|
+
A as extractLegendTicks,
|
|
86
|
+
O as getInnerRampStops,
|
|
87
|
+
k as legendRangeFromRamp,
|
|
88
|
+
H as lonLatToMapCoord,
|
|
89
|
+
V as mapCoordToLonLat,
|
|
90
|
+
j as rampToCssGradient,
|
|
91
|
+
q as rampToEvenCssGradient,
|
|
92
|
+
i as resolveLegendPanelStyle,
|
|
93
|
+
B as rgbaToCss,
|
|
94
|
+
F as tickIndexToEvenPercent,
|
|
95
|
+
I as valueToEvenLegendPercent,
|
|
96
|
+
W as valueToLegendPercent,
|
|
97
|
+
Y as viewExtentTo4326
|
|
98
|
+
};
|
|
99
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/ui/LegendPanel.ts"],"sourcesContent":["import type { ColorRampItem } from \"../data/gridDataCore\"\r\nimport type { GridMapView } from \"../core/GridMapView\"\r\nimport { LegendRangeSlider, type LegendRangeSliderOptions } from \"./LegendRangeSlider\"\r\nimport {\r\n resolveLegendPanelStyle,\r\n type LegendPanelPlacement,\r\n type LegendPanelStyle,\r\n} from \"./legendPanelTypes\"\r\nimport type { LegendDisplayMode } from \"../webgl/ColorRamp\"\r\n\r\nexport interface LegendPanelOptions {\r\n parent?: HTMLElement | string\r\n placement?: LegendPanelPlacement\r\n style?: LegendPanelStyle\r\n title?: string\r\n showTitle?: boolean\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 onChange?: (range: { displayMin: number; displayMax: number }) => void\r\n controlsSlot?: HTMLElement\r\n}\r\n\r\nexport class LegendPanel {\r\n readonly element: HTMLElement\r\n readonly sliderHost: HTMLElement\r\n readonly controlsSlot: HTMLElement\r\n readonly slider: LegendRangeSlider\r\n private titleEl: HTMLElement | null = null\r\n private overlayOnChange?: (range: { displayMin: number; displayMax: number }) => void\r\n\r\n constructor(options: LegendPanelOptions) {\r\n const parent = resolveParent(options.parent)\r\n\r\n this.element = document.createElement(\"div\")\r\n this.element.className = \"gred-legend-panel\"\r\n Object.assign(this.element.style, resolveLegendPanelStyle(options.placement, options.style))\r\n\r\n if (options.showTitle !== false && options.title) {\r\n this.titleEl = document.createElement(\"div\")\r\n this.titleEl.className = \"gred-legend-panel__title\"\r\n this.titleEl.textContent = options.title\r\n this.titleEl.style.marginBottom = \"6px\"\r\n this.titleEl.style.color = \"#333\"\r\n this.titleEl.style.fontSize = \"12px\"\r\n this.element.appendChild(this.titleEl)\r\n }\r\n\r\n this.sliderHost = document.createElement(\"div\")\r\n this.sliderHost.className = \"gred-legend-panel__slider\"\r\n this.element.appendChild(this.sliderHost)\r\n\r\n this.controlsSlot = document.createElement(\"div\")\r\n this.controlsSlot.className = \"gred-legend-panel__controls\"\r\n this.controlsSlot.style.marginTop = \"8px\"\r\n this.controlsSlot.style.display = \"flex\"\r\n this.controlsSlot.style.flexWrap = \"wrap\"\r\n this.controlsSlot.style.gap = \"6px\"\r\n if (options.controlsSlot) {\r\n while (options.controlsSlot.firstChild) {\r\n this.controlsSlot.appendChild(options.controlsSlot.firstChild)\r\n }\r\n }\r\n this.element.appendChild(this.controlsSlot)\r\n\r\n parent.appendChild(this.element)\r\n\r\n this.slider = new LegendRangeSlider({\r\n container: this.sliderHost,\r\n colorRamp: options.colorRamp,\r\n legendTicks: options.legendTicks,\r\n legendMode: options.legendMode ?? \"blocks\",\r\n displayMin: options.displayMin,\r\n displayMax: options.displayMax,\r\n precision: options.precision,\r\n showTitle: false,\r\n onChange: (range) => {\r\n this.overlayOnChange?.(range)\r\n options.onChange?.(range)\r\n },\r\n })\r\n }\r\n\r\n bindOverlay(overlay: GridMapView): void {\r\n this.overlayOnChange = ({ displayMin, displayMax }) => {\r\n overlay.setDisplayRange(displayMin, displayMax)\r\n }\r\n this.slider.setColorRamp(overlay.getColorRamp())\r\n const range = overlay.getDisplayRange()\r\n this.slider.setDisplayRange(range.min, range.max, true)\r\n }\r\n\r\n setTitle(title: string): void {\r\n if (this.titleEl) this.titleEl.textContent = title\r\n }\r\n\r\n applyStyle(style: LegendPanelStyle, placement?: LegendPanelPlacement): void {\r\n Object.assign(this.element.style, resolveLegendPanelStyle(placement, style))\r\n }\r\n\r\n setLegendMode(mode: LegendDisplayMode): void {\r\n this.slider.setLegendMode(mode)\r\n }\r\n\r\n destroy(): void {\r\n this.slider.destroy()\r\n this.element.remove()\r\n }\r\n}\r\n\r\nexport function createLegendPanel(options: LegendPanelOptions): LegendPanel {\r\n return new LegendPanel(options)\r\n}\r\n\r\nfunction resolveParent(parent?: HTMLElement | string): HTMLElement {\r\n if (!parent) return document.body\r\n if (typeof parent === \"string\") {\r\n const el = document.querySelector<HTMLElement>(parent)\r\n if (!el) throw new Error(`LegendPanel: parent \"${parent}\" not found`)\r\n return el\r\n }\r\n return parent\r\n}\r\n"],"names":["LegendPanel","options","__publicField","parent","resolveParent","resolveLegendPanelStyle","LegendRangeSlider","range","_a","_b","overlay","displayMin","displayMax","title","style","placement","mode","createLegendPanel","el"],"mappings":"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"}
|