OpenLayers 图层控制

关注我,带你一起学GIS ^

注:当前使用的是 ol [9.2.4] 版本,天地图使用的key请到天地图官网申请,并替换为自己的key

注:当前使用的是 ol 9.2.4 版本,天地图使用的key请到天地图官网申请,并替换为自己的key

图层资源目录是查看WebGIS系统数据资源的表现方式,在WebGIS开发中具有重要意义,通过图层资源目录可清晰查看系统资源以及组织结构,方便查找和查看。 图层控制就是实现图层资源的添加和移除,具体实现方式为当勾选图层复选框时添加图层,去除复选框时移除图层。

1. 创建图层资源目录

在开发工具中创建layer.json文件,编写layerJSON图层资源结构。根据图层属性,主要分为天地图、互联网地图以及ArcGIS地图三大类。示例中的图层资源都是网络公开服务,可以根据自己需要进行添加和移除。

layerJSON = [
  {
    "title""天地图",
    "id""1",
    "value""TDT",
    "checked"false,
    "spread"true,
    "disabled"false,
    "children": [
      {
        "title""天地图矢量",
        "url""http://t0.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=",
        "id""11",
        "value""vec_w",
        "layerName""tdtVec",
        "checked"false,
        "spread"true,
      },
      {
        "title""天地图影像",
        "url""http://t0.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=",
        "id""12",
        "value""img_w",
        "layerName""tdtImg",
        "checked"false,
        "spread"true,
      },
      {
        "title""天地图注记",
        "url""http://t0.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=",
        "id""13",
        "value""cva_w",
        "layerName""tdtCva",
        "checked"false,
        "spread"false,
      }
    ]
  },
  {
    "title""互联网地图",
    "id""2",
    "value""net_map",
    "checked"false,
    "spread"false,
    "disabled"false,
    "children": [
      {
        "title""百度矢量",
        "url""",
        "id""2.2",
        "value""bd",
        "checked"false,
        "layerName""bdLayer",
      },
      {
        "title""高德地图",
        "url""http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}",
        "id""2.3",
        "value""gd",
        "checked"false,
        "layerName""gdLayer",
      }
    ]
  },
  {
    "title""ArcGIS",
    "id""4",
    "value""ArcGIS",
    "checked"false,
    "layerName""arcgisLayer",
    "spread"true,
    "disabled"false,
    "children": [
      {
        "title""世界地图",
        "id""4.1",
        "value""arcgisWorld",
        "url""https://sampleserver5.arcgisonline.com/arcgis/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}",
        "checked"false,
        "layerName""arcgisWorld",
      },
      {
        "title""卫星影像",
        "id""4.2",
        "value""arcgisImg",
        "url""https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
        "checked"false,
        "layerName""arcgisImg",
      }
    ]
  }
]

2. 创建图层加载方法

在开发工具中创建layer.js文件,编写加载百度地图、天地图、ArcGIS地图图层方法以及移除图层方法等。加载图层方法只需要传入地图对象和服务地址。移除图层方法是根据layerName图层名进行移除,但是layerName是自定义属性,需要在加载图层时通过layer.set("name","")或者layer.setProperties({"name":""})进行设置。在移除图层时,需要获取图层名,可以通过layer.get("name")或者layer.getProperties()进行获取。

/**
 * 添加百度地图
 * @param map:地图对象
 */
function addBdLayer(map) {
  // 百度地图参数
  const resolutions = [];
  for (let z = 0; z < 19; ++z) {
    resolutions[z] = Math.pow(2, 18 - z);
  }
  let tilegrid = new ol.tilegrid.TileGrid({
    origin: [0, 0],
    resolutions: resolutions
  });
  let source = new ol.source.TileImage({
    projection: projection,
    tileGrid: tilegrid,
    tileUrlFunction: function (tileCoord, pixelRatio, proj) {
      if (!tileCoord) {
        return "";
      }
      var z = tileCoord[0];
      var x = tileCoord[1];
      // var y = tileCoord[2];
      var y = -tileCoord[2] - 1;

      if (x < 0) {
        x = "M" + (-x);
      }
      if (y < 0) {
        y = "M" + (-y);
      }
      return "http://online3.map.bdimg.com/onlinelabel/?qt=tile&x=" + x + "&y=" + y + "&z=" + z +
        "&styles=pl&udt=20151021&scaler=2&p=1"
    },
    crossOrigin: 'anonymous'
  })
  let layer = new ol.layer.Tile({
    sourcesource
  })
  layer.set("name""bdLayer")
  map.addLayer(layer);
}

/**
 * 加载高德地图
 * @param map:地图对象
 * @param url:地图服务地址
 */
function addGdLayer(map, url) {
  const gaodeLayer = new ol.layer.Tile({
    source: new ol.source.XYZ({
      title: "高德地图",
      url: url
    })
  })
  gaodeLayer.set("name""gdLayer")
  map.addLayer(gaodeLayer)
}

/**
 * 加载天地图影像
 * @param map:地图对象
 * @param url:地图服务地址
 */
function addTDTImgLayer(map, url) {
  const TDTImgLayer = new ol.layer.Tile({
    title: "天地图影像图层",
    source: new ol.source.XYZ({
      url: url,
      attibutions: "天地图影像",
      crossOrigin: "anoymous",
      wrapX: false
    })
  })
  TDTImgLayer.set("name""tdtImg")
  map.addLayer(TDTImgLayer)
}

/**
 * 加载天地图矢量
 * @param map:地图对象
 * @param url:地图服务地址
 */
function addTDTVecLayer(map, url) {
  const TDTVecLayer = new ol.layer.Tile({
    title: "天地图矢量图层",
    source: new ol.source.XYZ({
      url: url,
      attibutions: "天地图矢量",
      crossOrigin: "anoymous",
      wrapX: false
    })
  })
  TDTVecLayer.set("name""tdtVec")
  map.addLayer(TDTVecLayer)
}

/**
 * 加载天地图注记
 * @param map:地图对象
 * @param url:地图服务地址
 */
function addTDTCvaLayer(map, url) {
  const TDTCvaLayer = new ol.layer.Tile({
    title: "天地图注记图层",
    source: new ol.source.XYZ({
      url: url,
      attibutions: "天地图注记",
      crossOrigin: "anoymous",
      wrapX: false
    })
  })
  TDTCvaLayer.set("name""tdtCva")
  map.addLayer(TDTCvaLayer)
}

/**
 * 加载ArcGIS影像
 * @param map:地图对象
 * @param url:地图服务地址
 */
function addArcGISImg(map, url) {
  let source = new ol.source.XYZ({
    url: url,
    wrapX: true,
    crossOrigin: 'anonymous'
  })
  let layer = new ol.layer.Tile({
    sourcesource
  })
  layer.set("name""arcgisImg")
    map.addLayer(layer);
}

/**
 * 加载ArcGIS世界地图
 * @param map:地图对象
 * @param url:地图服务地址
 */
function addArcGISWorld(map, url) {
    let source = new ol.source.XYZ({
        url: url,
        wrapX: true,
        crossOrigin: 'anonymous'
    })
    let layer = new ol.layer.Tile({
        sourcesource
    })
    layer.set("name""arcgisWorld")
    map.addLayer(layer);
}

/**
 * 移除目标图层
 * @param layerName:图层名称
 */
function removeLayerByName(layerName) {
    const layers = map.getLayers().getArray()
    layers.forEach(layer => {
        if (layer.get('name') === layerName) map.removeLayer(layer)
    });
}

3. 图层资源控制

监听oncheck事件,通过checked属性判断是否添加或移除图层。

layui.use(function () {
    var tree = layui.tree;
    var layer = layui.layer;
    var util = layui.util;
    // 渲染
    tree.render({
        elem: '#layer-tree',
        id: "layer-tree",
        data: layerJSON,
        showCheckbox: true,
        oncheck: obj => {
            console.log(obj)
            // obj.checked // 是否被选中
            // obj.data // 数据项
            const layerObj = obj.data
            if (obj.checked) {
                switch (layerObj.value) {
                    case "bd":
                        addBdLayer(map)
                        break
                    case "gd":
                        addGdLayer(map, layerObj.url)
                        break
                    case "vec_w":
                        addTDTVecLayer(map, layerObj.url)
                        break
                    case "img_w":
                        addTDTImgLayer(map, layerObj.url)
                        break
                    case "cva_w":
                        addTDTCvaLayer(map, layerObj.url)
                        break
                    case "arcgisWorld":
                        addArcGISWorld(map, layerObj.url)
                        break
                    case "arcgisImg":
                        addArcGISImg(map, layerObj.url)
                        break

                }
            } else {
                const layerObj = obj.data
                removeLayerByName(layerObj.layerName)
            }
        }
    })
    tree.reload("layer-tree", {
        data: layerJSON
    })
})

4. 参考资料

服务资源:https://www.jianshu.com/p/e9123e2cdc5alayui:https://layui.dev/docs/2/tree/

5. 完整代码

其中libs文件夹下的包需要更换为自己下载的本地包或者引用在线资源。

<!DOCTYPE html>
<html>

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>图层控制</title>
    <meta charset="utf-8" />
    <script src="../../libs/js/jquery-2.1.1.min.js"></script>
    <script src="../../libs/proj4.js"></script>
    <script src="../../js/ol9.2.4.js"></script>
    <link rel="stylesheet" href="../../css/ol9.2.4.css">
    <script src="../../libs/layui/layui.js"></script>
    <link rel="stylesheet" href="../../libs/layui/css/layui.css">
    <script src="./layerJSON.json"></script>
    <script src="./layer.js"></script>

    <style>
        * {
            padding: 0;
            margin: 0;
            font-size: 14px;
            font-family: '微软雅黑';
        }

        html,
        body {
            width: 100%;
            height: 100%;
        }

        #map {
            position: absolute;
            top: 0;
            bottom: 0;
            width: 100%;
        }

        #layer-container {
            position: absolute;
            top: 5%;
            left: 20px;
            width: 15%;
            bottom: 5%;
            background: #fff;
            color: #fff;
            border-radius: 2.5px;
            border: 1px solid #ddd;
        }

        .layer-head {
            background: #16baaa;
            padding: 10px;
        }
    </style>
</head>

<body>
    <div id="map" title="地图显示"></div>
    <div id="layer-container">
        <h2 class="layer-head">图层资源</h2>
        <ul id="layer-tree"></ul>
    </div>
</body>

</html>

<script>

    proj4.defs('EPSG:4008''+proj=longlat +ellps=clrk66 +no_defs')
    proj4.defs('BD-MC''+proj=merc +lon_0=0 +units=m +ellps=clrk66 +no_defs')
    ol.proj.proj4.register(proj4)

    //地图投影坐标系
    const projection = ol.proj.get('EPSG:3857');
    //==============================================================================//
    //============================天地图服务参数简单介绍==============================//
    //================================vec:矢量图层==================================//
    //================================img:影像图层==================================//
    //================================cva:注记图层==================================//
    //======================其中:_c表示经纬度投影,_w表示球面墨卡托投影================//
    //==============================================================================//
    const TDTImgLayer = new ol.layer.Tile({
        title: "天地图影像图层",
        source: new ol.source.XYZ({
            url: "http://t0.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=2a890fe711a79cafebca446a5447cfb2",
            attibutions: "天地图注记描述",
            crossOrigin: "anoymous",
            wrapX: false
        })
    })
    const TDTImgCvaLayer = new ol.layer.Tile({
        title: "天地图影像注记图层",
        source: new ol.source.XYZ({
            url: "http://t0.tianditu.com/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=2a890fe711a79cafebca446a5447cfb2",
            attibutions: "天地图注记描述",
            crossOrigin: "anoymous",
            wrapX: false
        })
    })
    const map = new ol.Map({
        target: "map",
        loadTilesWhileInteracting: true,
        view: new ol.View({
            // center: [104.0635986160487, 30.660919181071225],
            // center: [11444274, 12707441],
            // center: [11421771, 4288300],
            center: ol.proj.transform([116.403414, 39.904091], 'EPSG:4326''EPSG:3857'),
            zoom: 5,
            worldsWrap: false,
            minZoom: 1,
            maxZoom: 20,
            projection: 'EPSG:3857',
        }),
        layers: [TDTImgLayer, TDTImgCvaLayer],
        // 地图默认控件
        controls: ol.control.defaults.defaults({
            zoom: false,
            attribution: true,
            rotate: true
        })
    })
    map.on('click', evt => {
        console.log(evt.coordinate)
    })

    layui.use(function () {
        var tree = layui.tree;
        var layer = layui.layer;
        var util = layui.util;
        // 渲染
        tree.render({
            elem: '#layer-tree',
            id: "layer-tree",
            data: layerJSON,
            showCheckbox: true,
            oncheck: obj => {
                console.log(obj)
                // obj.checked // 是否被选中
                // obj.data // 数据项
                const layerObj = obj.data
                if (obj.checked) {
                    switch (layerObj.value) {
                        case "bd":
                            addBdLayer(map)
                            break
                        case "gd":
                            addGdLayer(map, layerObj.url)
                            break
                        case "vec_w":
                            addTDTVecLayer(map, layerObj.url)
                            break
                        case "img_w":
                            addTDTImgLayer(map, layerObj.url)
                            break
                        case "cva_w":
                            addTDTCvaLayer(map, layerObj.url)
                            break
                        case "arcgisWorld":
                            addArcGISWorld(map, layerObj.url)
                            break
                        case "arcgisImg":
                            addArcGISImg(map, layerObj.url)
                            break

                    }
                } else {
                    const layerObj = obj.data
                    removeLayerByName(layerObj.layerName)
                }
            }
        })
        tree.reload("layer-tree", {
            data: layerJSON
        })
    })
</script>

OpenLayers示例数据下载,请在公众号后台回复:ol数据

全国信息化工程师-GIS 应用水平考试资料,请在公众号后台回复:GIS考试

GIS之路公众号已经接入了智能助手,欢迎大家前来提问。

欢迎访问我的博客网站-长谈GIShttp://shanhaitalk.com

都看到这了,不要忘记点赞、收藏+关注 

本号不定时更新有关 GIS开发  相关内容,欢迎关注 

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部