1. 地图显示流程图
基本的实现思路是:
1.准备数据;
2.map逐个加载数据,通过控制图层可见性进行跳转显示;
3.添加上一图层、下一图层、开始、暂停按钮进行图层控制。
2. 基本环境搭建
2.1 采用组件及环境
开发工具:WebStorm
所用组件:Openlayers 5.3、Geoserver 2.15.0、layui(可选)
2.2 搭建步骤
- 下载Openlayers插件,文件名为v5.3.0-dist.zip,加压文件,将其中的ol.js放置到开发工程目录底下,不用也行,直接引用在线ol.js
- 找个layui.css的样式组件放到工程目录底下(为了布局好看,没有也无所谓)
- 需要按时间展示的wmts地图链接,可以准备开工啦~
工程目录如图所示
3. 栅格WMTS时间地图展示
3.1 前端HTML页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--网页标题名-->
<title>栅格时间地图</title>
<!--引用的样式组件-->
<link rel="stylesheet" href="https://openlayers.org/en/v5.3.0/css/ol.css" type="text/css">
<link rel="stylesheet" href="./layui/css/layui.css">
</head>
<body>
<!--地图id及大小-->
<div id="map" class="map" style="width:1920px;height:700px"></div>
<!--地图标注-->
<div id="nowLayer">当前图层为:基准等高线</div>
<!--按钮控制-->
<button class="layui-btn" style="margin-left: 700px;" id="btn_onStarted" type="hidden">开始</button>
<button class="layui-btn" style="margin-left: 20px;" id="btn_onPaused" type="hidden">暂停</button>
<button class="layui-btn" style="margin-left: 20px;" id="btn_addLayer">下一图层</button>
<button class="layui-btn" style="margin-left: 20px;" id="btn_removeLayer">上一图层</button>
<button class="layui-btn" style="margin-left: 20px;" id="btn_onReset">复位</button>
<!--引用的js组件-->
<script src="./ol/ol.js"></script>
<script src="./layui/layui.js"></script>
<script src="./resources/jquery-3.3.1.js"></script>
<!--html对应的js脚本-->
<script src="js/showWMTRaster.js" async="async"></script>
</body>
</html>
3.2 Js脚本文件
//预备展示的栅格图层组
var m_layerNameGroup=["AvgNorResult5_2_R","AvgNorResult6_3_R","AvgNorResult7_4_R","AvgNorResult8_5_R"]
var animationId=null,map=null
var m_controlVisibile=2;
//图层参考系
var gridsetName = 'EPSG:4326';
//格网显示等级
var gridNames = ['EPSG:4326:0', 'EPSG:4326:1', 'EPSG:4326:2', 'EPSG:4326:3', 'EPSG:4326:4', 'EPSG:4326:5', 'EPSG:4326:6', 'EPSG:4326:7', 'EPSG:4326:8', 'EPSG:4326:9', 'EPSG:4326:10', 'EPSG:4326:11', 'EPSG:4326:12', 'EPSG:4326:13', 'EPSG:4326:14', 'EPSG:4326:15', 'EPSG:4326:16', 'EPSG:4326:17', 'EPSG:4326:18', 'EPSG:4326:19', 'EPSG:4326:20', 'EPSG:4326:21'];
//基础的wmts URL
var baseUrl='http://localhost:8080/geoserver/gwc/service/wmts'
var style = '';
var format = 'image/png';
//图层组名称
var m_layerName = 'main_TS_defo:';
//定义投用信息
var projection = new ol.proj.Projection({
code: 'EPSG:4326',
units: 'degrees',
axisOrientation: 'neu'
});
//格网分辨率
var resolutions = [0.703125, 0.3515625, 0.17578125, 0.087890625, 0.0439453125, 0.02197265625, 0.010986328125, 0.0054931640625, 0.00274658203125, 0.001373291015625, 6.866455078125E-4, 3.4332275390625E-4, 1.71661376953125E-4, 8.58306884765625E-5, 4.291534423828125E-5, 2.1457672119140625E-5, 1.0728836059570312E-5, 5.364418029785156E-6, 2.682209014892578E-6, 1.341104507446289E-6, 6.705522537231445E-7, 3.3527612686157227E-7];
baseParams = ['VERSION','LAYER','STYLE','TILEMATRIX','TILEMATRIXSET','SERVICE','FORMAT'];
/**
* 初始化图层加载
*/
function init(){
function ScaleControl(opt_options) {
var options = opt_options || {};
var element = document.createElement('div');
element.setAttribute('id', 'scale');
element.className = 'ol-scale-value';
ol.control.Control.call(this, {
element: element,
target: options.target
});
};
ol.inherits(ScaleControl, ol.control.Control);
ScaleControl.prototype.setMap = function(map) {
map.on('postrender', function() {
var view = map.getView();
var resolution = view.getResolution();
var dpi = 90.71428571428572;
var mpu = map.getView().getProjection().getMetersPerUnit();
var scale = resolution * mpu * 39.37 * dpi;
if (scale >= 9500 && scale <= 950000) {
scale = Math.round(scale / 1000) + 'K';
} else if (scale >= 950000) {
scale = Math.round(scale / 1000000) + 'M';
} else {
scale = Math.round(scale);
}
document.getElementById('scale').innerHTML = 'Scale = 1 : ' + scale;
}, this);
ol.control.Control.prototype.setMap.call(this, map);
}
var initLayerName=m_layerName+"AvgNorResult3_1";
//将定义的图层参数配置到图层中
params = {
'VERSION': '1.0.0',
'LAYER': initLayerName,
'STYLE': style,
'TILEMATRIX': gridNames,
'TILEMATRIXSET': gridsetName,
'SERVICE': 'WMTS',
'FORMAT': format
};
function constructSource() {
var url = baseUrl+'?'
for (var param in params) {
if (baseParams.indexOf(param.toUpperCase()) < 0) {
url = url + param + '=' + params[param] + '&';
}
}
url = url.slice(0, -1);
//wmts图层显示配置
var source = new ol.source.WMTS({
url: url,
layer: params['LAYER'],
matrixSet: params['TILEMATRIXSET'],
format: params['FORMAT'],
projection: projection,
tileGrid: new ol.tilegrid.WMTS({
tileSize: [256,256],
extent: [-180.0,-90.0,180.0,90.0],
origin: [-180.0, 90.0],
resolutions: resolutions,
matrixIds: params['TILEMATRIX']
}),
style: params['STYLE'],
wrapX: true
});
return source;
}
var layer = new ol.layer.Tile({
source: constructSource()
});
//天地图底图配置
var projection1 = ol.proj.get('EPSG:4326');
var resolutions1 = new Array(18);
var projectionExtent = projection1.getExtent();
var matrixIds = new Array(18);
var size = ol.extent.getWidth(projectionExtent) / 256;
for (var z = 1; z < 19; ++z) {
// generate resolutions and matrixIds arrays for this WMTS
resolutions1[z] = size / Math.pow(2, z);
matrixIds[z] = z;
}
var wmtsUrl_1 = 'http://t0.tianditu.gov.cn/vec_c/wmts?tk='; //矢量底图
var wmtsUrl_2 = 'http://t0.tianditu.gov.cn/cva_c/wmts?tk='; //矢量注记
//需要改为自己的token,如果不需要底图显示,可以将这段代码去掉
var webKey = 'your token';
//定义图层
var layers = [];
var layer1 =new ol.layer.Tile({
opacity: 0.7,
source: new ol.source.WMTS({
url: wmtsUrl_1 + webKey,
layer: 'vec',
matrixSet: 'c',
format: 'tiles',
style: 'default',
projection: projection1,
tileGrid: new ol.tilegrid.WMTS({
origin: ol.extent.getTopLeft(projectionExtent),
resolutions: resolutions1,
matrixIds: matrixIds
}),
wrapX: true
})
})
var layer2 =new ol.layer.Tile({
opacity: 0.7,
source: new ol.source.WMTS({
url: wmtsUrl_2 + webKey,
layer: 'cva',
matrixSet: 'c',
format: 'tiles',
style: 'default',
projection: projection1,
tileGrid: new ol.tilegrid.WMTS({
origin: ol.extent.getTopLeft(projectionExtent),
resolutions: resolutions1,
matrixIds: matrixIds
}),
wrapX: true
})
});
var view = new ol.View({
center: [0, 0],
zoom: 2,
projection: projection,
extent: [-180.0,-90.0,180.0,90.0]
});
map = new ol.Map({
controls: ol.control.defaults({attribution: false}).extend([
new ol.control.MousePosition(),
new ScaleControl()
]),
layers: [layer1,layer2,layer],
target: 'map',
view: view
});
map.getView().fit([113.97890540635177,37.77507734365083,114.0056545989984,37.79244001605483], map.getSize());
}
/**
* 控制延时
* @param numberMillis延时时长
*/
function sleep(numberMillis) {
var now = new Date();
var exitTime = now.getTime() + numberMillis;
while (true) {
now = new Date();
if (now.getTime() > exitTime)
return;
}
}
/**
* 全部加载图层
*/
function loadTimeMap(){
for(var i=0;i<m_layerNameGroup.length;i++){
var renderLayerName=m_layerName+m_layerNameGroup[i];
params = {
'VERSION': '1.0.0',
'LAYER': renderLayerName,
'STYLE': style,
'TILEMATRIX': gridNames,
'TILEMATRIXSET': gridsetName,
'SERVICE': 'WMTS',
'FORMAT': format
};
function constructSource() {
var url = baseUrl+'?'
for (var param in params) {
if (baseParams.indexOf(param.toUpperCase()) < 0) {
url = url + param + '=' + params[param] + '&';
}
}
url = url.slice(0, -1);
var source = new ol.source.WMTS({
url: url,
layer: params['LAYER'],
matrixSet: params['TILEMATRIXSET'],
format: params['FORMAT'],
projection: projection,
tileGrid: new ol.tilegrid.WMTS({
tileSize: [256,256],
extent: [-180.0,-90.0,180.0,90.0],
origin: [-180.0, 90.0],
resolutions: resolutions,
matrixIds: params['TILEMATRIX']
}),
style: params['STYLE'],
wrapX: true
});
return source;
}
var layer = new ol.layer.Tile({
source: constructSource()
});
map.addLayer(layer);
}
}
/**
* 控制图层组可见性
* @param mapLayerGroup
*/
function controlTimeLayer(mapLayerGroup) {
if(m_controlVisibile<7){
if(m_controlVisibile!=2){
mapLayerGroup.a[m_controlVisibile-1].N.visible=false;
}else{
mapLayerGroup.a[6].N.visible=false;
}
mapLayerGroup.a[m_controlVisibile].N.visible=true;
updateInfo(m_controlVisibile);
map.getView().fit([113.97890540635177,37.77507734365083,114.0056545989984,37.79244001605483], map.getSize());
m_controlVisibile=m_controlVisibile+1;
}else{
m_controlVisibile=2;
}
}
function updateInfo(m_controlVisibile){
var nowLayerName=null;
switch (m_controlVisibile) {
case 2:
nowLayerName="当前图层为:基准等高线"
break;
case 3:
nowLayerName="当前图层为:等高线1期"
break;
case 4:
nowLayerName="当前图层为:等高线2期"
break;
case 5:
nowLayerName="当前图层为:等高线3期"
break;
case 6:
nowLayerName="当前图层为:等高线4期"
break;
default:
nowLayerName="当前图层为:等高线数据"
}
document.getElementById('nowLayer').innerText = nowLayerName;
}
/**
* 添加图层
* @param inputLayerName 需要添加的图层名称
*/
function addLayertoMap(inputLayerName){
var renderLayerName=m_layerName+inputLayerName;
params = {
'VERSION': '1.0.0',
'LAYER': renderLayerName,
'STYLE': style,
'TILEMATRIX': gridNames,
'TILEMATRIXSET': gridsetName,
'SERVICE': 'WMTS',
'FORMAT': format
};
function constructSource() {
var url = baseUrl+'?'
for (var param in params) {
if (baseParams.indexOf(param.toUpperCase()) < 0) {
url = url + param + '=' + params[param] + '&';
}
}
url = url.slice(0, -1);
var source = new ol.source.WMTS({
url: url,
layer: params['LAYER'],
matrixSet: params['TILEMATRIXSET'],
format: params['FORMAT'],
projection: projection,
tileGrid: new ol.tilegrid.WMTS({
tileSize: [256,256],
extent: [-180.0,-90.0,180.0,90.0],
origin: [-180.0, 90.0],
resolutions: resolutions,
matrixIds: params['TILEMATRIX']
}),
style: params['STYLE'],
wrapX: true
});
return source;
}
var layer = new ol.layer.Tile({
source: constructSource()
});
var view = new ol.View({
center: [0, 0],
zoom: 2,
projection: projection,
extent: [-180.0,-90.0,180.0,90.0]
});
map.addLayer(layer);
map.setView(view);
map.getView().fit([113.97890540635177,37.77507734365083,114.0056545989984,37.79244001605483], map.getSize());
}
/**
* 复位(直接复位到第一个图层)
*/
$('#btn_onReset').click(function () {
map.getLayers().a[m_controlVisibile].N.visible=false;
m_controlVisibile=2;
map.getLayers().a[m_controlVisibile].N.visible=true;
updateInfo(m_controlVisibile)
map.getView().fit([113.97890540635177,37.77507734365083,114.0056545989984,37.79244001605483], map.getSize());
})
/**
* 上一图层(移除当前图层)
*/
$('#btn_removeLayer').click(function () {
if(m_controlVisibile>2){
map.getLayers().a[m_controlVisibile].N.visible=false;
map.getLayers().a[m_controlVisibile-1].N.visible=true;
map.getView().fit([113.97890540635177,37.77507734365083,114.0056545989984,37.79244001605483], map.getSize());
m_controlVisibile=m_controlVisibile-1
updateInfo(m_controlVisibile);
}else{
map.getLayers().a[m_controlVisibile].N.visible=false;
m_controlVisibile=6;
map.getLayers().a[m_controlVisibile].N.visible=true;
updateInfo(m_controlVisibile)
map.getView().fit([113.97890540635177,37.77507734365083,114.0056545989984,37.79244001605483], map.getSize());
}
})
/**
* 下一图层(在当前图层叠加图层)
*/
$('#btn_addLayer').click(function(){
if(m_controlVisibile<6){
map.getLayers().a[m_controlVisibile].N.visible=false;
map.getLayers().a[m_controlVisibile+1].N.visible=true;
map.getView().fit([113.97890540635177,37.77507734365083,114.0056545989984,37.79244001605483], map.getSize());
m_controlVisibile=m_controlVisibile+1
updateInfo(m_controlVisibile)
}else{
map.getLayers().a[m_controlVisibile].N.visible=false;
m_controlVisibile=2;
map.getLayers().a[m_controlVisibile].N.visible=true;
updateInfo(m_controlVisibile)
map.getView().fit([113.97890540635177,37.77507734365083,114.0056545989984,37.79244001605483], map.getSize());
}
})
/**
* 图层播放响应事件
* */
$('#btn_onStarted').click(function(){
animationId=window.setInterval(
function(){
controlTimeLayer(map.getLayers())
},
1000);
});
/**
* 图层暂停响应事件
*/
$('#btn_onPaused').click(function(){
window.clearInterval(animationId);
animationId=null;
})
init();
loadTimeMap();
//循环控制图层可见、隐藏
for(var j=0;j<map.getLayers().N.length;j++){
if(j>2){
map.getLayers().a[j].N.visible=false;
}
}