OpenLayers框架
- 学习目录:https://www.zhihu.com/column/c_1098918318844612608
- 当前学习位置:https://zhuanlan.zhihu.com/p/93134702
- OpenLayers的官方网站:https://openlayers.org/en/latest/doc/faq.html
- OpenLayers是一个用于开发WebGIS客户端的JavaScript包,最初基于BSD许可发行。
- OpenLayers是一个开源的项目,其设计之意是为互联网客户端提供强大的地图展示功能,包括地图数据显示与相关操作,并具有灵活的扩展机制。
- 目前OpenLayers已经成为一个拥有众多开发者和帮助社区的成熟、流行的框架。
Web墨卡托投影坐标系:
以整个世界范围,赤道作为标准纬线,本初子午线作为中央经线,两者交点为坐标原点,向东向北为正,向西向南为负。
X轴:由于赤道半径为6378137米,则赤道周长为2PIr = 2*20037508.3427892,因此X轴的取值范围:[-20037508.3427892,20037508.3427892]。
Y轴:由墨卡托投影的公式可知,同时上图也有示意,当纬度φ接近两极,即90°时,y值趋向于无穷。
这是那些“懒惰的工程师”就把Y轴的取值范围也限定在[-20037508.3427892,20037508.3427892]之间,搞个正方形。
众所周知,事先切好静态图片,提高访问效率云云。俺只是告诉你为什么会是这样子。因此在投影坐标系(米)下的范围是:最小(-20037508.3427892, -20037508.3427892 )到最大 (20037508.3427892, 20037508.3427892)。
//经纬度转Wev墨卡托 dvec3 CMathEngine::lonLat2WebMercator(dvec3 lonLat) { dvec3 mercator; double x = lonLat.x 20037508.34/180; double y = log(tan((90+lonLat.y)PI/360))/(PI/180); y = y 20037508.34/180; mercator.x = x; mercator.y = y; return mercator ; } //Web墨卡托转经纬度 dvec3 CMathEngine::WebMercator2lonLat( dvec3 mercator ) { dvec3 lonLat; double x = mercator.x/20037508.34180; double y = mercator.y/20037508.34180; y= 180/PI(2atan(exp(yPI/180))-PI/2); lonLat.x = x; lonLat.y = y; return lonLat; }
经纬度 地球是一个椭球,Datum是一组用于描述这个椭球的数据集合。最常用的一个Datum是WGS84(World Geodetic System 1984),它的主要参数有:
坐标系的原点是地球质心(center of mass); 子午线(meridian),即零度经线,位于格林威治子午线Royal Observatory所在纬度往东102.5米所对应的的经线圈; 椭球截面长轴为a=6378137米; 椭圆截面短轴为b=6356752.3142米,可选参数; 扁平比例(flattening)f=(a−b)/a=1/298.257223563; geoid,海平面,用于定义高度,本文从略。 通过以上参数设定,我们才能对地球上的任意一个位置用经度、纬度、高度三个变量进行描述。所以当我们获取一组经纬度信息时,首先要弄明白这组信息对应的Datum。
参考:https://segmentfault.com/a/1190000011276788
投影 地图是显示在平面上的,因此需要将球面坐标转换为平面坐标,这个转换过程称为投影。最常见的投影是墨卡托(Mercator)投影,它具有等角性质,即球体上的两点之间的角度方位与平面上的两点之间的角度方位保持不变,因此特别适合用于导航。
Web墨卡托投影(又称球体墨卡托投影)是墨卡托投影的变种,它接收的输入是Datum为WGS84的经纬度,但在投影时不再把地球当做椭球而当做半径为6378137米的标准球体,以简化计算。
Web墨卡托投影有两个相关的投影标准,经常搞混:
EPSG4326:Web墨卡托投影后的平面地图,但仍然使用WGS84的经度、纬度表示坐标; EPSG3857:Web墨卡托投影后的平面地图,坐标单位为米。
首先OpenLayers会在我们自定义的div元素(即id为map的div元素)中创建一个Viewport容器,地图中的所有内容都放置在Viewport中呈现。
在Viewport容器中分别创建了如下三个关键的元素层,分别渲染呈现地图容器中的内容:
- 地图渲染层 —— 这是一个canvas元素,地图基于canvas 2D方式渲染
- 内容叠加层 —— 用于放置叠置层(ol.Overlay,后面会详细介绍)内容,如在地图上添加弹窗、图片等等
- 地图控件层 —— 用于放置控件,默认情况下会放置ol.control.Zoom(用于控制地图放大、缩小)、ol.control.Rotate(用于控制地图旋转)、ol.control.Attribution(用于控制地图右下角标记)这三个控件。
OpenLayers封装了很多控件用于对地图进行操作、显示地图信息等。
- 归属控件(Attribution) —— 用于展示地图资源的版权或者归属,它会默认加入到地图中。
- 全屏控件(FullScreen) —— 控制地图全屏展示
- 坐标拾取控件(MousePosition) —— 用于在地图上拾取坐标
- 鹰眼控件(OverviewMap) —— 生成地图的一个概览图
- 旋转控件(Rotate) —— 用于鼠标拖拽旋转地图,它会默认加入到地图中。
- 比例尺控件(ScaleLine) —— 用于生成地图比例尺
- 滑块缩放控件(ZoomSlider) —— 以滑块的形式缩放地图
- 缩放至特定位置控件(ZoomToExtent) —— 用于将地图视图缩放至特定位置
- 普通缩放控件(Zoom) —— 普通缩放控件,它会默认加入到地图中。
OpenLayers的地图数据通过图层(Layer)进行组织渲染,然后通过数据源(Source)设置具体的地图数据来源。
Layer可看作渲染地图的层容器,具体的数据需要通过Source设置。
地图数据根据数据源(Source)可分为Image、Tile、Vector三大类型的数据源类,对应设置到地图图层(Layer)的Image、Tile、Vector三大类的图层中。其中,矢量图层Vector通过样式(Style)来设置矢量要素渲染的方式和外观。
Source和Layer是一对一的关系,有一个Source,必然需要一个Layer,然后把Layer添加到Map上,就可以显示出来了。
多源数据加载之数据组织图:https://pic1.zhimg.com/v2-6a7a73daeecd3e7ddd124db01cc9bac7_1440w.jpg?source=172ae18b
在数据源中:
- Tile类为瓦片抽象基类,其子类作为各类瓦片数据的数据源。
- Vector类为矢量数据源基类,为矢量图层提供具体的数据来源,包括直接组织或读取的矢量数据(Features)、远程数据源的矢量数据(即通过url设置数据源路径)等。若是url设置的矢量数据源,则通过解析器Format(即ol.format.Feature的子类)来解析各类矢量数据,如XML、Text、JSON、GML、KML、GPS、WFS、WKT、GeoJSON等地图数据。
- Image类为单一图像基类,其子类为画布(canvas)元素、服务器图片、单个静态图片、WMS单一图像等的数据源。它与Tile类的区别在于,Image类对应的是一整张大图片,而不像瓦片那样很多张小图片,从而无需切片,也可以加载一些地图,适用于一些小场景地图。
从复杂度来分析,Image类和Vector类都不复杂,其数据格式和来源方式都简单。而Tile类则不一样,由于一些历史问题,多个服务提供商,多种标准等诸多原因,导致要支持世界上大多数的瓦片数据,就需要针对这些差异(这些差异主要是瓦片坐标系不同、分辨率不同等,后面会详细介绍)提供不同的Tile数据源支持。我们先来看一下OpenLayers现在支持的Source具体有哪些: https://pic2.zhimg.com/80/v2-f801f289555ac752a52632b63e3c6c85_720w.jpg
上图中的类是按照继承关系,从左向右展开的,左边的为父类,右边的为子类。在使用时,一般来说,都是直接使用叶子节点上的类,基本就可以完成需求。父类需要自己进一步扩展或者处理才能有效使用。
我们先了解最为复杂的ol.source.Tile,其叶子节点类有很多,大致可以分为几类:
- 在线服务的Source,包括ol.source.BingMaps(微软提供的Bing在线地图数据)、ol.source.Stamen(Stamen提供的在线地图数据)。没有自己的地图服务器的情况下,可直接使用它们,加载地图底图。
- 支持协议标准的Source,包括ol.source.TileArcGISRest、ol.source.TileWMS、ol.source.WMTS、ol.source.UTFGrid、ol.source.TileJSON。如果要使用它们,首先你得先学习对应的协议,之后必须找到支持这些协议的服务器来提供数据源,这些服务器可以是底图服务提供商提供的,也可以是自己搭建的服务器,关键是得支持这些协议。
- ol.source.XYZ,这个需要单独提一下,因为是可以直接使用的,而且现在很多地图服务(在线的,或者自己搭建的服务器)都支持xyz方式的请求。国内在线的地图服务,高德、天地图等,都可以通过这种方式加载,本地离线瓦片地图也可以,用途广泛,且简单易学。
ol.source.Image虽然有几种不同的子类,但大多比较简单,因为不牵涉到过多的协议和服务提供商。而ol.source.Vector就更加简单了,但有时候其唯一的子类ol.source.Cluster(聚合要素时使用)在处理大量的要素时,我们可能需要使用。
在大概了解了整个Source之后,紧接着该介绍它的搭档Layer了,同样的,我们还是先从OpenLayers现有的Layer类图大致了解一下: https://pic2.zhimg.com/80/v2-4bf60e33d5d7c28cbc8e6631fe385d01_720w.jpg
为了便于了解和使用,图中标注了每一个Layer对应的Source。通过上图可以看到Layer相对于Source而言,真是太简单了。
其中ol.layer.Group是一个用于将多个图层存储在一起的集合类,以后接触到相关内容再介绍。
是不是觉得类有点多,一时难以招架?随着我们以后对这些类的详细介绍与使用,我们一定能够熟练掌握它们。
一、瓦片地图简介 瓦片地图(也叫切片地图)源于一种大地图解决方案,就是在多个比例尺下配置地图,然后提前把每个比例尺下的地图绘制为小块图片(瓦片),保存在服务器上用于缓存的目录中。这样客户端在访问地图时,可以直接获取需要的小块图片拼接成整幅地图,而不是由服务器动态创建(实时创建)出一幅图片再发送到客户端,从而极大提高了访问速度。
瓦片地图起始于谷歌地图。在2005年前后谷歌地图已经开始将矢量图层融合为一张栅格化的大图像,大图像被切分为256像素 x 256像素的图片(瓦片)。这些图片预先生成并存储在磁盘上,以便快速分发(通过AJAX)到客户端。这样做可以同时支持成千上万个并发请求(异步-因为瓦片地图根据请求范围加载),而这对于动态地图绘制而言基本是不可能的。
瓦片地图的缺点是不能改变图层的符号,可以认为它们是一些"死图片",不能进行更新。因此,WebGIS中通常的做法是将通用的基础底图图层发布为瓦片,在其上叠加另外的包含专题信息的图层,这种图层结构可以被比喻为"图层三明治"。 https://pic1.zhimg.com/80/v2-29f081268c1e067847f58c48233f4fc4_720w.jpg
二、LOD LOD是Levels of Detail(细节层级)的简写,用于根据当前的环境,渲染不同的图像,用于降低非重要内容的细节度,从而提高渲染效率,在电子游戏中经常运用,对于需要显示全球地图的GIS系统而言,更需要应用这项技术。
在不同的LOD下,自然分辨率就可能不一样,这两者是紧密结合在一起的。对于图形显示系统而言,分辨率作为屏幕坐标和世界坐标之间计算的纽带,其作用是非常重要的(例如,屏幕上两个像素点间的距离对应的现实世界的距离是多少,这就需要通过分辨率来衡量与计算——分辨率将在后面进行介绍)。
在详细讲解之前,假设给你两张A4纸,在其中一张纸上把你家整个绘制上去,在另一张纸上只把你睡的房间绘制上去。如果别人想看你家,你会给哪一张纸?如果想看你睡的房间,你会给哪一张纸?相信你不会给错,LOD就是这种根据不同需要,采用不同图的技术方案。在地图应用中,最直观的体验,就是地图放大缩小。当地图放大后,能看到更详细的地理信息,比如街道、商店等等。当地图缩小再缩小,原来能看到的街道、商店就看不见了,但是能看到更大的区域。我们的屏幕就相当于是A4纸,大小不变。
LOD这个技术方案非常棒!非常符合我们的自然习惯,所以在很多图形系统中都使用了这项技术。在GIS系统中,不断放大,就能看到更多地图细节,了解更加详细的信息。对于GIS引擎的开发者而言,需要实现这项技术,当发现用户放大地图时,就立马使用更有细节的地图图片,替换现在显示的地图图片。现在问题来了:意思是说对于同一个地点而言,需要有更多张呈现不同细节程度的图片?是的,你没有猜错。虽然在使用瓦片地图的过程中,感觉放大、缩小地图是浑然一体的,但其实就在你眼皮下发生了图片替换。不同层级使用具有不同细节的地图瓦片,这就需要为每一个层级准备图片,如果使用离线工具下载瓦片地图,会看到下载的图片是按照层级Z进行存储的。开发者不用担心数据源的处理,只需要知道这个原理就可以了。
为了便于理解GIS系统中不同层级,使用不同的图片,下面使用google在线瓦片地图进行说明。最小层级0情况下,只用了一张256*256像素的图片表示整个地球平面: https://pic2.zhimg.com/80/v2-ae5a8e99bd385044df511335fbdbd149_720w.jpg
稍大一个层级1情况下,用了四张256*256像素的图片(各张图片中表示的信息更丰富了)来表示整个地球: https://pic3.zhimg.com/80/v2-4998b045c5693d038393317c46a58e2a_720w.jpg 对照一下,是否更加的明白了LOD原理及其在GIS中的应用了?
一、瓦片计算 1.1、切片方式 如果对整个地球图片进行切片,需要考虑的是整个地球图片大小,以及切片规则,切片(瓦片)大小。
对于WebGIS而言,在线地图几乎都采用Web墨卡托投影坐标系(EPSG:3857,后面会详解介绍),地球投影到平面上就是一个正方形。为了方便使用,切片时大多按照正方形的方式来进行切片,比如大小为256256的瓦片(单位像素),一个10241024的地图,就可以切片4张小的256*256的瓦片。
瓦片大小几乎都是256256,有一些则会增加到512512(由于以前的屏幕分辨率通常比较低,所以256256的瓦片在低分辨率的屏幕上显示效果比较好,随着屏幕分辨率的提高,瓦片大小自然就会增加到512512。但目前主流仍是256*256大小的瓦片)。
LOD会使得不同层级下的全球地图大小不一致,结合瓦片地图技术一起,就出现了金字塔瓦片结构: https://pic4.zhimg.com/80/v2-e9b8b705ed3a49dce360f20c9af2177b_720w.jpg
在金字塔瓦片结构中,上一层级的一张瓦片,在更大一层级中,会用4张瓦片来表示,依次类推,比如上一篇文章中看到的Google在线瓦片地图的第0级和第1级的瓦片地图就呈现这样的规律。这样做可以维持正方形的投影方式不变,同时按照2的幂次方放大(瓦片的边长),计算效率非常高。
1.2、瓦片数量计算 通过上面切片的介绍,我们可以对每一层级拥有的瓦片的数量进行简单的计算:
- 层级0的瓦片数是 1 = 2^0 ∗ 2^0
- 层级1的瓦片数是 4 = 2^1 * 2^1
- 层级2的瓦片数是 16 = 2^2 * 2^2
- 层级3的瓦片数是 64 = 2^3 * 2^3
- 层级z的瓦片数是 2^z * 2^z
1.3、瓦片坐标系 从以上的金字塔瓦片结构可以看出来,瓦片的组织方式是三维的,因此对一幅地图进行切片时,需要给每一块瓦片进行详细的编号,即需要指定每一块瓦片的行号、列号以及层级数。
这个问题就涉及到了瓦片坐标系,瓦片坐标系是瓦片地图的组织参考框架。它规定每一块瓦片的行号、列号以及层级数,另外,在瓦片坐标系中列号一般从左到右方向递增,而在瓦片坐标系中行号有可能沿着从上到下的方向递增,或者从下到上递增,所以不同的瓦片坐标系的起始点(原点)不同。
不同的在线地图服务商,可能定义不一样的瓦片坐标系,瓦片坐标系不一样,那么对应的同一个位置的瓦片的坐标也会不一样。需要引起重视。
OpenLayers提供了一个用于调试瓦片坐标系的ol.source.TileDebug类。借助这个类,我们可以清晰的看到每一个瓦片的坐标: https://pic1.zhimg.com/80/v2-be252aba435ae137a0d18337574cc1f0_720w.jpg
二、分辨率 2.1、分辨率简介 分辨率的简单定义是屏幕上的1像素表示的现实世界的地面实际距离。
上一节说到了金字塔瓦片结构中每一个层级,会使用不同数量的瓦片来表示整个地球,那么无论是哪一个层级,所表示的实际地理空间范围都是一致的,但使用的瓦片个数却是不一样的,因此不同层级地图瓦片的分辨率也不同。
以Google在线地图为例,层级0使用了一个瓦片,层级1使用了4个瓦片。通过计算可以知道层级0的整个地球图像(瓦片)为256256像素大小,层级1整个地球图像为512512像素大小。而层级0和层级1表示的地球范围都是一样的(经度[-180°, 180°],纬度[-90°, 90°])。在层级0的时候,一个像素在水平方向就表示360°/256 = 1.40625°这么长的经度范围(以度为单位),在竖直方向就表示180°/256 = 0.703125°这么长的纬度范围(以度为单位)。而这两个数字就是分辨率了,即一个像素所表示的现实世界的范围是多少,这个范围可能是度(在地理坐标系统中),可能是米(在投影坐标系统中),或者其他单位,根据具体的情况而定。
2.2、Web墨卡托投影坐标系中的分辨率 我们知道,在WebGIS中使用的在线瓦片地图是采用的Web墨卡托(Mercator)投影坐标系,经过投影后,整个地球是一个正方形,所能表示的地球范围为:
经度[-180°, 180°],纬度[-85°, 85°],单位为度。
对应的Web墨卡托坐标系的范围为:
x[-20037508.3427892, 20037508.3427892],范围y同样是[-20037508.3427892, 20037508.3427892],单位为米。
或许,你会好奇这个范围是怎么计算而来的,如果详细了解过它的定义,应该知道Web墨卡托投影只是简单的把地球球面剖开拉伸为一个正方形,由于南北极两端采用这种拉伸会严重变形,并且南北极在使用过程中很少用到,所以干脆就只投影了地球的[-85, 85]纬度范围。然后在经度-180度(或+180)的地方从上到下剖开地球,然后按照赤道方向来展开成一张平面,那么这个平面的边长,就等于以地球赤道半径按照圆来计算的周长。近似的按照6378137米为地球半径来计算,那么整个赤道周长的一半,即为:
π∗r=3.1415926∗6378137=20037508.0009862
以上就是Web墨卡托投影坐标系范围的完整的计算过程,墨卡托投影也有很多变形,会有细微的不同,OpenLayers默认使用的就是EPSG:3857(Web墨卡托投影坐标系),对于该坐标系的详细定义,可以参见epsg.io.3867。
有了范围之后,要想计算Web墨卡托投影坐标系中的分辨率,按照上面的计算过程就非常简单了,还是以Google在线瓦片地图为例,x、y方向上的各层级瓦片地图分辨率计算公式可以归纳为:
resolution = rang / (256 * 2^z)
rang —— 表示x方向或y方向上的整个范围,比如20037508.3427892 * 2。 256 —— 表示一个瓦片的边长,单位为像素。 2^z —— 表示在层级z下,x或y方向上的瓦片个数。 那么整个公式计算出来就是在x或y方向,屏幕上一个像素所能代表的实际地理范围,即分辨率。
2.3、OpenLayers默认使用的分辨率 OpenLayers默认设置了加载瓦片地图时采用的分辨率,通过一个示例来看一下: https://pic3.zhimg.com/80/v2-ae1eb2fcec29c1ac7131184256e137f2_720w.jpg
缩放上面的地图,从层级0开始,用前面介绍的公式和当前地图显示的分辨率进行比较,你会发现OpenLayers默认采用的分辨率和Google在线瓦片地图一样。
OpenLayers瓦片地图默认分辨率表(地面比例尺): https://pic3.zhimg.com/80/v2-eb2226f935c5675c8e8aa67217de0b16_720w.jpg
注意事项
为什么我们上面一直以Google在线瓦片地图举例说明?
因为不同的在线瓦片地图可能采用不一样的分辨率,比如百度在线瓦片地图。所以在使用在线瓦片地图或者自己制作的瓦片地图时,都需要知道使用的分辨率是多少。如若不然,可能会出现位置偏移。
目前高德的瓦片地址有如下两种:
- http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=7和
- http://webst0{1-4}.is.autonavi.com/appmaptile?style=7&x={x}&y={y}&z={z} 前者是高德的新版地址,后者是老版地址。
高德新版的参数:
- lang可以通过zh_cn设置中文,en设置英文;
- size基本无作用;
- scl设置标注还是底图,scl=1代表注记,scl=2代表底图(矢量或者影像);
- style设置影像和路网,style=6为影像图,style=7为矢量路网,style=8为影像路网。
总结之:
- http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=7 为矢量图(含路网、含注记)
- http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=2&style=7 为矢量图(含路网,不含注记)
- http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=6 为影像底图(不含路网,不含注记)
- http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=2&style=6 为影像底图(不含路网、不含注记)
- http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=8 为影像路图(含路网,含注记)
- http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=2&style=8 为影像路网(含路网,不含注记) 高德旧版可以通过style参数设置影像、矢量、路网。
总结之:
- http://webst0{1-4}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z} 为影像底图(不含路网,不含注记)
- http://webst0{1-4}.is.autonavi.com/appmaptile?style=7&x={x}&y={y}&z={z} 为矢量地图(含路网,含注记)
- http://webst0{1-4}.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z} 为影像路网(含路网,含注记)
Yahoo地图的代码有点不一样:多了tileSize参数的设置。
默认情况下,tileSize为256,这也是现在绝大多数瓦片采用的大小。但Yahoo地图使用的是512,所以我们需要指定。
前面一篇文章讲到可以使用XYZ的方式非常简单的加载瓦片地图,但遗憾地是,这种简单方法并不适用于所有的在线瓦片地图,总有一些是特殊的,比如百度地图。
瓦片地图加载的关键在于找对瓦片,但要找对瓦片,就得知道瓦片的坐标,而瓦片坐标又基于明确的瓦片坐标系。
通过前面的API文档,我们可以知道OpenLayer的默认瓦片坐标系的原点在左上角,从左到右为x轴正方向,从下到上为y轴正方向。
具体到地图上来讲,地球经过投影,投影到一个平面上,平面最左边对应地球最西边,平面最上边对应地球最北边。原点就处于整个平面的左上角,即地球的西北角,从北向南为y轴负方向,从西向东为x轴正方向。理解这一点非常重要,因为并不是所有在线的瓦片地图都是采用这样的瓦片坐标系。用OpenLayers加载它们的时候,如果瓦片坐标系不同,计算出来的瓦片地址就获取不到对应的瓦片,为解决这个问题,我们必须要先对瓦片坐标进行转换。
那么,具体该怎么实现转换?最详细明了的方式还是看实例(查看baidu_map.html页面配置)。
如何分析不同在线瓦片地图的瓦片坐标系呢?非常重要的一点是,先从特例触发,找简单的情况分析,比如选择z为2或者3进行分析,这种情况下,瓦片的数量比较少,可以查看整个地球范围内的地图的瓦片请求,注意分析其请求的url参数。
瓦片的url解析对于想直接使用在线瓦片服务的开发者而言,是一项经常要做的事。根据难度,大致可以分为三种情况:
第一种情况最简单,请求瓦片的url明确有xyz参数,比如高德地图和百度地图。 第二种稍微难一点,xyz作为路径直接存在url里面,没有明确的参数表明哪些是xyz,比如Open Street Map和Yahoo地图,这种情况下,地图服务器收到请求后,就直接在服务器按照这个路径获取图片,按照这个逻辑,一般第一个参数表示是z,第二个参数为x,第三个参数为y。要想确认是否真是这样,可以写一个小程序来验证一下,如果还有问题,建议按照上面分析地图坐标系中的方法,从z比较小的情况入手来分析x、y、z的位置。 第三种则最难,地图服务提供商为了防止大家直接非法使用瓦片地图,对瓦片的url进行了加密,比如现在的微软Bing中文地图和Google地图,这种情况下只有知道如何解密才能使用。 前面两种url的实例已经有了,此处分享一下第三种情况的url解密,以微软Bing中文地图为例: https://pic1.zhimg.com/80/v2-14f5f294254ee34249ff214aaa7d0a20_720w.jpg 图中显示的瓦片地图请求的url,没有明显的xyz参数,最有可能的存放xyz参数的地方在于url前面那一串数字,真实情况确实是这样的,经过分析和解码,最终实现了加载Bing中文地图: https://pic4.zhimg.com/80/v2-d64a549503ce40f42a5927b0b314f923_720w.jpg
需要注意的是地图数据是非常昂贵的,如果使用某一个在线地图服务,请先核实对方的版权和数据使用申明,不要侵犯对方的权益,按照要求合法使用地图。几乎所有的在线地图服务都提供了响应的服务接口,强烈建议在商用项目中使用这些接口。对于这些接口的使用,服务商都有详细的说明,在此不赘述。
一、WMS规范简介 OGC(开发地理空间联盟)的WMS(Web Map Service)服务规范就是一种动态绘制地图服务的规范,许多WebGIS服务器实现了WMS规范,因此可以结合一些WebGIS服务器发布WMS服务,然后使用OpenLayers调用WMS服务在客户端呈现地图。目前比较流行的WebGIS服务器有GeoServer、ArcGIS Server等。
到目前为止,已发布了4个版本的WMS规范。这些版本是v1.0.0、v1.1.0、v1.1.1和v1.3.0(最新版本)。WMS规范的地址为:Web Map Service | OGC 。
WMS服务主要支持以下操作:
请求服务的元数据(GetCapabilities) 请求地图图像(GetMap) 请求关于地图要素的信息(GetFeatureInfo,可选) 请求图例(GetLegendGraphic,可选) 请求用户定义的样式(GetStyles,可选) 作为基本WMS服务,必须至少支持GetCapabilities和GetMap操作,如果作为可查询WMS,则需要支持可选的GetFeatureInfo操作。
对于样式化图层描述符WMS服务,还有两种可选的操作,一个是请求图例符号操作,即GetLegendGraphic;第二个是请求用户定义的样式操作,即GetStyles。
二、请求WMS服务的元数据(GetCapabilities) GetCapabilities操作返回服务的元数据。根据该服务的元数据来确定该服务支持哪些其他操作。
接下来,比如我想访问自己本地计算机安装的GeoServer的WMS服务的元数据,就可以直接在浏览器地址栏输入:
http://localhost:8084/geoserver/wms?service=wms&version=1.3.0&request=GetCapabilities
其中:
- http://localhost:8084/geoserver/wms —— 是请求的路径
- service=wms —— 表示使用WMS服务
- version=1.3.0 —— 表示使用的WMS规范版本是1.3.0(最新版本)
- request=GetCapabilities —— 表示请求服务的元数据 上面的地址返回或打开一个XML格式的文件。
XML格式的文件中: 1、与之间一段的内容描述的是该服务的名称、关键词以及联系信息等。 2、与之间描述了该服务支持的操作以及包含的图层。其中:
与之间描述的是该服务支持的操作,从上述响应可以看出该服务支持GetCapabilities、GetMap(得到地图)、GetFeatureInfo(得到要素信息)操作。 与之间罗列了该服务所包含的所有图层数据 与中的Format列出了GetMap请求所支持的返回图片的格式,包括PNG、TIFF、GIF、JPEG、WBMP等格式。 中规定了请求的方式,上面的例子表示支持HTTP的Get与Post两种方式。根据该响应我们可构造GetMap请求获取图层或某些图层指定范围的地图。