LeafLet 地图展示のwms和tms
目录
0 引言
Leaflet作为一款轻量级的地图展示JavaScript类库,其具备全开源、易上手、细节少、模型结构简单等优势,可用于小型、简单的GIS项目展示。同时,因其良好的可扩展性,也为兼容实际业务需求,提供了必要支持,而新晋的MapBox项目,其JS类库(非GL类库)就是基于LeafLet进行构建的。
1 Leaflet概述
1.1 优势与特点
- 相比于OpenLayer、MapBox或者ArcGis API For JavaScript,Leaflet具备以下几个优势;
- 轻量级:项目集成是只需要添加js和css文件即可进行使用
- 模型简单:没有资源、控制器等中间组件的概念
- 易上手:使用简单,通过图层和地图对象两个对象就可以,实现绝大部分的地图展示操作
- 易扩展:完全面向对象的结构设计,使得模型扩展非常便利。
另一方面,Leaflet控件库的基础功能比较弱,如矢量切片展示,wmts服务请求以及自定义坐标系统,都需要以plugins的形式集成。
1.2 基本概念说明
1.2.1 地图
Leaflet中地图对象就是图层的容器,并提供了一定的操作控制权限,例如,可以直接通过操作地图对象实现中心点设置、默认缩放比例,地图坐标系统设置等操作,而不需要像OpenLayer一样,通过控制器进行设置。
1.2.2 图层
Leaflet中图层即使数据源的集成封装,又是可以直接添加到图层中模型对象。也就是说,Leaflet中的图层对象,可以实现URL请求的可视化转换,而不用像OpenLayer一样,必须现先将请求封装成资源对象,再将资源对象绑定到图层中。
2 博客测试集成环境说明
- 库文件:Leatlet.js 和 leaflet.css 这两个文件均可在leaflet官网上直接下载,版本为1.2
- IDE 环境:本文选择HBuilder作为运行环境
- 服务器支持:本文选用Geoserver 2.1.11发布地图服务
- 数据存储:本文没有使用数据库进行空间数据的存储
3 简单地图展示(WMS服务调用)
3.1 实例代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script type="text/javascript" src="../js/Libs/leaflet.js" ></script>
<link rel="stylesheet" href="../css/leaflet.css" />
<title>Leaflet地图展示</title>
<style>
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<div id='map'></div>
<script>
//构建地图对象,并绑定到HTML中的map元素中
var map = L.map('map',
{
center :
{
lon : 114.15,
lat : 22.65
},
zoom:7
});
//加载wms服务的图层
var wmsLayer = L.tileLayer.wms
(
'http://localhost:8080/geoserver/gwc/service/wms?',
{
layers:'VTPK:Line2_VTPK',
}
);
//添加图层到地图
wmsLayer.addTo(map);
</script>
</body>
</html>
3.2 代码说明
本例中展示基础WMS服务地图的展示方式,可以看出脚本代码主要完成以下两方面的工作:
- 构建地图对象
- 创建可以解析wms的图层对象,并添加到地图中
对于地图对象,leaflet只需要指定待绑定HTML元素值即可实现地图构建,而地图操作均是以Option参数形式进行的设置。
对于图层对象,LeafLet要求只需要提供请求服务BaseURL和图层名称即可,而通过FireBug我们可以看到,WMS的绝大部分参数均由LeafLet默认值取代了。
特别注意:Leaflet中不论是地图还是图层,其默认的坐标系统均是3857。
具体的运行结果如下图所示:
4 切片地图服务(TMS)
对于瓦片地图服务,LeafLet可以通过L.tileLayer对象实现简单的展示。但目前LeafLet所支持的瓦片都是png,jpg等栅格瓦片,而对于Geojson或pbf格式的矢量瓦片,则需要另外导入插件实现。
4.1 实例代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script type="text/javascript" src="../js/Libs/leaflet.js" ></script>
<script type="text/javascript" src="../js/CusJS/Config.js" ></script>
<link rel="stylesheet" href="../css/leaflet.css" />
<title>Leaflet地图展示</title>
<style>
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<div id='map'></div>
<script>
//指定地图的坐标系统
var crs = L.CRS.EPSG4326;
//构建地图对象
var map = L.map('map',
{
crs : crs,
center :
{
lon : 114.15,
lat : 22.65
},
zoom:7
});
//加载TMS服务的图层,采用默认格网,也是标准格式
var tmsLayer = L.tileLayer
(
'http://localhost:8080/geoserver/gwc/service/tms/1.0.0/VTPK:Line2_VTPK@EPSG%3A4326@png/{z}/{x}/{y}.png',
{
tms: true
}
);
//tmsLayer.addTo(map);
//加载自定义的切片图层
var layername='VTPK:Line2_VTPK';
var layergrid='EPSG%3A4326';
var tileFormat='png';
//实现Tile的Extend模式
L.TileLayer.Custom = L.TileLayer.extend
(
{
//监听getTileUrl方法回调,参数为xyz坐标的结构体
getTileUrl : function(coords)
{
//拼接满足tms服务的格式的URL请求
url= 'http://localhost:8080/geoserver/gwc/service/tms/1.0.0/';
url= url+layername;
url= url+"@"+layergrid;
url= url+"@"+tileFormat;
//注意:这里返回的y坐标和geoserver生成的y坐标值存在一个转换关系
url= url+"/"+coords.z+"/"+coords.x+"/"+(Math.pow(2,coords.z)-coords.y-1)+"."+tileFormat;
return url;
}
}
);
//添加到地图
new L.TileLayer.Custom().addTo(map);
//展示格网
L.GridLayer.DebugCoords = L.GridLayer.extend
(
{
createTile: function (coords)
{
var tile = document.createElement('div');
var str_CallBackCoor=[coords.z, coords.x, (Math.pow(2,coords.z)-coords.y-1)].join(', ');
var str_UrlCoor=[coords.z, coords.x, coords.y].join(', ');
tile.innerHTML = "回调行列号:"+str_CallBackCoor+"<br>请求行列号:"+str_UrlCoor;
tile.style.outline = '1px solid red';
return tile;
}
}
);
//添加到图层
new L.GridLayer.DebugCoords().addTo(map);
</script>
</body>
</html>
4.2 代码分析
本例中代码功能主要分成三个部分
- 构建地图对象,并指定其坐标系统
- 利用默认的L.TileLayer加载切片服务
- 自定义L.TileLayer.Custom图层加载切片
4.2.1 定义其他坐标系统
本例中由于Geoserver服务器中发布的瓦片坐标系统为EPSG:4326,与Leaflet默认的3857坐标系统不一致,因此需要对地图对象的坐标系统进行重新赋值。另外,Leaflet默认只支持L.CRS.EPSG3395,L.CRS.EPSG3857,L.CRS.EPSG4326几个坐标系统,而对于其他坐标系统,则需要有Proj4Leaflet插件进行重定义。
4.2.2 L.TileLayer加载默认切片
这里只需要在L.TileLayer图层构建时,提供TMS服务的URL,并将可选参数tms设置true即可。相比于OpenLayer,屏蔽了资源、格网、分辨率等等中间细节。实现过程相对简单。(但到底采用了什么格网进行组织切片,本文还没有进行深入探究)
4.2.3 自定义L.TileLayer.Custom图层加载切片
自定义图层,主要是通过L.Tite.Extend方法进行扩展,在调用时主要监听getTileUrl回调监听,以手工方式拼接成一个合理的tms请求URL。
但特别需要注意,getTileUrl方法所获得参数的y坐标,和实际请求切片的所在格网位置,存在实际格网Y=Pow(2,回调Z)- 回调Y – 1的对应关系。同时,不同GIS服务器发布的服务可能转换关系都不是统一的,因此在展示时,需要对其进行行列号处理。为了印证行列号的对应关系,本文专门增加了一个GridLayer图层,标识当前回调的行列号和请求行列号的对应关系。其具体结果如图所示。
4 总结
总体说来,Leaflet在整个实现过程中通过默认参数、简化模型结构等方式,最大程度的减少的编程难度。同时,以其良好的扩展性能和丰富的插件,增加了功能完整性。非常适用与轻量级、小规模的GIS前端展示。
主要参考文献
LeafLet官网资源
LeafLet document http://leafletjs.com/reference-1.2.0.html
转载自:https://blog.csdn.net/cyoubo/article/details/78130497