首页 > C++/QT 学习项目,冒死上传企业级GIS项目
头像
青年牛马
发布于 04-25 17:32 湖南
+ 关注

C++/QT 学习项目,冒死上传企业级GIS项目

GIS Project Handbook 🗺️

基于 Qt/C++ 的 GIS 开发学习笔记与项目实战

📚 仓库简介

本仓库记录 GIS 开发的学习过程,重点聚焦:

  • 安装:QT的下载安装全步骤
  • 基础:项目所包含的技术点讲解以及原理
  • 实战:Qt 离线/在线地图引擎开发以及运行中可能出现的问题
  • 进阶:项目的高频面试题以及简历优化模板

这是一个功能完整的 Qt/C++ 地理信息系统(GIS)桌面应用程序。

你可以从这个项目学到什么?

序号    技能   难度
1 Qt 界面编程(布局、控件、事件)  ⭐⭐
2 QPainter 绘图(画图、画线、画文字) ⭐⭐⭐
3 网络编程(HTTP 请求、JSON 解析)  ⭐⭐⭐
4 地图投影算法(墨卡托公式)  ⭐⭐⭐⭐
5 缓存设计与 LRU 淘汰   ⭐⭐⭐
6 C++17 现代特性(variant、visit)  ⭐⭐⭐⭐
7 异步编程思维(信号槽、回调) ⭐⭐⭐
8 API 集成与签名计算(MD5)   ⭐⭐⭐
9 坐标转换算法(WGS84/GCJ02/BD09)   ⭐⭐⭐⭐
10    完整的项目架构设计  ⭐⭐⭐⭐⭐

运行这个项目需要什么?

  1. 开发环境:Qt 5.12+ 和 MinGW 编译器
  2. 网络:能访问高德、百度地图服务器
  3. API 密钥(个人开发不需要):    - 百度地图 AK(访问路线规划、周边搜索)    - 高德地图 Key(地理编码)
  4. C++17:项目配置文件中需添加 CONFIG += c++17

二、七天学习计划

适合初学者,每天 2-3 小时,目标是理解项目架构并能独立讲解/二次开发

第1天:环境搭建与项目概览

时间段 内容
30分钟 安装 Qt 5.12 + MinGW,配置环境变量
30分钟 克隆项目,编译运行,确认能看到地图
30分钟 浏览项目文件结构,理解每个文件的作用
30分钟 阅读 MainWindow.cppsetupUi(),了解界面布局
30分钟 动手:修改窗口标题、调整左侧面板宽度,观察变化

学习目标:能无障碍编译运行,知道每个文件大致负责什么。

验收:成功修改地图初始中心点为上海(121.47, 31.23)。

第2天:Qt 基础与坐标转换算法

时间段 内容
45分钟 学习 Qt 信号槽机制(connect 用法、Lambda 表达式)
45分钟 学习 Qt 绘图基础(QPainter:画图、画线、画文字)
30分钟 阅读 CoordConvert.h 全部代码
30分钟 理解墨卡托投影公式(lngLatToTile / tileToLngLat
30分钟 动手:手写代码,将天安门坐标(116.397, 39.909)转换为瓦片坐标(z=12)

学习目标:理解坐标转换原理,能写出墨卡托投影的关键公式。

验收:在纸上画出墨卡托投影的基本公式。

第3天:地图瓦片加载核心(最难的一天)

时间段 内容
30分钟 理解瓦片金字塔:什么是 z/x/y?0 级有 1 张,1 级有 4 张...
45分钟 阅读 TileManager.hTileIdTilePairQHash 缓存
60分钟 阅读 TileManager.cpprequestTilebuildUrl
30分钟 理解混合模式的双缓存同步逻辑
30分钟 动手:修改 buildUrl 将高德源换成 OpenStreetMap 瓦片

学习目标:能解释瓦片加载的全流程(计算→检查缓存→异步下载→绘制)。

验收:完整口述一次请求瓦片到显示的全过程,并能够理解瓦片加载原理。

第4天:地图控件与鼠标交互

时间段 内容
30分钟 阅读 MapWidgetlngLatToScreen / screenToLngLat
45分钟 理解 mousePressEvent / mouseMoveEvent 的拖拽逻辑
30分钟 理解 wheelEvent 的缩放逻辑
45分钟 阅读 drawTiles:如何计算可见瓦片范围
30分钟 动手:修改代码,让滚轮缩放速度加倍

学习目标:理解鼠标拖拽平移和滚轮缩放的数学原理。

验收:能用语言描述从鼠标拖拽到地图移动的计算过程。

第5天:覆盖物系统与交互绘制

时间段 内容
30分钟 阅读 Overlay.h:5 种覆盖物结构体
45分钟 学习 std::variant + std::visit 的使用
45分钟 阅读 drawOverlays:如何统一绘制不同的覆盖物
30分钟 阅读 mousePressEvent 中的绘制逻辑 + drawDrawingPreview
30分钟 动手:添加一种新的覆盖物类型 —— 三角形
30分钟 总结:if constexpr + std::is_same_v 如何实现编译期多态

学习目标:理解 variant + visit 的使用场景和优势。

验收:能向面试官解释为什么要用 variant 而不是继承。

第6天:API 集成与网络请求

时间段 内容
30分钟 阅读 BaiduApi.h:了解提供了哪些服务
45分钟 阅读 BaiduApi.cppgeocode / planRoute / areaSearch
30分钟 理解 SN 签名算法(calcSn
30分钟 理解 onReplyFinished 中的 JSON 解析
30分钟 阅读 MainWindow.cpp 中如何连接 API 信号和界面
30分钟 动手:添加一个"当前位置天气"功能(调用和风天气 API)

学习目标:能独立接入一个新的 REST API 并解析 JSON。

验收:成功添加天气查询功能并显示在日志面板。

第7天:项目总结与面试准备

时间段 内容
30分钟 画出完整的项目架构图(模块、依赖、数据流向)
30分钟 整理 5 个最值得讲的亮点(混合同步、variant、LRU、异步、坐标转换)
30分钟 模拟面试:口述项目难点 + 技术选型理由
30分钟 完善简历:将项目经历填入简历模板
30分钟 动手:录制 2-3 分钟的功能演示视频
30分钟 发布到 GitHub + 写 README + 推送到技术社区

学习目标:能自信地向面试官介绍项目,并展示代码。

验收:完成一篇技术博客或 GitHub README。

三、学习资料推荐

类型 资源
Qt 官方文档 Qt Documentation
墨卡托投影 Wikipedia - Mercator projection
GCJ02 原理 火星坐标系解密
std::variant C++17 特性详解
百度地图 API 百度地图 Web API 文档
高德地图 API 高德地图 Web API 文档
项目技术点讲解 刨析项目技术点,以及针对初学者的讲解
面试问题 涵盖该项目技术面试问题以及相关大厂面试题
简历模板 针对不同岗位对项目描写进行优化

四、学习进度追踪表

天数 核心模块 完成打 ✅
Day1 环境搭建 + 项目运行
Day2 Qt 基础 + 坐标转换
Day3 瓦片加载机制
Day4 鼠标交互 + 拖拽缩放
Day5 覆盖物系统 + variant
Day6 API 集成 + 网络请求
Day7 总结 + 面试准备

五、常见问题速查

问题 答案位置
瓦片 URL 怎么构建的? TileManager::buildUrl()
混合模式如何同步? requestTile 中的 hasBase + hasOverlay 判断
坐标转换精度多少? CoordConvert 中的多项式拟合
缓存满时怎么淘汰? 优先删 abs(key.z - currentZ) >= 2 的瓦片
信号槽怎么连接的? MainWindow::setupConnections()

祝学习顺利!如有任何问题,欢迎随时交流。

部分技术点和讲解展示:

部分技术点:

一、核心技术框架

  1. Qt 框架应用
  • QWidget 体系:自定义地图控件 MapWidget 继承自 QWidget
  • 事件系统:重写 paintEventmousePressEventmouseMoveEventwheelEventresizeEvent
  • 信号与槽:大量使用 Qt 的信号槽机制进行模块间通信
  • 网络模块:QNetworkAccessManager 异步 HTTP 请求瓦片和 API 数据
  • 定时器:QTimer 实现轨迹回放的动画效果
  • 布局管理:QSplitterQVBoxLayoutQHBoxLayoutQFormLayout

 2. C++ 现代特性(C++17)

  • std::variantOverlayData 使用 variant 存储多种覆盖物类型
  • std::visit:遍历 variant 时使用,配合 lambda 模板实现类型安全的多态绘制
  • std::clamp:限制缩放级别范围
  • if constexpr:编译期条件判断,用于 variant 访问
  • constexpr:编译期常量(如 kTileSize

二、地图渲染核心

 3. 瓦片地图机制

  • 墨卡托投影:Web 墨卡托投影(EPSG:3857)的经纬度与屏幕坐标转换
  • 瓦片坐标系统:基于 TMS(Tile Map Service)标准,计算当前视口所需的瓦片
  • 异步加载:瓦片通过网络异步下载,避免阻塞 UI
  • LRU 缓存:QHash<TileId, TilePair> 实现瓦片缓存,限制最大数量 2048
  • 混合模式支持:卫星图 + 透明路网叠加层,需等待两张图都加载完成才显示

4.坐标转换算法  

// 经纬度 → 屏幕坐标(核心公式)
tX = (lng + 180) / 360  2^z
tY = (1 - ln(tan(lat  π/180) + sec(lat  π/180)) / (2π)) / 2  2^z
  • 双向转换:lngLatToScreen()screenToLngLat()
  • 坐标系支持:WGS84、GCJ02(国测局)、BD09(百度)三种坐标系的相互转换

 5. 地图交互

  • 拖拽平移:鼠标拖拽时动态计算新中心点
  • 滚轮缩放:改变 m_z 后清空缓存并刷新
  • 点击定位:点击地图发射 mapClicked 信号,返回经纬度   详细请看技术点与原理

部分技术讲解

一、这个项目是做什么的?

这个项目就是用 C++ 和 Qt 自己实现一个简化版的地图应用,可以:

  • 拖拽、缩放查看地图
  • 在上面画点、线、圆、矩形
  • 输入地址找到位置
  • 规划从A到B的路线
  • 搜索附近的餐厅

二、核心技术分层讲解

第一层:Qt 基础 - 什么是 Qt?

通俗理解:Qt 是一个工具箱,里面有很多现成的"零件",帮你快速开发带界面的程序。

// 你不需要自己写代码来创建窗口、按钮、处理鼠标点击
// Qt 已经做好了:
QWidget window = new QWidget();  // 创建一个窗口
QPushButton btn = new QPushButton("点我");  // 创建一个按钮

本项目用到的 Qt 组件:

组件 作用 比喻
QWidget 所有界面的基础 一张白纸
QPainter 画图(画瓦片、画点线面) 一支笔
QNetworkAccessManager 从互联网下载地图图片 快递员
QTimer 定时执行任务(轨迹移动) 闹钟
QHash 缓存瓦片图片 临时储物柜
QVector 存储点坐标列表 购物清单
 
详细请看技术点与原理

部分面试题展示

适用于:C++/Qt 开发工程师、GIS 开发工程师、客户端开发工程师面试

一、项目概述(30秒自我介绍)

项目名称:基于 Qt/C++ 的跨平台 GIS 桌面应用

核心功能:

  • 多源地图瓦片加载(普通/卫星/混合模式)
  • 交互式图形绘制(点/线/面/圆/矩形)
  • 地理/逆地理编码、路线规划、POI 搜索
  • 轨迹回放、坐标转换(WGS84/GCJ02/BD09)

技术栈:C++17、Qt 5.12、QNetworkAccessManager、高德/百度/OSM API

二、架构设计(面试官常问)  

 2.1 整体架构图

┌─────────────────────────────────────────────────────────────┐
│                        MainWindow (UI层)                     │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────┐   │
│  │地图初始化│ │覆盖物管理│ │API调用面板│ │日志与调试面板│   │
│  └──────────┘ └──────────┘ └──────────┘ └──────────────┘   │
└─────────────────────────────────────────────────────────────┘
                              │ 信号/槽
┌─────────────────────────────────────────────────────────────┐
│                      MapWidget (核心控件)                    │
│  • 瓦片绘制与坐标转换  • 鼠标交互(拖拽/缩放/绘制)            │
│  • 覆盖物渲染          • 轨迹回放动画                        │
└─────────────────────────────────────────────────────────────┘
                    │                    │
          ┌─────────┴─────────┐  ┌───────┴────────┐
          ▼                   ▼  ▼                ▼
┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐
│   TileManager   │  │   BaiduApi      │  │  CoordConvert   │
│ 瓦片请求/缓存/   │  │ 路线规划/搜索/   │  │ WGS84/GCJ02/    │
│ URL构建(高德源)  │  │ 签名计算/JSON解析│  │ BD09转换        │
└─────────────────┘  └─────────────────┘  └─────────────────┘

2.2 模块职责

模块 职责 关键类 / 结构
UI 层 用户交互、参数输入、结果显示 MainWindow
地图控件 瓦片渲染、坐标转换、事件处理 MapWidget
瓦片管理 异步加载、LRU 缓存、多源 URL TileManager、TileId
API 封装 网络请求、签名、JSON 解析 BaiduApi
覆盖物系统 类型安全的图形数据存储 OverlayData(variant)
坐标转换 三种坐标系互转 CoordConvert

三、核心技术点详解

 3.1 地图瓦片渲染(必问)

Q:地图瓦片是怎么加载和显示的?

A:采用金字塔模型 + 异步加载 + LRU缓存架构。

// 瓦片坐标结构
struct TileId {
    int x, y, z;        // 列、行、缩放级别
    QString type;       // satellite / hybrid_road / normal
};


// 核心流程
void drawTiles(QPainter& p) {
    // 1. 根据中心点和缩放计算可见瓦片范围
    double n = pow(2.0, m_z);
    int cTX = floor((m_centerLng + 180) / 360 * n);
    // 2. 遍历可见瓦片
    for (dy in -vT/2 .. vT/2) {
        for (dx in -hT/2 .. hT/2) {
            // 3. 请求瓦片(同步检查缓存,异步下载)
            if (m_tiles->requestTile(id, tilePair)) {
                p.drawPixmap(px, py, tilePair.base);  // 绘制底图
                p.drawPixmap(px, py, tilePair.overlay); // 绘制叠加层
            } else {
                p.fillRect(px, py, bgColor);  // 占位色
            }
        }
    }
}

技术要点:

  • 墨卡托投影:lat → log(tan(lat) + sec(lat)) 将球面坐标映射到平面
  • 瓦片尺寸固定 256x256,便于缓存和拼接
  • 异步下载 + 信号槽触发重绘,保证 UI 不卡顿   详细请面试问题

部分简历模板展示:

简历使用指南(精准匹配岗位)

模板编号 适合投递岗位 核心突出侧重点
模板一 Qt/C++ 客户端开发工程师 Qt框架应用、C++17特性、异步网络、客户端封装
模板二 GIS 算法/开发工程师 坐标系转换、瓦片渲染、混合地图模式、GIS核心算法
模板三 C++ 网络编程工程师 HTTP异步请求、API集成、请求去重、缓存设计
模板四 图形学/渲染工程师 QPainter渲染、几何计算、渲染性能优化
模板五 全栈GIS开发工程师 桌面端开发+多地图服务集成、全流程落地
模板六 应届生/校招(GIS/Qt方向) 项目完整度、自主学习能力、动手能力
模板七 Qt界面/交互工程师 UI布局、QSS美化、交互设计、用户体验
模板八 后端/API集成工程师 REST API调用、签名验证、数据解析、降级机制
模板九 算法/数据结构工程师 坐标转换算法、缓存淘汰、几何计算、单元测试
模板十 技术文档/培训/宣讲岗 文档撰写、成果演示、知识传播、教学能力

模板一:Qt/C++ 桌面开发工程师(纯客户端方向)

核心项目经验
跨平台 GIS 桌面客户端开发 | 核心开发者 | 技术栈:Qt 5.12、C++17、QNetworkAccessManager、QPainter
•独立设计并封装可复用地图控件「MapWidget」,核心实现瓦片异步加载、墨卡托投影坐标转换,支撑地图浏览核心功能落地。
•基于QPainter引擎完成5种覆盖物(点/线/面/圆/矩形)的实时渲染与交互式绘制,支持鼠标拖拽编辑、属性自定义,提升用户交互体验。
•采用QTimer+轨迹点队列设计平滑轨迹回放动画,支持自定义播放速度(0.5x-2x),实现轨迹移动无卡顿、无跳帧。
•基于QNetworkAccessManager构建全异步HTTP请求框架,调用高德/百度地图API,结合Qt信号槽机制实现非阻塞UI,避免界面卡死。
•封装LRU瓦片缓存机制(基于QHash实现),设计智能淘汰策略,优先淘汰缩放级别差异≥2的瓦片,将内存占用稳定控制在200MB以内。
•运用C++17核心特性(std::variant、std::visit)实现类型安全的覆盖物统一存储,替代传统继承体系,降低代码耦合度、提升可维护性。
项目成果:独立完成可交互GIS桌面客户端开发,完整实现地图浏览、图形绘制、轨迹回放、地理编码等8+核心功能,代码可复用性强,运行稳定无异常。
```  
**详细请看简历模板**


全部评论

(2) 回帖
加载中...
话题 回帖