上一篇也说到瓦片,我们为什么使用瓦片?这一篇主要是关于如何拼接地图?
下面的一张图,可以一眼明了,地图是如何切割以及拼接的。
瓦片信息 |
瓦片信息包括切图原点,瓦片大小,格式,分辨率以及分辨率级别等。
切图原点,一般是整个坐标系的最左上角,比如说,web墨卡托是[-20037508.3427892, 20037508.3427892]。切图原点右侧列数是正数,左侧的列数是负数,下侧行数是正数,上侧行数是负数。
瓦片的宽度、高度,目前互联网最常见的瓦片宽度和高度都是256像素。
瓦片格式,可能是png,jpg等。
分辨率,这里不是指电脑的分辨率。而这里意思是一像素代表多少米,类似于比例尺。
分辨率级别,含有若干级别的分辨率,不同的分辨率下面,显示不同的要素信息。例如,低分辨率下面,显示洲名称和海洋名称。中分辨率下面,显示省名。高分辨率下面,就显示POI信息。互联网企业当中分辨率级别数在20上下。
地图范围,切图的范围,只在这个范围下面才切图,其他的区域都没有相应的瓦片。如果把所有的分辨率都切完的话,是非常耗时间的。仅仅是中国区域,一台8核的机器,也得需要一个月才能切完,更何况全世界了。
Google为例 |
谷歌使用的web墨卡托投影,分辨率级别一共22级,他的每一级分辨率大小20037508.3427892*2/(256*(2^i))。20037508.3427892*2代表整个的X轴范围,256代表图片的像素大小,2代表是0级时有两列(有的地图0级只有1列,这个时候就是2^(i-1)),i代表级别。
这个时候,分辨率集合就是[78271.51696402031, 39135.758482010155, 19567.879241005077, 9783.939620502539, 4891.969810251269, 2445.9849051256347, 1222.9924525628173, 611.4962262814087, 305.74811314070433, 152.87405657035217, 76.43702828517608, 38.21851414258804, 19.10925707129402, 9.55462853564701, 4.777314267823505, 2.3886571339117526, 1.1943285669558763, 0.5971642834779382, 0.2985821417389691, 0.14929107086948454, 0.07464553543474227, 0.037322767717371134]。
我们现在需要计算两个东东,一个是当前分辨率下面最大的行和列数,第二个某一个坐标在第几行几列。下面会列出好几个公式,一定要理解为什么这么计算,否则移植到其他的切图服务不会自己列出相应的公式了。
最大行数和列数 |
计算公式,20037508.3427892*2/(256*scale),20037508.3427892*2代表X轴和Y轴范围,256代表图片的像素大小,scale代表分辨率大小。
通过这个计算公式,我们知道最大的行数和列数,是[2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304],注意的是行列值是从0开始的。
比如说,1级下面,有两行和两列。这四张图片的地址如下:
我们把这四张图片合在一起的话,就变成如下的图,这就是一个世界的地图了。
计算行,列位置 |
计算行位置公式:Math.floor((x-(-20037508.3427892))/256/scale))。x-(-20037508.3427892)是最左侧的距离,scale分辨率,256代表宽度。Math.floor小于或等于指定数字的最大整数,这样值是从0开始的。
计算列位置公式:Math.floor((20037508.3427892-y)/256/scale))。20037508.3427892-y是到最上侧的距离,scale分辨率,256代表宽度。Math.floor小于或等于指定数字的最大整数,这样值是从0开始的。
左上角是X值最小,Y值最大。屏幕是X和Y值都是最小的。这一点转换关系需要明白,否则Y轴的方向都反了。
如果切图不是从左上角开始的,就得计算每一个分辨率下面的左上角和右下角所处的行和列,就可以知道行和列的范围。同理,可计算当前可视区域的行和列。
我们如果知道行列以及分辨率等级,就很容易知道这个瓦片的地址。http://mt2.google.cn/vt/x=0&y=0&z=1,这里的x代表参数行数,y代表列数,z代表分辨率等级。
Google这种图片地址属于非常好计算,幸好也是非常普遍的。比较难的,算是微软的,行列以及分辨率等级计算都差不多,难的是想x,y,z参数不知道怎么计算的。
例如,http://ak.dynamic.t2.tiles.virtualearth.net/comp/ch/1232?mkt=en-us&it=G,VE,BX,L,LA&shading=hill&og=31&n=z ,这个图片地址,这个1232不知道怎么来的。不过幸好找到一个论文才弄明白,《利用BingMaps地图切片实现网络地图服务》,地址http://wenku.baidu.com/link?url=7Mh7h8Vn94V2ha8LJLIy3WF2ONjLwcEaRCywujCR-fk4Pa-PGKrmcKL1zBaOmUK5eDmaIrXbO6SyAPdMHCOAXTn6PnhqBsL6yPsenWdMkfK
我下面列出相关计算代码。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
function
getBingMapsImageNumber(x,y,z){
//10进制转化为2进制,前面补充0
_f=
function
(n,m){
var
t= n.toString(2)+
""
;
for
(; t.length<m;){
t=
"0"
+t;
}
return
t;
}
var
_if=_f(x,z);
var
_jf=_f(y,z);
var
r=
""
;
for
(
var
k=0;k!=z;++k){
r+=_jf[k]+_if[k];
}
r=parseInt(r,2).toString(4);
return
_f(r,z);
}
|