Bing地图切片原理
Bing地图切片系统
Bing地图提供了一个可以直接平移和缩放的世界地图。为了让地图操作更加平滑和及时响应,我们选择提前渲染地图不同层级的细节,并把每个层级的地图切割成为瓦片以便快速的还原展示。这篇文档描述了,投影,坐标系统和地图瓦片编码的方案,这些统称为Bing地图的切片系统。
地图投影
为了确保地图中来自不同航拍影像的排版没有缝隙,我们不得不对整个地球进行投影,我们选择使用墨卡托投影,如下图所示:

尽管墨卡托投影极大的扭曲了地图比例和面积(特别是在极点附近),但它具有两个重要特征,这两个重要特征超过了它的比例失真带来的问题。
- 他是一个保持形状的投影,这意味着它保留了相对较小物体的形状。这在我们展示航拍影像的时候尤为重要,我们希望避免航拍影像中建筑物的形状不被扭曲,建筑物的形状应该是方形,而不是矩形。
- 他是一个圆柱投影,这意味着南北方向总是直上直下,东西总是左右延伸。
因为墨卡托投影在极点方向无穷大的特性,所以它没有真正展示整个世界。用一个方形宽高比来讲,最大唯独约为85.05度。
为了简化计算,我们使用球形来进行这种投影的,而不用椭球形式。由于投影仅用来显示地图,而不用来显示数字坐标,因此我们不需要对椭球投影带来的额外精度。球形投影在Y方向上大约会引起0.33%的比例失真,这在视觉上不明显。
地图分辨率和地图比例尺
除了地图投影外,在渲染地图之前地图分辨率和地图比例尺必须指定。在最低的地图层级(Level1),地图是512X512像素,在各个连续的地图层级,地图的宽度和高度以2的level次方形式增长,Level2 是1024X1024像素,Level3是2048X2048像素,等等。总之地图的宽度和高度可以通过以下方式计算:
地图 width = 地图 height = * 2level 像素
地图分辨率表示地图上一像素代表的实际距离,例如,地图分辨率为10m/pixel,表示地图上没像素代表真实距离10米。地图分辨率是通过地图层级(Level)和纬度来计算的。使用地球半径6378137米,地图的分辨率可以通过如下方式计算:
地图 resolution = cos(latitude * pi/180) * 地球周长 / map width =(cos(latitude * pi/180) * 2 * pi * 6378137 meters) / (256 * 2level 像素)
地图的比例尺表示了在同一个单位体系下地图上距离和地面距离的比值。举个例子,地图比例尺1::100000每英寸表示,地图上一英寸表示实际距离100000英寸。类似地图分辨率,地图比例尺也是通过地图层级和纬度确定的。通过给定了屏幕分辨率(通常96dpi),则可以根据地图分辨率计算得出:
scale = 1 : resolution * screen dpi / 0.0254 meters/inch
= 1 : (cos(latitude * pi/180) * 2 * pi * 6378137 * screen dpi) / (256 * 2level * 0.0254)
以下表格展示了从赤道出计算的每个层级上面的具体地图长宽、分辨率和比例尺信息。
|
层级 |
地图高度和宽度 (pixels) |
地图分辨率(meters / pixel) |
地图比例尺(at 96 dpi) |
|
1 |
512 |
78,271.5170 |
1 : 295,829,355.45 |
|
2 |
1,024 |
39,135.7585 |
1 : 147,914,677.73 |
|
3 |
2,048 |
19,567.8792 |
1 : 73,957,338.86 |
|
4 |
4,096 |
9,783.9396 |
1 : 36,978,669.43 |
|
5 |
8,192 |
4,891.9698 |
1 : 18,489,334.72 |
|
6 |
16,384 |
2,445.9849 |
1 : 9,244,667.36 |
|
7 |
32,768 |
1,222.9925 |
1 : 4,622,333.68 |
|
8 |
65,536 |
611.4962 |
1 : 2,311,166.84 |
|
9 |
131,072 |
305.7481 |
1 : 1,155,583.42 |
|
10 |
262,144 |
152.8741 |
1 : 577,791.71 |
|
11 |
524,288 |
76.4370 |
1 : 288,895.85 |
|
12 |
1,048,576 |
38.2185 |
1 : 144,447.93 |
|
13 |
2,097,152 |
19.1093 |
1 : 72,223.96 |
|
14 |
4,194,304 |
9.5546 |
1 : 36,111.98 |
|
15 |
8,388,608 |
4.7773 |
1 : 18,055.99 |
|
16 |
16,777,216 |
2.3887 |
1 : 9,028.00 |
|
17 |
33,554,432 |
1.1943 |
1 : 4,514.00 |
|
18 |
67,108,864 |
0.5972 |
1 : 2,257.00 |
|
19 |
134,217,728 |
0.2986 |
1 : 1,128.50 |
|
20 |
268,435,456 |
0.1493 |
1 : 564.25 |
|
21 |
536,870,912 |
0.0746 |
1 : 282.12 |
|
22 |
1,073,741,824 |
0.0373 |
1 : 141.06 |
|
23 |
2,147,483,648 |
0.0187 |
1 : 70.53 |
像素坐标
再通过使用地图层级确定分辨率和比例尺后,我们可以将地理坐标转换成为像素坐标。由于地图的高度和宽度在不同地图层级不一样,所以像素坐标也是如此。像素坐标在左上角总是(0,0),地图右上角为(width-1,height-1),或者参考之前的计算公式为:(256X2level-1,256X2level-1),举个例子,如果地图级别为3,则像素坐标从(0,0),到(2047,2047),如下:

给定经度纬度和地图缩放级别,像素坐标可以通过以下方式进行计算:
sinLatitude = sin(latitude * pi/180)
pixelX = ((longitude + 180) / 360) * 256 * 2level
pixelY = (0.5 – log((1 + sinLatitude) / (1 – sinLatitude)) / (4 * pi)) * 256 * 2level
其中经度纬度假设是在WGS84参考系统下的。即使Bing地图使用的是球形投影,将所有地理坐标转换为常用的椭球坐标也很重要,这里我们选择WGS84椭球坐标。我们假设经度范围从-180到+180度,纬度必须限制在-85.05112878到+85.05112878之间。这避免了投影到极点的严重变形,并且使得投影能是正方形。、
切片坐标和Quadkeys
为了优化地图检索和显示性能,每个层级渲染的地图都被切割成若干个256X256像素的瓦片。由于每个地图级别的像素数量不相同,因此切片的数量也是不同;
map width = map height = 2level tiles
所有切片给定了XY坐标,从左上角的(0,0)到右下角的(2level-1,2level-1)。例如,Level3切片坐标从(0,0)到(7,7),如图:

给定一个像素坐标,你可以根据以下公式很快的计算出包含该坐标的瓦片的XY坐标。
tileX = floor(pixelX / 256)
tileY = floor(pixelY / 256)
为了优化瓦片的所有和存储,二位瓦片坐标被组合成为四叉树的以为字符串,简称为“QuadKeys”。每个quadkey以特定的地图级别来唯一表示一个瓦片。并且可以将其用作常用的数据库B-tree索引中的键。为了将瓦片坐标转换成为quadkey,y和x坐标转换成二进制(补齐位数为最长结果二进制位数),然后依次从y到x的二进制位数由高到底组合成一个新的二进制数字。然后将其转为四进制字符串,过程如下:
tileX = 3 =011(二进制)
tileY = 5 =101(二进制) quadKey = 100111(二进制) = 213(四进制) = “231”
quadKey有一些很有趣的特性:
第一:quadKey的长度(组成quadKey的数字的个数)等于相应瓦片所对应的地图级别。
第二:任何一个瓦片的quadKey的前面几位都是他所在父瓦片(上一级别中包含该瓦片的瓦片)的前几位。
如下所示:瓦片2 瓦片20到23的父瓦片,瓦片13 是瓦片130到133的父瓦片。

最后,quadkeys提供了一个可以保留xy空间中所在切片位置的一维索引的关键字,换句话说,也就是,具有连接x,y坐标的两个瓦片通常具有相对靠近在一起的四个秘钥,这对于优化数据库性能非常重要,因为通常辉耀组的形式请求相邻的瓦片,并且希望将这些瓦片保留在想通的磁盘上,以尽量减少磁盘的读取次数。
Sample Code
略
文章翻译自:Bing Maps Tile System
Bing地图切片原理的更多相关文章
- Bing Maps进阶系列九:使用MapCruncher进行地图切片并集成进Bing Maps
Bing Maps进阶系列九:使用MapCruncher进行地图切片并集成进Bing Maps 在Bing Maps开发中,由于各种应用功能的不同,更多的时候用户可能需要将自己的一部分图片数据作为地图 ...
- Google 地图切片URL地址解析
一.Google地图切片的投影方式及瓦片索引机制 1.地图投影 Google地图采用的是Web墨卡托投影(如下图),为了方便忽略了两极变形较大的地区,把世界地图做成了一个边长等于赤道周长的正方形(赤道 ...
- 百度地图瓦片原理 | 百度map使用教程
百度地图瓦片原理: http://blog.csdn.net/mygisforum/article/details/22997879 百度map使用教程: http://www.myexception ...
- ArcGis(01)——地图切片以及发布底图服务
ArcGis(01)——地图切片以及发布底图服务 环境 操作系统:win10_x64 Gis版本:Arcis server 10.2 准备 1.tif格式地图资源 2.Arcis server 10. ...
- silverlight调用bing地图 和 显示中文地图
bing地图sdk: https://msdn.microsoft.com/en-us/library/ff428643.aspx 引用dll:https://www.microsoft.com/en ...
- 翻译:Bing地图瓦片体系
Bing Maps Tile System Bing地图瓦片体系 原文链接:http://msdn.microsoft.com/en-us/library/bb259689.aspx Bing Map ...
- golang slice 切片原理
golang 中的 slice 非常强大,让数组操作非常方便高效.在开发中不定长度表示的数组全部都是 slice .但是很多同学对 slice 的模糊认识,造成认为golang中的数组是引用类型,结果 ...
- python获取bing地图发布自己的TMS服务(一)下载瓦片
部分结果 bing地图瓦片使用QuadKey作为命名方式. QuadKey简介 如何计算quadkey 在给定level下,把行号tileY和列号tileX转换为2进制,然后行列交叉存储,再转换为4进 ...
- ArcMap 制作广州 18 级地图切片需要多少时间?
制作地图切片包会随着级别的上升,瓦片数量会指数级地上升,所需的计算时间也是指数级的. 但是 ArcMap 并不会提示时间信息,只有一个圈没完没了地转... 就在这无聊地等待中,我写了这篇帖子. 电脑配 ...
随机推荐
- HTML乱码问题
第一:定义网页显示编码.如果不定义网页编码,那么我们浏览网页的时候,IE会自动识别网页编码,这就有可能会导致中文显示乱码了.所以我们做网页的时候,都会用“<meta http-equiv=”Co ...
- MQTT---HiveMQ源代码具体解释(八)Netty-WebSocket
源博客地址:http://blog.csdn.net/pipinet123 MQTT交流群:221405150 基于netty实现Webscoket相对来说就是相当简单,所以本讲中就不搞太复杂的了,给 ...
- C语言实现使用动态数组实现循环队列
我在上一篇博客<C语言实现使用静态数组实现循环队列>中实现了使用静态数组来模拟队列的操作. 因为数组的大小已经被指定.无法动态的扩展. 所以在这篇博客中,我换成动态数组来实现. 动态数组能 ...
- python爬虫系列序
关于爬虫的了解,始于看到这篇分析从数据角度解析福州美食,和上份工作中的短暂参与. 长长短短持续近一年的时间,对其态度越来越明晰,噢原来这就是我想从事的工作. 于是想要系统学习的心理便弥散开来…… 参考 ...
- Android面试题集
前几天整理了Java面试题集合,今天再来整理下Android相关的面试题集合.假设你希望能得到最新的消息,能够关注https://github.com/closedevice/interview-ab ...
- 《AndroidStudio每日一贴》3.高速切换代码风格、配色方案和键盘
<AndroidStudio每日一贴>3.高速切换代码风格.配色方案和键盘 高速切换代码风格.配色方案和键盘,使用快捷键: control + ~ 很多其它有用技巧请查看<Andro ...
- 多年iOS开发经验总结(一)
总结了几个月的东西终于能和大家分享了,不多说,直接看东西! 1.禁止手机睡眠 1 [UIApplication sharedApplication].idleTimerDisabled = YES; ...
- hdoj--3062--party(2-sat 可行解)
Party Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Subm ...
- oracle得到建表语句
第一种方法是使用工具,如:pl/sql developer,在[工具]--[导出用户对象]出现就可以得到建表脚本. 第二种方法是,sql语句. DBMS_METADATA.GET_DDL包可以得到数据 ...
- 一个Python项目的创建架构
要进行Python项目的编写,很多人刚开始一筹莫展,不知道该如何去构建一个项目,现在粗略的描述一下一个项目的创建过程,供大家参考了解一下: 大家可以先忽略其中创建的函数 ,每个包的含义都有定义,大家可 ...