QGeoView 的底层就是 Qt 的 QGraphicsView / QGraphicsScene / QGraphicsItem 框架
(即 Qt 的 Graphics View Framework)。
具体关系
bash
QGeoView 的封装层 Qt 底层
───────────────── ─────────────────────
QGVMap (QWidget) → QGraphicsView
QGVCamera → QGraphicsView 的变换矩阵 + 场景坐标
QGVItem → QGraphicsItem(场景中的图元)
QGVDrawItem → 自定义 QGraphicsItem(重写 paint)
QGVLayer → QGraphicsItem 分组(父图元)
QGVWidget → QGraphicsWidget(场景中的控件)
QGVProjection → 坐标转换(地理坐标 ↔ 投影坐标 ↔ 场景坐标)
QGraphicsView 是什么
它是 Qt 提供的一个二维场景-视图框架,核心思想是:
bash
┌─────────────────────────────────────────┐
│ QGraphicsView (视图/窗口) │
│ ┌─────────────────────────────────── │
│ │ QGraphicsScene (场景/画布) │ │
│ │ │ │
│ │ ┌────┐ ────┐ ┌──────────┐ │ │
│ │ │Item│ │Item│ │ Item │ │ │
│ │ └────┘ └────┘ └──────────┘ │ │
│ │ │ │
│ └───────────────────────────────────┘ │
│ 支持:缩放、平移、旋转、碰撞检测、选择 │
└─────────────────────────────────────────┘
- QGraphicsScene:一个无限大的二维画布,所有图元(Item)放在这里
- QGraphicsView:一个窗口,显示 Scene 的一部分,负责渲染和用户交互
- QGraphicsItem:Scene 中的图元,可以嵌套形成树形结构
QGeoView 做了什么封装
Qt 的 QGraphicsView 是通用的 2D 框架,不懂地理坐标。
QGeoView 在它之上加了一层地理语义:
| QGraphicsView 原生能力 | QGeoView 增加的地理能力 |
|---|---|
| 场景坐标(像素/逻辑单位) | 地理坐标(经纬度) 投影坐标 ↔ 场景坐标的三层转换 |
| 缩放 = 改变 view 的 transform | 缩放 = 改变地图比例尺,联动瓦片层级 |
| 平移 = 拖动 view | 平移 = 改变地图中心点,联动瓦片加载 |
| 旋转 = 旋转 view 的 transform | 旋转 = 改变地图方位角(azimuth) |
| 普通 QGraphicsItem | QGVItem(支持地理边界、投影回调、选择/悬停语义) |
| 无瓦片概念 | QGVLayerTiles(按需计算、下载、缓存瓦片) |
为什么要基于 QGraphicsView
- 渲染能力强 --- 支持大量图元、反走样、透明度、变换
- 交互完善 --- 鼠标事件、拖拽、选择、碰撞检测都是现成的
- Qt 原生 --- 和 Qt 应用无缝集成,不需要额外的渲染后端
- 性能够用 --- 对于二维地图场景,QGraphicsView 配合合理的视口裁剪完全够用
这个架构的局限
QGraphicsView 是 CPU 渲染的,当图元数量非常大(比如几万个)时会有性能瓶颈。这也是 QGeoView 的 performance 示例和 10000 示例在探讨的问题。
如果需要 GPU 加速渲染大量矢量数据,可能需要换到 OpenGL/Vulkan方案(比如 Mapbox GL Native 或 osgEarth)。
但对于常规的二维地图应用(瓦片底图 + 几百到几千个业务图元),QGraphicsView 完全够用。