QGeoView与 Graphics View Framework

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

  1. 渲染能力强 --- 支持大量图元、反走样、透明度、变换
  2. 交互完善 --- 鼠标事件、拖拽、选择、碰撞检测都是现成的
  3. Qt 原生 --- 和 Qt 应用无缝集成,不需要额外的渲染后端
  4. 性能够用 --- 对于二维地图场景,QGraphicsView 配合合理的视口裁剪完全够用

这个架构的局限

QGraphicsView 是 CPU 渲染的,当图元数量非常大(比如几万个)时会有性能瓶颈。这也是 QGeoView 的 performance 示例和 10000 示例在探讨的问题。

如果需要 GPU 加速渲染大量矢量数据,可能需要换到 OpenGL/Vulkan方案(比如 Mapbox GL Native 或 osgEarth)。

但对于常规的二维地图应用(瓦片底图 + 几百到几千个业务图元),QGraphicsView 完全够用。