@ aeroswarm/ 天候
地图上的动画天气:风粒子,云,雨/雪,雾和闪电,加上海层(波,海洋)
气流,海平面)。 这需要 AnimationState 生产 @aeroswarm/weather (解码器)
和外地 @aeroswarm/marine,并画出它们。 没有网络访问.
与LuciadRIA、MapLibre/Mapbox GL、Leaflet和CesiumJS(D节)合作.
A. 平面覆盖(2D和3D)
import { animationSnapshot } from "@aeroswarm/weather";
import { createWeatherOverlay } from "@aeroswarm/weather-layer";
const overlay = createWeatherOverlay(map); // transparent canvases on map.domNode
const snapshot = animationSnapshot({ observation: metar, forecast: taf });
if (snapshot) overlay.setState(snapshot.state);
overlay.setVisible(false); // toggle from your layer panel
overlay.setOpacity(0.8);
overlay.destroy();
反应 :
import { useWeatherOverlay } from "@aeroswarm/weather-layer/react";
useWeatherOverlay(map, snapshot?.state, { visible, opacity });
风向沿着地图旋转( NamemapScreenOffset; 覆盖到 getScreenOffset) (中文(简体) ).
封面是地图上的一个画布,所以它不是 map.layerTree: 接线 visible 财务报告和审定财务报表
opacity 到您的层面板。 荣誉 prefers-reduced-motion (画个活框.
B. 实际高度的三维云
import { FeatureLayer } from "@mid/ria/view/feature/FeatureLayer";
import { createCloudLayer3D } from "@aeroswarm/weather-layer";
const clouds = createCloudLayer3D(
{ reference, Feature, FeatureModel, MemoryStore, FeatureLayer, FeaturePainter, createPoint },
{ center: { lat: -7.3798, lon: 112.7869 }, elevationM: 3 },
);
map.layerTree.addChild(clouds.layer);
clouds.setState(snapshot.state);
云高 = 空气田高 + 地上云基(METAR报告AGL). 闪光是
尺寸为米,所以它们有放大和透视的尺度. 仅在地图为 3D 时绘制
(单位:千美元)EPSG:4978除非 only3D: false. RIA 课程通过,所以这个包从不捆绑
自己的RIA副本.
C. 有风的字段(流粒+彩色图)
沿有网状风场的风粒子 以速度为颜色 加上云层的颜色图,
雨或温. 网格可以来自任何地方(参见: @aeroswarm/weather数字 : windGridFromStations
为几个METARs, parseGrib2Json, (中文(简体) ), parseGridJson, (中文(简体) ), stationWindsFromModelPoints) (中文(简体) ).
import { createFieldOverlay, createRiaUnproject, PRECIPITATION_RAMP } from "@aeroswarm/weather-layer";
const unproject = createRiaUnproject(map, { wgs84, createPoint, createTransformation });
const overlay = createFieldOverlay(map, { unproject });
overlay.setWind(windGrid); // particles
overlay.setScalar(cloudGrid); // cloud cover (default ramp)
overlay.setScalar(rainGrid, PRECIPITATION_RAMP); // or rain, temperature, ...
当地图移动时, 字段会被映射到屏幕网格上( 喉咙), 因此粒子读取一个 而不是将每个粒子投射到每个相框上。 地图上没有的点( 3D : 没有风能.
D. 其他地图(地图、叶片、CesiumJS)
软件包核心从不导入地图库 。 一个小地图描述的是 MapAdapter
(单位:千美元)container, (中文(简体) ), unproject(x, y), (中文(简体) ), screenOffset(), (中文(简体) ), onChange(cb)),每张地图都有自适应器
子路径。 适配器只调用您传递的地图对象上的方法, 因此没有额外的安装和
导入 /maplibre 从来没有拉出铯或RIA.
import { createFieldOverlay } from "@aeroswarm/weather-layer";
import { maplibreAdapter } from "@aeroswarm/weather-layer/maplibre"; // also works with Mapbox GL
const overlay = createFieldOverlay(maplibreAdapter(map));
import { leafletAdapter } from "@aeroswarm/weather-layer/leaflet";
const overlay = createFieldOverlay(leafletAdapter(map)); // no rotation unless you pass { bearing }
import { cesiumAdapter } from "@aeroswarm/weather-layer/cesium";
import * as Cesium from "cesium";
const overlay = createFieldOverlay(
cesiumAdapter(viewer, { Cartesian2: Cesium.Cartesian2, Cartographic: Cesium.Cartographic, toDegrees: Cesium.Math.toDegrees }),
);
import { riaAdapter } from "@aeroswarm/weather-layer/ria";
const overlay = createFieldOverlay(riaAdapter(map, { wgs84, createPoint, createTransformation }));
createWeatherOverlay 以同样的方式接受适配器。 旧的 createFieldOverlay(map, { unproject })
呼叫RIA继续工作。 注:在铯上,想念地球的屏幕点没有风;有倾斜的
相机 (MapLibre pitch, Cesium, RIA 3D) 屏幕上的风向是一个近似. 三维云
(B节)仍然只有区域一体化协定.
E. 准备就绪的UI/react-ui(中文(简体) )
反射组件, 这样您就不会自己组装控制器、 覆盖和时间 UI 。 一个 <WeatherLayer>
每个地图;内部的组件读取其状态,因此一页上的两个地图不会被干扰.
import { maplibreAdapter } from "@aeroswarm/weather-layer/maplibre";
import { WeatherLayer, WeatherLayerSwitch, WeatherLegend, WeatherTimeline } from "@aeroswarm/weather-layer/react-ui";
import "@aeroswarm/weather-layer/react-ui/weather-ui.css"; // optional default look
const adapter = useMemo(() => (map ? maplibreAdapter(map) : null), [map]);
<WeatherLayer adapter={adapter} store={store} grid={grid} series={series} locale="id" timeZone="Asia/Jakarta">
<WeatherLayerSwitch />
<WeatherTimeline />
<WeatherLegend />
</WeatherLayer>
| 导出 | 它会做什么 |
|---|---|
WeatherLayer | 挂载覆盖和控制器,提供上下文。 道具 : adapter (或区域影响评估) MapLike + 键 unproject, (中文(简体) ), store, (中文(简体) ), grid, (中文(简体) ), series, (中文(简体) ), blend, (中文(简体) ), locale, (中文(简体) ), timeZone, (中文(简体) ), messages |
WeatherLayerSwitch | 有风 有云 有雨 有温. 全部关闭直到打开; 颜色层是独有的 |
WeatherTimeline | 带有 TAF 周期块、 播放/ 暂停、 “ 现在” 、 窗口( 今天 / 接下来 3 天) 的滑动器 |
WeatherLegend | 活动层颜色条和单位 |
WeatherPreviewTable | 小时值(模型、报告或与报告相混合的模型) |
useWeatherController(), (中文(简体) ), useWeatherSnapshot(station) | 控制器 + 状态,以及显示时间的站点天气 |
windowFor(range, now, timeZone), (中文(简体) ), previewRows(...) | 其背后的纯正功能 |
- 语言数字 :
locale="id"给印度尼西亚文,其他任何英文;将单文本替换为:messages={{ wind: "Wind speed" }}。 。 。 . - 时区: IANA 名称,默认
UTC"今天"是那个区的24小时. - 样式: 不强制位置、大小或布局; 将组件放置在您的布局需要的地方。 类是
前缀
aw-(记录在weather-ui.css颜色来自--aw-*CSS 变量、光和 阴暗. 样式表是可选的,不依赖于Tailwind或任何UI套件. - 可访问性:本地按钮和范围输入,
radiogroup用箭头键,aria-valuetext在滑轮上,WeatherSummary用于屏幕阅读器句子的aria-live, (中文(简体) ),WeatherMotionToggle; 两个默认主题都相会 WCAG AA对比,组件通过轴-核心审计(jsdom,无法检查依赖布局的规则; 未使用真实的屏幕阅读器测试). - 运动: 粒子覆盖如下
prefers-reduced-motion(仍为图像),用户可以恢复运动; 粒子计数会自动滴入慢设备. - React 18+是一种对等依赖,对套件的其余部分是可选的.
F. 海地层和额外数据(流量层、提供者)
除了风,控制器可以画出几个 流层 (随向量字段的粒子)和 颜色层 马上.
| 仁爱 | 日记 | 来源 |
|---|---|---|
| 流动 | wind, (中文(简体) ), current, (中文(简体) ), wave | 气象网、洋流、波浪传播 |
| 颜色 | cloud, (中文(简体) ), rain, (中文(简体) ), temperature, (中文(简体) ), waveHeight, (中文(简体) ), seaLevel | 气候网、海洋网 |
controller.toggleFlowLayer("current"); // also setFlowLayers([...]); state.flows lists the ones on
controller.toggleColorLayer("waveHeight"); // several colour layers can be on together
controller.setLayerOpacity("seaLevel", 0.6);
闪光: LAYER_RAMPS 财务报告和审定财务报表 FLOW_RAMPS (单位:千美元)WAVE_HEIGHT_RAMP, (中文(简体) ), SEA_LEVEL_RAMP, (中文(简体) ), CURRENT_RAMP, (中文(简体) ), WAVE_FLOW_RAMP; 将其中任何一项替换为
<WeatherLayer ramps={{ waveHeight: [...] }}> (停车) [value, r, g, b, alpha?]) (中文(简体) ). 每个流层都有自己的帆布,坡道和运动尺度.
洋流的拉动速度远快于其实际速度,否则将看不到任何动静. WeatherLayerSwitch 接受新层
联 合 国 onChange 也报告 flows。 。 。 .
供应商 带来来自外部天气的田地。 A 类 FieldProvider 实值 { id, range(), fieldsAt(time) }时间范围延长了时间范围,
因此,现有的滑动器并播放按钮动画. @aeroswarm/marine 现成船舶:
import { marineFieldProvider, zoneTimeProvider } from "@aeroswarm/marine";
controller.setProviders([zoneTimeProvider(zones), marineFieldProvider(series)]); // or pass `providers` in the options
G. 将一层切入多边形( 任务)
海地层不得在陆地上作画,其边缘应与海岸相接,而不应是网格平方. setMask 将所选层限制为一组
GeoJSON 风格的多边形(例如: @aeroswarm/marine:
controller.setMask(polygons); // default layers: waveHeight, seaLevel, current, wave
controller.setMask(polygons, ["waveHeight"]); // only these
controller.setMask(null); // remove
- 它使用CSS系统
clip-path在地层画布上,所以 渲染器不支付每帧。 这需要MapAdapter.project,该地图是Libre、Leaflet和 RIA 适配器提供;没有它setMask什么也没做. - 环向风是正常的,所以触摸或相重叠的多边形合并而孔会留有孔(C
normalizeMask, (中文(简体) ),maskClipPath) . - 千个多边形点
clip-path弦长. 如果地图变慢,首先简化多边形. - 当地图在 2D 和 3D 之间切换时重建覆盖; 调用
setMask在新控制器存在后再次打开. - 说对了
fillMarineGaps从@aeroswarm/marine因此海值和多边形边缘之间的条是空白的.
文档
稳定性和版本化政策稳定性.md),使用限制
(单位:千美元)限制)和所测量的性能和大小
(单位:千美元)实绩)与 @aeroswarm/weather; 变化在
变动情况。 。 。 .
限制
METAR和TAF描述了一分(空地). 这部动画是围绕着 机场,不是云雨的真实位置. 没有地形; 唯一的土地被切断 是G区的多边形面具, 你提供。 海地层具有指示性(模型分辨率约为5-10千米),不用于导航.