WMS 是OGC制定的标准 WEB GIS 协议,现在众多的图形提供商都提供了自己的WEB图形服务,例如:ArcIMS、GoogleMaps、KaMap等等、要使用这些服务并制作自己的WEB客户端,使用 OpenLayers 是很方便的事情,其中 WMS 是比较通用的协议,尤其适合服务器端矢量图形的生成,但是在我们自己的项目中发现由于WMS每次发送给服务器的都是几何坐标的格式化字符串来表达视野,这导致服务器端在提供瓦片时无法很好的进行高效的服务,几乎总是需要对瓦片进行拼接和剪裁,通过分析 GOOGLE 和 TMS 协议,发现很多服务都不采用几何坐标的字符串来表达视野,而是直接提供瓦片的行列号,这样服务器端甚至可以直接使用一个简单的HTTP服务器就可以了,基于以上考虑决定扩展OpenLayers来提供一个自己的瓦片服务的客户端;
原理很简单,就是在构造 WMS请求的URL时,采用自己的方式进行构造,代码如下:
1
/*
*
2
* Class: ShineEnergy.Layer.TileImage
3
*
4
* Inherits from:
5
* - <OpenLayers.Layer.WMS>
6
*/
7
ShineEnergy.Layer.TileImage
=
OpenLayers.Class(OpenLayers.Layer.WMS, {
8
9
/*
*
10
* Constructor: ShineEnergy.Layer.TileImage
11
*
12
* Parameters:
13
* name - {String} A name for the layer
14
* url - {String} Base url for the TileImage
15
* params - {Object} An object with key/value pairs representing the
16
* GetMap query string parameters and parameter values.
17
* options - {Object} Hashtable of extra options to tag onto the layer
18
*/
19
initialize:
function
(name, url, params, options) {
20
OpenLayers.Layer.WMS.prototype.initialize.apply(
this
, arguments);
21
},
22
23
/*
*
24
* APIMethod:destroy
25
*/
26
destroy:
function
() {
27
//
for now, nothing special to do here.
28
OpenLayers.Layer.WMS.prototype.destroy.apply(
this
, arguments);
29
},
30
31
/*
*
32
* APIMethod: clone
33
*
34
* Parameters:
35
* obj - {Object}
36
*
37
* Returns:
38
* {<ShineEnergy.Layer.TileImage>} An exact clone of this <ShineEnergy.Layer.TileImage>
39
*/
40
clone:
function
(obj) {
41
42
if
(obj
==
null
) {
43
obj
=
new
ShineEnergy.Layer.TileImage(
this
.name,
44
this
.url,
45
this
.options);
46
}
47
48
//
get all additions from superclasses
49
obj
=
OpenLayers.Layer.WMS.prototype.clone.apply(
this
, [obj]);
50
51
//
copy/set any non-init, non-simple values here
52
53
return
obj;
54
},
55
56
/*
*
57
* Method: getURL
58
*
59
* Parameters:
60
* bounds - {<OpenLayers.Bounds>}
61
*
62
* Returns:
63
* {String} A string with the layer's url and parameters and also the
64
* passed-in bounds and appropriate tile size specified as
65
* parameters
66
*/
67
getURL:
function
(bounds) {
68
bounds
=
this
.adjustBounds(bounds);
69
var
res
=
this
.map.getResolution();
70
var
tileOriginY
=
this
.options.maxExtent.top;
71
var
tileOriginX
=
this
.options.maxExtent.left;
72
var
x
=
Math.round((bounds.left
-
tileOriginX)
/
(res
*
this
.tileSize.w));
73
var
y
=
Math.round((tileOriginY
-
bounds.bottom)
/
(res
*
this
.tileSize.h));
74
var
z
=
this
.map.getZoom();
75
var
path
=
"
?LAYER=
"
+
this
.params.LAYERS
+
"
&X=
"
+
x
+
"
&Y=
"
+
y
+
"
&Z=
"
+
z
+
"
&S=Map
"
;
76
var
url
=
this
.url;
77
if
(url
instanceof
Array) {
78
url
=
this
.selectUrl(path, url);
79
}
80
return
url
+
path;
81
},
82
83
CLASS_NAME:
"
ShineEnergy.Layer.TileImage
"
84
});
85
经过如上简单的进行扩展,就可以使用实现自定义的 WEB GIS 协议,服务器端只需要根据 LAYER/X/Y/Z参数可以确定唯一的一张瓦片图片,返回给客户端就可以了,同时也方便服务器端采用缓存优化处理;
在上面的例子中还有一个参数“S”,这个参数是备用参数,你也可以当做是一个展示如何增加自定义参数的例子来修改,例如增加控制客户端的缓存行为的功能就可以根据时间产生不同的参数来实现;
最后补充一点,WMS协议在根据视野填充瓦片的时候,是根据左下角的地理坐标开始进行填充的,而ARCGIS等工具则是根据左上角进行行列号进行编排的,所以要想能够和其他的图层完全配准,那么必须根据DPI和比例尺计算出一个确定的视野高度,这个高度要求能够正好在最大的视野情况下正好有整数个瓦片进行平铺;
















