1. 基本概念
1-1. 经纬度的描述
地球是一个椭球,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,即海平面,用于定义高度
1-2. 像素坐标系
像素坐标系,也可以成为屏幕坐标系,像素坐标系和地图的经纬度坐标系存在对应关系,屏幕上的每一个像素都对应一个经纬度点位置。 不同缩放级别下,像素坐标系和经纬度坐标系的对应关系是不同的。
1-3. 投影
地图投影是利用一定数学法则把地球表面的经、纬线转换到平面上的理论和方法。由于地球是一个赤道略宽两极略扁的不规则的梨形球体,故其表面是一个不可展平的曲面,所以运用任何数学方法进行这种转换都会产生误差和变形,为按照不同的需求缩小误差,就产生了各种投影方法。
关于投影我们只需要了解墨卡托投影(正轴等角圆柱投影)
1-4. 墨卡托投影
墨卡托投影,是正轴等角圆柱投影。由荷兰地图学家墨卡托 (G.Mercator) 于 1569 年创立。假想一个与地轴方向一致的圆柱切或割于地球,按等角条件,将经纬网投影到圆柱面上,将圆柱面展为平面后,即得本投影。等角条件是使地球面上微分区域内两个方向的夹角投影到平面以后,保持角度不变的条件。
而 Web 墨卡托投影(又称球体墨卡托投影)是墨卡托投影的变种,它接收的输入是 Datum 为 WGS84 的经纬度,但在投影时不再把地球当做椭球而当做半径为 6378137 米的标准球体,以简化计算。
Web 墨卡托投影的两个投影标准:
- EPSG4326:Web 墨卡托投影后的平面地图,但仍然使用 WGS84 的经度、纬度表示坐标;
- EPSG3857:Web 墨卡托投影后的平面地图,坐标单位为米。
这两个投影标准在我们调用 geoserver 的服务时可能会用到,所以简单了解即可。
1-5. 瓦片
经过投影后,地图就变为平面的一张地图。考虑到有时候我们需要看宏观的地图信息(如世界地图里每个国家的国界),有时候又要看很微观的地图信息(如导航时道路的路况信息)。为此,我们对这张地图进行等级切分。在最高级 (zoom=0),需要的信息最少,只需保留最重要的宏观信息,因此用一张 256x256 像素的图片表示即可;在下一级 (zoom=1),信息量变多,用一张 512x512 像素的图片表示;以此类推,级别越低的像素越高,下一级的像素是当前级的4倍。这样从最高层级往下到最低层级就形成了一个金字塔坐标体系。
对每张图片,我们将其切分为 256x256 的图片,称为瓦片(Tile)。这样,在最高级 (zoom=0) 时,只有一个瓦片;在下一级 (zoom=1) 时有4个瓦片;在下一级 (zoom=2) 时有16个瓦片,以此类推。
1-6. 瓦片的编号
瓦片生成后,就是一堆图片。怎么对这堆图片进行编号,是目前主流互联网地图商分歧最大的地方。总结起来分为四个流派:
- 谷歌 XYZ:Z 表示缩放层级,Z=zoom;XY 的原点在左上角,X 从左向右,Y 从上向下。
- TMS:开源产品的标准,Z 的定义与谷歌相同;XY 的原点在左下角,X 从左向右,Y 从下向上。
- QuadTree:微软 Bing 地图使用的编码规范,Z 的定义与谷歌相同,同一层级的瓦片不用 XY 两个维度表示,而只用一个整数表示,该整数服从四叉树编码规则
- 百度 XYZ:Z 从 1 开始,在最高级就把地图分为四块瓦片;XY 的原点在经度为 0 纬度位 0 的位置,X 从左向右,Y 从下向上
2. Geoserver
先看一段官方的介绍:
GeoServer 是基于 Java 的软件服务器,允许用户查看和编辑地理空间数据。使用开放地理空间联盟(OGC)提出的开放标准,GeoServer 在地图创建和数据共享方面具有极大的灵活性。
GeoServer 允许您向世界显示您的空间信息。实施Web地图服务 (WMS) 标准,GeoServer 可以创建各种输出格式的地图。一个免费的地图库 OpenLayers 已集成到 GeoServer 中,从而使地图生成快速简便。
GeoServer 符合 Web Feature Service(WFS)标准和 Web Coverage Service(WCS)标准,该标准允许共享和编辑用于生成地图的数据。GeoServer 还使用 Web Map Tile Service 标准将您发布的地图拆分为图块,以方便Web地图和移动应用程序使用。
GeoServer 使用的是图层与图层组的概念。将在服务器上准备发布为服务的数据定义为一组数据集,然后规定在发布为Web服务时的一些参数。Geoserve 提供了操作界面来管理各种配置:
3. leaflet 和 openlayers
上文说到的 openlayers 和 leaflet 都是用于在 Web 上创建交互式地图,可以显示从任何来源加载的地图图块、矢量数据和标记。
这里的两者都是开源的,相比起来 leaflet 更加轻量,适合移动端的场景,如果只是相对简单的地图需求,使用 leaflet 会是一个合适的选择。而 openlayers 具有数量更大,更复杂的 API。而 geoserver 提供的服务,对 leaflet 和 openlayers 都是支持的。
4. 调用 geoserver 的服务
4-1. 调用 WMS
1 | const wmsLayer = Map.tileLayer.wms( |
此处使用 Map.tileLayer.wms(url, params)
调用来自 geoserver 的 WMS 服务,使用的参数如下:
- url:请求的 geoserver 服务地址
- params:请求的目标图层相关配置参数,
layers
为请求的图层名,在 geoserver 服务中不同维度的地图图层对应不同的名字,在这里的dept_3
表示业务区的地图图层;request
表示此处调用的是 geoserver 的获取地图图层的服务;format
和tranparent
表示请求的瓦片图文件格式及背景是否透明; 而sld_body
则是需要自定义的 SLD 样式
4-2. 配置 SLD
对于 WMS 返回的地图图层,可以针对之进行样式的自定义,geoserver 支持多种方法定义图层样式,SLD 就是其中一种。
SLD (Style Layer Descriptor) 是2005年OGC提出的一个标准,这个标准在一定条件下允许WMS服务器对地图可视化的表现形式进行扩展。该 SLD 规范是采用XML定义地图显示样式,通过自定义SLD来配置地图图层渲染的可视化风格,可以设置过滤器,自定义图例等。
如果我们想要自定义图层的样式,肯定会用到的元素包括:
FeatureTypeStyle:这一部分是整个样式文档的根节点,并说明什么是它的样式将被应用的特征类型。FeatureTypeStyle 包含一个或者多个 Rule 元素,Rule 元素允许有条件的映射。
RULE(规则):规则是根据属性条件和地图比例尺来对要素进行分组渲染,一般 RULE 中只允许渲染一种类型的要素,即点,线,面等其中的一种,但是可以和注记同时使用。
Symbolizer(符号):Symbolizer 指定数据应该如何可视化,在1.0的标准中包含五忠类型的Symbolizer,分别是PointSymbolizer(点符号)、LineSymbolizer(线符号)、PloygonSymbolizer(面符号)、TextSymbolizer(注记)、RasterSymbolizer(栅格)。
除了一些预设的匹配规则,SLD 还提供了一些 Function
可应用于较为负责的筛选。
以实际应用举例,见以下代码:
1 | <Rule> |
这段 SLD 表示对数据对象进行筛选匹配,当对象的 code 属性为 591Y、592Y、595Y 和 791Y 四者的其一时,适用后续的样式。后续的样式表示对应的 PolygonSymbolizer 元素适用了 Fill 和 Stroke 的样式,具体的样式属性分别是填充颜色、填充透明度、边界颜色和边界宽度。
这里需要留意的是任何 Function 元素都会有一个返回值, <ogc:Function name="in"></ogc:Function>
对应的返回值是一个 Boolean 值,所以需要在后面紧跟 <ogc:Literal>true</ogc:Literal>
来对应返回值的匹配。
4-3. 获取点击位置所属业务区
还是看例子:
1 | // 监听地图的点击事件 |
geoserver 的 GetFeatureInfo 服务支持通过 jsonp 的方式调用,通过组装地址的方式就可以实现请求获取点击位置的所属业务区了,简单看一下请求参数:
- CRS Coordinate Reference System, 即上文提到的投影标准,这里使用的是 EPSG4326
- INFO_FORMAT 使用 jsonp 调用所需要的传参
- FEATURE_COUNT 查询命中的数据对象取数上限
- X, Y 在地图上的点击坐标,以地图容器左上为原点的坐标值
- WIDTH, HEIGHT 地图容器的尺寸
- BBOX Bounds Box, 当前所显示地图的四个角对应的经纬度
geoserver 主要是通过 X, Y, WIDTH, HEIGHT 和 BBOX 来定位到具体的点击位置,需要注意受限于地图缩放等级和容器大小等因素,最终的返回值可能不止一个。
扩展参考:
Leaflet - a JavaScript library for interactive maps
OpenLayers - A high-performance, feature-packed library for all your mapping needs.
SLD Styling — GeoServer 2.19.x User Manual
GeoServer中使用SLD样式
瓦片地图原理