[Qt]Graphics View实现简单离线地图
1. 瓦片地图概述
地图资源本身是图片资源,多张256×256分辨率的图片拼接起来,给用户显示的将是一个完整的地图效果。这些256×256的图片被称作瓦片地图。瓦片地图有着典型的金字塔结构,如下图:
在第0层级,仅有1张图片即可表示整个世界地图;在第1层级,需要4张图片表示整个世界地图,在第2层级,需要16张图片表示整个世界地图。所以规律就是层级每提升一级,那么原先1张图片就要拆分为4张图片,对应的瓦片数量也要扩大4倍。
同时,这里将每张图片进行分类和命名,才能快速索引!对于本地资源,每张图片是按照z/x/y.jpg
(或png)的方式存放的,目录结构如下:
├── 0
│ └── 0
│ └── 0.jpg
├── 1
│ ├── 0
│ │ ├── 0.jpg
│ │ └── 1.jpg
│ └── 1
│ ├── 0.jpg
│ └── 1.jpg
├── 2
│ └── 0
│ │ ├── 0.jpg
│ │ ├── 1.jpg
│ │ ├── 2.jpg
│ │ └── 3.jpg
│ ├── 1
│ │ ├── 0.jpg
│ │ ├── 1.jpg
│ │ ├── 2.jpg
│ │ └── 3.jpg
│ ├── 2
│ │ ├── 0.jpg
│ │ ├── 1.jpg
│ │ ├── 2.jpg
│ │ └── 3.jpg
│ └── 3
│ ├── 0.jpg
│ ├── 1.jpg
│ ├── 2.jpg
│ └── 3.jpg
├── 3
│ ……………………
z
是瓦片资源的最一层文件夹,代表瓦片所属的层级,以0为起始随层级增大而递增;
x
是瓦片资源的第二层文件夹,代表瓦片在水平方向的编号,以0为起始从左侧向右侧递增;
y.jpg
是瓦片资源的第二层文件夹里面的具体图片文件,代表瓦片在垂直方向的编号。以0为起始递增,值得注意的是,TMS协议的y编号是从下向上递增,而XYZ协议的y编号是从上向下递增。
2. 实现思路
首先,我们需要QGraphicsPixmapItem来显示瓦片;其次,我们还要所有的瓦片正确拼接,以及正确且及时地替换层级先后关系。那么,最简单的方法是将多个层级的图片缩放到同样的大小,再绘制到场景上,示意图如下:
上图中,我们是以第2层级的地图为基准,所以QGraphicsScene场景的大小是(256×4,256×4)。在实际开发中,瓦片地图资源通常是0到20层级,所以,建议将第10层级作为基准,这时候0层级的瓦片需要放大1024倍,20层级需要缩小0.0009765625倍。如果极端一点选用0层级作为基准,那么20层级需要缩小0.00000095367431640625倍,这会引起浮点数的精度问题!!!设base
为层级基准,那么某一层级的瓦片缩放公式如下:
s c a l e = 1.0 / 2 l e v e l − b a s e scale = 1.0\ /\ 2^{level-base} scale=