十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

deck.gl 非地理视口(Non-Geospatial Viewports)设计解析:从 v3 单一 Viewport 到 v4 视口类层次

deck.gl 非地理视口(Non-Geospatial Viewports)设计解析:从 v3 单一 Viewport 到 v4 视口类层次 deck.gl 非地理视口Non-Geospatial Viewports设计解析从 v3 单一 Viewport 到 v4 视口类层次【免费下载链接】deck.glWebGL2 powered visualization framework项目地址: https://gitcode.com/GitHub_Trending/de/deck.gl导读本篇文章以 deck.gl 历史上第一份 RFC——《Viewport Support for Infovis》dev-docs/RFCs/v4.0/non-geospatial-viewports-rfc.md为核心梳理 deck.gl 从 v3 面向地图的单一Viewport类演进为 v4 支持通用信息可视化infovis的视口类层次的设计动因、提案内容与最终落地形态。读者将掌握Viewport、OrthographicViewport、OrbitViewport等非地理视口的职责划分、核心参数语义以及它们在当前仓库源码中的实际实现从而能够在自己的数据可视化应用中正确选择与配置视口。一、RFC 背景v3 Viewport 的地理强耦合问题该 RFC作者 Ib Green日期 2016 年 12 月 7 日状态为Approved and Implemented明确指出deck.gl v3 时代的Viewport类在面向地图渲染时设计合理但对于通用的信息可视化如 3D 点云嵌入、散点图、网络图等非地图场景存在四类根本性问题参数强制地理化当时的Viewport总是期望longitude和latitude参数这对于与地图无关的可视化毫无意义。视图创建参数受限视图必须以lng、lat、zoom、pitch、bearing、altitude等参数创建。这些参数在存在明确地面的地图场景中很自然但对通用 3D 可视化例如 3D 点云嵌入却过于拘束也加大了事件处理等接口的编写难度。坐标系假设僵化当时的Viewport假设 layer 中的位置坐标x、y、z是墨卡托坐标或米制偏移量。除去墨卡托变换初始非线性部分的复杂性这还隐含了关于世界尺寸512 * zoom ^ 2的假设与通用数据集完全不匹配。浮点精度隐患RFC 提醒设计者在设计视口坐标系时容易直接挑选最优雅或最自然的坐标系例如 0-1 归一化但必须在着色器中校验此类选择带来的浮点精度影响。二、核心提案拆分为三层的 Viewport 类层次RFC 的核心提案是将当时的单一Viewport类拆分为三个类。三者都可与 deck.gl 配合使用并共享部分代码但面向应用暴露不同的接口类定位关键输入参数BaseViewport完全通用、线性的视口直接与矩阵打交道width、height、worldMatrix、projectionMatrix、viewMatrixScaledViewport通用线性视口但从center/zoom等参数计算 view 与 projection 矩阵centerX、centerY、zoom、altitude、pitch、bearingMercatorViewport在通用视口之上叠加非线性的 Web Mercator project/unprojectlng、lat、zoom内部转换为centerX、centerY、scaleRFC 中的原始构造示例// BaseViewport 工作于 [0,1] 世界坐标系可使用任意标准矩阵 new BaseViewport({ width, // 窗口宽度像素用于像素投影 height, // 窗口高度像素 worldMatrix, // 定义坐标系 projectionMatrix, viewMatrix, }); // ScaledViewport 接收 center、zoom、pitch、bearing 等参数 // 由此计算 ViewMatrix 与 ProjectionMatrix仍允许应用设置 worldMatrix 与 modelMatrix new ScaledViewport({ width, height, worldMatrix, centerX, centerY, // 当前中心点0-1 坐标或 worldMatrix 坐标 zoom, altitude, pitch, bearing, }); // MercatorViewport 增加非线性的 WebMercator project/unproject new MercatorViewport({ lng, lat, zoom, // 内部转换为 centerX、centerY、scale });从分层设计上看BaseViewport只关心纯矩阵运算ScaledViewport在此基础上引入相机语义中心点、缩放、俯仰、方位MercatorViewport再引入地理投影。层次越低越通用层次越高越贴近地图应用。三、RFC 的补充设计考量3.1 Model Matrix 支持RFC 提议为BaseViewport.getMatrices调用增加modelMatrix参数视口将modelMatrix右乘进组合矩阵中。这一机制对所有 Viewport 类均适用。在今天的源码中该设计已沉淀为基础Viewport的可选属性modelMatrix作为视口中心的模型矩阵参与矩阵链计算见 viewport.ts。3.2 对着色器的影响视口与 deck.gl 着色器的交互主要通过 uniform 完成。即 layer 顶点着色器中使用的投影 uniformview/projection 组合矩阵等由视口计算并提供视口类型的变化只影响 uniform 的取值而不改变着色器结构本身。四、落地形态v4 及以后的真实实现RFC 备注明确说明该提案以不同的类层次结构作为 deck.gl v4 的一部分实现。当前仓库中modules/core/src/viewports/目录下的实际类层次为Viewport // 通用基类等价于提案中的 BaseViewport ScaledViewport ├── WebMercatorViewport // 地理视口等价于提案中的 MercatorViewport ├── OrthographicViewport // 非地理正交投影视口2D 图表 ├── OrbitViewport // 非地理环绕目标点的 3D 相机视口 ├── FirstPersonViewport // 非地理第一人称视角 └── GlobeViewport // 地理三维球体视口可见提案中的三分类最终收敛为一个通用基类 若干地理/非地理专用子类而非严格复制BaseViewport / ScaledViewport / MercatorViewport的三层结构。4.1 基础 Viewport非地理能力的判定在 viewport.ts 中基础Viewport类通过一个关键判定区分地理与非地理视口const {longitude, latitude} opts; this.isGeospatial Number.isFinite(latitude) Number.isFinite(longitude);当未传入合法的经纬度时isGeospatial为false视口即处于非地理模式。这一判定直接驱动两个重要行为投影模式get projectionMode()见 viewport.ts地理视口在zoom 12时使用WEB_MERCATOR否则使用WEB_MERCATOR_AUTO_OFFSET非地理视口一律使用PROJECTION_MODE.IDENTITY即不做任何墨卡托变换直接使用线性坐标。非线性投影钩子projectFlat/unprojectFlat见 viewport.ts地理视口调用lngLatToWorld/worldToLngLat执行墨卡托非线性投影非地理视口则原样返回坐标。这正是 RFC 中MercatorViewport增加非线性的 Web Mercator project/unproject的现代表达——非线性能力被收敛为可覆写的钩子方法基类默认保持线性。此外基础Viewport的构造参数与 RFC 中BaseViewport的设想高度吻合支持直接传入viewMatrix与projectionMatrix自定义矩阵也支持通过orthographic、fovy、focalDistance、near、far、padding等参数由内部生成投影矩阵见 viewport.ts 与_initMatrices实现 viewport.ts。当未提供projectionMatrix时正交投影使用Matrix4().orthographic(...)透视投影使用Matrix4().perspective(...)padding则通过平移投影矩阵实现中心偏移。4.2 OrthographicViewport2D 非地理可视化的默认选择对于散点图、柱状图、热力图等 2D 非地理可视化RFC 所设想的通用、线性、可直接使用矩阵的视口在当代 deck.gl 中最直接的对应物是OrthographicViewportorthographic-viewport.ts。其关键设计强制非地理构造函数中显式传入longitude: undefined并注释说明确保基础 Viewport 类不会将其当作地理视口处理见 orthographic-viewport.ts。正交投影矩阵由getProjectionMatrix基于窗口宽高与near默认0.1、far默认1000构建左右对称的正交矩阵padding同样以像素偏移作用于矩阵边界orthographic-viewport.ts。坐标语义zoom: 0时 1 个单位距离对应屏幕上 1 像素zoom每增加 1同一对象放大一倍默认target为[0, 0, 0]flipY默认true控制使用左上角还是左下角坐标系orthographic-viewport.ts。X/Y 独立缩放支持zoomX/zoomY分别控制两个轴的缩放级别这是数据可视化中不等比缩放例如宽屏散点图拉伸的实用能力通过自定义distanceScales与覆写projectFlat/unprojectFlat实现orthographic-viewport.ts。与之配套的视图类OrthographicVieworthographic-view.ts在OrthographicViewState中进一步提供target、zoom、zoomX/zoomY、minZoom/maxZoom、flipY等完整状态参数并通过OrthographicController提供拖拽平移与滚轮缩放交互。官方文档 orthographic-view.md 将其定位为自上而下观察 XY 平面通常用于非地理场景下的 2D 图表渲染。4.3 OrbitViewport3D 非地理可视化的默认选择对于三维数据点云、网络图、分子结构等RFC 提到的3D 点云嵌入等通用 3D 可视化场景由OrbitViewportorbit-viewport.ts承担。其定位是围绕目标点旋转的 3D 相机。关键设计相机构造通过lookAt构建视图矩阵相机位于[0, -focalDistance, 0]orbitAxis: Z或[0, 0, focalDistance]orbitAxis: Y配合rotationX绕 X 轴旋转角与rotationOrbit绕轨道轴旋转角实现环绕orbit-viewport.ts。像素映射保证代码注释明确说明相机距离的设定使目标处 1 个 common space 单位对应 1 个屏幕像素与 web mercator 投影采用同类技术从而允许在顶点着色器中高效地在 common space 与屏幕空间之间换算尺寸orbit-viewport.ts。参数语义orbitAxis仅支持Y或Z默认Zfovy默认 50 度透视投影orthographic默认falsenear/far默认0.1/1000orbit-viewport.ts。同样强制非地理构造函数中同样传入longitude: undefinedorbit-viewport.ts确保不触发地理模式。配套的OrbitVieworbit-view.ts在OrbitViewState中提供target、zoom、rotationOrbit、rotationX、minRotationX默认 -90/maxRotationX默认 90等状态参数。官方文档 orbit-view.md 明确其用途为非地理场景下对 3D 场景的检视。五、从 View 到 Viewport应用侧的使用方式现代 deck.gl 中应用一般不直接实例化 Viewport而是通过更高层的View子类如OrthographicView、OrbitView、MapView声明相机由 Deck 实例在每一帧根据viewState自动创建对应的 Viewport 并计算投影矩阵。View基类view.ts负责解析x/y/width/height支持相对百分比、padding、controller等布局与交互选项并通过抽象方法getViewportType/ControllerType关联到具体的 Viewport 与控制器类型。一个典型的非地理应用示例2D 正交视图 环绕 3D 视图的 viewState 形态// OrthographicView 的 viewState { target: [0, 0, 0], // 视口中心的世界坐标 zoom: 0, // zoom 0 时 1 单位 1 像素 // 可选zoomX / zoomY 独立轴缩放 } // OrbitView 的 viewState { target: [0, 0, 0], zoom: 0, rotationOrbit: 0, // 绕轨道轴的旋转角度 rotationX: 0, // 绕 X 轴的旋转角度范围默认 -90 ~ 90 }View的通用属性id、x、y、width、height、padding、clear、controller等对所有视图类型一致见 view.ts 与 deck.md 中关于deck.gl 同时提供面向地理与非地理场景的多种视图类型的说明。六、总结这份 RFC 留下的设计遗产回看这份 deck.gl 的第一份 RFC其影响延续至今非地理视口成为一等公民isGeospatial判定、PROJECTION_MODE.IDENTITY与projectFlat/unprojectFlat钩子使同一套 layer/shader 体系能同时服务地图与纯数据可视化。矩阵与相机语义分离基础Viewport既接受外部viewMatrix/projectionMatrix也能从zoom/fovy/orthographic等参数推导矩阵——这正是 RFC 中BaseViewport与ScaledViewport两层职责的合并实现。线性坐标优先非线性作为扩展墨卡托投影被封装为地理视口特有的可覆写行为通用视口保持线性从根本上解决了 RFC 指出的世界尺寸假设不适用于通用数据集的问题。对于需要在 deck.gl 中构建非地图类可视化的开发者OrthographicView2D 图表与OrbitView3D 场景检视就是这份 RFC 直接催生的落地成果二者共享同一套矩阵计算与着色器协议可在同一 Deck 实例中与其他视图混合使用。延伸阅读RFC 原文dev-docs/RFCs/v4.0/non-geospatial-viewports-rfc.md基础视口实现modules/core/src/viewports/viewport.ts非地理视口实现orthographic-viewport.ts、orbit-viewport.ts视图类实现orthographic-view.ts、orbit-view.ts官方 API 文档orthographic-view.md、orbit-view.md、view.md开发者指南developer-guide/views.md【免费下载链接】deck.glWebGL2 powered visualization framework项目地址: https://gitcode.com/GitHub_Trending/de/deck.gl创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表