在地图上渲染一层类似于经纬线的网格层,更有利于准确的确定区域,在WGS84坐标系下,以度,分,秒为单位,称之为“经纬网”,其网格是以经纬线来划分的。在OpenLayers3中,渲染网格的类是“ol.Graticule”。本文中,我结合实例,讲解“ol.Graticule”的用法和具体实现。
初始化一个网格层,然后将其关联的map对象设置为map(预先定义好的),网格层便会在关联的地图上渲染。初始化网格层可传的参数和方法下面会说明,例子如下(完整的例子可以到我的GitHub查看):
var graticuleLayer = new ol.Graticule({
// map: map,
strokeStyle: new ol.style.Stroke({
color: 'rgba(12, 12, 12, 0.8)',
width: 0.6
}),
targetSize: 100
});
graticuleLayer.setMap(map);
执行结果如下图:
初始化“ol.Gracule”时可调节的参数有四个(map,maxLines,strokeStyle和targetSize),如下:
“ol.Gracule”对外开放的API也有四个,如下:
OL3中的类构造都使用构造函数模式和原型模式,在构造函数中,除了赋值一些参数外,最后调用了“setMap”,setMap会对地图对象的“POSTCOMPOSE”事件绑定“handlePostCompose_”监听函数,“handlePostCompose_”做了所有初始化并渲染网格的工作。其中,“createGraticule_”做渲染工作,“addMeridian”和“addParallel”做实际的渲染经线和纬线的工作。
setMap定义如下:
/**
* Set the map for this graticule. The graticule will be rendered on the
* provided map.
* @param {ol.Map} map Map.
* @api
*/
ol.Graticule.prototype.setMap = function(map) {
if (this.map_) {
this.map_.un(ol.render.EventType.POSTCOMPOSE,
this.handlePostCompose_, this);
this.map_.render();
}
if (map) {
map.on(ol.render.EventType.POSTCOMPOSE,
this.handlePostCompose_, this);
map.render();
}
this.map_ = map;
};
setMap首先判断初始化时是否指定了“map_”参数,如果指定了,首先解除绑定地图对象“POSTCOMPOSE”事件的监听函数“handlePostCompose_”,如果指定新的地图对象,则对新指定的 map 对象,绑定`POSTCOMPOSE`事件监听函数“handlePostCompose_”,并调用 map 对象的 render 方法,最后将地图对象赋值给“this.map_”。从以上的类脉络图看,“handlePostCompose_”功能是初始化网格并渲染在地图上,并随着地图缩放等操作触发的“POSTCOMPOSE”事件,根据实际情况重新渲染。
/**
* @param {number} lon Longitude.
* @param {number} minLat Minimal latitude.
* @param {number} maxLat Maximal latitude.
* @param {number} squaredTolerance Squared tolerance.
* @return {ol.geom.LineString} The meridian line string.
* @param {number} index Index.
* @private
*/
ol.Graticule.prototype.getMeridian_ = function(lon, minLat, maxLat,
squaredTolerance, index) {
goog.asserts.assert(lon >= this.minLon_,
'lon should be larger than or equal to this.minLon_');
goog.asserts.assert(lon <= this.maxLon_,
'lon should be smaller than or equal to this.maxLon_');
var flatCoordinates = ol.geom.flat.geodesic.meridian(lon,
minLat, maxLat, this.projection_, squaredTolerance);
goog.asserts.assert(flatCoordinates.length > 0,
'flatCoordinates cannot be empty');
var lineString = this.meridians_[index] !== undefined ?
this.meridians_[index] : new ol.geom.LineString(null);
lineString.setFlatCoordinates(ol.geom.GeometryLayout.XY, flatCoordinates);
return lineString;
};