OpenLayers 图层控制

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

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

1. 创建图层资源目录

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

ini 复制代码
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()进行获取。

php 复制代码
/**
 * 添加百度地图
 * @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({
    source: source
  })
  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({
    source: source
  })
  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({
        source: source
    })
    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属性判断是否添加或移除图层。

go 复制代码
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. 参考资料

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

5. 完整代码

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

xml 复制代码
<!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开发 相关内容,欢迎关注 !

相关推荐
testleaf4 分钟前
前端面经整理【1】
前端·面试
好了来看下一题5 分钟前
使用 React+Vite+Electron 搭建桌面应用
前端·react.js·electron
啃火龙果的兔子6 分钟前
前端八股文-react篇
前端·react.js·前端框架
小前端大牛马12 分钟前
react中hook和高阶组件的选型
前端·javascript·vue.js
刺客-Andy12 分钟前
React第六十二节 Router中 createStaticRouter 的使用详解
前端·javascript·react.js
萌萌哒草头将军2 小时前
🚀🚀🚀VSCode 发布 1.101 版本,Copilot 更全能!
前端·vue.js·react.js
GIS之路2 小时前
OpenLayers 图层叠加控制
前端·信息可视化
90后的晨仔3 小时前
ArkTS 语言中的number和Number区别是什么?
前端·harmonyos
菜鸡爱上编程3 小时前
React16,17,18,19更新对比
前端·javascript·reactjs·react
陈龙龙的陈龙龙3 小时前
uniapp 金额处理组件
前端·javascript·uni-app