返回知识库

GIS

综合练习

综合练习 封面
GISengine-webgpu综合练习

前情回顾:本系列已覆盖从坐标系、瓦片、地形、相机、矢量、渲染管线到 3D Tiles 和调优的完整知识链。本篇是收官,将 Phase 1-10 的核心概念编织成一个可落地的 GIS 应用图景——从”能看到地球”到”能交互的 3D 城市”。

直觉问题

看完前 10 篇,你可能在想:

  • 我之前学的知识怎么用在一个真实项目里? Web 墨卡托、四叉树、RTE、Tone Mapping……这些东西是怎么组合起来变成一个能用的产品的?
  • 如果我要做一个”某城市 3D 可视化”,需要哪些模块? 哪些是必需的?哪些是可选的?
  • 不同框架(CesiumJS / Three.js / Mapbox GL JS)应该怎么选? 它们的适用场景和学习曲线有什么区别?

本篇前 10 篇的知识点进行串联,形成一个完整的应用视角

核心概念白话讲

用”做一道菜”理解 GIS 应用构建

构建一个 GIS 应用就像做一道完整的宴席——每种食材(数据)和每道工序(模块)都有它的角色。

做菜步骤GIS 应用模块知识来源
食材准备数据层(影像 / 高程 / 矢量 / 3D 模型)04 影像图层 · 05 地形与 Worker
刀工处理调度层(四叉树 LOD、视锥剔除、Worker 管线)03 四叉树与 LOD
调味上色渲染层(Shader、Tone Mapping、大气散射)08 渲染管线
摆盘出餐交互层(相机控制、拾取、飞行漫游)06 相机与拾取
点缀装盘矢量标绘层(点、线、面、文字、Billboard)07 矢量与实体

真实 GIS 应用的”五大要素”

一个最小可用的 3D GIS 应用必须包含:

  1. 底图(影像瓦片):让用户看到地球表面
  2. 地形(DEM):让地面有起伏,不是平的
  3. 相机(交互):让用户能看、能飞、能缩放
  4. 矢量(标绘):在地图上画点、线、面
  5. 拾取(Picking):用户点击后知道点到了什么

在此基础上可叠加:

原理与数学/机制

1. GIS 应用 7 层架构

一个完整的 GIS 应用从上到下可分为 7 个逻辑层级,每一层只与上下层交互:

┌────────────────────────────────────────也不对现的──────┐
│ 7. 用户体验层    │ 飞行动画、过渡特效、响应式反馈             │
├──────────────────┼──────────────────────────────────────┤
│ 6. UI 层        │ HTML/CSS 叠加面板、信息弹窗、图例控件       │
├──────────────────┼──────────────────────────────────────┤
│ 5. 控件层        │ Drawing / Ruler / ElevationProfile / 测量   │
├──────────────────┼──────────────────────────────────────┤
│ 4. 交互层        │ 鼠标/触摸/键盘事件 → Picking → 派发事件     │
├──────────────────┼──────────────────────────────────────┤
│ 3. 渲染层        │ 8步帧循环 → FBO → Tone Mapping → 屏幕输出   │
├──────────────────┼──────────────────────────────────────┤
│ 2. 调度层        │ 四叉树遍历 → LOD选择 → 瓦片请求 → Worker解码 │
├──────────────────┼──────────────────────────────────────┤
│ 1. 数据层        │ XYZ / WMS / BIL / COG / 3D Tiles / GeoJSON  │
└──────────────────┴──────────────────────────────────────┘

NOTE

第 1–3 层属于引擎核心(通常用 C++/Rust/WebGL 实现),第 4–7 层则是框架封装的 JavaScript API 层。入门学习时,先掌握上层概念,再逐步深入下层原理。

2. 端到端事件流:从点击到弹窗

用户点击地球上一个点到弹出信息框,经历了哪些关键步骤?

flowchart LR
    A[用户点击屏幕 x,y] --> B[射线从相机发出\n进入 Picking FBO]
    B --> C[读取 x,y 像素颜色]
    C --> D[颜色编码 → Entity ID]
    D --> E[查询 Entity 属性表]
    E --> F[派发 click 事件]
    F --> G[UI 层渲染弹窗]
    G --> H[用户看到信息框]

关键用到 Phase 06 相机与拾取中的 Picking 原理:每个 Entity 分配唯一 RGB 颜色,写入独立 FBO,鼠标处颜色直接解码为 ID

3. 坐标变换链:用户输入到屏幕像素的完整路径

GIS 应用中最频繁的操作之一是”用户输入了一个经纬度,屏幕上该显示在哪里”。这背后是一整串坐标变换:

WGS84 经纬度 (λ, φ, h)


WGS84 椭球 → ECEF 地心地固直角坐标 (X, Y, Z)


多视锥 RTE 高精度矩阵变换


投影矩阵 → NDC 归一化设备坐标 (x, y, z, w)


视口变换 → 屏幕像素坐标 (px, py)

其中精度处理是关键难点:

  • 近景下,相机与目标距离很近,差异很小时,用 32 位浮点会丢失精度(见 06 相机与拾取中 RTE 推导)
  • 远景下,相机退到太空,地球整体缩成小球,此时需切换视锥(01 第一帧多视锥角色)

4. Phase 知识索引

功能模块涉及核心知识点对应笔记
坐标转换WGS84 → ECEF → 屏幕像素;Web 墨卡托投影02 坐标与投影
瓦片加载四叉树、LOD、SSE 选择策略、视锥/地平线剔除03 四叉树与 LOD
影像叠加XYZ/WMS/WMTS、多纹理混合、OGC 标准04 影像图层
地形渲染DEM、RGB/BIL 高程编码、Geoid、Worker 管线05 地形与 Worker
相机交互RTE 高精度、多视锥、Picking FBO、Slerp 飞行06 相机与拾取
矢量标绘ECS、GPU 实例化、Billboard、MSDF 字体07 矢量与实体
大气/光照Rayleigh/Mie 散射、Tone Mapping、HDR08 渲染管线
城市模型3D Tiles 标准、BVH 空间索引、地理锚定变换09 3D Tiles 与 BIM
性能优化LRU 缓存、帧预算、GPU 分析与工具链10 调优手册

5. 飞行动画的数学原理

相机从 A 点飞向 B 点的过程不是简单的线性插值,而是球面线性插值(Slerp)

设 A、B 是单位球面上的两个三维向量(已归一化),插值参数 t ∈ [0, 1]

Slerp(A,B,t)=\susin((1t)θ)sinθcdotA+sin(tθ)sinθcdotBSlerp(A, B, t) = \frac{\su sin((1-t)\theta)}{\sin \theta} \\cdot A + \frac{\sin(t\theta)}{\sin \theta} \\cdot B

其中 θ = arccos(A·B) 是两点夹角。

TIP

为什么要用 Slerp?因为线性插值在球面上会产生”内凹弧线”,穿过地球内部。Slerp 保证插值轨迹沿大圆最短路径,飞行更符合直觉,不会穿地。

飞行路径还包含 ease-in 和 ease-out 曲线,让速度先加速后减速:

速度

 │      ╱╲
 │     ╱  ╲
 │    ╱    ╲
 │   ╱      ╲
 │  ╱        ╲
 │ ╱          ╲
 └─────────────▶ 时间
   加速    减速

6. 完整 GIS 应用的初始化流水线

flowchart TD
    A[初始化场景] --> B[加载底图瓦片]
    A --> C[加载地形数据高程]
    B --> D[建立四叉树索引]
    C --> D
    D --> E[首帧渲染]
    E --> F[激活相机控制器]
    F --> G[启用 Picking]
    G --> H[进入交互运行态]
    H --> I[渲染每一帧更新]
    I --> J[异步瓦片加载与调度]
    J --> I

对应的模块协作关系:

阶段主导模块依赖知识核心任务
阶段 1 初始化Scene全局配置创建 Renderer、Camera、SceneGraph
阶段 2 数据加载DataLoader瓦片编码、Worker并行请求 XYZ/DEM/矢量数据
阶段 3 索引建立Quadtree四叉树、LOD构建空间索引,分级加载
阶段 4 首帧渲染Rendering Engine8 步帧循环渲染底图、地形、大气
阶段 5 交互就绪InteractionPicking、事件绑定鼠标/键盘/触摸控制器
阶段 6 运行态Main Loop帧预算、资源调度持续更新瓦片、相机、Entity

可视化对比与动手实验

实验 1:5 个典型应用场景

场景必需模块可选模块推荐框架
城市 3D 可视化底图 + 地形 + 3D Tiles大气散射、Tone MappingCesiumJS
路径规划导航底图 + 矢量线 + 相机控制实时交通路况Mapbox GL JS
人口密度热力图底图 + 热力图层时间轴动画deck.gl
航天态势感知底图 + 轨道线 + 3D 模型大气光照、阴影CesiumJS
室内精细导航矢量 + 地板分层 + 相机3D Tiles BIM + 剖切Three.js

实验 2:必需 vs 可选模块

模块必需/可选说明
底图渲染必需没有底图用户啥也看不到
地形高程可选平原地区可省略,05 地形讲清 Geoid 与椭球面差异
相机控制必需没有相机,无法交互浏览
矢量标绘可选纯浏览场景可省略
Picking 拾取可选不需要点击交互可省略
3D Tiles可选没有精细城市模型可省略
大气散射可选Rayleigh/Mie 仅游戏级渲染需要
Tone Mapping可选HDR 到 LDR 映射,高画质场景需要
Anti-aliasing可选边缘锯齿不明显时可省略
水面效果可选仅涉及水域场景需要额外实现

实验 3:框架选型决策树

是否需要 3D 地球视角?
  ├── 是 → 需要 3D Tiles 或 BIM 集成?
  │       ├── 是 → CesiumJS(原生支持 OGC 3D Tiles 标准)
  │       └── 否 → Three.js + 地球球体插件(高度可定制)
  └── 否 → 需要海量大数据可视化?
          ├── 是 → deck.gl(GPU 加速聚合渲染)
          └── 否 → 需要严格 OGC 标准支持?
                  ├── 是 → OpenLayers(政企标准首选)
                  └── 否 → Mapbox GL JS(移动端流畅体验)

实验 4:主流 GIS 框架能力均衡图

用「3D 地球能力」和「数据规模能力」两个维度来看各框架的定位:

  3D 地球能力


  极高  │   CesiumJS ★
       │            │
  高   │            │    Three.js
       │            │      ·
  中   │   OpenLayers      │
       │      ·           │
  低   │   Mapbox    deck.gl

       └────────────────────────────────▶ 数据规模
           低       中        高       极高

TIP

CesiumJS 是唯一同时覆盖”3D 地球 + 大数据”双象限的成熟框架,但也最重。 Three.js 更灵活但需自行组装地球、瓦片、相机等模块。 选择框架的核心准则是:先做减法——列出”绝对不可少的功能”,再找最小满足条件的框架

常见误区

WARNING

误区 1:综合 demo 必须包含 3D Tiles 基础”底图 + 地形 + 矢量”已是完整可交互应用。3D Tiles 是锦上添花,不是必需品。很多场景(如城市公交查询、行政区划浏览)根本不需要精细建模。

WARNING

误区 2:所有功能都从轮子造起 GIS 框架(CesiumJS / Mapbox GL JS)已经封装了大量底层工作,如瓦片调度、相机控制、Picking、坐标转换。你的精力应放在业务逻辑和数据上,而不是从零写四叉树和投影计算。

WARNING

误区 3:demo 越大越好 简洁的 demo 更有教学价值。一个只含”底图 + 相机 + 一个标记点”的 demo,比一个包含 10 个功能的臃肿 demo 更能让人快速理解核心原理。

WARNING

误区 4:CesiumJS = 唯一选择 不同场景匹配不同框架。城市 3D 可视化选 CesiumJS,移动端地图导航选 Mapbox GL JS,大数据可视化选 deck.gl,完全定制化自由渲染选 Three.js。

WARNING

误区 5:Slerp 飞行 = 万能相机运动 Slerp 只保证大圆最短路径,不解决碰撞检测。如果飞行路径穿入地下或建筑内部,需要在插值轨迹上做地形/碰撞避让。实际产品中,先在地面上方保留安全高度,再应用 Slerp。

延伸阅读与自测

延伸阅读

  1. CesiumJS Tutorials — 最系统的 3D GIS 框架教程,涵盖从入门到 3D Tiles 的完整学习路径:https://cesium.com/learn/
  2. deck.gl Documentation — 大数据可视化首选,通过 GPU 聚合 10^6+ 点数据:https://deck.gl/
  3. Mapbox GL JS — 移动端地图开发指南,矢量切片渲染引擎:https://docs.mapbox.com/mapbox-gl-js/
  4. OpenLayers — 2D 标准地图框架,OGC 标准支持最完整:https://openlayers.org/
  5. OGC 3D Tiles Specification — 官方标准文档,理解 3D 瓦片组织的权威参考

自测题

1. 设计题

假设你是一个三线城市的智慧交通项目技术负责人,需要构建一个”实时公交监控”系统(在地图上显示所有公交车的实时位置和行驶路线),你会选择哪个框架?为什么?列出必需模块可选模块

2. 流程题

用户在地图上点击一个公交站点(Entity),弹窗显示站点信息。画出从”点击”到”弹窗”的完整事件流,并标出每个步骤对应到 Phase 1-10 的知识点。

3. 方案对比

CesiumJS 和 Mapbox GL JS 的核心区别是什么?分别列出 3 个 CesiumJS 更适合的场景3 个 Mapbox GL JS 更适合的场景。提示:从”投影方式、数据规模、性能开销、移动端支持”四个维度分析。

4. 数学计算

设相机在单位球面上从 A 点到 B 点,其中 A = (0, 0, 1)B = (1, 0, 0),参数 t = 0.25

  • 先用线性插值计算中间点 P_linear
  • 再用Slerp计算中间点 P_slerp
  • 比较两个结果,解释为什么 Slerp 不会穿入地球内部

5. 架构题

设计一个支持 10 万用户同时在线的全球气象监控系统,核心需求包括:

  • 实时的全球卫星云图覆盖
  • 用户可以在任意位置叠加本地气象站数据(矢量点、温度/湿度图表)
  • 支持 VR 模式(沉浸式地球浏览体验)

请回答:

  • 技术栈选什么框架?为什么?
  • 瓦片数据源如何组织?如何处理高并发下的缓存?
  • 全球气象站数据如何索引和渲染?(提示:思考点聚类和 LOD 策略)
  • VR 模式下,Picking 和相机控制需要做哪些特殊处理?

下一篇导引:本系列至此完结。建议按照 00 阅读指南 中的学习路径,根据自身掌握程度查漏补缺。如果你要入门 GIS 应用开发,推荐的动手路径是:CesiumJS Hello World → 叠加底图 → 加载 DEM 地形 → 添加简单 Entity → 实现飞行动画 → 接入 3D Tiles。每一步都有对应的笔记知识点支撑,祝你学习顺利!