meface/docs/article/gis/openlayers/34layerscontrol.md

14 KiB
Raw Blame History

title date author tags categories
图层控制 2020-10-20 ac
OpenLayers
GIS

1. 简述

ol中对图层显隐性的控制可以通过修改图层的visible属性或设置不透明度opacity属性来实现。

与且它地图API对比,获取图层的方法比较繁琐,比如在ArcGIS for JS中使用map.getLayerById()就可直接获得对应的图层了,但在ol中添加到map中的图层都存储在一个图层集合layers中的,需要使用map.getLayers()方法先获得该集合,再循环遍历筛选才能得到想要的图层。

图层集合中先添加进来的图层在底部,会被后加入的图层遮挡。所以通常将瓦片底图放在底部,上面的图层依次按面、线、点要素添加,这样有利于各图层的显示。如果想当前图层不被遮挡可以设置后续加入图层的opacity不透明度属性。

核心代码:

function changeLayerVisibility(layerId,prop) {
    //获取图层数组
    var layers = map.getLayers();
    for(var i=0;i<layers.getLength();i++){
        if(layers.item(i).get("id") === layerId){
            layers.item(i).setVisible(prop);
        }
    }
}

相关API

image-20201110143812069

map.getLayers()返回的是图层(BaseLayer)集合对象。

ol.Collection是对JS中数组的扩展,添加许多方便的方法,如item(index)方法获取相应index位置的数组元素。BaseLayerLayer的基类。

在构建Layer时,传入的option都会有相应的get/set访问器,所以可以拿到初始化图层时自定义的id属性。

2. 示例

这里使用了一个很久很久以前比较流行的js树形插件ztree

image-20201214112707035

下面我们使用ztree树形插件来创建图层控制示例(完整代码):

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <style>
        .map {
            height: 400px;
            width: 100%;
        }
    </style>
    <link rel="stylesheet" href="css/ol.css" type="text/css">
    <link rel="stylesheet" href="lib/zTree_v3/css/zTreeStyle/zTreeStyle.css" type="text/css">
    <script src="lib/ol.js"></script>
    <script src="lib/jquery-3.1.1.js"></script>
    <script src="lib/zTree_v3/js/jquery.ztree.all.min.js"></script>
    <title>Layer</title>
</head>
<body>
<h2>ztree图层控制</h2>
<p>zTree 是一个依靠 jQuery 实现的多功能 “树插件”。</p>
<div id="map" class="map"></div>
<div id="treeDemo" class="ztree"></div>
<script type="text/javascript">

    var zTreeObj;
    // zTree 的参数配置,深入使用请参考 API 文档setting 配置详解)
    var setting = {
        check: {
            enable: true,
            nocheckInherit: false
        },
        data: {
            simpleData: {enable: true}
        },
        view:{
            showIcon:false
        },
        callback:{
            //配置复选框点击事件的处理函数
            onCheck:handleCheck
        }
    };
    // zTree 的数据属性,深入使用请参考 API 文档zTreeNode 节点数据详解)
    var zNodes = [
        {
            Id:1,pid:0,name:"矢量数据", open:true, checked:true,children:
            [
                {id:11,pId:1,name:"GeoJson数据",id:"GeoJsonData", checked:true},
                {id:12,pId:1,name:"kml数据",id:"kmlData", checked:true},
                {id:13,pId:1,name:"gpx数据",id:"gpxData", checked:true},
                {id:14,pId:1,name:"loader函数加载的数据",id:"load", checked:true},
                {id:15,pId:1,name:"已知坐标添加的图层",id:"pointLayer", checked:true},
            ]
        },
        {
            id:2,pId:0,name:"栅格数据", open:true, checked:true,children:
            [
                {id:21,pId:2,name:"OpenStreetMap",id:"osm", checked:true},
                {id:22,pId:2,name:"ArcGIS MapServer瓦片",id:"arcgis_tile", checked:true},
                {id:23,pId:2,name:"ArcGIS online瓦片服务",id:"arcgis_online", checked:true},
                {id:24,pId:2,name:"Bing影像 Aerial",id:"bing_Aerial", checked:true},
                {id:25,pId:2,name:"Bing影像 AerialWithLabelsOnDemand",id:"bing_AerialWithLabelsOnDemand", checked:true},
                {id:26,pId:2,name:"Bing影像 RoadOnDemand",id:"bing_RoadOnDemand", checked:true},
                {id:27,pId:2,name:"Bing影像 CanvasDark",id:"bing_CanvasDark", checked:true},
            ]
        },
        {
            id:3,pId:0,name:"公共网络地图服务",open:true,checked:true,children:
            [
                {id:31,pId:3,name:"百度地图",id:"BMap", checked:true},
                {id:32,pId:3,name:"天地图矢量图层",id:"tdt_vec", checked:true},
                {id:33,pId:3,name:"天地图矢量注记图层",id:"tdt_cva", checked:true},
                {id:34,pId:3,name:"Mapbox",id:"mapbox_tile", checked:true},
            ]
        }
    ];
    $(document).ready(function(){
        zTreeObj = $.fn.zTree.init($("#treeDemo"), setting, zNodes);
    });
    //ztree复选框点击事件处理函数
    function handleCheck(e,treeId,treeNode){
        if(treeNode.level !== 0){
            //叶子节点时
            changeLayerVisibility(treeNode.id,treeNode.checked)
        }else{
            //非叶子节点时
            if(treeNode.children !== null){
                for(var j=0;j<treeNode.children.length;j++){
                    changeLayerVisibility(treeNode.children[j].id,treeNode.checked);
                }
            }
        }
    }

    function changeLayerVisibility(layerId,prop) {
        var layers = map.getLayers();
        for(var i=0;i<layers.getLength();i++){
            if(layers.item(i).get("id") === layerId){
                layers.item(i).setVisible(prop);
            }
        }
    }

    //初始化地图,加载图层
    var map;
    function initMap() {
        var shenzhen = [113.958334, 22.535640];
        var url =  'https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StateCityHighway_USA/MapServer';
        var onlineTileUrl =  'http://server.arcgisonline.com/arcgis/rest/services/USA_Topo_Maps/MapServer/tile/{z}/{y}/{x}'
        var bingKey = 'AmosL5A0GtVryl4sXNZm6U5EQMD6brAd5E8AJPGJf8AUU1saDYXDkb5CwQFijans';
        var key = "bf156eb3c72350d62b008dc8a4ae1016";
        var mapboxkey = "pk.eyJ1IjoicWl1c2hpamllIiwiYSI6ImNrYTYzNmlhdDAzb2YydG13YjZic2t2M3AifQ.XiCKl8HOEAy0MBo5v2yjvA";
        var vectorSource = new ol.source.Vector({
            format: new ol.format.GeoJSON(),
            loader: function (extent, resolution, projection) {
                var proj = projection.getCode();
                var url = 'http://gisserver.tianditu.gov.cn/TDTService/wfs?service=WFS&' +
                    'version=1.1.0&request=GetFeature&typename=LRRL&' +
                    'outputFormat=application/json&srsname=' + proj + '&' +
                    'bbox=' + extent.join(',') + ',' + proj;
                var xhr = new XMLHttpRequest();
                xhr.open('GET', url);
                var onError = function () {
                    vectorSource.removeLoadedExtent(extent);
                }
                xhr.onerror = onError;
                xhr.onload = function () {
                    if (xhr.status == 200) {
                        vectorSource.addFeatures(
                            vectorSource.getFormat().readFeatures(xhr.responseText));
                    } else {
                        onError();
                    }
                }
                xhr.send();
            },
            strategy: ol.loadingstrategy.bbox
        })
        var pointFeature = new ol.Feature({
            geometry: new ol.geom.Point([12703928.421,2575539.521]),
            name: '点要素'
        });
        var resolutions = [];
        for(var i=0;i<19;i++){
            resolutions[i] = Math.pow(2,18 - i)
        }

        map = new ol.Map({
            target:"map",
            view: new ol.View({
                center:ol.proj.fromLonLat(shenzhen),
                zoom:8
            }),
            layers:[
                //加载矢量Vector服务图层
                new ol.layer.Vector({
                    source:new ol.source.Vector({
                        url:'data/geojson/countries.geojson',
                        format:new ol.format.GeoJSON()
                    }),
                    name:"国界(JSON格式的矢量图层)",
                    id:"GeoJsonData"
                }),
                //加载矢量Vector服务图层
                new ol.layer.Vector({
                    source:new ol.source.Vector({
                        url:'data/kml/2012_Earthquakes_Mag5.kml',
                        format:new ol.format.KML({
                            extractStyles:false
                        })
                    }),
                    name:"点(KML格式的矢量图层)",
                    id:"kmlData"
                }),
                new ol.layer.Vector({
                    source:new ol.source.Vector({
                        url:'data/gpx/fells_loop.gpx',
                        format:new ol.format.GPX()
                    }),
                    name:"GPX数据",
                    id:"gpxData"
                }),
                new ol.layer.Vector({
                    source: vectorSource,
                    name: "天地图中的道路数据",
                    id: "load"
                }),
                new ol.layer.Vector({
                    source: new ol.source.Vector({
                        features:[pointFeature]
                    }),
                    id:"pointLayer"
                }),
                //加载瓦片图层
                new ol.layer.Tile({
                    source:new ol.source.OSM(),
                    name:"世界地图(OSM瓦片)",
                    id:"osm"
                }),
                new ol.layer.Tile({
                    // extent:[-13884991, 2870341,  -7455066, 6338219],
                    source:new  ol.source.TileArcGISRest({
                        url:url
                    }),
                    name:"ArcGIS瓦片服务",
                    id:"arcgis_tile"
                }),
                new ol.layer.Tile({
                    // extent:[-13884991, 2870341,  -7455066, 6338219],
                    source:new  ol.source.XYZ({
                        url:onlineTileUrl
                    }),
                    name:"ArcGIS online瓦片服务",
                    id:"arcgis_online"
                }),
                new ol.layer.Tile({
                    source:new ol.source.BingMaps({key:bingKey,imagerySet:"Aerial"}),
                    name:"BingMaps(Aerial)",
                    id:"bing_Aerial"
                }),
                new ol.layer.Tile({
                    source:new ol.source.BingMaps({key:bingKey,imagerySet:"AerialWithLabelsOnDemand"}),
                    name:"BingMaps(AerialWithLabelsOnDemand)",
                    id:"bing_AerialWithLabelsOnDemand"
                }),
                new ol.layer.Tile({
                    source:new ol.source.BingMaps({key:bingKey,imagerySet:"RoadOnDemand"}),
                    name:"BingMaps(RoadOnDemand)",
                    id:"bing_RoadOnDemand"
                }),
                new ol.layer.Tile({
                    source:new ol.source.BingMaps({key:bingKey,imagerySet:"CanvasDark"}),
                    name:"BingMaps(CanvasDark)",
                    id:"bing_CanvasDark"
                }),
                new ol.layer.Tile({
                    id:"BMap",
                    source:new ol.source.TileImage({
                        //设置坐标参考
                        projection:ol.proj.get('EPSG:3857'),
                        //设置分辨率
                        tileGrid:new ol.tilegrid.TileGrid({
                            origin:[0,0],
                            resolutions:resolutions
                        }),
                        //设置百度地图的瓦片地图请求地址
                        tileUrlFunction:function (tileCoord,pixelRatio,proj) {
                            if(!tileCoord){
                                return "";
                            }
                            var z = tileCoord[0];
                            var x = tileCoord[1];
                            var y = tileCoord[2];

                            if(x < 0){
                                x = "M" + (-x);
                            }
                            if(y < 0){
                                x = "M" + (-y);
                            }
                            return "http://online3.map.bdimg.com/onlinelabel/?qt=tile&x=" + x + "&y=" + y + "&z=" + z + "&style=pl&udt=20151021&scale=1&p=1";
                        }
                    })
                }),
                new ol.layer.Tile({
                    id:"tdt_vec",
                    title:"天地图矢量图层",
                    source:new ol.source.XYZ({
                        // url:"http://t0.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILECOL={x}&TILEROW={y}&TILEMATRIX={z}&tk="+key,
                        url: 'http://t' + Math.round(Math.random() * 7) + '.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk='+key,
                        crossOrigin:"anonymous",
                        wrapX:false
                    })
                }),
                new ol.layer.Tile({
                    id:"tdt_cva",
                    title:"天地图矢量注记图层",
                    source:new ol.source.XYZ({
                        url:"https://t2.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk="+key,
                        crossOrigin:"anonymous",
                        wrapX:false
                    })
                }),
                new ol.layer.Tile({
                    id:"mapbox_tile",
                    source: new ol.source.XYZ({
                        url: 'https://api.mapbox.com/styles/v1/mapbox/streets-v11/tiles/256/{z}/{x}/{y}?access_token='+mapboxkey
                    })
                }),
            ]
        });
    }
    window.onload = initMap();
</script>
</body>
</html>