@3clear/basegis 0.1.1 → 0.1.3
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/README.md +592 -100
- package/dist/WindDataGrid-AGJaASUG.js +96 -0
- package/dist/basegis.js +9177 -5237
- package/dist/leaflet-pixi-overlay-BSJNo_DO.js +253 -0
- package/dist/methods.js +2185 -1077
- package/dist/pixi-vendor-BFDHT3Bf.js +25208 -0
- package/dist/pointLarge-Ct8TsOPW.js +690 -0
- package/dist/style.css +1 -1
- package/package.json +5 -4
- package/dist/result-D03zgqh0.js +0 -39
package/README.md
CHANGED
|
@@ -4,26 +4,47 @@
|
|
|
4
4
|
把leaflet cesium 常用方法做了二次封装统一了api 使同一套代码可以适配2套地图引擎
|
|
5
5
|
当前包包含:
|
|
6
6
|
|
|
7
|
-
- `BaseGIS`:地图初始化、引擎切换、视角控制、底图切换、绘制、图层显隐、DEM
|
|
7
|
+
- `BaseGIS`:地图初始化、引擎切换、视角控制、底图切换、绘制、图层显隐、DEM、点击事件、Cesium / Leaflet 统一粒子风场、GPU 粒子风场、三维体渲染、三维切片/剖面渲染等基础能力。
|
|
8
8
|
- `methods`:图片图层、网格图层、海量点、点位抽稀、等值线、等压线、风场、图形组等高级控制器。
|
|
9
9
|
- `layers`:天地图、GeoServer 金字塔瓦片、WMS、WMTS 图层配置快捷构造器。
|
|
10
10
|
- `assets`:GIS 示例资源。
|
|
11
11
|
- `style.css`:Leaflet、GIS 图层和标注相关基础样式。
|
|
12
12
|
|
|
13
|
+
## 能力总览
|
|
14
|
+
|
|
15
|
+
下表以当前 npm 包的真实出口和本项目源码为准。使用位置列展示原测试路由,点击后会在新标签页打开代码演练场,并通过 `path` 参数自动选中对应路由;没有独立页面的辅助函数与其所属控制器合并展示。
|
|
16
|
+
|
|
17
|
+
| <small>导出 / 能力</small> | <small>功能</small> | <small>在本项目中的使用位置或路由</small> |
|
|
18
|
+
| --- | --- | --- |
|
|
19
|
+
| <small>[`BaseGIS`](#base-gis)</small> | <small>Cesium / Leaflet 统一入口,负责地图初始化、引擎切换、视角控制、场景模式、底图、DEM、绘制、点击事件,以及 GeoJSON、风场、三维体渲染和剖面渲染等能力。</small> | <small>基础能力:<a href="http://61.50.111.214:31166/lgmap/test-page-2" target="_blank" rel="noopener noreferrer">查看示例</a>、<a href="http://61.50.111.214:31166/lgmap/test-page-3" target="_blank" rel="noopener noreferrer">查看示例</a><br>专项能力:<a href="http://61.50.111.214:31166/lgmap/test-page-14" target="_blank" rel="noopener noreferrer">查看示例</a>、<a href="http://61.50.111.214:31166/lgmap/test-page-15" target="_blank" rel="noopener noreferrer">查看示例</a>、<a href="http://61.50.111.214:31166/lgmap/test-page-20" target="_blank" rel="noopener noreferrer">查看示例</a>、<a href="http://61.50.111.214:31166/lgmap/test-page-21" target="_blank" rel="noopener noreferrer">查看示例</a>、<a href="http://61.50.111.214:31166/lgmap/test-page-23" target="_blank" rel="noopener noreferrer">查看示例</a></small> |
|
|
20
|
+
| <small>[`GraphicGroupController`](#graphic-group-controller)</small> | <small>统一装载和清理一组点、线、面、文字及 Marker 图形。</small> | <small><a href="http://61.50.111.214:31166/lgmap/test-page-2" target="_blank" rel="noopener noreferrer">查看示例</a>、<a href="http://61.50.111.214:31166/lgmap/test-page-3" target="_blank" rel="noopener noreferrer">查看示例</a></small> |
|
|
21
|
+
| <small>[`ImageLayerController` / `toImageLayerArea`](#image-layer-controller)</small> | <small>加载普通图片、GeoTIFF、灰度图着色和多时次栅格,并提供范围参数转换。</small> | <small><a href="http://61.50.111.214:31166/lgmap/test-page-4" target="_blank" rel="noopener noreferrer">查看示例</a>、<a href="http://61.50.111.214:31166/lgmap/test-page-18" target="_blank" rel="noopener noreferrer">查看示例</a></small> |
|
|
22
|
+
| <small>[`GridLayerController`](#grid-layer-controller)</small> | <small>加载灰度图或 GeoTIFF 数值网格,支持着色、探针、网格注记和生命周期控制。</small> | <small><a href="http://61.50.111.214:31166/lgmap/test-page-4" target="_blank" rel="noopener noreferrer">查看示例</a></small> |
|
|
23
|
+
| <small>[`PointLargeLayerController`](#point-large-layer-controller)</small> | <small>面向海量点位的异步构建、样式规则、点击、高亮、删除和显隐控制。</small> | <small><a href="http://61.50.111.214:31166/lgmap/test-page-5" target="_blank" rel="noopener noreferrer">查看示例</a></small> |
|
|
24
|
+
| <small>[`PointDensityController`](#point-density-controller)</small> | <small>点位视野裁剪和屏幕网格抽稀,支持动态图标、点击回调、配置更新和状态统计。</small> | <small><a href="http://61.50.111.214:31166/lgmap/test-page-8" target="_blank" rel="noopener noreferrer">查看示例</a>、<a href="http://61.50.111.214:31166/lgmap/test-page-9" target="_blank" rel="noopener noreferrer">查看示例</a>、<a href="http://61.50.111.214:31166/lgmap/test-page-13" target="_blank" rel="noopener noreferrer">查看示例</a></small> |
|
|
25
|
+
| <small>[`PressureContourLayer` / `createPressureDataResolver` / `buildPressureRenderData`](#pressure-contour-layer)</small> | <small>解析气压数据并生成等值线、数值标签及高低压中心标注。</small> | <small><a href="http://61.50.111.214:31166/lgmap/test-page-7" target="_blank" rel="noopener noreferrer">查看示例</a></small> |
|
|
26
|
+
| <small>[`ContourLayerController`](#contour-layer-controller)</small> | <small>统一管理等值线图层的加载、更新、显隐、引擎切换和销毁。</small> | <small><a href="http://61.50.111.214:31166/lgmap/test-page-18" target="_blank" rel="noopener noreferrer">查看示例</a></small> |
|
|
27
|
+
| <small>[`RasterContourController`](#raster-contour-controller)</small> | <small>从 GeoTIFF、灰度图或数值网格提取并渲染等值线。</small> | <small><a href="http://61.50.111.214:31166/lgmap/test-page-18" target="_blank" rel="noopener noreferrer">查看示例</a></small> |
|
|
28
|
+
| <small>[`WindFieldMethods`](#wind-field-methods)</small> | <small>提供 Cesium / Leaflet 风场数据加载、粒子动画、速度底图、交互和生命周期控制。</small> | <small><a href="http://61.50.111.214:31166/lgmap/test-page-2" target="_blank" rel="noopener noreferrer">查看示例</a>、<a href="http://61.50.111.214:31166/lgmap/test-page-3" target="_blank" rel="noopener noreferrer">查看示例</a></small> |
|
|
29
|
+
| <small>[`createTiandituLayer` / `createGeoserverPyramidLayer` / `createWmsLayer` / `createWmtsLayer`](#layer-config-builders)</small> | <small>构造天地图、GeoServer 金字塔瓦片、WMS 和 WMTS 图层配置。</small> | <small><a href="http://61.50.111.214:31166/lgmap/test-page-2" target="_blank" rel="noopener noreferrer">查看示例</a>、<a href="http://61.50.111.214:31166/lgmap/test-page-3" target="_blank" rel="noopener noreferrer">查看示例</a></small> |
|
|
30
|
+
| <small>[`gisMarkerSample`](#gis-marker-sample)</small> | <small>可直接导入的 GIS Marker 示例资源。</small> | <small><a href="http://61.50.111.214:31166/lgmap/test-page-2" target="_blank" rel="noopener noreferrer">查看示例</a>、<a href="http://61.50.111.214:31166/lgmap/test-page-3" target="_blank" rel="noopener noreferrer">查看示例</a></small> |
|
|
31
|
+
|
|
13
32
|
## 安装
|
|
14
33
|
|
|
15
34
|
```bash
|
|
16
|
-
npm install @3clear/basegis leaflet axios
|
|
35
|
+
npm install @3clear/basegis leaflet axios
|
|
17
36
|
```
|
|
18
37
|
|
|
38
|
+
`d3-contour`、`pixi.js` 和 `leaflet-pixi-overlay` 已随 BaseGIS 构建产物发布,业务项目不需要单独安装。其中 Pixi 相关代码只在首次使用 Leaflet 海量点能力时按需加载。
|
|
39
|
+
|
|
19
40
|
使用样式:
|
|
20
41
|
|
|
21
42
|
```js
|
|
22
43
|
import '@3clear/basegis/style.css'
|
|
23
44
|
```
|
|
24
45
|
|
|
25
|
-
Cesium 当前不随 npm
|
|
26
|
-
如果需要加载 GeoTIFF
|
|
46
|
+
Cesium 当前不随 npm 包发布,项目需要按原项目方式把 Cesium 静态资源放到 `public/lib/Cesium`,并保证初始化前能访问 `window.Cesium`。
|
|
47
|
+
如果需要加载 GeoTIFF 网格,需要项目提前提供 `window.GeoTIFF`。
|
|
27
48
|
|
|
28
49
|
## 出口
|
|
29
50
|
|
|
@@ -39,6 +60,7 @@ import {
|
|
|
39
60
|
PointLargeLayerController,
|
|
40
61
|
PointDensityController,
|
|
41
62
|
ContourLayerController,
|
|
63
|
+
RasterContourController,
|
|
42
64
|
PressureContourLayer,
|
|
43
65
|
createPressureDataResolver,
|
|
44
66
|
buildPressureRenderData,
|
|
@@ -263,6 +285,70 @@ mapCore.setBasemap({
|
|
|
263
285
|
| `parameters` | 选填 | WMS 附加参数。 |
|
|
264
286
|
| `engineSupport` | 选填 | 支持的引擎列表,如 `['cesium', 'leaflet']`。 |
|
|
265
287
|
|
|
288
|
+
<a id="layer-config-builders"></a>
|
|
289
|
+
|
|
290
|
+
## 图层配置构造器
|
|
291
|
+
|
|
292
|
+
`layers` 出口提供四个快捷构造器,只负责生成标准图层配置,不会直接操作地图。构造结果可以放入 `config.basemap.list`,也可以传给 `setBasemap()`。
|
|
293
|
+
|
|
294
|
+
```js
|
|
295
|
+
import { BaseGIS } from '@3clear/basegis'
|
|
296
|
+
import {
|
|
297
|
+
createGeoserverPyramidLayer,
|
|
298
|
+
createTiandituLayer,
|
|
299
|
+
createWmsLayer,
|
|
300
|
+
createWmtsLayer,
|
|
301
|
+
} from '@3clear/basegis/layers'
|
|
302
|
+
|
|
303
|
+
const basemapList = [
|
|
304
|
+
createTiandituLayer({
|
|
305
|
+
id: 'tianditu-imagery',
|
|
306
|
+
name: '天地图影像',
|
|
307
|
+
category: 'basemap',
|
|
308
|
+
resourceKey: 'imagery',
|
|
309
|
+
annotationResourceKey: 'imageryLabel',
|
|
310
|
+
}),
|
|
311
|
+
createGeoserverPyramidLayer({
|
|
312
|
+
id: 'geoserver-pyramid',
|
|
313
|
+
name: 'GeoServer 金字塔瓦片',
|
|
314
|
+
category: 'basemap',
|
|
315
|
+
url: 'https://example.com/tiles/{z}/{x}/{y}.png',
|
|
316
|
+
}),
|
|
317
|
+
createWmsLayer({
|
|
318
|
+
id: 'weather-wms',
|
|
319
|
+
name: '气象 WMS',
|
|
320
|
+
category: 'basemap',
|
|
321
|
+
serviceUrl: 'https://example.com/geoserver/wms',
|
|
322
|
+
layers: 'workspace:weather',
|
|
323
|
+
parameters: {
|
|
324
|
+
transparent: true,
|
|
325
|
+
format: 'image/png',
|
|
326
|
+
},
|
|
327
|
+
}),
|
|
328
|
+
createWmtsLayer({
|
|
329
|
+
id: 'weather-wmts',
|
|
330
|
+
name: '气象 WMTS',
|
|
331
|
+
category: 'basemap',
|
|
332
|
+
url: 'https://example.com/wmts',
|
|
333
|
+
layer: 'weather',
|
|
334
|
+
tileMatrixSet: 'EPSG:3857',
|
|
335
|
+
}),
|
|
336
|
+
]
|
|
337
|
+
|
|
338
|
+
const mapCore = new BaseGIS({
|
|
339
|
+
containerId: 'map',
|
|
340
|
+
config: {
|
|
341
|
+
basemap: {
|
|
342
|
+
list: basemapList,
|
|
343
|
+
defaultVisibleId: 'tianditu-imagery',
|
|
344
|
+
},
|
|
345
|
+
},
|
|
346
|
+
})
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
四个构造器都会保留额外传入字段,便于继续配置 `engineSupport`、缩放级别、注记资源或服务参数。
|
|
350
|
+
|
|
351
|
+
<a id="base-gis"></a>
|
|
266
352
|
|
|
267
353
|
## BaseGIS 基础能力
|
|
268
354
|
|
|
@@ -281,15 +367,8 @@ const mapCore = new BaseGIS({
|
|
|
281
367
|
// 创建地图实例。
|
|
282
368
|
mapCore.init()
|
|
283
369
|
|
|
284
|
-
//
|
|
285
|
-
mapCore.setEngine('leaflet')
|
|
286
|
-
|
|
287
|
-
// 真正切换地图引擎,需要再次 init。
|
|
288
|
-
// init 内部会先销毁旧 adapter,再按新 engineType 创建新地图实例。
|
|
289
|
-
mapCore.init({
|
|
290
|
-
engineType: 'leaflet',
|
|
291
|
-
containerId: 'map',
|
|
292
|
-
})
|
|
370
|
+
// 只传目标引擎即可完成切换、视野保留和托管图层恢复。
|
|
371
|
+
await mapCore.setEngine('leaflet')
|
|
293
372
|
|
|
294
373
|
// 覆盖运行时配置,不会自动重建地图。
|
|
295
374
|
mapCore.setConfig({ view: { defaultSceneMode: '2d' } })
|
|
@@ -304,13 +383,33 @@ mapCore.getMapInstance()
|
|
|
304
383
|
mapCore.destroy()
|
|
305
384
|
```
|
|
306
385
|
|
|
386
|
+
Cesium 默认使用最高 2 倍设备像素比、FXAA 和 4 倍 MSAA,避免高分屏上的细线出现明显像素阶梯。可按设备性能覆盖:
|
|
387
|
+
|
|
388
|
+
```js
|
|
389
|
+
const mapCore = new BaseGIS({
|
|
390
|
+
config: {
|
|
391
|
+
engine: {
|
|
392
|
+
cesium: {
|
|
393
|
+
renderQuality: {
|
|
394
|
+
maximumDevicePixelRatio: 1.5,
|
|
395
|
+
fxaa: true,
|
|
396
|
+
msaaSamples: 4,
|
|
397
|
+
},
|
|
398
|
+
},
|
|
399
|
+
},
|
|
400
|
+
},
|
|
401
|
+
})
|
|
402
|
+
```
|
|
403
|
+
|
|
307
404
|
方法说明:
|
|
308
405
|
|
|
309
406
|
| 方法 | 参数 | 说明 |
|
|
310
407
|
| --- | --- | --- |
|
|
311
|
-
| `init(options)` | `{ container, containerId, engineType }` |
|
|
312
|
-
| `
|
|
313
|
-
| `
|
|
408
|
+
| `init(options)` | `{ container, containerId, engineType }` | 初始化地图。重复调用时会自动恢复 BaseGIS 托管图层。 |
|
|
409
|
+
| `setEngine(engineType, options)` | 引擎类型、初始化参数 | 未初始化时记录默认引擎;已初始化时自动切换、保留视野并恢复托管图层。 |
|
|
410
|
+
| `switchEngine(engineType, options)` | 引擎类型、初始化参数 | `setEngine()` 的兼容别名。 |
|
|
411
|
+
| `whenReady()` | 无 | 等待最近一次 `init()` 触发的托管图层恢复完成。 |
|
|
412
|
+
| `destroy()` | 无 | 销毁当前地图实例和 adapter,并清空托管图层快照。 |
|
|
314
413
|
| `setConfig(config)` | `Object` | 合并运行时配置;不自动重建地图。 |
|
|
315
414
|
| `getEngineType()` | 无 | 返回当前引擎类型。 |
|
|
316
415
|
| `getConfig()` | 无 | 返回当前运行时配置。 |
|
|
@@ -318,62 +417,55 @@ mapCore.destroy()
|
|
|
318
417
|
|
|
319
418
|
#### 推荐的引擎切换写法
|
|
320
419
|
|
|
321
|
-
页面上做 Cesium / Leaflet
|
|
420
|
+
页面上做 Cesium / Leaflet 切换时,直接调用 `setEngine()`。它会保留当前视野、重建目标引擎,并等待托管图层自动恢复。
|
|
322
421
|
|
|
323
422
|
```js
|
|
324
|
-
async function
|
|
423
|
+
async function changeEngine(engineType) {
|
|
325
424
|
if (!mapCore || mapCore.getEngineType() === engineType) {
|
|
326
425
|
return
|
|
327
426
|
}
|
|
328
427
|
|
|
329
|
-
const result = mapCore.
|
|
330
|
-
engineType,
|
|
331
|
-
containerId: 'map',
|
|
332
|
-
})
|
|
428
|
+
const result = await mapCore.setEngine(engineType)
|
|
333
429
|
|
|
334
430
|
if (!result.success) {
|
|
335
431
|
console.warn(result.message)
|
|
336
432
|
return
|
|
337
433
|
}
|
|
338
|
-
|
|
339
|
-
// 地图实例已经重建,业务图层需要用自己的数据源重新加载。
|
|
340
|
-
await reloadBusinessLayers()
|
|
341
434
|
}
|
|
342
435
|
```
|
|
343
436
|
|
|
344
|
-
|
|
437
|
+
直接重复调用 `init({ engineType })` 也会自动开始恢复;如果后续逻辑依赖恢复完成,需要再等待 `whenReady()`:
|
|
345
438
|
|
|
346
439
|
```js
|
|
347
|
-
mapCore.setEngine('leaflet')
|
|
348
440
|
const result = mapCore.init({
|
|
441
|
+
engineType: 'leaflet',
|
|
349
442
|
containerId: 'map',
|
|
350
443
|
})
|
|
444
|
+
|
|
445
|
+
if (result.success) {
|
|
446
|
+
await mapCore.whenReady()
|
|
447
|
+
}
|
|
351
448
|
```
|
|
352
449
|
|
|
353
|
-
|
|
450
|
+
`switchEngine()` 作为兼容别名保留,行为与 `setEngine()` 一致。
|
|
354
451
|
|
|
355
452
|
#### 切换后的图层处理
|
|
356
453
|
|
|
357
|
-
引擎切换不是把 Cesium
|
|
454
|
+
引擎切换不是把 Cesium 图层对象“搬到” Leaflet,也不是把 Leaflet 图层对象“搬到” Cesium。BaseGIS 会保存托管图层的业务参数,并在新 adapter 中重新创建图层。
|
|
358
455
|
|
|
359
|
-
- `
|
|
360
|
-
-
|
|
361
|
-
-
|
|
456
|
+
- 自动恢复范围包括图片、网格、海量点、点位抽稀、等值线和三维体图层,对应 `upsert*Layer` 方法及 Controller。
|
|
457
|
+
- 图层最新的数据参数、显隐、清空、删除、海量点删除和高亮状态会同步到 BaseGIS 快照。
|
|
458
|
+
- 快照只保存业务参数引用,不复制大数组,不保存任何底层引擎对象。
|
|
459
|
+
- 三维体图层切到 Leaflet 时会返回不支持结果,但快照仍保留,切回 Cesium 后会继续恢复。
|
|
362
460
|
- Cesium 专有能力在 Leaflet 下不可用,例如 DEM、三维体渲染、三维切片/剖面渲染。
|
|
363
|
-
-
|
|
461
|
+
- 一次性绘制对象、点击监听、风场、剖面图层和页面直接操作底层引擎创建的对象不在托管范围内,需要业务自行恢复。
|
|
364
462
|
|
|
365
|
-
|
|
463
|
+
切换结果中可以查看恢复明细:
|
|
366
464
|
|
|
367
465
|
```js
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
await contour.load(currentContourPayload)
|
|
372
|
-
|
|
373
|
-
if (mapCore.getEngineType() === 'cesium') {
|
|
374
|
-
mapCore.upsertVolumeLayer(currentVolumePayload)
|
|
375
|
-
}
|
|
376
|
-
}
|
|
466
|
+
const result = await mapCore.setEngine('leaflet')
|
|
467
|
+
console.log(result.data.restore.restored)
|
|
468
|
+
console.log(result.data.restore.failed)
|
|
377
469
|
```
|
|
378
470
|
|
|
379
471
|
|
|
@@ -570,6 +662,25 @@ mapCore.addMarker({
|
|
|
570
662
|
})
|
|
571
663
|
```
|
|
572
664
|
|
|
665
|
+
<a id="gis-marker-sample"></a>
|
|
666
|
+
|
|
667
|
+
#### 使用 gisMarkerSample 示例资源
|
|
668
|
+
|
|
669
|
+
`gisMarkerSample` 是可直接导入的 Marker 图片资源,适合快速验证 `addMarker()` 或控制器图标配置。
|
|
670
|
+
|
|
671
|
+
```js
|
|
672
|
+
import { gisMarkerSample } from '@3clear/basegis/assets'
|
|
673
|
+
|
|
674
|
+
mapCore.addMarker({
|
|
675
|
+
id: 'marker-sample',
|
|
676
|
+
name: '示例站点',
|
|
677
|
+
position: [104, 35],
|
|
678
|
+
iconUrl: gisMarkerSample,
|
|
679
|
+
iconSize: [42, 50],
|
|
680
|
+
iconAnchor: [21, 50],
|
|
681
|
+
})
|
|
682
|
+
```
|
|
683
|
+
|
|
573
684
|
清理图形:
|
|
574
685
|
|
|
575
686
|
```js
|
|
@@ -659,6 +770,8 @@ Leaflet 当前返回坐标点击:
|
|
|
659
770
|
- 海量点、点位抽稀等图层自己的点击事件,应使用对应 Controller 的 `onClick` 参数。
|
|
660
771
|
|
|
661
772
|
|
|
773
|
+
<a id="graphic-group-controller"></a>
|
|
774
|
+
|
|
662
775
|
## GraphicGroupController
|
|
663
776
|
|
|
664
777
|
用于一次性加载一组点、线、面、文字、marker。它只调用 `BaseGIS.drawPoint / drawLine / drawPolygon / drawText / addMarker`。
|
|
@@ -696,10 +809,28 @@ graphics.clear()
|
|
|
696
809
|
graphics.getState()
|
|
697
810
|
```
|
|
698
811
|
|
|
812
|
+
<a id="image-layer-controller"></a>
|
|
813
|
+
|
|
699
814
|
## ImageLayerController
|
|
700
815
|
|
|
701
816
|
用于管理一个图片覆盖层。所有更新都走 `update(payload)`;页面有很多时次数据时,自己维护数据列表,然后把当前时次的数据传给 `update`。
|
|
702
817
|
|
|
818
|
+
`toImageLayerArea()` 可以把经纬度数组、Leaflet Bounds 或常见范围对象统一转换成 `{ startLon, startLat, endLon, endLat }`:
|
|
819
|
+
|
|
820
|
+
```js
|
|
821
|
+
import {
|
|
822
|
+
ImageLayerController,
|
|
823
|
+
toImageLayerArea,
|
|
824
|
+
} from '@3clear/basegis/methods'
|
|
825
|
+
|
|
826
|
+
const area = toImageLayerArea({
|
|
827
|
+
west: 73,
|
|
828
|
+
south: 18,
|
|
829
|
+
east: 135,
|
|
830
|
+
north: 54,
|
|
831
|
+
})
|
|
832
|
+
```
|
|
833
|
+
|
|
703
834
|
先创建控制器。这里是控制器级默认参数,后续每次 `update(payload)` 都可以覆盖这些默认值:
|
|
704
835
|
|
|
705
836
|
```js
|
|
@@ -863,6 +994,8 @@ await imageLayer.update({
|
|
|
863
994
|
})
|
|
864
995
|
```
|
|
865
996
|
|
|
997
|
+
Leaflet 会对经度跨度达到 360° 的全球图片按当前视野自动补充相邻世界副本,全球 TIF / 灰度格点的注记和鼠标探针也会使用同一套经度循环,因此业务页面不需要手动创建 `±360°` 图片层。原始图片按 `0° ~ 360°` 排列时传 `isSplit: true`,适配层会在交换左右半幅的同时把显示范围统一为 `-180° ~ 180°`,确保图片与格点值落在同一经度位置。
|
|
998
|
+
|
|
866
999
|
`loadGrayImage` 的灰度值换算规则:
|
|
867
1000
|
|
|
868
1001
|
```js
|
|
@@ -1070,6 +1203,8 @@ imageLayer.destroy({ layerId: 'radar-image' })
|
|
|
1070
1203
|
- `switchTo(idOrIndex)`:在已加载的 `items` 内切换到某一项。
|
|
1071
1204
|
- `next() / prev()`:只适合本地小数组演示,不推荐作为业务时次更新主路径。
|
|
1072
1205
|
|
|
1206
|
+
<a id="grid-layer-controller"></a>
|
|
1207
|
+
|
|
1073
1208
|
## GridLayerController
|
|
1074
1209
|
|
|
1075
1210
|
用于 TIF 网格、灰度图网格、外部数值网格。
|
|
@@ -1132,6 +1267,176 @@ gridLayer.show()
|
|
|
1132
1267
|
gridLayer.destroy()
|
|
1133
1268
|
```
|
|
1134
1269
|
|
|
1270
|
+
## 统一粒子风场
|
|
1271
|
+
|
|
1272
|
+
同一组 API 会根据当前引擎自动选择渲染器:Cesium 使用 GPU 粒子风场,Leaflet 使用迁自 one-map 的 Canvas 粒子风场。
|
|
1273
|
+
|
|
1274
|
+
```js
|
|
1275
|
+
const windData = await fetch('/mock/uv.json').then((response) => response.json())
|
|
1276
|
+
|
|
1277
|
+
await mapCore.upsertWindLayer({
|
|
1278
|
+
layerId: 'surface-wind',
|
|
1279
|
+
windData,
|
|
1280
|
+
maxParticles: 6400,
|
|
1281
|
+
speedFactor: 0.15,
|
|
1282
|
+
lineWidth: 2,
|
|
1283
|
+
fadeOpacity: 0.92,
|
|
1284
|
+
color: '#b7d9ff',
|
|
1285
|
+
particleOpacity: 0.72,
|
|
1286
|
+
})
|
|
1287
|
+
|
|
1288
|
+
await mapCore.updateWindLayer({
|
|
1289
|
+
layerId: 'surface-wind',
|
|
1290
|
+
speedFactor: 0.2,
|
|
1291
|
+
})
|
|
1292
|
+
mapCore.hideWindLayer({ layerId: 'surface-wind' })
|
|
1293
|
+
mapCore.showWindLayer({ layerId: 'surface-wind' })
|
|
1294
|
+
mapCore.flyToWindLayer({ layerId: 'surface-wind', duration: 0.8 })
|
|
1295
|
+
const stateResult = mapCore.getWindLayerState({ layerId: 'surface-wind' })
|
|
1296
|
+
mapCore.removeWindLayer({ layerId: 'surface-wind' })
|
|
1297
|
+
```
|
|
1298
|
+
|
|
1299
|
+
| 方法 | 说明 |
|
|
1300
|
+
| --- | --- |
|
|
1301
|
+
| `upsertWindLayer(payload)` | 创建或更新当前引擎的风场 |
|
|
1302
|
+
| `updateWindLayer(payload)` | 更新数据或部分参数 |
|
|
1303
|
+
| `showWindLayer(payload)` / `hideWindLayer(payload)` | 显隐风场 |
|
|
1304
|
+
| `flyToWindLayer(payload)` | 定位到风场数据范围 |
|
|
1305
|
+
| `getWindLayerState(payload)` | 获取渲染器、粒子数量、范围和显隐状态 |
|
|
1306
|
+
| `removeWindLayer(payload)` | 删除风场并释放资源 |
|
|
1307
|
+
|
|
1308
|
+
跨引擎统一使用 `Bound / DataAry` 数据格式。公共参数包括 `maxParticles`、`speedFactor`、`lineWidth`、`fadeOpacity`、`particleOpacity`、`color` 和 `visible`;适配层会统一速度、帧率拖尾、屏幕线宽、设备像素比和粒子视觉密度。`maxParticles` 表示跨引擎视觉预算:Cesium 的实际粒子数会按 GPU 纹理向上取整为整数平方,Leaflet 会按 Canvas 拖尾覆盖率换算实际粒子数,均可通过图层状态查看;算法和投影不同,因此不保证逐像素完全一致。Leaflet 还支持 `particleGap`、`maxAge`、`frameRate`、`minSpeed`。统一风场属于 BaseGIS 托管图层,`setEngine()` 切换引擎时会自动使用原数据和最新参数恢复。
|
|
1309
|
+
|
|
1310
|
+
## GPU 粒子风场
|
|
1311
|
+
|
|
1312
|
+
GPU 粒子风场是 Cesium 专有能力,直接通过 `BaseGIS` 调用。它使用显卡纹理保存和更新粒子,相机平移或缩放期间清空轨迹,操作结束后按新视野重新生成粒子。Leaflet 调用同名方法时会返回 `UNSUPPORTED_CAPABILITY`,不会抛异常。
|
|
1313
|
+
|
|
1314
|
+
Cesium 由宿主通过 `window.Cesium` 提供。启用 `terrainEnabled` 后,图层会采样当前 `viewer.terrainProvider`,让轨迹高度随地形变化;如果当前使用椭球地形,采样高度为 0。
|
|
1315
|
+
|
|
1316
|
+
### 基础用法
|
|
1317
|
+
|
|
1318
|
+
```js
|
|
1319
|
+
const response = await fetch('/mock/uv.json')
|
|
1320
|
+
const windData = await response.json()
|
|
1321
|
+
|
|
1322
|
+
const result = await mapCore.upsertGpuWindLayer({
|
|
1323
|
+
layerId: 'surface-gpu-wind',
|
|
1324
|
+
windData,
|
|
1325
|
+
maxParticles: 10000,
|
|
1326
|
+
particleHeight: 0,
|
|
1327
|
+
terrainEnabled: false,
|
|
1328
|
+
fadeOpacity: 0.901,
|
|
1329
|
+
dropRate: 0.001,
|
|
1330
|
+
dropRateBump: 0.002,
|
|
1331
|
+
speedFactor: 0.15,
|
|
1332
|
+
lineWidth: 4.23,
|
|
1333
|
+
color: '#ffffff',
|
|
1334
|
+
particleOpacity: 1,
|
|
1335
|
+
})
|
|
1336
|
+
|
|
1337
|
+
if (!result.success) {
|
|
1338
|
+
console.warn(result.code, result.message)
|
|
1339
|
+
}
|
|
1340
|
+
```
|
|
1341
|
+
|
|
1342
|
+
创建和更新是异步方法,可能等待地形采样,建议始终使用 `await`。
|
|
1343
|
+
|
|
1344
|
+
### 数据格式
|
|
1345
|
+
|
|
1346
|
+
可直接使用 BaseGIS 现有 Canvas 风场的 `Bound / DataAry` 数据:
|
|
1347
|
+
|
|
1348
|
+
```js
|
|
1349
|
+
const windData = {
|
|
1350
|
+
// 经度最小值、纬度最小值、经向格点数、纬向格点数、
|
|
1351
|
+
// 经度跨度、纬度跨度、数值缩放倍数。
|
|
1352
|
+
Bound: [100, 10, 181, 91, 80, 40, 10],
|
|
1353
|
+
// 每个格点按 U、V 交错;纬度行从南向北排列。
|
|
1354
|
+
DataAry: [u0, v0, u1, v1],
|
|
1355
|
+
}
|
|
1356
|
+
```
|
|
1357
|
+
|
|
1358
|
+
也可以传独立 U/V 分量:
|
|
1359
|
+
|
|
1360
|
+
```js
|
|
1361
|
+
const windData = {
|
|
1362
|
+
width: 181,
|
|
1363
|
+
height: 91,
|
|
1364
|
+
bounds: {
|
|
1365
|
+
west: 100,
|
|
1366
|
+
east: 180,
|
|
1367
|
+
south: 10,
|
|
1368
|
+
north: 50,
|
|
1369
|
+
},
|
|
1370
|
+
u: new Float32Array(181 * 91),
|
|
1371
|
+
v: new Float32Array(181 * 91),
|
|
1372
|
+
// index-gpu.vue 解码结果从北向南排列,因此使用 north-to-south。
|
|
1373
|
+
rowOrder: 'north-to-south',
|
|
1374
|
+
}
|
|
1375
|
+
```
|
|
1376
|
+
|
|
1377
|
+
也可以不改 `windData`,在 `upsertGpuWindLayer` 参数中传 `flipY: true`。这与 `rowOrder: 'north-to-south'` 等价。
|
|
1378
|
+
|
|
1379
|
+
### 更新、显隐和移除
|
|
1380
|
+
|
|
1381
|
+
```js
|
|
1382
|
+
await mapCore.updateGpuWindLayer({
|
|
1383
|
+
layerId: 'surface-gpu-wind',
|
|
1384
|
+
maxParticles: 40000,
|
|
1385
|
+
speedFactor: 0.2,
|
|
1386
|
+
lineWidth: 3,
|
|
1387
|
+
terrainEnabled: true,
|
|
1388
|
+
particleHeight: 20,
|
|
1389
|
+
})
|
|
1390
|
+
|
|
1391
|
+
mapCore.hideGpuWindLayer({ layerId: 'surface-gpu-wind' })
|
|
1392
|
+
mapCore.showGpuWindLayer({ layerId: 'surface-gpu-wind' })
|
|
1393
|
+
mapCore.flyToGpuWindLayer({ layerId: 'surface-gpu-wind', duration: 0.8 })
|
|
1394
|
+
|
|
1395
|
+
const stateResult = mapCore.getGpuWindLayerState({
|
|
1396
|
+
layerId: 'surface-gpu-wind',
|
|
1397
|
+
})
|
|
1398
|
+
console.log(stateResult.data)
|
|
1399
|
+
|
|
1400
|
+
mapCore.removeGpuWindLayer({ layerId: 'surface-gpu-wind' })
|
|
1401
|
+
```
|
|
1402
|
+
|
|
1403
|
+
`updateGpuWindLayer` 只传参数时复用现有数据;传入新的 `windData` 或 `data` 时会重建 GPU 图层。
|
|
1404
|
+
|
|
1405
|
+
### 方法总表
|
|
1406
|
+
|
|
1407
|
+
| 方法 | 参数 | 说明 |
|
|
1408
|
+
| --- | --- | --- |
|
|
1409
|
+
| `upsertGpuWindLayer(payload)` | 数据和完整配置 | 创建或替换同 `layerId` 的 GPU 风场 |
|
|
1410
|
+
| `updateGpuWindLayer(payload)` | `{ layerId, ...partialOptions }` | 更新参数;传新数据时重建 |
|
|
1411
|
+
| `showGpuWindLayer(payload)` | `{ layerId }` | 显示图层 |
|
|
1412
|
+
| `hideGpuWindLayer(payload)` | `{ layerId }` | 隐藏图层 |
|
|
1413
|
+
| `removeGpuWindLayer(payload)` | `{ layerId }` | 删除图层并释放 GPU 资源 |
|
|
1414
|
+
| `flyToGpuWindLayer(payload)` | `{ layerId, duration? }` | 飞到风场数据范围 |
|
|
1415
|
+
| `getGpuWindLayerState(payload)` | `{ layerId }` | 获取粒子、范围、地形采样和显隐状态 |
|
|
1416
|
+
|
|
1417
|
+
### 参数总表
|
|
1418
|
+
|
|
1419
|
+
| 参数 | 是否必填 | 默认值 | 说明 |
|
|
1420
|
+
| --- | --- | --- | --- |
|
|
1421
|
+
| `layerId` / `gpuWindLayerId` / `id` | 建议必填 | `gpu-wind-default` | 图层 id |
|
|
1422
|
+
| `windData` / `data` | 创建时必填 | - | 上述任一种风场数据 |
|
|
1423
|
+
| `maxParticles` | 选填 | `10000` | 请求粒子数;实际值向上取整为整数平方 |
|
|
1424
|
+
| `particleHeight` | 选填 | `0` | 离地高度,单位米 |
|
|
1425
|
+
| `terrainEnabled` | 选填 | `false` | 是否贴合 Cesium 地形 |
|
|
1426
|
+
| `fadeOpacity` | 选填 | `0.901` | 拖尾保留系数,范围 0~1 |
|
|
1427
|
+
| `dropRate` | 选填 | `0.001` | 基础粒子丢弃率 |
|
|
1428
|
+
| `dropRateBump` | 选填 | `0.002` | 随风速增加的附加丢弃率 |
|
|
1429
|
+
| `speedFactor` | 选填 | `0.15` | 移动速度倍率 |
|
|
1430
|
+
| `lineWidth` | 选填 | `4.23` | 轨迹线宽 |
|
|
1431
|
+
| `color` | 选填 | `#ffffff` | 粒子轨迹颜色 |
|
|
1432
|
+
| `particleOpacity` | 选填 | `1` | 粒子轨迹透明度,范围 0~1 |
|
|
1433
|
+
| `visible` | 选填 | `true` | 初始是否显示 |
|
|
1434
|
+
| `terrainMaxSamples` | 选填 | `4096` | 单次地形采样点上限,允许 4~16384 |
|
|
1435
|
+
| `terrainSampleLevel` | 选填 | 自动计算 | 固定地形采样层级,允许 0~15 |
|
|
1436
|
+
| `flipY` | 选填 | `false` | 独立 U/V 数据为北到南行序时传 `true` |
|
|
1437
|
+
|
|
1438
|
+
GPU 专用 API 不属于跨引擎自动恢复图层。切换 Cesium/Leaflet 后,业务应重新调用 `upsertGpuWindLayer`;需要自动恢复时改用 `upsertWindLayer`。核心渲染流程改编自 [RaymanNg/3D-Wind-Field](https://github.com/RaymanNg/3D-Wind-Field),遵循源码目录内 `LICENSE-RaymanNg.txt` 的 MIT License。
|
|
1439
|
+
|
|
1135
1440
|
## 三维体渲染
|
|
1136
1441
|
|
|
1137
1442
|
三维体渲染是 Cesium 专有能力,直接通过 `BaseGIS` 调用。Leaflet 调用时会返回不支持结果,不会抛出破坏页面的异常。
|
|
@@ -1440,10 +1745,14 @@ if (result.success) {
|
|
|
1440
1745
|
| `lon / lat / hpa` | hover 取值必填 | Cesium 拾取得到的经度、纬度、气压高度。 |
|
|
1441
1746
|
| `showZLayer` | hover 取值选填 | Z 切片是否参与 hover 命中,默认参与。 |
|
|
1442
1747
|
|
|
1748
|
+
<a id="point-large-layer-controller"></a>
|
|
1749
|
+
|
|
1443
1750
|
## PointLargeLayerController
|
|
1444
1751
|
|
|
1445
1752
|
用于海量点位渲染。它会尽量把传入的有效点位全部渲染出来,适合站点、设备、告警、监测点等需要保留全部点位并支持点击、高亮、删除、显隐的场景。
|
|
1446
1753
|
|
|
1754
|
+
Leaflet 模式使用 BaseGIS 内置的 `pixi.js` 和 `leaflet-pixi-overlay` 异步渲染,业务项目无需安装这两个依赖;Cesium 模式不加载 Pixi 相关代码。
|
|
1755
|
+
|
|
1447
1756
|
如果业务目标是“地图缩小时按屏幕网格抽稀,只显示代表点”,应使用后文的 `PointDensityController`。
|
|
1448
1757
|
|
|
1449
1758
|
### Demo 位置
|
|
@@ -1800,6 +2109,8 @@ console.log(state)
|
|
|
1800
2109
|
```
|
|
1801
2110
|
|
|
1802
2111
|
|
|
2112
|
+
<a id="point-density-controller"></a>
|
|
2113
|
+
|
|
1803
2114
|
## PointDensityController
|
|
1804
2115
|
|
|
1805
2116
|
用于点位密度抽稀。地图移动、缩放后会按当前视野和屏幕网格重新计算可见点,适合站点、设备、告警、空气质量监测点等高密度点位。
|
|
@@ -2159,6 +2470,8 @@ console.log(state)
|
|
|
2159
2470
|
// }
|
|
2160
2471
|
```
|
|
2161
2472
|
|
|
2473
|
+
<a id="contour-layer-controller"></a>
|
|
2474
|
+
|
|
2162
2475
|
## ContourLayerController
|
|
2163
2476
|
|
|
2164
2477
|
用于等值线图层,支持加载、更新、显隐、清空和销毁。
|
|
@@ -2189,6 +2502,8 @@ await contour.load({
|
|
|
2189
2502
|
color: '#ff4d4f',
|
|
2190
2503
|
width: 2,
|
|
2191
2504
|
},
|
|
2505
|
+
showLabel: true,
|
|
2506
|
+
labelFormatter: (item) => String(item.value),
|
|
2192
2507
|
})
|
|
2193
2508
|
|
|
2194
2509
|
await contour.update({
|
|
@@ -2203,71 +2518,224 @@ contour.clear()
|
|
|
2203
2518
|
contour.destroy()
|
|
2204
2519
|
```
|
|
2205
2520
|
|
|
2206
|
-
数据别名支持 `contours / isolines / isoline / lines / data / items
|
|
2521
|
+
数据别名支持 `contours / isolines / isoline / lines / data / items`。开启 `showLabel` 后,Cesium 和 Leaflet 都会根据当前屏幕范围重新选择可见线段上的位置。Leaflet 传入经度跨度达到 360° 的 `worldCopyArea` 后,还会按当前视野动态更新等值线路径和标签的世界副本;这个过程只重建可见路径,不重新解析栅格或追踪等值线。`RasterContourController` 会自动把栅格范围作为 `worldCopyArea` 传入。
|
|
2207
2522
|
|
|
2208
|
-
|
|
2209
|
-
[//]: # (## PressureContourLayer)
|
|
2523
|
+
Cesium 在默认椭球地表上使用 `PolylineCollection` 批量落图;真正启用 DEM 地形后才使用 `GroundPolylinePrimitive`。新批次就绪后再替换旧批次,不为每条线创建独立 Entity。标签定位可通过 `labelLineThinStep` 抽样投影点,不会改变实际绘制的等值线。
|
|
2210
2524
|
|
|
2211
|
-
|
|
2212
|
-
[//]: # (用于等压线和高低压中心标注。`buildPressureRenderData()` 可把 Windy 风格的 `press.json` 数据整理成渲染结构,`createPressureDataResolver()` 提供简单缓存。)
|
|
2525
|
+
Leaflet 默认复用高精度 SVG renderer,并使用 `smoothFactor: 0.5` 做屏幕空间简化:缩小时清理挤在同一像素内的折点,放大后自动保留曲线细节,避免全局 `preferCanvas` 放大细线锯齿。线位于 `dt-contour-pane`(层级 `450`),稳定显示在图片图层上方,并保持在 `markerPane` 数值标签下方;显式传入 `pane` 时仍以业务配置为准。
|
|
2213
2526
|
|
|
2214
|
-
|
|
2215
|
-
[//]: # (```js)
|
|
2527
|
+
屏幕标注参数:
|
|
2216
2528
|
|
|
2217
|
-
|
|
2529
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
2530
|
+
| --- | --- | --- | --- |
|
|
2531
|
+
| `showLabel/showLabels` | `boolean` | `false` | 是否显示等值线数值。 |
|
|
2532
|
+
| `labelFormatter(item, record)` | `Function` | 等值级别 | 格式化标签文本。 |
|
|
2533
|
+
| `labelColor` | `string` | `#34464f` | 文字颜色。 |
|
|
2534
|
+
| `labelBackgroundColor` | `string` | `rgba(255,255,255,0.78)` | 背景色。 |
|
|
2535
|
+
| `labelBorderColor/labelBorderWidth` | `string/number` | `rgba(93,112,116,0.35)` / `0.5` | 边框颜色和宽度。 |
|
|
2536
|
+
| `labelBorderRadius` | `number` | `8` | 圆角,单位 px。 |
|
|
2537
|
+
| `labelFontSize/labelFontWeight` | `number/string` | `10/600` | 字号和字重。 |
|
|
2538
|
+
| `labelPaddingX/labelPaddingY` | `number` | `4/0` | 标签内部留白。 |
|
|
2539
|
+
| `labelMinWidth` | `number` | `32` | 标签最小宽度,短数值保持横向胶囊形状。 |
|
|
2540
|
+
| `labelViewportPadding` | `number/object/Function` | `24` | 屏幕安全边距;对象为 `top/right/bottom/left`,函数接收 `{width,height}`。 |
|
|
2541
|
+
| `labelMinScreenLength` | `number` | `72` | 可见线段达到该像素长度后才允许放标签。 |
|
|
2542
|
+
| `labelLineThinStep` | `number` | Cesium `3`,Leaflet `1` | 标签定位时的投影抽样步长,不影响实际线几何。 |
|
|
2543
|
+
| `labelCollisionPadding` | `number` | `7` | 标签碰撞间距。 |
|
|
2544
|
+
| `labelMaxPerLevel` | `number` | `Infinity` | 每个等值级别在当前视野中的标签上限;默认按可见线数量自动决定。 |
|
|
2545
|
+
| `labelDisableDepthTestDistance` | `number` | `Infinity` | Cesium 标签关闭深度检测的距离。 |
|
|
2218
2546
|
|
|
2219
|
-
|
|
2547
|
+
`getState()` 的 `labelCount` 是当前视野实际显示的标签数量。Cesium 状态额外包含 `lineRenderer/lineBuildElapsed/labelLayoutElapsed/primitiveReadyElapsed`,用于区分线构建、标签排版和异步就绪耗时。`onStateChange(state)` 会在视野重排后回传新状态。页面存在侧栏等遮挡时,可通过 `labelViewportPadding` 排除对应区域。
|
|
2220
2548
|
|
|
2221
|
-
|
|
2549
|
+
<a id="raster-contour-controller"></a>
|
|
2222
2550
|
|
|
2223
|
-
|
|
2551
|
+
## RasterContourController
|
|
2224
2552
|
|
|
2225
|
-
|
|
2226
|
-
[//]: # (const resolvePressureData = createPressureDataResolver({)
|
|
2553
|
+
用于从 GeoTIFF、灰度图或数值网格直接计算并绘制等值线。内部统一使用 `d3-contour` 追踪等值线,输出仍交给 `ContourLayerController`,所以页面不需要区分 Cesium 和 Leaflet;调用 `BaseGIS.setEngine()` 时,已经生成的等值线会随托管图层自动恢复。
|
|
2227
2554
|
|
|
2228
|
-
|
|
2555
|
+
### 1. GeoTIFF 生成等值线
|
|
2229
2556
|
|
|
2230
|
-
|
|
2557
|
+
```js
|
|
2558
|
+
import { RasterContourController } from '@3clear/basegis/methods'
|
|
2231
2559
|
|
|
2232
|
-
|
|
2560
|
+
const rasterContour = new RasterContourController({
|
|
2561
|
+
mapCore,
|
|
2562
|
+
layerId: 'temperature-raster-contour',
|
|
2563
|
+
// thresholds / interval / thresholdCount 三选一。
|
|
2564
|
+
interval: 5,
|
|
2565
|
+
smooth: true,
|
|
2566
|
+
visible: true,
|
|
2567
|
+
})
|
|
2233
2568
|
|
|
2234
|
-
|
|
2235
|
-
|
|
2569
|
+
const result = await rasterContour.loadGeoTiff({
|
|
2570
|
+
tifUrl: '/data/temperature.tif',
|
|
2571
|
+
// TIF 范围不准确时可用 WGS84 四至覆盖文件元数据。
|
|
2572
|
+
area: {
|
|
2573
|
+
startLon: -180,
|
|
2574
|
+
startLat: -90,
|
|
2575
|
+
endLon: 180,
|
|
2576
|
+
endLat: 90,
|
|
2577
|
+
},
|
|
2578
|
+
band: 0,
|
|
2579
|
+
interval: 5,
|
|
2580
|
+
clampToGround: true,
|
|
2581
|
+
showLabel: true,
|
|
2582
|
+
labelFormatter: (item) => String(Math.round(item.value)),
|
|
2583
|
+
labelViewportPadding: { top: 32, right: 32, bottom: 32, left: 360 },
|
|
2584
|
+
styleCallback: (item) => ({
|
|
2585
|
+
color: item.value >= 30 ? '#ff6b6b' : '#d5f4ff',
|
|
2586
|
+
width: item.value % 10 === 0 ? 2 : 1,
|
|
2587
|
+
weight: item.value % 10 === 0 ? 2 : 1,
|
|
2588
|
+
}),
|
|
2589
|
+
})
|
|
2236
2590
|
|
|
2237
|
-
|
|
2591
|
+
if (!result.success) {
|
|
2592
|
+
console.warn(result.message)
|
|
2593
|
+
}
|
|
2238
2594
|
|
|
2239
|
-
|
|
2595
|
+
// 仅调整等值距时复用已解析网格,不再请求和解码 TIF。
|
|
2596
|
+
await rasterContour.update({ interval: 2 })
|
|
2597
|
+
```
|
|
2240
2598
|
|
|
2241
|
-
|
|
2599
|
+
GeoTIFF 依赖宿主页面提供 `window.GeoTIFF`。控制器会读取波段、尺寸、坐标系和范围;当前原生支持 EPSG:4326、EPSG:3857。其他投影可先转换为 WGS84,或传入 WGS84 `area` 覆盖原始范围。
|
|
2600
|
+
|
|
2601
|
+
### 2. 灰度图生成等值线
|
|
2602
|
+
|
|
2603
|
+
```js
|
|
2604
|
+
await rasterContour.loadGrayImage({
|
|
2605
|
+
grayImageUrl: '/data/pressure-gray.png',
|
|
2606
|
+
area: [-180, -90, 180, 90],
|
|
2607
|
+
grayMinValue: 0,
|
|
2608
|
+
grayMaxValue: 255,
|
|
2609
|
+
minValue: 960,
|
|
2610
|
+
maxValue: 1040,
|
|
2611
|
+
noDataValue: 255,
|
|
2612
|
+
interval: 4,
|
|
2613
|
+
})
|
|
2614
|
+
```
|
|
2615
|
+
|
|
2616
|
+
灰度换算规则:
|
|
2617
|
+
|
|
2618
|
+
```text
|
|
2619
|
+
业务值 = (灰度值 - grayMinValue) / (grayMaxValue - grayMinValue)
|
|
2620
|
+
* (maxValue - minValue) + minValue
|
|
2621
|
+
```
|
|
2242
2622
|
|
|
2243
|
-
|
|
2623
|
+
灰度图片本身没有地理范围和业务值含义,因此 `area` 必填;要表达真实数据,还应传正确的灰度范围与业务值范围。已经着色的彩色 PNG 不能反推出原始业务值,应使用对应 TIF 或直接传数值网格。
|
|
2244
2624
|
|
|
2245
|
-
|
|
2625
|
+
### 3. 数值网格生成等值线
|
|
2246
2626
|
|
|
2247
|
-
|
|
2627
|
+
```js
|
|
2628
|
+
await rasterContour.loadGrid({
|
|
2629
|
+
values: [12, 14, 16, 18, 20, 22],
|
|
2630
|
+
width: 3,
|
|
2631
|
+
height: 2,
|
|
2632
|
+
area: [100, 20, 103, 22],
|
|
2633
|
+
thresholds: [15, 20],
|
|
2634
|
+
})
|
|
2248
2635
|
|
|
2249
|
-
|
|
2636
|
+
// values 也可以直接传二维数组,此时不需要 width / height。
|
|
2637
|
+
await rasterContour.loadGrid({
|
|
2638
|
+
values: [
|
|
2639
|
+
[12, 14, 16],
|
|
2640
|
+
[18, 20, 22],
|
|
2641
|
+
],
|
|
2642
|
+
area: [100, 20, 103, 22],
|
|
2643
|
+
thresholdCount: 6,
|
|
2644
|
+
})
|
|
2645
|
+
```
|
|
2250
2646
|
|
|
2251
|
-
|
|
2647
|
+
### 4. 参数
|
|
2648
|
+
|
|
2649
|
+
数据源参数:
|
|
2650
|
+
|
|
2651
|
+
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|
|
2652
|
+
| --- | --- | --- | --- | --- |
|
|
2653
|
+
| `mapCore/baseGIS` | `BaseGIS` | 构造时必填 | `null` | 当前 BaseGIS 实例。 |
|
|
2654
|
+
| `layerId/contourLayerId` | `string` | 否 | `raster-contour-default` | 等值线图层 id。 |
|
|
2655
|
+
| `sourceType` | `geotiff/grayscale/grid` | 否 | 自动判断 | `loadGeoTiff/loadGrayImage/loadGrid` 会自动补齐。 |
|
|
2656
|
+
| `tifUrl/tiffUrl` | `string` | GeoTIFF 必填 | `''` | GeoTIFF 地址。 |
|
|
2657
|
+
| `arrayBuffer` | `ArrayBuffer` | 否 | `null` | 可代替 `tifUrl` 直接传 TIF 内容。 |
|
|
2658
|
+
| `band` | `number` | 否 | `0` | GeoTIFF 波段下标,从 0 开始。 |
|
|
2659
|
+
| `imageIndex` | `number` | 否 | `0` | 多图像 GeoTIFF 的图像下标。 |
|
|
2660
|
+
| `grayImageUrl/imageUrl` | `string` | 灰度图必填 | `''` | 灰度图地址,服务端必须允许 Canvas 跨域读取。 |
|
|
2661
|
+
| `values/data/grid` | `Array/TypedArray` | 数值网格必填 | - | 一维或二维数值。 |
|
|
2662
|
+
| `width/height` | `number` | 一维网格必填 | `0` | 一维数组的网格尺寸。 |
|
|
2663
|
+
| `area` | `object/number[]` | 图片和普通网格必填 | `null` | WGS84 范围;数组顺序为 `[west,south,east,north]`。 |
|
|
2664
|
+
| `sourceProjection` | `string` | 否 | 自动读取 | 支持 `EPSG:4326`、`EPSG:3857`。 |
|
|
2665
|
+
| `noDataValue` | `number` | 否 | TIF 自动读取 | 指定无效值;灰度图不传时仅透明像素无效。 |
|
|
2666
|
+
| `validMin/validMax` | `number` | 否 | - | 过滤值域外数据。 |
|
|
2667
|
+
| `scale/offset` | `number` | 否 | `1/0` | 数值换算为 `value * scale + offset`。 |
|
|
2668
|
+
| `isSplit` | `boolean` | 否 | `false` | 把左右半幅交换,处理以 0° 经线为边界的全球数据。 |
|
|
2669
|
+
|
|
2670
|
+
等值线参数:
|
|
2671
|
+
|
|
2672
|
+
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|
|
2673
|
+
| --- | --- | --- | --- | --- |
|
|
2674
|
+
| `thresholds/levels` | `number[]` | 三选一 | - | 显式等值线级别,仅保留实际值域内的值。 |
|
|
2675
|
+
| `interval/contourInterval` | `number` | 三选一 | - | 固定等值距。 |
|
|
2676
|
+
| `thresholdCount/levelCount` | `number` | 三选一 | `12` | 自动均分级别数量,范围 1~100。 |
|
|
2677
|
+
| `smooth` | `boolean` | 否 | `true` | 是否平滑等值线。 |
|
|
2678
|
+
| `smoothingIterations` | `number` | 否 | `0` | Chaikin 补点平滑次数,范围 0~3;气象格点通常取 1~2,次数越高,点数越多。 |
|
|
2679
|
+
| `excludeBoundary` | `boolean` | 否 | `true` | 去掉 d3 面边界中贴着栅格四边的伪矩形线。 |
|
|
2680
|
+
| `maxCells` | `number` | 否 | `1000000` | 超过该像元数时先等比例抽样,避免大图阻塞页面。 |
|
|
2681
|
+
| `minimumLinePoints` | `number` | 否 | `3` | 最短线点数,用于过滤栅格四角的两点补边。 |
|
|
2682
|
+
| `coordinatePrecision` | `number` | 否 | `6` | 输出经纬度小数位数。 |
|
|
2683
|
+
| `visible` | `boolean` | 否 | `true` | 初始显隐。 |
|
|
2684
|
+
| 其他渲染参数 | - | 否 | - | 与 `ContourLayerController` 相同,如 `color/width/weight/styleCallback/showLabel/labelViewportPadding`。 |
|
|
2685
|
+
|
|
2686
|
+
### 5. 方法和状态
|
|
2252
2687
|
|
|
2253
|
-
|
|
2688
|
+
| 方法 | 说明 |
|
|
2689
|
+
| --- | --- |
|
|
2690
|
+
| `load(payload, options)` | 自动判断数据源并生成等值线。 |
|
|
2691
|
+
| `loadGeoTiff(payload, options)` | 从 GeoTIFF 生成。 |
|
|
2692
|
+
| `loadGrayImage(payload, options)` | 从灰度图生成。 |
|
|
2693
|
+
| `loadGrid(payload, options)` | 从数值网格生成。 |
|
|
2694
|
+
| `update(payload)` | 合并配置后重新计算;仅修改等值线或渲染参数时复用已解析网格,修改数据源参数时自动重新加载。 |
|
|
2695
|
+
| `show/hide/toggle` | 控制等值线显隐。 |
|
|
2696
|
+
| `clear/destroy` | 清空或销毁控制器。 |
|
|
2697
|
+
| `getState()` | 返回尺寸、值域、级别、线数、当前标注数、投影、耗时和底层 contour 状态。 |
|
|
2698
|
+
| `getRasterData()` | 返回当前标准栅格,包含 `values/width/height/area`。 |
|
|
2254
2699
|
|
|
2255
|
-
|
|
2700
|
+
<a id="pressure-contour-layer"></a>
|
|
2256
2701
|
|
|
2257
|
-
|
|
2702
|
+
## PressureContourLayer
|
|
2258
2703
|
|
|
2259
|
-
|
|
2260
|
-
[//]: # (pressureLayer.mount())
|
|
2704
|
+
用于等压线、线值标签和高低压中心标注。`buildPressureRenderData()` 可把 Windy 风格的气压数据整理成 `{ isolines, centers }`,`createPressureDataResolver()` 在此基础上提供按数据版本缓存的解析函数。
|
|
2261
2705
|
|
|
2262
|
-
|
|
2706
|
+
```js
|
|
2707
|
+
import {
|
|
2708
|
+
PressureContourLayer,
|
|
2709
|
+
buildPressureRenderData,
|
|
2710
|
+
createPressureDataResolver,
|
|
2711
|
+
} from '@3clear/basegis/methods'
|
|
2263
2712
|
|
|
2264
|
-
|
|
2713
|
+
// 单份原始数据可以直接转换。
|
|
2714
|
+
const renderData = buildPressureRenderData(pressJson)
|
|
2265
2715
|
|
|
2266
|
-
|
|
2716
|
+
// 多个时次或版本可用解析器按 key 缓存转换结果。
|
|
2717
|
+
const resolvePressureData = createPressureDataResolver({
|
|
2718
|
+
default: pressJson,
|
|
2719
|
+
next: pressJson2,
|
|
2720
|
+
})
|
|
2267
2721
|
|
|
2268
|
-
|
|
2722
|
+
const pressureLayer = new PressureContourLayer({
|
|
2723
|
+
mapCore,
|
|
2724
|
+
layerId: 'pressure',
|
|
2725
|
+
color: 'rgba(255,255,255,0.82)',
|
|
2726
|
+
width: 1.15,
|
|
2727
|
+
smoothFactor: 0.2,
|
|
2728
|
+
// Cesium 用它判断标签碰撞和屏幕范围,Leaflet 可复用同一容器 id。
|
|
2729
|
+
mapContainerId: 'map',
|
|
2730
|
+
isAnnotationVisible: () => true,
|
|
2731
|
+
})
|
|
2269
2732
|
|
|
2270
|
-
|
|
2733
|
+
pressureLayer.mount()
|
|
2734
|
+
await pressureLayer.load(renderData)
|
|
2735
|
+
await pressureLayer.update(resolvePressureData('next'))
|
|
2736
|
+
pressureLayer.hide()
|
|
2737
|
+
pressureLayer.destroy()
|
|
2738
|
+
```
|
|
2271
2739
|
|
|
2272
2740
|
说明:
|
|
2273
2741
|
|
|
@@ -2275,6 +2743,8 @@ contour.destroy()
|
|
|
2275
2743
|
- Leaflet 使用 `divIcon` 绘制 H/L 中心和线值标签。
|
|
2276
2744
|
- Cesium 使用独立标注集合,地图变化时会调度刷新。
|
|
2277
2745
|
|
|
2746
|
+
<a id="wind-field-methods"></a>
|
|
2747
|
+
|
|
2278
2748
|
## WindFieldMethods
|
|
2279
2749
|
|
|
2280
2750
|
用于叠加 Canvas 风场粒子动画。它通过 `BaseGIS` 获取容器、投影、视野范围和视图变化事件,不直接依赖某个引擎。
|
|
@@ -2460,20 +2930,19 @@ export function useBaseGIS(options = {}) {
|
|
|
2460
2930
|
mapCore.value = null
|
|
2461
2931
|
})
|
|
2462
2932
|
|
|
2463
|
-
function
|
|
2933
|
+
async function setEngine(engineType) {
|
|
2464
2934
|
if (!mapCore.value || mapCore.value.getEngineType() === engineType) {
|
|
2465
2935
|
return { success: true }
|
|
2466
2936
|
}
|
|
2467
2937
|
|
|
2468
|
-
return mapCore.value.
|
|
2938
|
+
return mapCore.value.setEngine(engineType, {
|
|
2469
2939
|
...options,
|
|
2470
|
-
engineType,
|
|
2471
2940
|
})
|
|
2472
2941
|
}
|
|
2473
2942
|
|
|
2474
2943
|
return {
|
|
2475
2944
|
mapCore,
|
|
2476
|
-
|
|
2945
|
+
setEngine,
|
|
2477
2946
|
}
|
|
2478
2947
|
}
|
|
2479
2948
|
```
|
|
@@ -2488,22 +2957,22 @@ export function useBaseGIS(options = {}) {
|
|
|
2488
2957
|
<script setup>
|
|
2489
2958
|
import { useBaseGIS } from './useBaseGIS'
|
|
2490
2959
|
|
|
2491
|
-
const { mapCore,
|
|
2960
|
+
const { mapCore, setEngine } = useBaseGIS({
|
|
2492
2961
|
engineType: 'cesium',
|
|
2493
2962
|
containerId: 'map',
|
|
2494
2963
|
})
|
|
2495
2964
|
</script>
|
|
2496
2965
|
```
|
|
2497
2966
|
|
|
2498
|
-
|
|
2967
|
+
BaseGIS 托管图层会自动恢复,页面不需要重新请求数据:
|
|
2499
2968
|
|
|
2500
2969
|
```js
|
|
2501
|
-
const result =
|
|
2502
|
-
|
|
2503
|
-
await reloadBusinessLayers()
|
|
2504
|
-
}
|
|
2970
|
+
const result = await setEngine('leaflet')
|
|
2971
|
+
console.log(result.data?.restore)
|
|
2505
2972
|
```
|
|
2506
2973
|
|
|
2974
|
+
只有风场、剖面、一次性绘制对象或页面直接创建的底层引擎对象需要在切换成功后自行恢复。
|
|
2975
|
+
|
|
2507
2976
|
## 能力支持说明
|
|
2508
2977
|
|
|
2509
2978
|
| 能力 | Cesium | Leaflet |
|
|
@@ -2524,6 +2993,34 @@ if (result.success) {
|
|
|
2524
2993
|
| 三维切片 / 剖面渲染 | 支持 | 不支持 |
|
|
2525
2994
|
| DEM 地形 | 支持 | 不支持 |
|
|
2526
2995
|
|
|
2996
|
+
## 第三方许可
|
|
2997
|
+
|
|
2998
|
+
GPU 粒子风场核心改编自 RaymanNg/3D-Wind-Field:
|
|
2999
|
+
|
|
3000
|
+
```text
|
|
3001
|
+
MIT License
|
|
3002
|
+
|
|
3003
|
+
Copyright (c) 2019 RaymanNg
|
|
3004
|
+
|
|
3005
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
3006
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
3007
|
+
in the Software without restriction, including without limitation the rights
|
|
3008
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
3009
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
3010
|
+
furnished to do so, subject to the following conditions:
|
|
3011
|
+
|
|
3012
|
+
The above copyright notice and this permission notice shall be included in all
|
|
3013
|
+
copies or substantial portions of the Software.
|
|
3014
|
+
|
|
3015
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
3016
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
3017
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
3018
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
3019
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
3020
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
3021
|
+
SOFTWARE.
|
|
3022
|
+
```
|
|
3023
|
+
|
|
2527
3024
|
## 本地开发与打包
|
|
2528
3025
|
|
|
2529
3026
|
在仓库根目录执行:
|
|
@@ -2634,18 +3131,13 @@ mapCore.init()
|
|
|
2634
3131
|
|
|
2635
3132
|
### 切换引擎后图层没了
|
|
2636
3133
|
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
处理方式是:页面或 store 保存业务数据,切换成功后重新调用对应的加载方法。
|
|
3134
|
+
直接使用 `setEngine()`。BaseGIS 会保留视野,并自动恢复图片、网格、海量点、点位抽稀、等值线和三维体等托管图层:
|
|
2640
3135
|
|
|
2641
3136
|
```js
|
|
2642
|
-
const result = mapCore.
|
|
2643
|
-
engineType: 'leaflet',
|
|
2644
|
-
containerId: 'map',
|
|
2645
|
-
})
|
|
3137
|
+
const result = await mapCore.setEngine('leaflet')
|
|
2646
3138
|
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
await pointLayer.load({ points: currentPoints })
|
|
2650
|
-
}
|
|
3139
|
+
console.log(result.data?.restore?.restored)
|
|
3140
|
+
console.log(result.data?.restore?.failed)
|
|
2651
3141
|
```
|
|
3142
|
+
|
|
3143
|
+
如果丢失的是 `drawPoint/drawLine/drawPolygon/drawText/addMarker`、点击监听、风场、剖面图层或页面直接创建的 Cesium / Leaflet 对象,它们不属于托管图层,需要业务在切换成功后自行恢复。
|