arcgis api for js 动态图层树生成与控制

  • Post author:
  • Post category:其他




功能简述


arcgis api for javascript 3.31

加载

动态图层

后动态获取

图层信息

以及

子图层信息

,动态生成HTML结构。


根据自己加载的图层动态生成图层树。



图层树生成整体思路

  1. 创建HTML结构
  2. 创建自己的图层方法
  3. 获取地图中图层
  4. 获取图层的子图层
  5. 动态生成HTML结构

  6. 获取图层部分整体代码
  7. 为生成的结构绑定事件

  8. 整体代码
  9. 何时执行代码



HTML结构

首先确定好动态生成的HTML结构模板,为接下来js动态生成提供参考。

<!--从map获取图层-->
<div class="outside-layer-group">
  <input type="checkbox">-图层1
  <!--从图层获取子图层-->
  <div class="inside-layer-group">
    <div class="layer">
      <input type="checkbox">-子图层1
    </div>
    <div class="layer">
      <input type="checkbox">-子图层2
    </div>
  </div>
</div>



创建自己的图层方法

考虑到有底图等因素,并不是所有图层都需要进行图层控制,我们需要通过创建自定义的图层添加方法以便对图层进行筛选。

通过原型链的方式自定义方法(只演示添加图层,删除图层思想类似)

// 添加自定义图层列表
  Map.prototype.myLayers = [];
// 添加自定义添加图层
  Map.prototype.myAddLayers = function (layerList) {
    this.addLayers(layerList); // arcgis api的添加图层方法
    this.myLayers.push(...layerList); // 将图层添加至自己的图层数组
  }



获取地图中图层

首先创建构建图层树的方法。

function buildTree() { }

动态获取HTML结构容器(要放置图层树控制器的容器)并清空容器(为更新图层树做准备),获取map中的图层,动态生成结构并逐个添加至容器中。



  • buildTree()

    方法中添加如下代码
// 清空容器
document.querySelector(".layer-tree").innerHTML = "";
// 获取map中的图层(通过之前自定义的图层数组)
const layers = map.myLayers;
// 遍历图层数组
layers.forEach((item) => {
  // 生成一个div容器(显示map中的图层)
  let newOutNode = document.createElement("div");
  newOutNode.className = "outside-layer-group";
  newOutNode.id = item.id;
  newOutNode.innerHTML = `<input id="${item.id}" type="checkbox" ${item.visible ? "checked" : ''}>-${item.id}<div id="${item.id}" class="inside-layer-group"></div>`;
  // 获取容器并将生成的div插入其中
  document.querySelector('.layer-tree').appendChild(newOutNode);
})



获取图层的子图层

通过动态图层的

layerInfos

属性获取其子图层信息。


layerInfos

属性使用前提:

图层已经加载完毕

,否则该属性为空数组。

通过

layer.loaded

判断是否加载完毕。



  • buildTree()

    方法中添加如下代码
// 判断图层是否加载完毕,item为上一步遍历中的item
if (item.loaded) {
  // 遍历子图层信息数组
  item.layerInfos.forEach((layer) => {
    // 动态生成div容器(显示图层中的子图层)
    let newInnerNode = document.createElement('div');
    newInnerNode.id = layer.id;
    newInnerNode.className = "layer";
    newInnerNode.innerHTML = `<input id=${layer.id} type="checkbox" ${layer.defaultVisibility ? "checked" : ''}>-${layer.name}`;
    // 在刚才创建的外层容器中插入该节点,符合自己的HTML结构
    newOutNode.querySelector('.inside-layer-group').appendChild(newInnerNode);
  })
}



获取图层部分整体代码

function buildTree() {
  document.querySelector(".layer-tree").innerHTML = "";
  const layers = map.myLayers;
  layers.forEach((item) => {
    let newOutNode = document.createElement("div");
    newOutNode.className = "outside-layer-group";
    newOutNode.id = item.id;
    newOutNode.innerHTML = `<input id="${item.id}" type="checkbox" ${item.visible ? "checked" : ''}>-${item.id}<div id="${item.id}" class="inside-layer-group"></div>`;
    if (item.loaded) {
      item.layerInfos.forEach((layer) => {
        let newInnerNode = document.createElement('div');
        newInnerNode.id = layer.id;
        newInnerNode.className = "layer";
        newInnerNode.innerHTML = `<input id=${layer.id} type="checkbox" ${layer.defaultVisibility ? "checked" : ''}>-${layer.name}`;
        newOutNode.querySelector('.inside-layer-group').appendChild(newInnerNode);
      })
    }
    document.querySelector('.layer-tree').appendChild(newOutNode);
  })
}



为生成的结构绑定事件

绑定事件分为两部分,除了dom的不同,也要注意方法的不同。

  • map中图层的显示与隐藏
  • 图层子图层的显示与隐藏


map中图层的显示与隐藏

通过

hide()



show()

方法控制。



  • buildTree()

    方法中添加如下代码
// 获取外部图层节点
const outNode = document.querySelectorAll('.outside-layer-group>input');
// 为外部图层节点绑定点击事件
outNode.addEventListener('click',function(){
  // 遍历外部图层节点,检查多选框的checked状态,选中的显示,未选中的隐藏。
  outNode.forEach((item) => {
  	if(item.checked){
	  map.getLayer(item.id).show();
	} else {
	  map.getLayer(item.id).hide();
	}
  })
})


图层子图层的显示与隐藏

通过

setVisibleLayers()

方法控制。



  • buildTree()

    方法中添加如下代码
// 获取内部图层节点
const innerNode = document.querySelectorAll('.outside-layer-group>input');
// 为内部图层节点绑定点击事件
innerNode.addEventListener('click',function(){
  // 创建显示子图层数组,用于存放要显示的子图层的id信息
  let visibleLayers = [];
  // 获取父节点id,和父图层id相同
  let layerId = this.parentNode.parentNode.id;
  // 遍历内部图层节点,检查多选框checked状态,选中的加入显示子图层数组,未选中的子图层被隐藏
  innerNode.forEach((item) => {
    if (item.checked) {
      visibleLayers.push(item.id);
    }
  })
  // 根据id显示数组中的子图层,其他子图层被隐藏
  map.getLayer(layerId).setVisibleLayers(visibleLayers);
})



整体代码

function buildTree() {
  /*------------------- 获取图层构建图层树结构 -------------------*/
  document.querySelector(".layer-tree").innerHTML = "";
  const layers = map.myLayers;
  layers.forEach((item) => {
    let newOutNode = document.createElement("div");
    newOutNode.className = "outside-layer-group";
    newOutNode.id = item.id;
    newOutNode.innerHTML = `<input id="${item.id}" type="checkbox" ${item.visible ? "checked" : ''}>-${item.id}<div id="${item.id}" class="inside-layer-group"></div>`;
    if (item.loaded) {
      item.layerInfos.forEach((layer) => {
        let newInnerNode = document.createElement('div');
        newInnerNode.id = layer.id;
        newInnerNode.className = "layer";
        newInnerNode.innerHTML = `<input id=${layer.id} type="checkbox" ${layer.defaultVisibility ? "checked" : ''}>-${layer.name}`;
        newOutNode.querySelector('.inside-layer-group').appendChild(newInnerNode);
      })
    }
    document.querySelector('.layer-tree').appendChild(newOutNode);
  })
  
  /*------------------- 绑定DOM事件控制显示隐藏 -------------------*/
  const outNode = document.querySelectorAll('.outside-layer-group>input');
  outNode.addEventListener('click',function(){
    outNode.forEach((item) => {
  	  if(item.checked){
	    map.getLayer(item.id).show();
	  } else {
	    map.getLayer(item.id).hide();
	  }
    })
  })
  
  const innerNode = document.querySelectorAll('.outside-layer-group>input');
  innerNode.addEventListener('click',function(){
    let visibleLayers = [];
    let layerId = this.parentNode.parentNode.id;
    innerNode.forEach((item) => {
      if (item.checked) {
        visibleLayers.push(item.id);
      }
    })
    map.getLayer(layerId).setVisibleLayers(visibleLayers);
  })
}



何时执行代码

由于子图层的读取需要在图层加载完毕后进行,所以需要绑定事件来监控图层加载完毕。

// 为图层添加加载完毕监听事件,加载完毕后执行buildTree,构建图层树。
dojo.connect(layer, "onLoad", function () {
  buildTree();
});



结束

至此,动态图层树已基本完成,可以实现基本功能。可以根据自己所需的功能进行修改。



版权声明:本文为qq_39142804原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。