Openlayers加载WMTS时间地图,加载天地图底图

1. 地图显示流程图

Openlayers加载WMS时间地图实现流程图

基本的实现思路是:
1.准备数据;
2.map逐个加载数据,通过控制图层可见性进行跳转显示;
3.添加上一图层、下一图层、开始、暂停按钮进行图层控制。

2. 基本环境搭建

2.1 采用组件及环境

开发工具:WebStorm
所用组件:Openlayers 5.3、Geoserver 2.15.0、layui(可选)

2.2 搭建步骤

  1. 下载Openlayers插件,文件名为v5.3.0-dist.zip,加压文件,将其中的ol.js放置到开发工程目录底下,不用也行,直接引用在线ol.js
  2. 找个layui.css的样式组件放到工程目录底下(为了布局好看,没有也无所谓)
  3. 需要按时间展示的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;
    }
}

3.3 运行演示

二维栅格时间地图.gif
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,348评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,122评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,936评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,427评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,467评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,785评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,931评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,696评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,141评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,483评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,625评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,291评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,892评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,741评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,977评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,324评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,492评论 2 348

推荐阅读更多精彩内容