功能简述
arcgis api for javascript 3.31
加载
动态图层
后动态获取
图层信息
以及
子图层信息
,动态生成HTML结构。
根据自己加载的图层动态生成图层树。
图层树生成整体思路
- 创建HTML结构
- 创建自己的图层方法
- 获取地图中图层
- 获取图层的子图层
- 动态生成HTML结构
-
获取图层部分整体代码
- 为生成的结构绑定事件
-
整体代码
- 何时执行代码
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();
});
结束
至此,动态图层树已基本完成,可以实现基本功能。可以根据自己所需的功能进行修改。