赞
踩
目录
一、OpenLayers概览
二、OpenLayers调用方式
三、OpenLayers基本组件
四、OpenLayers的Map、Layers、Source、Viewer使用
一、OpenLayers概览
OpenLayers是一个WebGIS前端开发的JavaScript包,用于地图服务的访问、操作和展示等。
OpenLayers访问地理信息网络数据符合行业标准,通过远程调用(rest\soap)的方式,将数据服务加载到浏览器中显示。OpenLayers 支持商业地图服务源,包括Google Maps、Yahoo、 Map、微软Virtual Earth 等,支持OGC制定的WMS(Web Mapping Service)、WMTS(Web Map Tile Service)、WFS(Web Feature Service)等网络地图服务源,如OSM、天地图等,也支持描述性矢量文件或矢量切片访问,如:XML、GML、GeoJSON、GeoRSS、JSON、KML、WFS、WKT等。
OpenLayers采用面向对象方式开发,使用来自Prototype.js和Rico中的一些组件,支持Canvas、webgl等渲染方式,动态扩展。
OpenLayers 可以实现地图浏览的基本操作,如:放大(Zoom In)、缩小(Zoom Out)、平移(Pan)等,也可以实现简单地点、线、面等空间查询操作,还可以实现一些较为复杂的地图操作,如:图层叠加、地理编码、矢量编辑、空间分析、聚类图、热力图、自定义交互、渲染优化、路线追踪、飞行动画等等,有较好的人机交互和用户体验效果。
openlayers官网:https://openlayers.org/
二、OpenLayers调用方式
1、在https://openlayers.org/download/找到OpenLayers压缩包下载;
2、选择版本压缩包下载,完成后解压文件;
3、可以使用网络或者本地两种方式调用OpenLayers。
(1)网络方式调用,在openlayers官网中找到层叠样式表css和openlayers的js API网络路径:
<link stylesheet"href="https://openlayers.org/en/v5.3.0/css/ol.css" type="text/css">
<script src="https://openlayers.org/en/v5.3.0/build/ol.js"></script>
(2)本地方式调用,将路径指向下载到本地的css和js:
假如将文件解压到了F盘,路径指向为:
<link href="F:\v5.3.0\v5.3.0\css\ol.css" rel="stylesheet" type="text/css"/>
<script src="F:\v5.3.0\v5.3.0\build\ol.js" type="text/javascript" ></script>
注:你也可以将OpenLayers的css和js文件下载下来,然后使用tomcat、apache等web工具发布成服务,采用网络服务的方式引用。
要显示下面地图
代码如下:
- <!Doctype html>
- <html xmlns=http://www.w3.org/1999/xhtml>
- <head>
- <meta http-equiv=Content-Type content="text/html;charset=utf-8">
- <meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1">
- <meta content=always name=referrer>
- <title>地图示例</title>
- <link href="F:\v5.3.0\v5.3.0\css\ol.css" rel="stylesheet" type="text/css" />
- <script type="text/javascript" src="F:\v5.3.0\v5.3.0\build\ol.js" charset="utf-8"></script>
- </head>
-
- <body>
- <div id="map" style="width: 100%"></div>
- <script>
- // 创建地图
- new ol.Map({
- // 设置地图图层
- layers: [
- // 创建一个使用Open Street Map地图源的瓦片图层
- new ol.layer.Tile({source: new ol.source.OSM()})
- ],
- // 设置显示地图的视图
- view: new ol.View({
- // 定义地图显示中心于经度0度,纬度0度处
- center: [0, 0],
- // 定义地图显示层级为2
- zoom: 2
- }),
- // 让id为map的div作为地图对象的容器
- target: 'map'
- });
- </script>
- </body>
-
- </html>
拷贝该段代码在空的txt文件上,另存为html文件格式,用浏览器打开html文件即可看到地图。如果在本地,只需改写红色部分ol.css和ol.js位置,当然以上代码注明html文件编码为utf-8,所以你新建的html文件本身编码需要保证为utf-8,不然会导致中文乱码。(也可以用notepad、Visual Studio Code、Atom、WebStorm、sublime text等编辑器)
(注:如果你需要将该网页发布到网站上,需要使用iis、tomcat等容器,配置网页进行发布。)
以上代码基本过程是:创建一个地图对象(new ol.Map),设置地图对象三个属性参数(对象):图层( layer:new ol.layer.Tile),视图 (view: new ol.View),地图容器挂接( target: 'map' )。其中,图层属性项引入地图服务(source: new ol.source.OSM())。
openlayers样例:
https://openlayers.org/en/latest/examples/
openlayers API:
https://openlayers.org/en/latest/apidoc/
三、OpenLayers基本组件
OpenLayers框架结构
OpenLayers访问地图服务到网页展示地图的过程为:网络地图服务URL-----数据源Source:URL-----图层Layers:Source----地图Map:Layers---网页容器Div:Map(map需要读取view中的地图显示参数)---网页展示。
1、地图(Map),对应的类是ol.map。地图map是网络地图服务数据显示、操作和管理的容器,它将整个地图的各组成部分(如:layers、source、control、view)组织在一起,起到纽带和基础支撑作用,ol.map的实例对象嵌入到网页中。Map本身没有提供太多的功能,需要拓展的话,应在map上添加laysers(OpenLayers.Control)和controls(OpenLayers.Layer)。
2、地图图层(Layer),对应的类ol.layer。在现行的GIS软件中,图层layer是制作电子地图的最基本单位,它用以表示一个地理数据集(如:道路、水系、居民地、植被等)在GIS软件中的展示方式,一个图层代表一个数据集(该数据集可以是地图服务,也可以是矢量、栅格等数据)。ol.layer的实例化对象layers,是创建、管理各种图层的集合,图层可以引入各类的数据源。
3、数据源(Source),对应的类ol.source。在WebGIS中,数据源是各个地图厂商提供的网络地图服务(WMS\WFS\WMTS等)和各类GIS数据,ol.source的实例化对象用以访问数据源,驱动网络地图服务。ol支持多种多样在线或离线的数据源,可以是静态图像或者瓦片,也可以是栅格化的或者矢量的。如果你想在地图上加载某种格式的数据,或者某种服务提供的数据,都可以优先查看一下OpenLayers是否已经支持了此类地图服务。
4、视图区域(View),对应的类是ol.view。视图view表示在当前浏览器视角下地图展示的方式,如:地图在哪块区域(四至)显示、显示的方位角如何、以多大的比例尺或者分辨率进行显示等等,类似于一个虚拟的正射相机。ol.view的实例对象用以控制地图显示的位置、范围、分辨率、旋转、显示层级等。
5、控件(Control),对应的类ol.control。
地图控件用于实现电子地图中各种图层数据的管理、操作、显示和一些特定的功能,如平移、放大、缩小等按钮。
6、交互(Interaction),对应的类ol.interaction。计算机交互操作是所有图形界面软件都应该具备的功能,如果交互操作实现的不好,会是一件令用户非常痛苦的事情,如linux的shell界面。OpenLayers的交互实现类放在包ol.interaction
下面,提供用户与软件交互,比如我们用鼠标控制地图放大、缩小、移动等等。
以上各地图组件使用的逻辑是:map提供程序的入口,首先寻找到source,source读取网络地图服务,source导入layer,layer将参数传递给map,map通过读取view显示地图的参数,将数据展示在浏览器上。在地图展示过程中,如果涉及到map 的放大、缩小、空间选择及控件control传参等交互事件时,以事件方式向map发送消息,通过消息的参数触发map做出相应的操作。
四、OpenLayers的Map、Layers、Source、Viewer使用
1、Map(地图)
OpenLayers的基础组件是map。单从层次结构上看,网页包含了div容器,div容器包含了map对象,而map对象则包含了layers、view、键盘监听、交互等所有的地图组件对象,layers包含了source(地图服务),依次包含嵌套。map对象是地图浏览、导航、互操作、数据处理的基石,它承载了浏览器上整个地图服务显示的窗口,而layers、view、control、Interaction等拼凑了map。从上面代码的过程,我们也可得知map是所有地图组件的容器,map以搭积木方式搭载在网页上。
(1)创建容器标签div:
- <style>
- html, body, #map{
- margin: 0;
- height: 100%;
- width: 100%;
- font-family: sans-serif;
- }
- <style>
- <div id="map"></div>
(2)将map对象绑定到网页中的div容器标签:
var map = new Map({target:'map'});
(3)map对象创建
构造函数
new ol.map(divid,options?) | 在给定的HTML容器中创建地图,HTML容器通常是DIV。地图大小和容器大小一致。地图的构造函数也能包含选项参数。这些选项参数能包容任意顺序。options是指要标记在地图上有属性的object对象。 |
map参数
参数divid:指定将map对象绑定的网页容器ID。
参数options:对地图容器进行初始化设置。
属性 | 类型 | 描述 |
---|---|---|
events | events | 一个事件对象,可以处理地图上的所有事件。 |
allOverlays | Boolean | 只允许地图使用函数进行覆盖。默认是false,如若是true的话,最底层的图层将作为基图层。 |
div | DOMElement|String | 包含地图的要素。 |
layers | Array(OpenLayers.Layer) | 图层的有序列表的映射。 |
controls | Array(OpenLayers.Control) | 与地图相关的控件的列表,注意它有默认的添加的控件,可进行修改。 |
baseLayer | OpenLayers.Layer | 当前选中的基础层,它决定了缩放级别,坐标系参考系等等。 |
options | Object | 用于传递给类构造函数的参数选项。 |
tileSize | OpenLayers.Size | 可以更改这个参数来改变地图默认的瓦片的大小。 |
projection | String | 设置地图选项,指定投影层添加到地图中。 |
units | String | 地图的单位 |
resolutions | Float | 地图的分辨率,没有在构造函数中设置的时候会以其他与分辨率相关的属性为基础进行设置。 |
maxResolution | Float | 地图的最大的分辨率。 |
minResolution | Float | 地图的最小的分辨率。 |
maxScale | Float | 地图的最大的显示比例。 |
minScale | Float | 地图的最小的显示比例。 |
maxExtent | OpenLayers.Bounds|Array | 地图的最大的显示范围,有四至。 |
maxExtent | OpenLayers.Bounds|Array | 地图的最小的显示范围。 |
restrictedExtent | OpenLayers.Bounds|Array | 尽可能的限制地图导航到这个级别,如果没有限制的话,平移将会限制在给定的范围。 |
numZoomLevels | Integer | 地图的缩放的级别。 |
theme | String | 是一个css文件相对的路径,用于加载主题的风格。 |
displayProjection | OpenLayers.Projection | 数据采用的坐标系。 |
tileManager | OpenLayers.TileManager|Object | 默认的情况下,如果包含TileManager.js,地图将使用它处理图像请求和缓存瓦片图像的元素。 |
fallThrough | Boolean | OpenLayer是否允许地图上的事件销毁其他页面上的元素,或者接受它们,默认是接受的。 |
autoUpdateSize | Boolean | OpenLayer是否自动调整地图的大小,当resize事件被触发的时候,默认是。 |
eventListeners | object | 如果在结构中设置选项,那么eventlistene对象将在OpenLayers.Events.on中注册,对象结构必须是一个监听器对象。 |
eventListeners | object | 如果在结构中设置选项,那么eventlistene对象将在OpenLayers.Events.on中注册,对象结构必须是一个监听器对象。 |
panMethod | Function | 用来进行移动的函数。 |
zoomMethod | Function | 用来行缩放的函数。 |
map对象常用初始化参数有:
layers(地图图层):核心参数,地图图层用于向map对象传递地图数据。如果未定义,则将渲染没有图层的地图。layers为复数,说明可以在map对象中放置多个图层,如在加载影像服务和影像注记服务的时候,可以将影像注记服务放在影像服务上面。
controls(控件):初始化控件。如果未指定,使用默认模式
pixelRatio:设备上物理像素和逻辑像素的比例
interactions(交互):初始化交互模式。如果未指定,使用默认模式
keyboardEventTarget(键盘监听事件):这是触发敲击键盘发出的事件消息与map交互的,如果未指定,使用默认方式。
maxTilesLoading:在map对象里同时最大加载的切片数量
moveTolerance(光标靠近容差):光标必须移动的最小距离(以像素为单位)才能被检测为地图移动事件,而非点击。增加此值可以更轻松地单击地图。
overlays(图层叠加):初始化时叠加图层。默认情况下不叠加
target(地图容器):用以挂载map对象
view(地图视图):控制地图的显示
注:以上参数并非初始化地图必须项,部分参数选择性填写即可。其中,layers、target、view一般为必填项。因为OpenLayers 初始化一幅地图(map),至少需要一个可视区域(view)、一个或多个图层( layer)和 一个地图加载的目标 HTML 标签(target)。
官网中初始化map对象的代码如下:
- <div id="map" style="width: 100%"></div>
- var map = new Map({
- view: new View({
- center: [0, 0],
- zoom: 1
- }),
- layers: [
- new TileLayer({
- source: new OSM()
- })
- ],
- target: 'map'
- });
map对象方法较多,如下:
方法 | 返回值 | 描述 |
---|---|---|
getViewport() | DOMElement | 获取DOMElement 描述视图的端口,返回一个Dom元素。 |
render(div) | null | 将地图发送到指定的容器中。 |
destroy() | null | 删除地图。 |
setOptions(options) | null | 设置地图的参数。 |
getTileSize() | OpenLayers.Size | 获取地图瓦片的大小,并返回值。 |
getBy(array,property,match) | Array | 获取对象的列表属性和一个匹配项,返回一个集合。 |
getLayersBy(property,match) | Array(OpenLayers.Layer) | 获取与给出的条件相符合的图层列表。 |
getLayersByName(match) | Array(OpenLayers.Layer) | 通过图层名匹配的方式获取图层列表 。 |
getLayersByClass(match) | Array(OpenLayers.Layer) | 通过 CLASS_NAME匹配的方式获取图层。 |
getControlsBy(property,match) | Array(OpenLayers.Control) | 获取与给出的条件相符合的控件的列表。 |
getControlsByClass(match) | Array(OpenLayers.Control) | 通过 CLASS_NAME匹配的方式获取控件,并返回。 |
getLayer(id) | OpenLayers.Layer | 通过图层的id获取图层 。 |
addLayer(layer) | Boolean | 添加图层返回true则添加成功否则失败 。 |
addLayers(layers) | null | 添加一系列图层。 |
removeLayer(layer,setNewBaseLayer) | null | 清除图层(所有的内容)。 |
getNumLayers() | Integer | 得到地图上加载的图层的数量。 |
Integer | getLayerIndex(layer) 得到给定的图层在图层栈堆中的位置 返回值为-1,代表地图上不存在该图层 | |
setLayerIndex(layer,idx) | null | setLayerIndex(layer,idx) 改变地图的z_index编号,这个不能有效的提高基础层上的覆盖。 |
raiseLayer(layer,delta) | null | 改变delta(?)给定的图层的编号。 |
setBaseLayer(newBaseLayer) | null | 设置baselayer。 |
addControl(control,px) | null | 在地图上添加单个控件 控件的位置可以选取。 |
addControls(controls,pixels) | null | 在地图上添加多个控件。 |
getControl(id) | OpenLayers.Control | 通过ID得到某个控件。 |
removeControl(control) | null | 从地图上移除某个控件。 |
addPopup(popup,exclusive) | null | 添加弹出的窗口,可以设置exclusive值为true,先关闭其他的弹出窗口。 |
removePopup (popup) | null | 移除弹出窗口。 |
getSize() | OpenLayers.Size | 得到某个元素的大小 。 |
updateSize() | null | 动态的改变某个元素的大小。 |
getCenter() | null | 获取视图的中心位置。 |
getZoom() | Integer | 获取地图缩放的级别。 |
pan(dx,dy,options) | null | 在屏幕上移动一定像素的距离。 |
panTo(lonlat) | null | 移动到某一个坐标。 |
setCenter(lonlat,zoom,dragging,forceZoomChange) | null | 在一定的缩放级别下设置地图的中心点的位置。 |
getMinZoom() | Number | 获取当前地图视图下的最小的缩放级别。 |
getProjection() | String | 返回投影的方式。 |
getProjectionObject() | OpenLayers.Projection | 返回基图层投影对象。 |
getMaxResolution() | String | 获取地图的最大的显示比例。 |
getMaxExtent(options) | OpenLayers.Bounds | 获取最大的显示的范围 。 |
getNumZoomLevels() | Integer | 当前基图层能过显示缩放的级别数。 |
getExtent() | OpenLayers.Bounds | 获取当前视口的范围。 |
getResolution() | Float | 获取当前地图的缩放比例。 |
getUnits() | Float | 获取当前地图的单位。 |
getScale() | Float | 获取当前地图比例的分母。 |
getZoomForExtent(bounds,closest) | Integer | 获取与指定的显示范围相匹配的缩放级别 。 |
getResolutionForZoom(zoom) | Float | 获取与指定的缩放的级别相匹配的分辨率 。 |
getZoomForResolution(resolution,closest) | Integer | 获取与指定的分辨率相匹配的缩放级别 。 |
zoomTo(zoom,xy) | null | 缩放到一个指定的缩放级别。 |
zoomIn() | null | 放大。 |
zoomOut() | null | 缩小。 |
zoomToExtent(bounds,closest) | null | 缩放到指定的显示的范围,并且回到中心处。 |
zoomToMaxExtent(options ) | null | 满屏显示,并且回到中心处。 |
zoomToScale(scale,closest) | null | 缩放到指定的比例。 |
getViewPortPxFromLonLat(lonlat) | OpenLayers.Pixel | 根据经纬度坐标获取视口像素。 |
getLonLatFromPixel(px) | OpenLayers.LonLat | 根据视口的像素获取坐标经纬度 。 |
getPixelFromLonLat(lonlat) | OpenLayers.Pixel | 根据地图的位置获取位置的像素,这个位置像素是一个整数。 |
getViewPortPxFromLayerPx(layerPx) | OpenLayers.Pixel | 将图层像素转换为视口坐标 。 |
getLayerPxFromViewPortPx(viewPortPx) | OpenLayers.Pixel | 将视口像素转换为图层的坐标。 |
getLayerPxFromLonLat(lonlat) | OpenLayers.Pixel | 根据传入的经纬度转换为图层的坐标。 |
在上述方法中,有增加控件、删除控件、增加图层、删除图层、设置地图参数、获取和改变地图显示方式等功能。方法较为简单,不做介绍,可参看api docs或者例子。
API:https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html
https://openlayers.org/en/latest/apidoc/module-ol_View-View.html
2、layers(地图图层):
地图由一个或多个图层组成,不同的图层存储不同类型的地物,如线状图层存储线状地物:道路、河流;点状图层存储POI信息:机构、学校等地名地址点;面状地物存储诸如公园等有一定范围的地物。图层layers是介于map对象和source对象的一个中间对象。layers包含了矢量和栅格两种图层,矢量图层是指在渲染发生在浏览器的图层,source返回的数据类型是矢量,如geojson的坐标串;栅格图层则是由服务器渲染,返回到浏览器的是图像。图层layers也包含以上两类数据的变种,栅格切片图层(TileLayer)和矢量切片图层(vector tile)。切片是为了加快浏览器访问效率在服务器端预先配置好的缓存数据。栅格切片图层是指图片数据,如:jpg/png/bundle,一般为256*256大小,手机中使用为512*512大小,常见的为WMTS服务。矢量切片数据是指类似xml文档型的描述型数据,如:GeoJSON,TopoJSON和mvt等等。因此,图层layer按照数据源的访问方式不同,可以分为四个类:ol.layer.Tile(静态栅格切片)、ol.layer.Image(动态地图:此处的image并非指遥感影像,而是特指地图图像,地图可以是遥感影像制作的,也可以是矢量数据制作的,还可以是遥感影像和矢量制作的地图)、ol.layer.Vector(矢量)、ol.layer.VectorTile(矢量切片)
- layers: [
- new ol.layer.Tile({
- source: new ol.source.OSM()
- })
- ]
ol.layer.Tile构造函数
ol.layer.Tile(name,options) | name:{String} 图层名字. options :{Object} 图层选项 |
参数name:设置图层名字
参数options:初始化图层参数
ol.layer.Tile options参数如下:
名称 | 类型 | 描述 |
---|---|---|
className | 字符串 (默认为“ ol-layer”) | 设置为layer元素的CSS类名称。 |
opacity | 整数 (默认为1) | 不透明度(0,1)。 |
visible | 布尔值 (默认为true) | 能见度。 |
extent | 模块:ol /范围〜范围 | 图层渲染的边界范围。该图层不会在此范围之外渲染。 |
zIndex | 整数 | 图层渲染的Z索引。在渲染时,将首先按Z索引然后按位置对图层进行排序。当时 |
minResolution | 整数 | 该层可见的最低分辨率(含)。 |
maxResolution | 整数 | 在该层以下可见的最大分辨率(不包括)。 |
minZoom | 整数 | 最小视图缩放级别(不包括此级别),在该级别之上,该层将可见。 |
maxZoom | 整数 | 该图层可见的最大视图缩放级别(包括该级别)。 |
preload | 整数 (默认为0) | 预加载。将低分辨率图块加载到 |
source | 模块:ol / source / Tile〜TileSource | 该层的来源。 |
map | 模块:ol / PluggableMap〜PluggableMap | 将图层设置为地图上的叠加层。地图将不会在其图层集合中管理此图层,并且该图层将呈现在顶部。这对于临时层很有用。在地图上添加图层并由地图管理图层的标准方法是使用 |
useInterimTilesOnError | 布尔值 (默认为true) | 出现错误时使用临时磁贴。 |
layers基本参数:
source:核心参数,数据源用于向layers传递地图数据,图层作用是以一定的样式渲染数据,source则指定了数据;
className:图层各个元素的样式;
opacity:透明度,默认为 1 ,即完全透明;
visible:是否可见;
zIndex:图层的叠加次序,默认是0,最底层,如果使用setMap方法添加的图层,zIndex值是Infinity,在最上层;
extent:图层渲染的区域,即浏览器窗口中可见的地图区域。extent 是一个矩形范围,格式是[number, number, number, number] 分别代表 [left, bottom, right, top] 。为了提升渲染效率和加载速度,extent范围之外的瓦片是不会请求的,当然也不会渲染;
minResolution:图层可见的最小分辨率;
maxResolution:图层可见的最大分辨率;
minZoom:图层可见的最小zoom level;
maxZoom:图层可见的最大zoom level。
其中,source是layers最重要的参数,用于访问地图数据(也就是网络地图服务)。
- new ol.layer.Vector({//以下为图层的属性选项, 都可设置,所以皆有getter/setter
- opacity:2,//透明度 区间范围为(0, 1) 默认为1
- visible:true,//显示属性 布尔值 默认为true
- extent:[],//图层渲染的边界范围。该层将不会在此范围之外呈现
- zIndex:2,//图层渲染的索引层级。在渲染时,图层将被排序,首先是z-idnex,然后是位置,当为undefined时,对于添加到映射的layers集合中的层,zIndex为0,或者当使用该层的setMap()方法时,zIndex为无穷大
- minResolution:3,//该层可见的最小分辨率(包括在内)
- maxResolution:6,//该层可见的最大分辨率(包括在内)
- renderOrder:,//呈现顺序。函数用于在呈现前对特性进行排序。默认情况下,特性是按照创建它们的顺序绘制的。使用null来避免排序,但是得到一个未定义的绘制顺序
- renderBuffer:100,//默认为100 缓冲区
- renderMode:'vector',//默认为'vector' 矢量图层的渲染模式
- source:new ol.source.VectorSource(),//图层源
- map: ,//把图层覆盖在地图上,地图不会在它的图层集合中管理这个图层,这个图层将被呈现在顶部,这对于临时层非常有用
- declutter:false,//默认为false 整理图片和文字。清理应用于所有图像和文本样式,优先级由样式的z-index定义。z-index指数越低,优先级越高
- style:new ol.style.Style(),//图层样式
- updateWhileAnimating:false,//默认为false
- updateWhileInteracting:false,//默认为false
- })
layers 对象方法如下:
方法 | 返回值 | 描述 |
---|---|---|
setName(newName) | 浮点 | 设置该层的新层名称。 |
addOptions(newOptions,reinitialize) | 浮点 | |
onMapResize() | 浮点 | 该功能可以由子类实现 |
redraw() | 布尔型 | 重绘图层。 |
removeMap(map) | 浮点 | 正如setMap()允许每一层对添加到地图上采取个性化操作的可能性一样,removeMap()允许每一层对从其删除上进行个性化操作。 |
getImageSize(bounds) | {OpenLayers.Size} | |
setTileSize(size) | 浮点 | 根据地图尺寸设置平铺尺寸。 |
getVisibility() | {布尔} | 应该显示该图层(如果在范围内)。 |
setVisibility(可见性) | 浮点 | 设置图层的可见性标志,并相应地隐藏/显示和重绘。 |
显示(显示) | 浮点 | 隐藏或显示图层。 |
computeInRange() | {布尔} | 该图层可在当前地图的当前分辨率下显示。 |
setIsBaseLayer(isBaseLayer) | 浮点 | |
getResolution() | 浮点 | 从分辨率数组中获取的地图的当前选定分辨率,由当前缩放级别索引。 |
getExtent() | {OpenLayers.Bounds} | 一个Bounds对象,它表示当前viewPort的lon / lat边界。 |
getZoomForExtent(范围,最接近) | 浮点 | |
getResolutionForZoom(zoom) | 浮点 | |
getZoomForResolution(分辨率,最接近) | 浮点 | |
getLonLatFromViewPortPx(viewPortPx) | {OpenLayers.LonLat} | |
getViewPortPxFromLonLat(lonlat,resolution) | {OpenLayers.Pixel} | 返回给定地图位置的像素位置。 |
setOpacity(不透明度) | 无 | 设置整个图层的不透明度(所有图像) |
- new ol.layer.Tile/Image({//以下为图层的属性选项, 都可设置,所以皆有getter/setter
- opacity:2,//透明度 区间范围为(0, 1) 默认为1
- visible:true,//显示属性 布尔值 默认为true
- extent:[],//图层渲染的边界范围。该层将不会在此范围之外呈现
- zIndex:2,//图层渲染的索引层级。在渲染时,图层将被排序,首先是z-idnex,然后是位置,当为undefined时,对于添加到映射的layers集合中的层,zIndex为0,或者当使用该层的setMap()方法时,zIndex为无穷大
- minResolution:3,//该层可见的最小分辨率(包括在内)
- maxResolution:6,//该层可见的最大分辨率(包括在内)
- repload:0,//预加载。将低分辨率瓦片加载到预加载级别。0表示没有预加载 默认为0
- source:new ol.source.TileSource()/ImageSource(),//图层源
- map: ,//把图层覆盖在地图上,地图不会在它的图层集合中管理这个图层,这个图层将被呈现在顶部,这对于临时层非常有用。
- })
API:
TileLayer:https://openlayers.org/en/latest/apidoc/module-ol_layer_Tile-TileLayer.html
imagelayer:https://openlayers.org/en/latest/apidoc/module-ol_layer_Image-ImageLayer.html
Vector:https://openlayers.org/en/latest/apidoc/module-ol_layer_Vector-VectorLayer.html
vector tile:https://openlayers.org/en/latest/apidoc/module-ol_layer_VectorTile-VectorTileLayer.html
3、source(地图数据源)
source 表示图层的数据来源,可以是矢量和栅格数据,也就是网络地图服务。在GIS中,数据是GIS的核心,它同样也适用于WebGIS。在WebGIS中,数据常常指的是网络地图服务,网络地图服务分类如下:
(1)以各个厂商发布的服务来分,网络地图服务有:天地图,高德地图,百度地图、Google地图、Open Street Map服务等。
(2)以OGC标准来分,网络地图服务有地图服务、切片服务、覆盖服务、要素服务、地理处理服务等。
OGC 网络地图服务 (WMS):网络地图服务用于提供按地理配准的地图图像。WMS 服务也可包含样式化图层描述符 (SLD),用于指定 WMS 图层的符号化和描绘方式。
OGC Web 地图切片服务 (WMTS):Web 地图切片服务提供预先生成的地理配准的地图图像。WMTS 服务可包含一个或多个样式、维度或切片方案,以指定 WMTS 图层的显示方式。
OGC 网络覆盖服务 (WCS):网络覆盖服务提供栅格数据、像元值的地图覆盖和目录,如数字高程模型 (DEM) 的高程值或多波段图像的像素值。
OGC 网络要素服务 (WFS):网络要素服务使用地理标记语言 (GML) 配置文件提供、查询和更新要素几何和属性。
(3)以OpenLayers的角度来分,地图数据可以分为三种:ol.source.Tile、ol.source.Image、ol.source.Vector,这三个类已经将各个图商或者OGC标准地图服务进行了封装,网络地图服务的请求和响应方式也放置在source对象内部,如:GetCapabilities,GetMap,GetFeatureinfo,以至于我们很难看到这些rest方法的存在。
ol.source.Tile:对应的是切片数据源(包含静态缓存瓦片和矢量切片),在现行的网络地图服务中,为加快地图访问的效率,绝大多数地图服务器都是使用的静态缓存切片,该类数据是已经在服务器端预先生成好的静态缓存数据,而OpenLayers作为一个WebGIS的网络地图服务驱动引擎,支持了众多的WMTS服务。
ol.source.Image:对应的是一整张地图(地图被本能地看作是一张栅格图像,该地图可以是数据源为遥感影像或矢量数据制作的一张地图图像),在服务器上请求该类数据时,服务器动态调取数据,响应浏览器请求。
ol.source.Vector:对应的是矢量地图源,点,线,面等等矢量,就是此类数据。
(以上说法容易混淆制作地图时用的遥感影像、地图图像、服务器生成的静态缓存瓦片和矢量切片、电子地图的概念,应根据不同的语境来区分)
下图为OpenLayers source层次关系图谱:
其中,ol.source.tile分支最多,因为它需要兼容不同图商的地图底图切片服务,大致可以分为几类:
网络地图服务源说明:
常用图源:
免费
https://wiki.openstreetmap.org/wiki/List_of_OSM-based_services (openstreetmap)
http://lbs.tianditu.gov.cn/server/MapService.html (天地图)
http://maps.stamen.com/ (stamen)
收费
https://cloud.google.com/maps-platform/ (谷歌地图)
http://lbsyun.baidu.com/(百度地图)
https://www.microsoft.com/en-us/maps (BingMaps)
一般而言,各个厂商的底图服务,都是网络地图切片服务,只要ol.source.Tile能识别他们,就可以直接传递给ol.source.Layer加载到浏览器中。因此如何使用ol.source.Tile能识别各种不同厂商的数据源变成了关键。
(1)带有现成接口或者协议标准的网络地图加载方式
ol.source对于一些厂商提供了接口,由于地图厂商众多,也只是少部分提供而已。如:open street map、 bing、arcgisrest等已有现成接口,直接加载就行,代码如下:
- // Open Street Map 地图层
- var openStreetMapLayer = new ol.layer.Tile({
- source: new ol.source.OSM()
- });
-
- // Bing地图层
- var bingMapLayer = new ol.layer.Tile({
- source: new ol.source.BingMaps({
- key: 'AkjzA7OhS4MIBjutL21bkAop7dc41HSE0CNTR5c6HJy8JKc7U9U9RveWJrylD3XJ',
- imagerySet: 'Road'
- })
- });
-
- // Stamen地图层
- var stamenLayer = new ol.layer.Tile({
- source: new ol.source.Stamen({
- layer: 'watercolor'
- })
- });
-
- // MapQuest地图层
- var mapQuestLayer = new ol.layer.Tile({
- source: new ol.source.MapQuest({
- layer: 'osm'
- })
- });
-
- //加载ArcGISRest服务
- var ArcGISRestLayer=new ol.layer.Tile({
- source: new ol.source.TileArcGISRest({
- ratio: 1,
- params: {},
- url: 'https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StateCityHighway_USA/MapServer'
- })
- })
(2)ol.source.WMTS
调用方式
大部分地图服务都会使用WMTS服务进行发布,
我们现行的天地图服务(https://www.tianditu.gov.cn/)支持OGC标准,使用了wmts服务,利用ol.source.WMTS驱动WMTS服务,
使用OpenLayers中的ol.layer.Tile类 与 ol.source.WMTS类来加载和管理WMTS服务数据。
ol.layer.Tile类参数:
className | 字符串 (默认为“ ol-layer”) | 设置为layer元素的CSS类名称。 |
opacity | 整数 (默认为1) | 不透明度(0,1)。 |
visible | 布尔值 (默认为true) | 能见度。 |
extent | 模块:ol /范围〜范围 | 图层渲染的边界范围。该图层不会在此范围之外渲染。 |
zIndex | 整数 | 图层渲染的Z索引。在渲染时,将首先按Z索引然后按位置对图层进行排序。当时 |
minResolution | 整数 | 该层可见的最低分辨率(含)。 |
maxResolution | 整数 | 在该层以下可见的最大分辨率(不包括)。 |
minZoom | 整数 | 最小视图缩放级别(不包括此级别),在该级别之上,该层将可见。 |
maxZoom | 整数 | 该图层可见的最大视图缩放级别(包括该级别)。 |
preload | 整数 (默认为0) | 预加载。将低分辨率图块加载到 |
source | 模块:ol / source / Tile〜TileSource | 该层的来源。 |
map | 模块:ol / PluggableMap〜PluggableMap | 将图层设置为地图上的叠加层。地图将不会在其图层集合中管理此图层,并且该图层将呈现在顶部。这对于临时层很有用。在地图上添加图层并由地图管理图层的标准方法是使用 |
useInterimTilesOnError | 布尔值 (默认为true) | 出现错误时使用临时磁贴。 |
其中,ol.layer.Tile中的source参数关联网络地图服务,即数据源。
new ol.layer.Tile({
source: wmtsSource
})
ol.source.WMTS参数如下:
名称 | 类型 | 描述 |
---|---|---|
attributions | 模块:ol / source / Source〜AttributionLike | 归因。 |
cacheSize | 数 | 初始图块缓存大小。将自动增长以至少容纳视口中的图块数量。 |
crossOrigin | 空 | 串 |
|
imageSmoothing | 布尔值 (默认为true) | 启用图像平滑。 |
tileGrid | 模块:ol / tilegrid / WMTS〜WMTSTileGrid | 平铺网格。 |
projection | 模块:ol / proj〜ProjectionLike | 投影。默认为视图投影。 |
reprojectionErrorThreshold | 数字 (默认为0.5) | 最大允许的重新投影误差(以像素为单位)。较高的值可以提高重投影性能,但会降低精度。 |
requestEncoding | 模块:ol / source / WMTSRequestEncoding | 字符串 (默认为“ KVP”) | 请求编码。 |
layer | 串 | WMTS功能中公布的层名称。 |
style | 串 | WMTS功能中公布的样式名称。 |
tileClass | 类。< 模块:ol / ImageTile〜ImageTile > | 用于实例化图像图块的类。默认值为 |
tilePixelRatio | 数字 (默认为1) | 切片服务使用的像素比率。例如,如果图块服务对256px x 256px的图块进行广告宣传,但实际上发送了512px x 512px的图像(对于视网膜/ hidpi设备), |
format | 字符串 (默认为“ image / jpeg”) | 图像格式。只有当使用的 |
version | 字符串 (默认为“ 1.0.0”) | WMTS版本。 |
matrixSet | 串 | 矩阵集。 |
dimensions | 目的 | 磁贴请求的其他“尺寸”。这是一个对象,其属性的名称类似于广告的WMTS维度。 |
url | 串 | 服务的URL。对于RESTful请求编码,这是一个URL模板。对于KVP编码,它是普通URL。甲 |
tileLoadFunction | 模块:ol / Tile〜LoadFunction | 可选功能,用于在给定URL的情况下加载图块。默认是 |
urls | 数组。<字符串> | URL数组。请求将在此数组中的URL之间分配。 |
wrapX | 布尔值 (默认为false) | 是否水平包装世界。 |
transition | 数 | 用于渲染的不透明度过渡的持续时间。要禁用不透明过渡,请传递 |
其中url、matrixSet、format、projection、tileGrid、style等参数必须填写,我们需要找到这些信息。
undefined
。以国家天地图WMTS服务为例,说明ol.source.WMTS如何调用国家天地服务。
(注:如果需要当地的天地图服务,请选择相应省份的天地图,如:天地图江苏、天地图浙江、天地图广东等,每个省都有本地的天地图服务,注册相应账户,获取服务。)
使用天地图服务流程:注册账户---申请天地图开发者----获取key----使用API服务。
国家天地图网站:https://www.tianditu.gov.cn/
国家天地图服务,地图API:http://lbs.tianditu.gov.cn/server/MapService.html
// 全球影像地图服务(经纬度) http://t0.tianditu.com/img_c/wmts
// 全球影像注记服务(经纬度) http://t0.tianditu.com/cia_c/wmts
// 全球影像地图服务(墨卡托投影) http://t0.tianditu.com/img_w/wmts
// 全球影像注记服务(墨卡托投影) http://t0.tianditu.com/cia_w/wmts
// 全球矢量地图服务(经纬度) http://t0.tianditu.com/vec_c/wmts
// 全球矢量注记服务(经纬度) http://t0.tianditu.com/cva_c/wmts
// 全球矢量地图服务(墨卡托投影) http://t0.tianditu.com/vec_w/wmts
// 全球矢量注记服务(墨卡托投影) http://t0.tianditu.com/cva_w/wmts
天地图地图服务支持HTTP和HTTPS协议。
天地图地图服务采用OGC WMTS标准,具体使用方法请参考OGC WMTS标准 中GetCapabilities 和GetTile。
天地图地图服务对所有用户开放。使用本组服务之前,需要申请Key。
*天地图地图服务二级域名包括t0-t7,您可以随机选择使用,如http://t2.tianditu.gov.cn/vec_c/wmts?tk=您的密钥
根据以上提示,天地图服务需要key,需要在后面加入一段key代码(从国家天地图网站开发者用户那获得)。自2018年开始,国家天地服务加入key,如果获取key,需要先成为使用用户,注册国家天地图用户:https://uums.tianditu.gov.cn/register
跳转至我要成为开发者 http://lbs.tianditu.gov.cn/home.html
在控制台界面https://console.tianditu.gov.cn/api/key申请浏览器端key:
在http://t0.tianditu.com/img_c/wmts后面加入您的key ,查询国家天地图影像服务元数据:
http://t0.tianditu.gov.cn/img_c/wmts?request=GetCapabilities&service=wmts&tk= "您的key"
返回一个XML文档,包含了地图服务的请求方式、编码方式、数据原点、图层、数据格式、范围大小、坐标系、瓦片大小、瓦片格网矩阵等等。
由元数据可以知,该数据服务包含以下信息:
(1)基于OGC标准的WMTS服务
(2)请求方式:GetCapabilities、GetTile
(3)请求格式:KVP格式
(4)图层名称:img
(5)显示风格:default
(6)瓦片格式:tiles
(7)四至坐标:-180.0 -90.180.0 90.0
(8)坐标系:EPSG::4490
(9)瓦片大小:256*256
(10)瓦片层级矩阵:c
(11)瓦片层级矩阵标识:[ '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18'] ,国家天地图服务瓦片层级为1到18级。
(12)瓦片分辨率矩阵:[0.703125,0.3515625,0.17578125,0.087890625,0.0439453125,0.02197265625,0.010986328125, 0.0054931640625,0.00274658203125,0.001373291015625, 0.0006866455078125,0.00034332275390625,0.000171661376953125,8.58306884765625e-005,4.291534423828125e-005,2.1457672119140625e-005,1.0728836059570313e-005, 5.36441802978515625e-006]
天地图瓦片分辨率、比例尺与OSM、谷歌地图相同,只是层级起始数不同,谷歌以0开始,天地图以1开始:
- {"level": 1, "resolution": 0.7031250000000002, "scale": 2.9549759305875003E8},
- {"level": 2, "resolution": 0.3515625000000001, "scale": 1.4774879652937502E8},
- {"level": 3, "resolution": 0.17578125000000006, "scale": 7.387439826468751E7},
- {"level": 4, "resolution": 0.08789062500000003, "scale": 3.6937199132343754E7},
- {"level": 5, "resolution": 0.043945312500000014, "scale": 1.8468599566171877E7},
- {"level": 6, "resolution": 0.021972656250000007, "scale": 9234299.783085939},
- {"level": 7, "resolution": 0.010986328125000003, "scale": 4617149.891542969},
- {"level": 8, "resolution": 0.005493164062500002, "scale": 2308574.9457714846},
- {"level": 9, "resolution": 0.002746582031250001, "scale": 1154287.4728857423},
- {"level": 10, "resolution": 0.0013732910156250004, "scale": 577143.7364428712},
- {"level": 11, "resolution": 6.866455078125002E-4, "scale": 288571.8682214356},
- {"level": 12, "resolution": 3.433227539062501E-4, "scale": 144285.9341107178},
- {"level": 13, "resolution": 1.7166137695312505E-4, "scale": 72142.9670553589},
- {"level": 14, "resolution": 8.583068847656253E-5, "scale": 36071.48352767945},
- {"level": 15, "resolution": 4.2915344238281264E-5, "scale": 18035.741763839724},
- {"level": 16, "resolution": 2.1457672119140632E-5, "scale": 9017.870881919862},
- {"level": 17, "resolution": 1.0728836059570316E-5, "scale": 4508.935440959931},
- {"level": 18, "resolution": 5.364418029785158E-6, "scale": 2254.4677204799655},
-
部分开发者用户不能正常调出天地图服务,是因为在使用ol.source.WMTS方式时,瓦片格网矩阵中的瓦片分辨率与比例尺层级是相互错位的,可参看上述地图层级、分辨率和比例尺的对应关系。
也有根据瓦片的实际宽度与像素数目来计算瓦片分辨率矩阵的,其数值是一样的。如:
-
- var projectionExtent = projection.getExtent();
- var size = getWidth(projectionExtent) / 256;
- var resolutions = new Array(18);
- var matrixIds = new Array(18);
- for (var z = 1; z < 19; ++z) {
- resolutions[z] = size / Math.pow(2, z);
- matrixIds[z] = z;}
创建天地图影像地图服务wmtsSource对象,参数设置如下:
-
- var wmtsSource = new ol.source.WMTS({ //配置瓦片数据源
- url:'http://t{0-7}.tianditu.com/img_c/wmts?tk="您的KEY" ',
- //配置数据源服务地址,注:img_c中的C表示经纬度,W表示网络墨卡托。
-
- layer: 'img', //图层名称
- format:'tiles'(image/png), //配置瓦片格式
- matrixSet: 'c', //配置瓦片矩阵
- projection:ol.proj.get("EPSG:4326"), //配置数据投影坐标系,天地图经纬度直投为cgcs2000坐标系,ol只支持wgs84参数,使用EPSG 4326编号,对应的网络墨卡托投影为EPSG 3857,你也可以使用pro.4自定义cgcs2000坐标系
-
- tileGrid: new ol.tilegrid.TileGrid({ //配置瓦片参数,注:此项涉及较多参数,涉及地图服务原点,地图各级分辨率大小,以及地图层级,应与元数据信息相一致
-
- origin:[-400, 400], //设置屏幕坐标原点(左上角)
- resolutions:[0.703125,0.3515625,0.17578125,0.087890625,0.0439453125,0.02197265625,0.010986328125, 0.0054931640625,0.00274658203125,0.001373291015625, 0.0006866455078125,0.00034332275390625,0.000171661376953125,8.58306884765625e-005,4.291534423828125e-005,2.1457672119140625e-005,1.0728836059570313e-005, 5.36441802978515625e-006]
- //设置瓦片分辨率矩阵
- matrixIds: ['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18']
- //设置地图层级矩阵标识
- }),
-
- style:'default', //设置地图显示风格,默认风格
-
- wrapX:'true' //地图平铺方式,水平平铺
- })
将map对象、layers对象与wmtsSource对象挂接起来:
- new ol.Map({
- layers: [
- new ol.layer.Tile({source:wmtsSource})
- ],
- view: new ol.View({
- center: [0, 0],
- zoom:2
- }),
- target: 'map',
- });
最后将视图的中心点位置配置到你需要的位置即可。如:深圳:(114.04,22.55)
source对象方法:
(3)通用接口加载方式ol.source.XYZ
在谷歌浏览器上,我们按住F12,进入开发者模式,随便找一个网络地图,如百度地图,找到一张切片如下:
后面的有u=x=1473;y=315;z=13的字样(我们通常使用xyz这样的坐标来精确定位一张瓦片。通常z用于表示地图层级,而xy表示某个层级内的瓦片平面,x为横纵坐标,y为纵轴坐标,类似于数学上常见的笛卡尔坐标系。在这个瓦片平面上的每一个瓦片在横轴和纵轴上都有对应的坐标:x和y。),说明它也是瓦片地图常规的表示形式,这也是所有瓦片需要定位显示的基本参数。
正因为如此,OpenLayers 提供了ol.source.XYZ
这种通用的Source
来适应广大的在线瓦片地图数据源,具备很好的适用性。通常情况下,开发者想要加载不同的在线瓦片地图源,则只需要更改ol.source.XYZ
的构造参数中url
就可以了。 比如我们就可以不用ol.source.OSM
,而用ol.source.XYZ
来加载Open Street Map地图,结果一样:
Open Street Map地图:
- // Open Street Map 地图层
- var openStreetMapLayer = new ol.layer.Tile({
- source: new ol.source.XYZ({
- url: 'http://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png'
- })
- });
高德地图:
- // 高德地图层
- var gaodeMapLayer = new ol.layer.Tile({
- source: new ol.source.XYZ({
- url:'http://webst0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}'
- })
- });
Yahoo地图:
- var yahooMapLayer = new ol.layer.Tile({
- source: new ol.source.XYZ({
- tileSize: 512,
- url:'https://{0-3}.base.maps.api.here.com/maptile/2.1/maptile/newest/normal.day/{z}/{x}/{y}/512/png8?lg=ENG&ppi=250&token=TrLJuXVK62IQk0vuXFzaig%3D%3D&requestid=yahoo.prod&app_id=eAdkWGYRoc4RfxVo0Z4B'
- })
- });
天地图:
https://t{0-7}.tianditu.gov.cn/DataServer?T=img_c&x={x}&y={y}&l={z}&tk="您的密钥"
- var tiandituMapLayer=new ol.layer.Tile({
- source:new ol.source.XYZ({
- url:'https://t{0-7}.tianditu.gov.cn/DataServer?T=img_c&x={x}&y={y}&l={z}&tk="您的密钥"'
- })
- })
通过上面的示例我们已经发现,其实可以非常轻松地加载多种不同来源的在线瓦片地图。但遗憾地是,上面这种简单方法并不适用于所有的在线瓦片地图,总有一些是特殊的,比如百度地图,上面这种方式就不生效了。此时,我们需要回过头来思考一下瓦片地图加载的整个过程:瓦片地图加载的关键在于找对瓦片,但要找对瓦片,就得知道瓦片的坐标,而坐标又需要明确的坐标系。我们在坐标里说过,任何坐标都得有坐标系才有意义。在OpenLayers中,默认使用的瓦片地图的坐标系是如何定义的?经分析可知,OpenLayers 的瓦片坐标系的原点在左上角,向上为y轴正方向,向右为x轴正方向。具体到地图上来讲,地球经过投影,投影到一个平面上,平面最左边对应地球最西边,平面最上边对应地球最北边。原点就处于整个平面的左上角,即地球的西北角,从北向南为y轴负方向,从西向东为x轴正方向。理解这一点非常重要,因为并不是所有在线的瓦片地图都是采用这样的坐标系。用OpenLayers加载它们的时候,如果坐标系不同,计算出来的瓦片地址就获取不到对应的瓦片,为解决这个问题,我们必须要先对瓦片坐标进行转换。那么,具体该怎么实现转换?最详细明了的方式还是看实例,下面我们看一下加载百度地图一种实现方式:
代码如下:
- <div id="baiduMap" style="width: 100%"></div>
- <script>
- // 百度地图层
- var baiduMapLayer = new ol.layer.Tile({
- source: new ol.source.XYZ({
- tilePixelRatio: 2,
- tileUrlFunction: function(tileCoord){ // 参数tileCoord为瓦片坐标
- var z = tileCoord[0];
- var x = tileCoord[1];
- var y = tileCoord[2];
-
- // 计算当前层级下瓦片总数的一半,用于定位整个地图的中心点
- var halfTileNum = Math.pow(2, z-1);
- // 原点移到中心点后,计算xy方向上新的坐标位置
- var baiduX = x - halfTileNum;
- var baiduY = y + halfTileNum;
-
- // 百度瓦片服务url将负数使用M前缀来标识
- if (baiduX < 0) {
- baiduX = 'M' + (-baiduX);
- }
- if (baiduY < 0) {
- baiduY = 'M' + (-baiduY);
- }
-
- // 返回经过转换后,对应于百度在线瓦片的url
- return 'http://online2.map.bdimg.com/onlinelabel/?qt=tile&x=' + baiduX + '&y=' + baiduY + '&z=' + z + '&styles=pl&udt=20160321&scaler=2&p=0';
- }
- })
- });
-
- // 创建地图
- var map = new ol.Map({
- layers: [
- baiduMapLayer
- ],
- view: new ol.View({
- // 设置地图中心点
- center: [104.06, 30.67],
- projection: 'EPSG:4326',
- zoom: 4
- }),
- target: 'baiduMap'
- });
- </script>
和前面几个加载在线瓦片地图的例子不一样的地方在于,我们没有设置url
,而是设置了tileUrlFunction
,这是一个获取瓦片url
的函数,如果自定义这个函数,就可以实现不同坐标系之间的转换,从而返回在线地图服务对应瓦片的url
。通过代码可以看到,函数入参是一个瓦片坐标,然后进行一系列的转换,得到百度在线地图的瓦片地址。效果参见上方地图,不妨拖动、缩放试试,拼接无缝,并没有什么问题。
tileUrlFunction
这个自定义函数的代码实现有可能看不懂,虽然知道在进行坐标转换,但并不知道为什么要这样实现。为了彻底弄明白代码,我们必须得把之前遗漏的一个很重要环节补上:弄明白待加载的在线瓦片地图的坐标系。对百度在线瓦片坐标系进行简单分析发现,它是以某一个位置为原点,向右为x正方向,向上为y正方向的坐标系,进一步分析发现,原点应该在中心位置,为此,我们假设百度地图是以经纬度[0,0]为原点,在此基础上编写函数tileUrlFunction
的实现。halfTileNum
表示的是在当前缩放层级之下,总的瓦片个数的一半,意味着它就是中心位置。对于baiduX
小于0的情况,百度使用了M
来表示负号,所以要特殊处理一下。想必这下应该更加理解代码实现了。不同的在线瓦片地图的转换代码可能不同,需要根据对应的坐标系来确定。
但上面这个地图并不完美,因为我们设定的地图中心为成都,然而实际上显示的地图中心并不在成都。虽然无缝拼接,但位置偏差有点远。由此基本可以排除坐标转换的问题,看起来应该是OpenLayers 3的分辨率和百度在线瓦片地图使用的分辨率对不上。经过分析发现,确实如此,在网上也有很多分析文章可以查阅。那么我们是否可以重新定义分辨率呢? 答案是肯定的,我们可以使用ol.source.XYZ
的父类来解决问题。
重新定义OpenLayers 的瓦片坐标系
ol.source.TileImage
作为ol.source.XYZ
的父类,除了可以转换坐标之外,还具备更加强大的功能,修改分辨率。下面我们使用它来加载百度地图,这次是正确的:
对应的代码:
- <div id="baiduMap2" style="width: 100%"></div>
- <script>
-
- // 自定义分辨率和瓦片坐标系
- var resolutions = [];
- var maxZoom = 18;
-
- // 计算百度使用的分辨率
- for(var i=0; i<=maxZoom; i++){
- resolutions[i] = Math.pow(2, maxZoom-i);
- }
- var tilegrid = new ol.tilegrid.TileGrid({
- origin: [0,0], // 设置原点坐标
- resolutions: resolutions // 设置分辨率
- });
-
- // 创建百度地图的数据源
- var baiduSource = new ol.source.TileImage({
- projection: 'EPSG:3857',
- tileGrid: tilegrid,
- tileUrlFunction: function(tileCoord, pixelRatio, proj){
- var z = tileCoord[0];
- var x = tileCoord[1];
- var y = tileCoord[2];
-
- // 百度瓦片服务url将负数使用M前缀来标识
- if(x<0){
- x = 'M' + (-x);
- }
- if(y<0){
- y = 'M' + (-y);
- }
-
- return "http://online0.map.bdimg.com/onlinelabel/?qt=tile&x="+x+"&y="+y+"&z="+z+"&styles=pl&udt=20160426&scaler=1&p=0";
- }
- });
-
- // 百度地图层
- var baiduMapLayer2 = new ol.layer.Tile({
- source: baiduSource
- });
-
- // 创建地图
- new ol.Map({
- layers: [
- baiduMapLayer2
- ],
- view: new ol.View({
- // 设置地图中心点
- center: ol.proj.transform([104.06, 30.67], 'EPSG:4326', 'EPSG:3857'),
- zoom: 10
- }),
- target: 'baiduMap2'
- });
- </script>
这个代码同上面的代码相比,引入了ol.tilegrid.TileGrid
,由名字可见,这是定义瓦片网格,其实就是瓦片坐标系,构造时需要设定原点,紧接着设置分辨率,其作用在于设定每一地图层级的分辨率。我们是否遗漏了坐标系的正向和负向的设定?默认情况下,从左向右为x正方向,从下向上为y轴正方向。这和我们数学上通常定义的笛卡尔坐标系是一样的,这一点需要大家记住。如代码所示,就可以重新定义OpenLayers 3的瓦片地图坐标系,这种方式的代码比上一种方式更加的可读和简洁。 如果用通用的方法解决不了,请别忘记还有这一强大灵活的处理方式。
分析瓦片地图坐标系
如何分析不同在线瓦片地图的坐标系呢?非常重要的一点是,先从特例出发,找简单的情况分析,比如选择z为2或者3进行分析,这种情况下,瓦片的数量比较少,可以查看整个地球范围内的地图的瓦片请求,注意分析其请求的url
参数。上述的所有地图都可以以这样的方式入手来分析,包括百度地图,可以自行尝试该方法。如果你有更好的方法,愿意的话,请给大家一起分享一下。
解密瓦片url
瓦片的url解析对于想直接使用在线瓦片服务的开发者而言,是一项经常要做的事。根据难度,大致可以分为三种情况:
url
明确有xyz参数,比如高德地图和百度地图。xyz
作为路径直接存在于url
里面,没有明确的参数表明哪些是xyz,比如Open Street Map和Yahoo地图,这种情况下,地图服务器接收到请求后,就直接在服务器按照这个路径获取图片,按照这个逻辑,一般第一个参数表示是z,第二个参数为x,第三个参数为y。要想确认是否真是这样,可以写一个小程序来验证一下,如果还有问题,建议按照上面分析地图坐标系中的方法,从z比较小的情况入手来分析x,y,z的位置。加载微软Bing中文地图
前面两种url的实例已经有了,此处分享一下第三种情况的url解密,以微软Bing中文地图为例:
图中显示的瓦片地图请求的url,没有明显的xyz参数,最有可能的存放xyz参数的地方在于url前面那一串数字,真实情况确实是这样的,经过分析和解码,最终实现了加载Bing中文地图:
代码如下:
- <div id="bingMap" style="width: 100%"></div>
- <script>
- // Bing中文地图层
- var bingMapLayer = new ol.layer.Tile({
- source: new ol.source.XYZ({
- tileUrlFunction: function(tileCoord){
- var z = tileCoord[0];
- var x = tileCoord[1];
- var y = -tileCoord[2] - 1;
- var result='', zIndex=0;
-
- for(; zIndex<z; zIndex++) {
- result = ((x&1)+2*(y&1)).toString() + result;
- x >>= 1;
- y >>= 1;
- }
- return 'http://dynamic.t0.tiles.ditu.live.com/comp/ch/' + result + '?it=G,VE,BX,L,LA&mkt=zh-cn,syr&n=z&og=111&ur=CN';
- }
- })
- });
-
- // 创建地图
- var map = new ol.Map({
- layers: [
- bingMapLayer
- ],
- view: new ol.View({
- // 设置地图中心点
- center: [104.06, 30.67],
- projection: 'EPSG:4326',
- zoom: 10
- }),
- target: 'bingMap'
- });
- </script>
需要注意的是地图数据是非常昂贵的,如果使用某一个在线地图服务,请先核实对方的版权和数据使用申明,不要侵犯对方的权益,按照要求合法使用地图。几乎所有的在线地图服务都提供了响应的服务接口,强烈建议在商用项目中使用这些接口。对于这些接口的使用,服务商都有详细的说明,在此不累述。
google地图加载
有许多人都在问google地图加载的问题,因为地图url是加密的,通过分析url,可以采用下面的方式来加载:
代码如下:
- <div id="googleMap" style="width: 100%"></div>
- <script>
- // google地图层
- var googleMapLayer = new ol.layer.Tile({
- source: new ol.source.XYZ({
- url:'http://www.google.cn/maps/vt/pb=!1m4!1m3!1i{z}!2i{x}!3i{y}!2m3!1e0!2sm!3i345013117!3m8!2szh-CN!3scn!5e1105!12m4!1e68!2m2!1sset!2sRoadmap!4e0'
- })
- });
-
- // 创建地图
- var map = new ol.Map({
- layers: [
- googleMapLayer
- ],
- view: new ol.View({
- // 设置地图中心点
- center: [104.06, 30.67],
- projection: 'EPSG:4326',
- zoom: 10
- }),
- target: 'googleMap'
- });
- </script>
各类地图加载深入
关于瓦片图层加载相关的重要方法。
- ol.tilegrid.TileGrid.prototype.getTileRangeForExtentAndResolution = function(
- extent, resolution, opt_tileRange) {
- var tileCoord = ol.tilegrid.TileGrid.tmpTileCoord_;
- // 根据extent的左下角的计算瓦片坐标;
- this.getTileCoordForXYAndResolution_(
- extent[0], extent[1], resolution, false, tileCoord);
- var minX = tileCoord[1];
- var minY = tileCoord[2];
- // 根据extent的右上角的计算瓦片坐标;
- this.getTileCoordForXYAndResolution_(
- extent[2], extent[3], resolution, true, tileCoord);
- // 得到某个resolution级别下的瓦片范围(左下角瓦片坐标 - 右上角瓦片坐标)
- return ol.TileRange.createOrUpdate(
- minX, tileCoord[1], minY, tileCoord[2], opt_tileRange);
- };
-
- // 根据extent左下角及右上角的坐标-origin后得到地图的长宽 / resolution得到像素值;
- // 然后 / tileSize 得到需要多少张瓦片;
- // 当计算extent右上角的瓦片坐标时,因为瓦片坐标是从0开始计算,当瓦片数量为例如1.5此类小数时,
- // 应该是2张瓦片,从0开始计算,那么XY就应该向下取整,取1;0,1两张瓦片;
- ol.tilegrid.TileGrid.prototype.getTileCoordForXYAndResolution_ = function(
- x, y, resolution, reverseIntersectionPolicy, opt_tileCoord) {
- var z = this.getZForResolution(resolution);
- var scale = resolution / this.getResolution(z);
- var origin = this.getOrigin(z);
- var tileSize = ol.size.toSize(this.getTileSize(z), this.tmpSize_);
-
- var adjustX = reverseIntersectionPolicy ? 0.5 : 0;
- var adjustY = reverseIntersectionPolicy ? 0 : 0.5;
- var xFromOrigin = Math.floor((x - origin[0]) / resolution + adjustX);
- var yFromOrigin = Math.floor((y - origin[1]) / resolution + adjustY);
- var tileCoordX = scale * xFromOrigin / tileSize[0];
- var tileCoordY = scale * yFromOrigin / tileSize[1];
-
- if (reverseIntersectionPolicy) {
- tileCoordX = Math.ceil(tileCoordX) - 1;
- tileCoordY = Math.ceil(tileCoordY) - 1;
- } else {
- tileCoordX = Math.floor(tileCoordX);
- tileCoordY = Math.floor(tileCoordY);
- }
-
- return ol.tilecoord.createOrUpdate(z, tileCoordX, tileCoordY, opt_tileCoord);
- };
通过上述分析后,应该能较好的理解瓦片的坐标是如何计算的,当应用到不同的地图瓦片加载时就可以得心应手。以下通过不同的几种类型继续说明瓦片计算的方式:
1、TMS瓦片加载
先看看TMS瓦片的规则,origin在左下角,X轴从左至右递增,Y轴从下往上递增(先计算左下角,然后计算右上角)。
而TileGrid设置origin为ol.extent.getBottomLeft(extent)后,规则也是从左下角到右上角,X轴从左至右递增,Y轴从下往上递增,与TMS规则是完全一致的,参考代码与参考效果如下:
- var resolutions = [];
- var tileSize = 256;
- var extent = [12665080.52765571, 2550703.6338763316, 12725465.780000998, 2601457.820657688]; //深圳地区
- var projection = new ol.proj.get("EPSG:3857");
- var projectionExtent = projection.getExtent();
-
- for (var i = 0; i < 19; i++) {
- resolutions[i] = Math.pow(2, 18 - i);
- }
-
- var tilegrid = new ol.tilegrid.TileGrid({
- origin: ol.extent.getBottomLeft(projectionExtent),
- resolutions: resolutions,
- extent: projectionExtent,//extent,
- tileSize: [256, 256],
- });
-
- var map = new ol.Map({
- target: "map",
- layers: [
- // 调试瓦片
- new ol.layer.Tile({
- source: new ol.source.TileDebug({
- projection: projection,
- tileGrid: tilegrid,
- tileSize: [256, 256],
- extent : projectionExtent,
- wrapX: false
- }),
- })
- ],
- view: new ol.View({
- projection: projection,
- center: [12697184.079535482, 2563239.3065151004],//深圳
- resolutions: resolutions,
- }),
- });
- map.getView().setZoom(1);
假如上面代码中,我想只显示深圳地区的瓦片,其余的瓦片不显示,这种场景是很普遍的,那么代码调整如下:
- var tilegrid = new ol.tilegrid.TileGrid({
- origin: ol.extent.getBottomLeft(projectionExtent), //origin位置不能变!!!!!!
- resolutions: resolutions,
- extent: extent,//projectionExtent //设置extent为深圳片区的extent;
- tileSize: [256, 256],
- });
-
- // ..................
-
- // 调试瓦片
- new ol.layer.Tile({
- source: new ol.source.TileDebug({
- projection: projection,
- tileGrid: tilegrid,
- extent: extent,//projectionExtent //设置extent为深圳片区的extent;
- wrapX: false
- }),
- })
2、WMTS瓦片加载
WMTS规则如下,origin在左上角,X轴从左至右递增,Y轴是从上往下递增(先计算左上角,然后计算右下角)
那么将tileGrid设置origin为ol.extent.getTopLeft(projectionExtent), 但是TileGrid始终都是先计算左下角的瓦片坐标,然后计算右上角的瓦片坐标,因此Y轴是相反的。那么修改Y轴坐标就可以得到正确值:
- var tilegrid = new ol.tilegrid.TileGrid({
- origin: ol.extent.getTopLeft(projectionExtent), // WMTS Origin在左上角,origin位置不能变;
- resolutions: resolutions,
- extent: extent,
- tileSize: [256, 256],
- });
-
- // 其余代码略.....
- new ol.layer.Tile({
- source: new ol.source.TileImage({
- projection: projection,
- tileGrid: tilegrid(),
- tileUrlFunction: function (tileCoord, pixelRatio, proj) {
- if (!tileCoord) {
- return "";
- }
- var z = tileCoord[0];
- var x = tileCoord[1];
- var y = -tileCoord[2] - 1; // y轴取反,-1目的是为了从0开始计数;
-
- return ''; // 自行设置URL ,请注意 WMTS中用TileRow标识Y,用TileCol表示X;
- }
- }),
- })
3、百度地图瓦片加载
百度瓦片片规则如下:Origin在[0,0],X轴从左至右递增,Y轴从下往上递增(从左下角到右上角)。
从百度的瓦片规则看出来,与TileGrid的规则是完全一致,将origin设置为[0,0]即可。参考代码如下:
- var tilegrid = new ol.tilegrid.TileGrid({
- origin: [0, 0],
- resolutions: resolutions,
- extent: extent,//projectionExtent,
- tileSize: [256, 256],
- });
-
- var tilesource = new ol.source.TileImage({
- projection: projection,
- tileGrid: tilegrid,
- tileUrlFunction: function (xyz, obj1, obj2) {
- if (!xyz) {
- return "";
- }
- var z = xyz[0]+ 11; // 从第11级开始加载;深圳地区;
- var x = xyz[1];
- var y = xyz[2];
- if (x < 0) {
- x = "M" + (-x);
- }
- if (y < 0) {
- y = "M" + (-y);
- }
- return "http://online3.map.bdimg.com/tile/?qt=tile&x=" + x + "&y=" + y + "&z=" + z + "&styles=pl&udt=20141119&scaler=1";
- }
- });
4、腾讯地图瓦片加载
腾讯地图完全遵守TMS规则,地图投影坐标系采用Web Mercator投影,最小缩放级别为第4级。参考代码如下:
- // QQ地图完全遵守TMS规则;
- var tileGrid = new ol.tilegrid.TileGrid({
- resolutions: resolutions3857,
- tileSize: [256, 256],
- extent: projection3857Extent,
- origin: ol.extent.getBottomLeft(projection3857Extent), // Origin左下角
- });
-
- var tilesource = new ol.source.TileImage({
- tileUrlFunction: function (xyz, obj1, obj2) {
- if (!xyz) {
- return "";
- }
- var z = xyz[0];
- var x = xyz[1];
- var y = xyz[2];
- return "http://rt1.map.gtimg.com/realtimerender?z=" + z + "&x=" + x + "&y=" + y + "&type=vector&style=0&v=1.1.2"
- },
- projection: projection3857,
- tileGrid : tileGrid
- });
矢量地图加载
网络的矢量地图有GeoJSON
,TopoJSON
,GML
,KML等,使用ol.source.vector即可加载:
- new ol.layer.Vector({
- source: new ol.source.Vector({
- url: '../data/geojson/line-samples.geojson', // 地图来源
- format: new ol.format.GeoJSON() // 解析矢量地图的格式化类
- })
source与layer配套使用,有什么样的source,就用什么样的layer加载。
4、View
View,视图的意思,视图是每个webgis实例的基本组成部分。在前面的代码中,已经或多或少的接触到view这个对象,也大致可以看到view的一些参数,如:center、zoom、Resolution、projection、Rotation等等
。从地图开发的角度来说,不管我们使用何种开发方式,地图视图的一些基本属性似乎是必备的:分辨率、比例尺、中心点、地图投影、旋转参数等等。
构造视图
名称 | 类型 | 描述 |
---|---|---|
center | 模组:ol / coordinate〜Coordinate | 视图的初始中心。如果未设置用户投影,则使用 |
constrainRotation | 布尔 | 数字 (默认为true) | 旋转约束。 |
enableRotation | 布尔值 (默认为true) | 启用旋转。如果为 |
extent | 模块:ol /范围〜范围 | 限制视图的范围,换句话说,超出此范围的任何内容都无法在地图上看到。 |
constrainOnlyCenter | 布尔值 (默认为false) | 如果为true,则范围约束将仅适用于视图中心,而不适用于整个范围。 |
smoothExtentConstraint | 布尔值 (默认为true) | 如果为true,则范围约束将被平滑应用,即,允许视图略微超出给定范围 |
maxResolution | 数 | 用于确定分辨率约束的最大分辨率。它与 |
minResolution | 数 | 用于确定分辨率约束的最小分辨率。它与 |
maxZoom | 数字 (默认为28) | 用于确定分辨率约束的最大缩放级别。它与 |
minZoom | 数字 (默认为0) | 用于确定分辨率约束的最小缩放级别。它与 |
multiWorld | 布尔值 (默认为false) | 如果 |
constrainResolution | 布尔值 (默认为false) | 如果为true,则视图在交互后将始终设置为最接近的缩放级别。false表示允许中间缩放级别。 |
smoothResolutionConstraint | 布尔值 (默认为true) | 如果为true,则分辨率的最小值/最大值将被平滑应用,即允许视图稍微超过给定的分辨率或缩放范围。 |
showFullExtent | 布尔值 (默认为false) | 允许缩小视图以显示完整的配置范围。默认情况下,在为视图配置了范围时,用户将无法缩小,因此视口在任一维度上都超出了范围。这意味着如果视口比配置的范围的纵横比高或宽,则整个范围可能不可见。如果showFullExtent为true,则用户将能够进行缩小,以使视口超过配置的范围的高度或宽度,但不能同时超过两者,从而显示整个范围。 |
projection | module:ol / proj〜ProjectionLike (默认为'EPSG:3857') | 投影。默认值为球形墨卡托。 |
resolution | 数 | 视图的初始分辨率。单位是 |
resolutions | 数组。<数字> | 确定分辨率约束的分辨率。如果设置了 |
rotation | 数字 (默认为0) | 视图的初始旋转(弧度)(顺时针正旋转,0表示北)。 |
zoom | 数 | 仅在 |
zoomFactor | 数字 (默认为2) | 缩放系数,用于计算相应的分辨率。 |
center(视图中心对象):表示
地图视图的中心位置,用二维坐标点表示,用于初始化地图视图的中心位置
constrainRotation(旋转约束值):布尔值,false
意味着没有约束。true
意味着没有约束。4表示四个旋转状态值:0度,90度,180度和270度。
enableRotation(启用旋转):布尔值,false,不能旋转,true,可旋转。
extent(范围):视图显示范围,[左下角经度,左下角纬度,右上角经度,右上角纬度]。
maxResolution(最大分辨率),minResolution(最小分辨率)
maxZoom(最大缩放级别),minZoom(最小缩放级别)
projection(地图投影):默认地图投影为网络墨卡托投影
resolution(视图初始分辨率)
resolutions(分辨率矩阵)
rotation(初始化旋转参数):弧度为单位,0时,北正向
zoom(初始化缩放级别)
zoomFactor(缩放系数):maxResolution(最大分辨率),minResolution(最小分辨率)maxZoom(最大缩放级别),minZoom(最小缩放级别)都设置了,此项无效。
layers、view 、target都是map对象的填充参数,此三者并列。视图对象的存在主要在于显示地图,虽然layer也有控制地图范围的功能,但是视图对象侧重于我们的观感,在哪里显示,显示范围多大,分辨率是多少,缩放级别是多少等等。相对应的需要临时改变这些参数的时候,视图也提供了相应的方法,方便传参,进而可以控制显示地图。
- view: new ol.View({
- // 设置地图中心点
- center: [104.06, 30.67],
- projection: 'EPSG:4326',
- zoom: 10
- }),
为地图创建一个新的视图,中心点在[104.06, 30.67],地图投影为'EPSG:4326'(经纬度直投),缩放比例尺10.
在官网api上可以查询相关方法:https://openlayers.org/en/latest/apidoc/module-ol_View-View.html
以配合控件、事件进行导航操作。
附件一:openlayers类
附件二:arcgis destop 加载天地图服务
为了防止数据被随意爬取和盗链,天地图服务加入了tokey,请先申请服务端key,并确保arcgis destop版本在10.3以上,10.3以下的版本没有能够加入key的选项。
ArcMap——Catalog——GIS Servers——Add WMTS Server
自定义参数,点右边的+号,输入:tk ,参数:您的key。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。