前言
在地圖上渲染一層類似于經緯線的網格層,更有利于準确的确定區域,在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),如下:
- map 參數指定了網格層關聯的地圖對象,也可以不設定該參數,使用其setMap()函數;
- maxLines 指定以地圖中心為參考,左右經線和上下緯線的最大數量,預設值是 100,這表示将繪制200條經線和緯線。需要注意渲染速度會随着maxLines的變大而下降;
- strokeStyle 指定線的樣式,值是一個“ol.style.Stroke”對象,如果沒有指定該參數,其預設樣式是rgba(0,0,0,0.2);
- targetSize 指定每個網格覆寫的區域的大小,機關是像素,預設是100,也就是 10 像素 × 10 像素。
API
“ol.Gracule”對外開放的API也有四個,如下:
- getMap,取得與網格相關聯的地圖對象;
- setMap,設定與網格相關聯的地圖對象,網格将在關聯的地圖之上渲染;
- getMeridians,取得所有經線組成的數組,每條繪制的經線都是“ol.geom.LineString”對象;
- getParallels,取得所有緯線組成的數組,每條繪制的維線也都是“ol.geom.LineString”對象。
實作
提供的可配置參數和API都比較有限,能做的事情也比較有限,接下來我們看看其實作原理,友善我們對其進行定制改寫。 要了解一個類的具體實作,我們首先要分析其結構,其公私有變量和成員函數,歸納其内部互相調用關系,理清脈絡。“ol.Graticule”的脈絡如下:
OL3中的類構造都使用構造函數模式和原型模式,在構造函數中,除了指派一些參數外,最後調用了“setMap”,setMap會對地圖對象的“POSTCOMPOSE”事件綁定“handlePostCompose_”監聽函數,“handlePostCompose_”做了所有初始化并渲染網格的工作。其中,“createGraticule_”做渲染工作,“addMeridian”和“addParallel”做實際的渲染經線和緯線的工作。
setMap
setMap定義如下:
<span style="font-family:Times New Roman;">/**
* 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;
};</span>
setMap首先判斷初始化時是否指定了“map_”參數,如果指定了,首先解除綁定地圖對象“POSTCOMPOSE”事件的監聽函數“handlePostCompose_”,如果指定新的地圖對象,則對新指定的 map 對象,綁定`POSTCOMPOSE`事件監聽函數“handlePostCompose_”,并調用 map 對象的 render 方法,最後将地圖對象指派給“this.map_”。從以上的類脈絡圖看,“handlePostCompose_”功能是初始化網格并渲染在地圖上,并随着地圖縮放等操作觸發的“POSTCOMPOSE”事件,根據實際情況重新渲染。
addMeridian_&addParallel_
實際的渲染工作是由“addMeridian_”和“addParallel_”完成的,我們選擇一個來進行說明,“addMeridian_”将從“getMeridian_”獲得的經線添加到“this.meridians_”數組,“addMeridian_”函數添加前會判斷經線是否在地圖視口内,如果是才會添加,“handlePostCompose_”将“this.meridians_”數組中的經線對象(lineString)渲染到地圖之上:vectorContext.drawLineString(line, null),“getMeridian”實作如下:
/**
* @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;
};
ol.geom.flatgeodesic.meridian方法傳回經線的坐标集合, lineString.setFlatCoordinates方法将lineString坐标設定為flatCoordinates,這樣就完成了一條經線的初始化。
總結
本文總結了“ol.Graticule”的用法和具體實作,openlayers3中的網格支援目前還不是很完善,如果需要更多的功能,要自己去擴充和實作。
文中的執行個體可以到我的GitHub下載下傳, 好的,就寫到這裡,有什麼問題,可以在文章下面留言或者給我發郵件。