OpenLayers 3 之 添加地图网格

前言

在地图上渲染一层类似于经纬线的网格层,更有利于准确的确定区域,在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下载,好的,就写到这里,有什么问题,可以在文章下面留言或者给我发邮件。

时间: 2024-10-10 16:29:08

OpenLayers 3 之 添加地图网格的相关文章

OpenLayers 3 之 添加地图鼠标右键菜单

添加右键菜单,首先我们要监听鼠标右键点击的操作,我们知道鼠标右键事件名是 contextmenu,当鼠标在 html 元素之上,点击鼠标右键,便会触发 contextmenu 事件,在 contextmenu 事件的回调函数中实现相应的显示菜单功能即可. 那么在 openlayers 中,在地图中添加这个事件,我们从哪里下手呢?首先我们得了解 openlayers 的初始化页面的过程. openlayers 初始化页面过程 openlayers 也是一个前端库,那么它肯定离不开 html 的运用

supermap布局设定地图网格及布局网格

地图网格设定 LayoutElements elements = m_mapLayoutControl.MapLayout.Elements; //构造GeoMap GeoMap geoMap = new GeoMap(); geoMap.MapName = "京津地区交通干线图"; // 新建一个 GeoMapGrid 对象. GeoMapGrid geoMapGrid = new GeoMapGrid(); // 设置 GeoMapGrid 对象的相关属性,即设置地图的经纬网的风格

中科燕园webgis外包 讲解2----使用geoserver+openLayers加载google地图

1. 准备工作 安装java环境即JDK 下载geoserver  官网:http://geoserver.org/display/GEOS/Welcome 我的描述使用的是geoserver1.7版本,2.0版本类似,只是1.7是中文的,2.0版本可以再使用过1.7版本后自己摸索,大同小异. 下载openLayers 官网:http://www.openlayers.org/ 配置好JAVA_HOME 下载地图(shp格式) 可到此网站:http://nfgis.nsdi.gov.cn/asp

ArcGIS Engine添加地图元素的实现

在ArcGIS中,我们使用的制图控件除了MapControl之外,还有PageLayoutControl,用于页面布局和制图,生成一幅成品地图. PageLayoutControl 封装了PageLayout对象,提供布局视图中控制元素的属性和方法,其中包括图形的位置属性.标尺和对齐网格的设置,以及确定页面显示在屏幕上的方法. 我们将实现在布局视图下的添加图例.指北针.比例尺和文本的操作. 添加地图元素: /// <summary> /// 添加地图元素 /// </summary>

ArcEngine添加地图属性字段

/// <summary> /// 添加地图属性字段 /// </summary> /// <param name="name">名称</param> /// <param name="aliasName">别名</param> /// <param name="length">长度</param> /// <param name="d

005.使用百度SDK写hello baidumap时,在布局xml文件中添加地图控件时;提示&#39;clickable&#39; attribute found, please also add &#39;focusable&#39; 错误

0.报错&提示信息: 'clickable' attribute found, please also add 'focusable'  A widget that is declared to be clickable but not declared to be focusable is not accessible via the keyboard. Please add the focusable attribute as well. 1.原因: 一个控件,如果没有定义focusable

openLayers加载高德地图

之前用openlayers对高德,百度,腾讯,bing,supermap,天地图,arcgis,google等地图进行了对接,今天简单介绍一下openlayers+高德: 在Openlayers.Layer.XYZ.js中有如下更改:(百度兴趣点下载工具:http://www.cnblogs.com/songjiang6940/p/baiduPOI.html) 1 * bounds - {<OpenLayers.Bounds>} 2 * 3 * Returns: 4 * {String} A

如何在网页中添加地图

@{ Layout = null;} <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equi

openlayers3添加地图控件

//添加属性控件 map.addControl(new ol.control.Attribution()); //添加鼠标定位控件 map.addControl(new ol.control.MousePosition({ undefinedHTML: 'outside', projection: 'EPSG:4326', coordinateFormat: function(coordinate) { return ol.coordinate.format(coordinate, '{x},