npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

cesium-uvw-wind

v0.3.0

Published

Cesium UVW 3D wind field renderer with particles and analysis overlays.

Downloads

557

Readme

Cesium UVW Wind

Cesium UVW Wind 是一个基于 Cesium 的三维 u / v / w 矢量场渲染图层,适合展示风场、洋流、数值模式输出等规则网格数据。

安装

npm install cesium-uvw-wind

基本用法

import { UvwWindLayer } from "cesium-uvw-wind";

const layer = new UvwWindLayer(viewer);

await layer.load({
  source: "/data/demo-uvw.json",
  format: "json",
  preset: {
    particlesTextureSize: 64,
    particleHeight: { min: 20000, max: 640000 },
    speedFactor: 2,
    displayRange: { min: 0, max: 50 },
    lineLength: { min: 40, max: 220 },
  },
});

UvwWindLayer

const layer = new UvwWindLayer(viewer);

| 参数 | 必填 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | --- | | viewer | 是 | Cesium.Viewer | 无 | 已创建好的 Cesium Viewer。 |

layer.load(config)

加载数据源并创建粒子图层。

| 字段 | 必填 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | --- | | source | 是 | string \| object | 无 | 数据源。支持 URL、JSON 元数据对象、GeoTIFF 分量对象。 | | format | 否 | "json" \| "netcdf" \| "geotiff" | 按扩展名推断 | 数据格式。无法从扩展名判断时必须传。 | | sourceOptions | 否 | object | {} | 数据解析参数。不同格式支持的字段不同。 | | preset | 否 | object | 见 preset 表 | 粒子渲染参数。 |

layer.update(config)

更新同网格尺寸的数据,复用当前粒子图层。

await layer.update({
  source: "/data/typhoon/2022-09-02T06.json",
  format: "json",
});

config 字段与 load(config) 相同。width / height / depth 必须一致;bounds 可以变化。

layer.setPreset(preset)

更新粒子渲染参数,不重新加载数据。

layer.setPreset({
  speedFactor: 3,
  useViewerBounds: true,
  viewBoundsPadding: 0.4,
});

| 字段 | 类型 | 默认值 | 取值约束 | 说明 | | --- | --- | --- | --- | --- | | particlesTextureSize | number | 48 | 正整数 | 粒子纹理边长。实际粒子数为 particlesTextureSize * particlesTextureSize。 | | particleHeight | number \| { min, max } | { min: 20000, max: 520000 } | 必须与数据高度范围有交集 | 粒子出生和运动的高度范围,最终会裁剪到数据高度范围内。 | | speedFactor | number | 1 | 有限数字 | 整体运动速度系数。 | | speedContrast | number | 0 | 0..2 | 速度差异增强系数。值越大,快慢粒子速度差越明显。 | | verticalFactor | number | 1 | 有限数字 | 垂直速度 w 放大系数。 | | dropRate | number | 0.003 | 0..1 | 粒子随机重生率。 | | dropRateBump | number | 0.01 | 0..1 | 强风区域额外重生率。 | | domain | { min, max } | { min: 0, max: 55 } | min <= max | 速度归一化的数据域。 | | displayRange | { min, max } | { min: 0, max: 55 } | min <= max | 色带和尾迹可见长度的映射范围。 | | lineLength | { min, max } | { min: 40, max: 180 } | 0 <= min <= max | 粒子尾迹长度范围。速度越高越接近 max。 | | colorRamp | string[] | ["#47c7ff", "#73ff9e", "#ffbf38"] | 至少 2 个 CSS 颜色 | 按速度映射的色带。 | | opacity | number | 0.82 | 0..1 | 粒子透明度。 | | useViewerBounds | boolean | true | - | 是否按当前相机视窗裁剪粒子。 | | viewBoundsPadding | number | 0.35 | 0..2 | 视窗裁剪外扩比例。 | | adaptiveParticleCount | boolean | true | - | 是否按可视面积动态降低活动粒子数。 | | adaptiveParticleMinRatio | number | 0.18 | 0..1 | 自适应粒子数最低保留比例。 | | adaptiveSegmentCount | boolean | true | - | 是否按可视面积动态降低尾迹段数。 | | adaptiveSegmentMinRatio | number | 0.45 | 0..1 | 自适应尾迹段数最低保留比例。 | | updateStride | number | 1 | 整数 1..8 | 分批更新步长。值越大,每帧更新的粒子越少。 | | dynamic | boolean | true | - | 是否更新粒子动画。 |

layer.setAnalysis(options)

更新分析图层,返回切面和点位风廓线数据。

const result = layer.setAnalysis({
  slice: {
    enabled: true,
    mode: "vertical",
    height: 180000,
    heading: 90,
    pitch: 90,
    roll: 0,
    fill: true,
    contours: false,
    barbs: false,
    contourThreshold: 12,
    barbScale: 1,
    barbDensity: 1,
    barbColor: "#ffffff",
    contourLineColor: "#ffffff",
    contourLineWidth: 1,
    contourInterval: 4,
    particleFilter: { mode: "side", side: "negative", widthKm: 120 },
  },
  profile: {
    enabled: true,
    layers: 16,
    probe: { lon: 114, lat: 24 },
  },
});

入参:

options.slice

| 字段 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | enabled | boolean | false | 是否启用切面分析。 | | mode | "horizontal" \| "vertical" \| "custom" | "horizontal" | horizontal 为固定高度面;vertical 为按方位角穿过数据范围的垂直剖面;custom 为按 heading / pitch / roll 定义的任意姿态平面。 | | height | number | 0 | 切面高度,单位米。水平切面和自定义切面的中心高度使用该值。 | | heading | number | 90 | 方位角,单位度。 | | pitch | number | 水平 0,其他 90 | 自定义姿态俯仰角,单位度。 | | roll | number | 0 | 自定义姿态翻滚角,单位度。 | | offset | number | 0 | 切面相对数据中心的偏移,范围 -100..100。 | | samples | number | 96 | 切面横向采样数,整数 8..1000。值越大,小格子越细,开销越高。 | | layers | number | 36 | 切面纵向采样数,整数 8..1000。值越大,小格子越细,开销越高。 | | fillOpacity | number | 0.4 | 速度填色面的整体透明度,范围 0..1。 | | fill | boolean | true | 是否显示速度填色。 | | contours | boolean | false | 是否显示等值线。 | | barbs | boolean | false | 是否显示风羽。 | | contourThreshold | number | 12 | 等值线阈值。 | | barbScale | number | 1 | 风羽大小倍率,范围 0.1..5。 | | barbDensity | number | 1 | 风羽密度倍率,范围 0.25..4。 | | barbColor | string | "#ffffff" | 风羽轮廓色。 | | contourLineColor | string | "#ffffff" | 等值线轮廓色。 | | contourLineWidth | number | 1 | 等值线轮廓粗细倍率,范围 0..5。 | | contourInterval | number \| "auto" | "auto" | 等值线间距,单位 m/s;不传或 "auto" 时按最大风速自动计算。 | | particleFilter.mode | "all" \| "band" \| "side" | "side" | 主粒子场切面过滤方式。 | | particleFilter.widthKm | number | 120 | band 模式带宽,单位千米。 | | particleFilter.side | "positive" \| "negative" | "negative" | side 模式保留的切面一侧。 |

options.profile

| 字段 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | enabled | boolean | false | 是否启用点位垂直廓线。 | | layers | number | 16 | 点位风廓线采样层数,整数 4..256。 | | probe | { lon, lat } | 无 | 启用 profile.enabled 时必填。 |

返回值:

| 字段 | 类型 | 说明 | | --- | --- | --- | | slice | object \| null | 切面分析结果。水平、垂直、自定义姿态都返回到这个字段;未启用 slice.enabled 时为 null。 | | profile | object \| null | 点位垂直廓线结果。未启用 profile.enabled 时为 null。 |

返回值中的 slice 字段:

| 字段 | 类型 | 说明 | | --- | --- | --- | | mode | "horizontal" \| "vertical" \| "custom" | 切面模式。 | | height | number | 切面高度,单位米。 | | bearing | number | 方位角,单位度。水平切面通常不使用。 | | pitch | number | 自定义姿态俯仰角,单位度。 | | roll | number | 自定义姿态翻滚角,单位度。 | | widthMeters | number | 切面横向长度,单位米。 | | heightMeters | number | 切面纵向长度,单位米。 | | points | Array | 切面采样点,顺序为 z * samples + x。 | | speeds | Float32Array | 每个采样点的三维风速模长。 | | along | Float32Array | 每个采样点沿切面横轴的风速分量。 | | vertical | Float32Array | 每个采样点沿切面纵轴的风速分量。 | | minSpeed | number | 最小风速。 | | maxSpeed | number | 最大风速。 | | meanSpeed | number | 平均风速。 | | sampleCount | number | 统计采样点数量。 | | strongRatio | number | 达到阈值的采样点占比,范围 0..1。 |

其他方法

| 方法 | 返回值 | 说明 | | --- | --- | --- | | update(config) | Promise<UvwWindLayer> | 更新同网格尺寸数据,复用当前粒子图层。 | | clearAnalysis() | UvwWindLayer | 移除分析图层,并取消粒子剖面过滤。 | | pickLonLat(windowPosition) | null \| { lon, lat } | 将 Cesium 屏幕坐标拾取为地球表面经纬度。 | | setPaused(paused) | UvwWindLayer | 设置粒子动画暂停状态。 | | reset() | UvwWindLayer | 重置粒子位置和生命周期。 | | destroy() | void | 销毁图层创建的 Cesium 资源。 |

数据格式

JSON

JSON 支持纯 JSON 和 JSON + BIN 两种形式。

纯 JSON:

{
  "type": "uvw-grid",
  "width": 2,
  "height": 2,
  "depth": 1,
  "bounds": {
    "west": 110,
    "south": 20,
    "east": 120,
    "north": 30,
    "minHeight": 10000,
    "maxHeight": 10000
  },
  "u": [1, 2, 3, 4],
  "v": [0, 0, 0, 0],
  "w": [0, 0, 0, 0]
}

JSON + BIN:

{
  "type": "uvw-grid",
  "width": 28,
  "height": 22,
  "depth": 10,
  "bounds": {
    "west": 112,
    "south": 18,
    "east": 126,
    "north": 38,
    "minHeight": 20000,
    "maxHeight": 640000
  },
  "layout": "uvw-float32",
  "data": "/data/demo/json/demo-uvw.bin"
}

| 字段 | 必填 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | --- | | type | 否 | "uvw-grid" | 无 | UVW 网格标识。 | | name | 否 | string | "UVW grid" | 数据名称。 | | unit | 否 | string | "m/s" | 数据单位。 | | width | 是 | number | 无 | 经度方向网格数,正整数。 | | height | 是 | number | 无 | 纬度方向网格数,正整数。 | | depth | 是 | number | 无 | 高度方向网格数,正整数。 | | bounds | 是 | object | 无 | 数据经纬度和高度范围。 | | u | 纯 JSON 必填 | array \| typed array | 无 | U 分量。 | | v | 纯 JSON 必填 | array \| typed array | 无 | V 分量。 | | w | 纯 JSON 必填 | array \| typed array | 无 | W 分量。 | | layout | JSON + BIN 必填 | "uvw-float32" | 无 | BIN 布局。 | | data | JSON + BIN 必填 | string | 无 | BIN 文件地址。传 JSON 对象时必须是根路径或绝对 URL。 |

u / v / w 的长度必须等于 width * height * depth,数组顺序为 z -> y -> x,纬度行按北到南排列。

BIN 文件必须是交错 Float32:u0, v0, w0, u1, v1, w1, ...

| sourceOptions 字段 | 必填 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | --- | | baseUrl | 否 | string | 按 JSON URL 推断 | 当 JSON 元数据里的 data 是相对路径时使用。 | | spawnThreshold | 否 | number | undefined | 出生点速度阈值。速度小于等于该值的格点不会作为出生点。 |

NetCDF v3

NetCDF 加载器支持 NetCDF v3 classic 文件,不支持 NetCDF4/HDF5。

await layer.load({
  source: "/data/demo-uvw-v3.nc",
  format: "netcdf",
});

自定义变量名:

await layer.load({
  source: "/data/reanalysis.nc",
  format: "netcdf",
  sourceOptions: {
    variables: {
      u: "uwnd",
      v: "vwnd",
      w: "omega",
      lon: "lon",
      lat: "lat",
      height: "level",
    },
    minHeight: 0,
    maxHeight: 12000,
  },
});

规则:

  • source 必须是 URL 字符串。
  • 必须存在 U 和 V 变量。
  • W 变量可缺省,缺省时按 0 处理。
  • 需要 lon/lat 坐标变量,或者显式传 sourceOptions.bounds
  • 变量维度应为规则网格,常见形式为 (height, lat, lon)

| sourceOptions 字段 | 必填 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | --- | | variables | 否 | object | { u: "U", v: "V", w: "W", lon: "lon", lat: "lat", height: "lev" } | 变量名映射。 | | bounds | 否 | object | 从坐标变量推断 | 显式数据范围。 | | minHeight | 否 | number | 0 | 无高度坐标时的兜底最小高度。 | | maxHeight | 否 | number | max(1, depth - 1) | 无高度坐标时的兜底最大高度。 | | name | 否 | string | 全局 title"NetCDF v3 UVW" | 数据名称。 | | unit | 否 | string | U 变量单位或 "m/s" | 数据单位。 | | spawnThreshold | 否 | number | undefined | 出生点速度阈值。 |

GeoTIFF

GeoTIFF 当前按单高度层读取,即 depth = 1

多波段:

await layer.load({
  source: "/data/uvw.tif",
  format: "geotiff",
  sourceOptions: {
    samples: { u: 0, v: 1, w: 2 },
    minHeight: 10000,
    maxHeight: 260000,
  },
});

分量文件:

await layer.load({
  source: {
    u: "/data/u.tif",
    v: "/data/v.tif",
    w: "/data/w.tif",
  },
  format: "geotiff",
  sourceOptions: {
    minHeight: 10000,
    maxHeight: 260000,
  },
});

规则:

  • 多波段模式需要至少包含 U、V 波段。
  • 分量文件模式必须提供 source.usource.v
  • W 可缺省,缺省时按 0 处理。
  • 如果 GeoTIFF 无法读取地理范围,必须显式传 sourceOptions.bounds
  • bounds 只接受 west / south / east / north,高度通过 minHeight / maxHeight 传。

| sourceOptions 字段 | 必填 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | --- | | samples | 否 | object | 多波段 { u: 0, v: 1, w: 2 };分量文件均为 0 | U/V/W 波段索引。 | | bounds | 条件必填 | object | 从 GeoTIFF 读取 | 地理范围。GeoTIFF 无地理信息时必填。 | | minHeight | 否 | number | 0 | 单高度层最小高度。 | | maxHeight | 否 | number | 1 | 单高度层最大高度。 | | imageIndex | 否 | number | 0 | TIFF image index。 | | name | 否 | string | "GeoTIFF UVW" | 数据名称。 | | unit | 否 | string | "m/s" | 数据单位。 | | spawnThreshold | 否 | number | GeoTIFF nodata 为 0 时默认 0,否则 undefined | 出生点速度阈值。 |

bounds

| 字段 | 必填 | 类型 | 说明 | | --- | --- | --- | --- | | west | 是 | number | 西边界,经度。 | | south | 是 | number | 南边界,纬度。 | | east | 是 | number | 东边界,经度,必须大于 west。 | | north | 是 | number | 北边界,纬度,必须大于 south。 | | minHeight | 是 | number | 最小高度,米。 | | maxHeight | 是 | number | 最大高度,米,必须大于或等于 minHeight。 |