EarthGlobeSystem 🌐 3D交互式地球仪系统

C++17 OpenGL 3.3 GLFW/GLEW OpenCV · GLM

一个完整的3D地球仪可视化系统,支持纹理映射、地理标记、机器人仿真控制、多传感器数据融合。基于现代OpenGL渲染,提供沉浸式地球交互体验。

📖 概述

EarthGlobeSystem 是一个跨平台的3D地球仪可视化框架,专为地理信息系统、机器人导航、军事仿真和教育应用设计。系统采用模块化架构,核心组件包括:

🎨 3D渲染引擎

基于OpenGL 3.3,支持地球纹理映射、光照模型、线框模式、经纬网格。

🎮 交互控制

鼠标拖拽旋转/缩放、键盘快捷键(WASD/R/F/G),实时响应。

📍 标记系统

地理坐标标记(城市/兴趣点),支持JSON持久化,动态增删改查。

🤖 机器人仿真

模拟机器人运动、路径规划、电池管理,支持TCP远程控制。

🔗 Python客户端

通过Socket与系统通信,实现远程指令下发和数据获取。

✨ 核心特性

⚡ 快速开始

最简单的运行方式:

# 克隆仓库
git clone https://github.com/example/EarthGlobeSystem.git
cd EarthGlobeSystem

# 创建构建目录
mkdir build && cd build

# 配置并编译
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j4

# 运行程序 (确保纹理文件在正确位置)
./EarthGlobeSystem
💡 提示:如果缺少地球纹理,程序将使用纯色渲染。您可以将任意地球贴图命名为 earth_texture.jpg 放入可执行目录。

📦 编译与依赖

Ubuntu/Debian 依赖安装

sudo apt update
sudo apt install build-essential cmake git \
    libglfw3-dev libglew-dev libopengl-dev \
    libopencv-dev libglm-dev nlohmann-json3-dev

CMake 配置选项

选项说明默认值
BUILD_EXAMPLES构建示例程序ON
BUILD_TESTS构建单元测试OFF
USE_SYSTEM_JSON使用系统nlohmann_jsonON

🏗️ 系统架构

系统采用分层架构,各模块职责清晰

🎨 渲染引擎 (GlobeRenderer)

核心渲染类,负责OpenGL初始化、球体网格生成、着色器编译和场景绘制。

bool initialize(const std::string& texturePath)

初始化GLFW窗口、GLEW、创建球体网格、编译着色器、加载纹理。

void render()

每帧调用,清空缓冲区 → 更新投影/视图矩阵 → 渲染地球 → 渲染网格 → 渲染标记点。

void rotate(double deltaAzimuth, double deltaElevation)

修改相机方位角和仰角,实现地球旋转效果。

GeoCoordinate screenToGeo(int x, int y)

屏幕坐标转地理坐标(射线-球体相交,当前为简化实现)。

着色器说明:地球着色器支持纹理漫反射+镜面高光,光照位置固定为(5,5,5)。简单着色器用于标记点和网格线框。

🎮 交互控制 (GlobeController)

封装GLFW回调,提供直观的交互体验。

鼠标控制

键盘快捷键

回调系统支持自定义鼠标点击、移动、滚轮事件,方便扩展业务逻辑。

📍 标记管理 (MarkerManager)

提供完整的地理标记生命周期管理。

int addMarker(const std::string& name, const GeoCoordinate& coord, const cv::Scalar& color, const std::string& description)

添加新标记,返回自动生成的ID,同时保存到JSON文件。

bool removeMarker(int id)

按ID删除标记。

std::vector<Marker> getMarkersInRange(const GeoCoordinate& center, double radiusKm)

获取指定中心点半径范围内的所有标记,使用大圆距离计算。

bool loadFromFile() / saveToFile()

markers.json 加载/保存标记数据。

JSON格式示例:

[
  {
    "id": 1,
    "name": "London",
    "latitude": 51.5074,
    "longitude": -0.1278,
    "altitude": 0,
    "color": [255, 0, 0],
    "description": "Capital of UK"
  }
]

🤖 机器人接口 (RobotInterface)

仿真机器人运动控制与状态管理,支持多线程命令处理。

核心功能

void moveToCoordinate(const GeoCoordinate& coord)

发送移动命令,机器人开始向目标点移动。

void setStatusCallback(std::function<void(const RobotStatus&)> callback)

注册状态变化回调,用于UI更新或日志记录。

Python客户端示例robot_client.py 展示了如何通过Socket发送JSON命令,控制机器人移动和添加标记。

🧰 工具类 (Utils)

提供地理坐标转换和几何计算。

static Point3D geoTo3D(const GeoCoordinate& geo, double radius)

经纬度转3D笛卡尔坐标(右手坐标系,Y轴向上)。

static GeoCoordinate point3DToGeo(const Point3D& p)

反向转换,返回经纬度。

static double calculateDistance(const GeoCoordinate& geo1, const GeoCoordinate& geo2)

计算两点间的大圆距离(单位: 公里),基于Haversine公式。

数据结构

📚 API 参考摘要

GlobeRenderer 主要接口

void render();                           // 渲染一帧
void rotate(double deltaAz, double deltaEl); // 旋转相机
void zoom(double factor);                // 缩放
void addMarker(const Marker& marker);    // 添加标记点
void setWireframeMode(bool enabled);     // 线框模式
GeoCoordinate screenToGeo(int x, int y); // 屏幕坐标转地理坐标

MarkerManager 接口

int addMarker(...);
bool removeMarker(int id);
Marker* getMarker(int id);
std::vector<Marker> getMarkersInRange(const GeoCoordinate& center, double radiusKm);
bool saveToFile();

RobotInterface 接口

bool start();                            // 启动工作线程
void stop();                             // 停止
void moveToCoordinate(const GeoCoordinate& coord);
RobotStatus getStatus() const;
void setStatusCallback(std::function<void(const RobotStatus&)> callback);

💡 使用示例

1. 添加自定义标记

MarkerManager manager;
int id = manager.addMarker("Eiffel Tower", GeoCoordinate(48.8584, 2.2945), 
                            cv::Scalar(255, 255, 0), "Paris landmark");
renderer.addMarker(*manager.getMarker(id));

2. 控制机器人移动并监听状态

RobotInterface robot;
robot.start();
robot.setStatusCallback([](const RobotStatus& s) {
    std::cout << "Position: " << s.currentPosition.latitude 
              << ", " << s.currentPosition.longitude << std::endl;
});
robot.moveToCoordinate(GeoCoordinate(34.0522, -118.2437)); // 洛杉矶

3. Python远程控制

from robot_client import RobotClient
client = RobotClient()
client.connect()
client.move_to(35.6895, 139.6917)  # 东京
status = client.get_status()
print(status)
client.close()

⚙️ 配置文件

markers.json — 标记点数据,自动保存/加载,位于可执行目录。

earth_texture.jpg — 地球纹理图片,建议分辨率4096x2048或更高。

运行时参数 (可在代码中修改):

🔧 故障排除

❌ 无法创建OpenGL上下文
确保系统支持OpenGL 3.3+,虚拟机可能需要启用3D加速。
❌ 纹理加载失败
检查 earth_texture.jpg 是否存在于当前目录,或修改 main.cpp 中的路径。
❌ 编译找不到 nlohmann_json
执行 sudo apt install nlohmann-json3-dev 或手动下载头文件。
💡 性能优化建议
- 降低球体细分段数 createSphere(32)
- 关闭网格显示 renderer.setGridVisible(false)
- 减少标记点数量

⚖️ 许可证

MIT License

Copyright (c) 2025 EarthGlobeSystem Contributors

本软件按“原样”提供,不提供任何明示或暗示的保证。任何人可以自由使用、复制、修改、合并、发布、分发、再许可和/或销售软件的副本,但需包含上述版权声明和许可声明。

🌍 EarthGlobeSystem · 3D Interactive Globe · 文档生成于 2026-03-21