OSGearth城市可视化功能详解
本文详细解析了 3D 城市可视化中 12 个核心功能的实现原理与应用场景
目录
- [鹰眼(Mini-map / Overview Camera)](#鹰眼(Mini-map / Overview Camera))
- [城市(City Generation / Building System)](#城市(City Generation / Building System))
- [漫游(Roaming / Fly-Through)](#漫游(Roaming / Fly-Through))
- [经纬线(Latitude/Longitude Grid)](#经纬线(Latitude/Longitude Grid))
- [坡度分析(Slope Analysis)](#坡度分析(Slope Analysis))
- [飞线(Flow Lines / Arc Lines)](#飞线(Flow Lines / Arc Lines))
- [动态纹理(Dynamic Textures)](#动态纹理(Dynamic Textures))
- [卫星模拟(Satellite Simulation)](#卫星模拟(Satellite Simulation))
- [航拍模拟(Aerial Photography Simulation)](#航拍模拟(Aerial Photography Simulation))
- [绘制坐标点(Point Drawing)](#绘制坐标点(Point Drawing))
- [绘制图形(Shape Drawing)](#绘制图形(Shape Drawing))
- [下雪(Snow Effect)](#下雪(Snow Effect))
- [剖面分析(Section / Profile Analysis)](#剖面分析(Section / Profile Analysis))
1. 鹰眼(Mini-map / Overview Camera)
实现原理
鹰眼功能本质是一个独立的小地图渲染系统,主要步骤:
- 创建独立摄像机:在场景正上方设置一个俯视摄像机,位置固定在高空(如 y = 100)
- 独立渲染器:创建小尺寸的 WebGLRenderer(如 200×200),覆盖在主窗口角落
- 位置同步:小地图摄像机跟随主摄像机在 XZ 平面的位置,保持俯视视角
- 标记绘制:在小地图上用不同颜色的点或图标标记主摄像机位置和朝向
核心技术
- 双渲染器(Multi-Renderer)
- 摄像机位置同步(Camera Position Sync)
- Mini-map 标记(CSS2DRenderer 或 Sprite)
应用场景
- 导航辅助:在大场景中快速定位自身位置
- 城市漫游辅助:实时显示摄像机在城市中的相对位置
- 游戏/模拟器:战略地图、雷达图

2. 城市(City Generation / Building System)
实现原理
城市生成通常分为程序化生成 和数据驱动两种方式:
- 地块划分:将城市区域划分为若干街区(Block),每个街区有尺寸和位置属性
- 建筑生成 :在每个街区内随机放置建筑,参数包括:
- 宽度/深度(5~25 单位)
- 高度(10~80 单位,产生天际线变化)
- 颜色(HSL 色相变化)
- 纹理细节 :
- 使用 Canvas 生成窗户纹理(随机亮暗表示灯光)
- 建筑贴图(LOD 多级细节)
- 性能优化 :
- InstancedMesh 批量渲染同类型建筑
- LOD(Level of Detail)远距离简化
- Frustum Culling 视锥裁剪
核心技术
- BoxGeometry / InstancedMesh
- CanvasTexture 程序化纹理
- LOD 多级细节
- 随机化算法
应用场景
- 数字孪生城市:智慧城市可视化
- 城市规划:建筑密度、天际线仿真
- 游戏开放世界:程序化城市生成

3. 漫游(Roaming / Fly-Through)
实现原理
- 路径定义:设置一系列路点(Waypoints),每个路点包含位置(Position)和注视点(LookAt)
- 插值运动:在两路点之间进行线性插值或贝塞尔曲线插值
- 摄像机控制 :
- 位置插值:
camera.position.lerpVectors(current, next, progress) - 朝向插值:
camera.lookAt(lookTarget)
- 位置插值:
- 路径类型 :
- 直线路径(线性插值)
- 曲线路径(Catmull-Rom / Bezier 曲线)
- 环绕路径(Orbit Controls 自动旋转)
核心技术
- 线性插值(Lerp)
- CatmullRomCurve3 曲线路径
- 摄像机动画系统
- Tween.js / GSAP 动画库
应用场景
- 城市宣传片:自动生成的飞行游览路径
- 建筑漫游:室内/室外漫游展示
- 游戏过场动画:脚本化摄像机运动

4. 经纬线(Latitude/Longitude Grid)
实现原理
-
纬线(Latitude Lines):
- 在球面上沿纬度方向(φ)等间距取点
- 每个纬度圈的水平圆周由 64+ 个顶点构成
- 通过
sin(φ)*cos(θ),cos(φ),sin(φ)*sin(θ)计算顶点位置
-
经线(Longitude Lines):
- 在球面上沿经度方向(θ)等间距取点
- 每条经线是从南极到北极的弧线
-
视觉效果:
- 赤道线高亮(不同颜色/粗度)
- 透明度区分(经线透明度低于纬线)
- 可点击交互(拾取经纬度坐标)
核心技术
- SphereGeometry 参数化
- BufferGeometry.setFromPoints()
- LineBasicMaterial(透明度/颜色区分)
应用场景
- 地球/星球可视化:经纬度参考网格
- 气象数据展示:全球数据分析
- 卫星轨道模拟:定位参考系统

5. 坡度分析(Slope Analysis)
实现原理
坡度分析通过计算地形三角面的法向量与水平面的夹角来实现:
-
法向量计算:
edge1 = v2 - v1 edge2 = v3 - v1 normal = edge1 × edge2(归一化) -
坡度角度:
angle = acos(|normal · up|) slope = angle * 180 / π -
分级着色(两种实现方式):
CPU 方式:
- 遍历所有三角面,计算坡度
- 按坡度分级赋予颜色(绿→黄→橙→红)
GPU 方式(Shader):
- 在顶点着色器中计算法向量
- 在片元着色器中实时计算坡度并着色
- 性能更高,支持实时更新
坡度分级标准
| 坡度范围 | 颜色 | 等级 | 描述 |
|---|---|---|---|
| 0°~5° | 绿色 #22cc44 | Ⅰ级 | 平坦 |
| 5°~15° | 黄色 #cccc22 | Ⅱ级 | 缓坡 |
| 15°~30° | 橙色 #cc6622 | Ⅲ级 | 陡坡 |
| >30° | 红色 #cc2222 | Ⅳ级 | 极陡 |
应用场景
- 地形分析:建筑用地适宜性评估
- 道路规划:选线方案比选
- 地质灾害评估:滑坡风险区域识别

6. 飞线(Flow Lines / Arc Lines)
实现原理
飞线用于表示两点之间的数据流动,核心是弧形轨迹 + 动态流动效果:
-
弧线生成:
- 起点(startPos)和终点(endPos)
- 计算中点:
mid = (startPos + endPos) / 2 - 弧高控制:
mid.y += distance * 0.3 - 使用 QuadraticBezierCurve3 生成贝塞尔曲线
-
流动动画:
- CPU 方式:更新顶点透明度,形成光点沿路径移动的效果
- GPU 方式(Shader) :
- 使用
aProgress属性表示每个顶点在路径上的进度 - 片元着色器中计算流动位置:
flowPos = mod(vProgress + time * speed, 1.0) - 亮度随流动位置变化,产生拖尾效果
- 使用
-
多线渲染优化:
- 使用 LineSegments 批处理
- 颜色编码(不同数据类别使用不同颜色)
核心技术
- QuadraticBezierCurve3(贝塞尔弧线)
- ShaderMaterial 流动效果
- 透明度混合(AdditiveBlending)
应用场景
- 数据流向可视化:人口迁移、物流路线
- 网络拓扑展示:通信数据流
- 交通流量:航线、车流轨迹

7. 动态纹理(Dynamic Textures)
实现原理
动态纹理是通过实时更新纹理内容实现的视觉效果:
方式一:Canvas 纹理
- 创建 HTML Canvas 元素
- 使用 Canvas 2D API 绘制内容
- 创建
THREE.CanvasTexture(canvas) - 在动画循环中更新 Canvas 内容并设置
texture.needsUpdate = true
方式二:Video 纹理
- 创建 HTML Video 元素,加载视频源
- 创建
THREE.VideoTexture(video) - 视频自动播放,纹理实时更新
方式三:DataTexture(像素级操作)
- 创建
THREE.DataTexture(data, width, height) - 直接操作像素缓冲区(Uint8Array)
- 适用于粒子系统、噪声生成等
动态纹理类型示例
| 类型 | 实现方式 | 更新频率 |
|---|---|---|
| 水波纹 | Canvas 绘制椭圆弧线 | 每帧更新 |
| 建筑灯光 | 像素级随机闪烁 | 每帧更新 |
| 信息流动 | Canvas 绘制移动文字/图形 | 每帧更新 |
| 视频播放 | VideoTexture | 视频帧率 |
应用场景
- 水面/流体模拟:实时水纹理
- 信息展示屏:数据大屏动态内容
- 特效制作:动态光效、LED屏幕

8. 卫星模拟(Satellite Simulation)
实现原理
地球模型
- 球体创建 :
SphereGeometry(radius, 64, 64) - 纹理映射:地表贴图 + 法线贴图 + 高光贴图
- 大气层 :
- 略大于地球的半透明球体(radius × 1.02)
- Shader 实现边缘发光效果(Fresnel 效应)
- 混合模式:
AdditiveBlending
卫星轨道
-
轨道参数:
- 半长轴(a)、偏心率(e)
- 轨道倾角(i)、升交点赤经(Ω)
- 真近点角(θ)
-
轨道计算:
r = a * (1 - e²) / (1 + e * cos(θ)) x = r * cos(θ) z = r * sin(θ) // 应用倾角和升交点赤经旋转 -
卫星模型:
- 主体(BoxGeometry)
- 太阳能板(两侧展开)
- 朝向运动方向(Quaternion 旋转)
动画逻辑
- 卫星沿轨道点移动
- 位置插值平滑运动
- 速度可配置(不同卫星不同速度)
应用场景
- 航天任务可视化:卫星轨道模拟
- 天基观测:卫星覆盖区域分析
- 教育科普:轨道力学教学

9. 航拍模拟(Aerial Photography Simulation)
实现原理
无人机模拟
- 三维模型:机身 + 旋翼臂(简化模型)
- 飞行路径 :
- 环绕飞行(Orbit):圆心 + 半径 + 高度
- 航线飞行(Waypoints):预设路径点
- 自由飞行(Free):用户控制
摄像机参数模拟
- 焦距(focalLength):模拟真实相机镜头
- 地面采样距离(GSD)= (高度 × 传感器宽度) / (焦距 × 1000)
- 快门速度:影响运动模糊
- ISO:模拟噪声效果
视觉效果
- 大气雾效 :
FogExp2模拟空气透视 - 摄像机抖动:添加微小随机偏移,模拟真实航拍
- 光晕/眩光:镜头光晕效果(Lens Flare)
应用场景
- 影视预可视化:航拍镜头规划
- 测绘模拟:无人机航测路径规划
- 游戏/VR:飞行体验

10. 绘制坐标点(Point Drawing)
实现原理
屏幕坐标转世界坐标
-
射线检测(Raycaster):
javascriptmouse.x = (event.clientX / width) * 2 - 1 mouse.y = -(event.clientY / height) * 2 + 1 raycaster.setFromCamera(mouse, camera) raycaster.ray.intersectPlane(groundPlane, intersectPoint) -
地面平面检测:与水平面(y=0)求交
标记点的三种实现方式
| 方式 | 优势 | 劣势 |
|---|---|---|
| Sprite(精灵) | 始终面向摄像机,性能好 | 不能立体显示 |
| 3D 几何体(Cone/Sphere) | 立体感强,可加光照 | 远距离变小 |
| CSS2DRenderer | 可渲染 HTML 标签,交互性强 | 渲染层分离 |
标记功能
- 脉冲动画 :
scale = 1 + sin(time) * 0.2实现呼吸效果 - 颜色编码:不同类别使用不同颜色
- 文本标签:使用 CSS2DRenderer 或 Sprite 显示文字
应用场景
- 地图标注:POI 点标记
- 数据可视化:事件位置标记
- 测量工具:坐标采集
11. 绘制图形(Shape Drawing)
实现原理
多边形绘制
-
交互绘制:
- 鼠标点击收集顶点
- 实时预览当前绘制状态
- 双击/右键完成绘制
-
3D 几何体生成:
Shape(2D轮廓)→ ExtrudeGeometry(挤压成3D) → 旋转至水平(rotation.x = -π/2) → 设置透明度填充 -
边框绘制:
- 将顶点连接为 LineLoop
- 可设置不同颜色和粗细
图形类型
| 类型 | 实现方式 | 应用 |
|---|---|---|
| 矩形 | 对角两点定义 | 选择框、区域标注 |
| 圆形 | 圆心+半径 | 缓冲区、覆盖范围 |
| 多边形 | 多点序列 | 任意区域标注 |
| 箭头 | 方向向量+箭头计算 | 方向指示 |
| 曲线 | 贝塞尔/样条 | 路径标注 |
交互功能
- 拖拽调整:拖动顶点修改形状
- 吸附功能:顶点吸附到网格或其他顶点
- 面积/周长计算:实时显示测量数据
应用场景
- 地理标注:区域划定、地物标注
- 测量工具:距离、面积测量
- 规划设计:建筑红线、用地范围

12. 下雪(Snow Effect)
实现原理
下雪效果使用**粒子系统(Points/PointsMaterial)**实现:
1. 粒子初始化
javascript
const particleCount = 10000;
const geometry = new THREE.BufferGeometry();
const positions = new Float32Array(particleCount * 3);
const velocities = new Float32Array(particleCount);
// 在三维空间随机分布
for (let i = 0; i < particleCount; i++) {
positions[i * 3] = (Math.random() - 0.5) * 200; // X
positions[i * 3 + 1] = Math.random() * 100; // Y
positions[i * 3 + 2] = (Math.random() - 0.5) * 200; // Z
velocities[i] = 0.5 + Math.random() * 1.5; // 下落速度
}
geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
2. 粒子材质
javascript
const texture = createSnowflakeTexture(); // Canvas绘制雪花形状
const material = new THREE.PointsMaterial({
size: 0.5,
map: texture,
transparent: true,
opacity: 0.8,
blending: THREE.AdditiveBlending,
depthWrite: false,
});
3. 雪花纹理(Canvas绘制)
- 绘制六角形雪花形状
- 边缘模糊处理产生透明度渐变
- 可随机生成多种雪花形态
4. 动画循环
javascript
// 每个粒子向下移动
positions[i * 3 + 1] -= velocities[i] * deltaTime;
// 添加水平飘动
positions[i * 3] += Math.sin(time + i) * 0.02;
positions[i * 3 + 2] += Math.cos(time * 0.7 + i * 0.3) * 0.02;
// 超出底部则重置到顶部
if (positions[i * 3 + 1] < -10) {
positions[i * 3 + 1] = 100;
positions[i * 3] = (Math.random() - 0.5) * 200;
positions[i * 3 + 2] = (Math.random() - 0.5) * 200;
}
5. 风效果(可选)
- 添加风向向量,粒子沿风向偏移
- 风速变化产生飘忽感
- 旋转粒子产生旋转效果
优化技巧
- 使用
BufferGeometry而非Geometry - 粒子数量控制在合理范围(5000~20000)
- 使用
frustumCulled = false避免裁剪问题 - LOD:远景减少粒子数
应用场景
- 天气模拟:降雪可视化
- 场景氛围:冬季城市效果
- 特效制作:粒子系统教学

13. 剖面分析(Section / Profile Analysis)
实现原理
剖面分析用于展示地形或模型在某一截面上的高程变化:
方法一:切割平面(Clipping Plane)
-
定义切割平面 :使用
THREE.Plane定义切割位置和方向 -
渲染器启用裁剪 :
javascriptrenderer.localClippingEnabled = true; material.clippingPlanes = [clippingPlane]; material.clipShadows = true; -
截面填充 :使用
Stencil Buffer在切割面处绘制填充颜色
方法二:采样插值(适合地形)
-
定义剖面线:在水平面上定义一条直线或折线
-
高程采样 :
- 沿剖面线等距采样点
- 对每个采样点,获取地形高度(通过射线检测或高度图采样)
-
生成剖面图 :
采样点 (x, z) → 获取 y(高度) 展平为 2D:横坐标 = 沿路径距离,纵坐标 = 高程 -
绘制剖面曲线:使用 Line 或 AreaChart 绘制
方法三:Shader 实现(实时切割)
- 在片元着色器中判断像素是否在切割面一侧
- 丢弃另一侧的片段(discard)
- 在切割边缘绘制高亮线
剖面图内容
| 元素 | 说明 |
|---|---|
| 地形曲线 | 沿剖面线的高程变化 |
| 地质分层 | 不同地质材料的分层显示 |
| 标注信息 | 最高点、最低点、坡度标注 |
| 比例尺 | 水平和垂直比例尺 |
| 网格线 | 参考网格 |
应用场景
- 地形分析:山谷、山脊、坡度变化分析
- 道路设计:纵断面设计、填挖方计算
- 地质勘探:地层结构可视化
- 管线规划:地下管线剖面展示

总结
| 功能 | 核心技术 | 主要应用 |
|---|---|---|
| 鹰眼 | 双渲染器 + 摄像机同步 | 导航辅助 |
| 城市 | InstancedMesh + 程序化纹理 | 数字孪生 |
| 漫游 | 路径插值 + 摄像机动画 | 自动游览 |
| 经纬线 | 球面参数化 + LineSegments | 参考网格 |
| 坡度分析 | 法向量计算 + Shader着色 | 地形评估 |
| 飞线 | 贝塞尔曲线 + Shader流动 | 数据流向 |
| 动态纹理 | Canvas/Video/DataTexture | 特效展示 |
| 卫星模拟 | 轨道力学 + 地球渲染 | 航天可视化 |
| 航拍模拟 | 飞行路径 + 相机参数模拟 | 航拍规划 |
| 绘制坐标点 | Raycaster + Sprite/几何体 | 地图标注 |
| 绘制图形 | Shape + ExtrudeGeometry | 区域标记 |
| 下雪 | 粒子系统 + PointsMaterial | 天气模拟 |
| 剖面分析 | ClippingPlane / 高程采样 | 地形分析 |