使用ArcGIS API for JavaScript实现类似ArcMap的图层控制面板Tab of Contents

来源:互联网 发布:淘宝取消订单有影响吗 编辑:程序博客网 时间:2024/05/17 02:50

最近由于项目需要封装了一个web端类似ArcMap中的Table of Contents的图层控制面板,暂时只是支持WMTS为 底图,动态服务和要素服务作为业务图层。

/*********封装接口************/define(["dojo/_base/declare",        "dojo/_base/lang",        "esri/map",        "esri/layers/WMTSLayer",        "esri/layers/ArcGISDynamicMapServiceLayer",        "esri/layers/FeatureLayer"], function(Declare, Lang, Map, WMTSLayer, ArcGISDynamicMapServiceLayer, FeatureLayer) {return Declare("AIMapToc", null, {map:null,ztree:null, layerIds:null,allChildrenIds:nullconstructor : function(_map){this.map = _map;// 控制服务及图层当前比例尺是否可见map.on("zoom-end", Lang.hitch(this, function(){// 更新图层树this.updateTree();}));},createTree:function(domId){if(this.ztree != null){// 重置ztree,因为跟踪map的addlayer事件,需要重新读取地图图层数据建立图层面板this.ztree  = null;$('#'+domId).empty();}var layerAutoNodes = [];// ztree节点集合this.layerIds = this.map.layerIds;// 动态图层var graphicsIds = this.map.graphicsLayerIds;// 几何图层this.layerIds = this.layerIds.concat(graphicsIds);var currentScale = this.map.getScale();// 当前比例尺var isServiceScale = true;// 服务在当前比例尺下是否可见var isLayerScale = true;// 图层在当前比例尺下是否可见var check = false;//  节点选中情况// 遍历所有的图层,构造ztreefor(var i = 0, len = this.layerIds.length;i < len;i++){var layer = this.map.getLayer(this.layerIds[i]);if(layer instanceof WMTSLayer){// 底图不加入图层面板continue;}else{if(layer instanceof ArcGISDynamicMapServiceLayer){//动态地图服务isServiceScale = (!layer.minScale || currentScale >= layer.maxScale && currentScale <= layer.minScale);// 不设置图层显示比例尺范围时minScale等于0var layerInfos = layer.layerInfos;isCheck = layer.visible;layerAutoNodes.push({"name":"地图服务"+i,"id":i, "pId":-1,"checked":isCheck,"chkDisabled":!isServiceScale});if(layerInfos && layerInfos.length > 0){// 遍历服务的所有子图层for(var j=0, len2 = layerInfos.length; j < len2; j++){isLayerScale = (!layerInfos[j].minScale || currentScale >= layerInfos[j].maxScale && currentScale <= layerInfos[j].minScale);isCheck = layerInfos[j].defaultVisibility;var pId = layerInfos[j].parentLayerId;if(pId == -1){// 一级子图层设置父id为当前服务序号layerAutoNodes.push({"name":layerInfos[j].name,"id": (layerInfos[j].id + (i+1) * 1000), "pId":i,"checked":isCheck,"chkDisabled":!isLayerScale});}else{// 大于一级子图层设置父id为(pId + (i+1) * 1000),主要是为了防止不同服务的子图层id重复,以后用的时候解密到自然idlayerAutoNodes.push({"name":layerInfos[j].name,"id": (layerInfos[j].id + (i+1) * 1000), "pId":(pId + (i+1) * 1000),"checked":isCheck,"chkDisabled":!isLayerScale});}}}}else if(layer instanceof FeatureLayer){// 要素地图服务isServiceScale = (!layer.minScale || currentScale >= layer.maxScale && currentScale <= layer.minScale);check = layer.visible;layerAutoNodes.push({"name":"要素服务"+i,"id":i, "pId":-1,"checked":isCheck,"chkDisabled":!isServiceScale});}else{// 其他图层类型忽略(有待扩展)continue;}}}// ztree 初始化设置var setting={check: {          enable: true,   chkStyle: "checkbox"        },         view: {                                             dblClickExpand: true       },                                   data: {                                             simpleData: {                                   enable: true,            idKey: "id",            pIdKey: "pId",            rootPId: -1           }                                   },         callback: {                 onCheck: Lang.hitch(this,this.layersOnCheck)              } };$('#'+domId).append("<div id='maptree' class='tree_info tree_right'><div id='layertree' class='ztree'></div></div>");this.ztree = $.fn.zTree.init($("#layertree"),setting, layerAutoNodes);this.ztree.expandAll(true);// 主动触发一次,去除子节点都禁用时父节点未禁用的情况this.updateTree();},// 节点点击操作函数layersOnCheck:function (event, treeId, treeNode){var id = treeNode.id;// 节点加密idvar pid = treeNode.pId;// 节点加密父idvar checked = treeNode.checked;// 节点选中情况var layer = null;// 地图服务图层var visibleLayers = [];// 可视化图层数组this.allChildrenIds = [];// 节点的所有子节点自然序号var layerId = null;// 图层idvar layerSeq = null;// 地图服务序号if(pid == -1){// 地图服务节点layerSeq = id;layerId = this.layerIds[layerSeq];layer = this.map.getLayer(layerId);// 设置图层可见情况layer.setVisibility(checked);}else if(!treeNode.isParent){// 叶子图层节点var node = treeNode;// 寻找这是第几个地图服务var pnodes = [];// 存储当前节点的所有父节点,不包括服务根节点while(node.getParentNode()){node = node.getParentNode();pnodes.push(node);}pnodes.pop();// 删除服务根节点,不计入考虑layerSeq = node.id;layerId = this.layerIds[layerSeq];layer = this.map.getLayer(layerId);visibleLayers = layer.visibleLayers;if(checked){// 从可视化图层数组中添加当前节点visibleLayers.push(treeNode.id - 1000 * (layerSeq +1));}else{// 从可视化图层数组中删除所有父节点for(var j in pnodes){var pnode = pnodes[j];for(var i in visibleLayers){if(visibleLayers[i] == (pnode.id - 1000 * (layerSeq +1))){visibleLayers.splice(i,1);break;}}}// 从可视化图层数组中删除当前节点for(var i in visibleLayers){if(visibleLayers[i] == (treeNode.id - 1000 * (layerSeq +1))){visibleLayers.splice(i,1);break;}}// 从可视化图层数组中清空if(visibleLayers.length == 0){visibleLayers.push(-1);}}// 设置可见子图层layer.setVisibleLayers(visibleLayers);}else{//  非根非叶子节点的情况var node = treeNode;// 寻找这是第几个地图服务var pnodes = [];// 存储当前节点的所有父节点,不包括服务根节点while(node.getParentNode()){node = node.getParentNode();pnodes.push(node);}pnodes.pop();// 删除服务根节点,不计入考虑layerSeq = node.id;// 寻找所有子节点的自然序号this.findAllChildren(treeNode, layerSeq);layerId = this.layerIds[layerSeq];layer = this.map.getLayer(layerId);visibleLayers = layer.visibleLayers;if(checked){visibleLayers = visibleLayers.concat(this.allChildrenIds);}else{// 从可视化图层数组中删除所有父节点for(var j in pnodes){var pnode = pnodes[j];for(var i in visibleLayers){if(visibleLayers[i] == (pnode.id - 1000 * (layerSeq +1))){visibleLayers.splice(i,1);break;}}}// 从可视化图层数组中删除当前节点for(var i in visibleLayers){if(visibleLayers[i] == (treeNode.id - 1000 * (layerSeq +1))){visibleLayers.splice(i,1);break;}}// 从可视化图层数组中删除子节点for(var j in this.allChildrenIds){for(var i in visibleLayers){if(this.allChildrenIds[j] == visibleLayers[i]){visibleLayers.splice(i,1);break;}}}// 从可视化图层数组中清空if(visibleLayers.length == 0){visibleLayers.push(-1);}}// 设置可见子图层layer.setVisibleLayers(visibleLayers);} }, // 更新图层树 updateTree:function(){ var currentScale = this.map.getScale();// 当前比例尺     var layerId = null;// 图层id     var layerSeq = null;// 地图服务序号     var layer = null;// 地图服务图层     var isServiceScale = true;// 服务在当前比例尺下是否可见     var isLayerScale = true;// 图层在当前比例尺下是否可见     // 获取ztree对象 var treeObj = $.fn.zTree.getZTreeObj("layertree");          //获取所有服务节点          var nodes = treeObj.getNodes();          // 广度遍历获取所有节点(利用队列的非递归方式)          var queue = [];// 队列          var arr = [];// 遍历结果          for(var i in nodes){         queue.push(nodes[i]);          }          var tnode = queue.shift();          arr.push(tnode);          while(tnode){         var tnodes = tnode.children;         for(var j in tnodes){         queue.push(tnodes[j]);         }         tnode = queue.shift();         if(tnode){         arr.push(tnode);         }          }          // 倒序处理数组(从树的底层向上遍历)          for(var i = arr.length - 1; i >= 0; i-- ){          var node = arr[i];         // 寻找这是第几个地图服务   var pnode = node.getParentNode();   while(node.getParentNode()){   node = node.getParentNode();   }   layerSeq = node.id;       layerId = this.layerIds[layerSeq];   layer = this.map.getLayer(layerId);   if(layer instanceof ArcGISDynamicMapServiceLayer){//动态服务   var layerInfos = layer.layerInfos;         if(!arr[i].isParent){ //叶子节点         var k = arr[i].id - 1000 * (layerSeq +1);         isLayerScale = (!layerInfos[k].minScale || currentScale >= layerInfos[k].maxScale && currentScale <= layerInfos[k].minScale);         treeObj.setChkDisabled(arr[i], !isLayerScale);         }else{// 非叶子节点         var cnodes = arr[i].children;         chkDisabled = true;         for(var j in cnodes){         chkDisabled = chkDisabled && cnodes[j].chkDisabled;         }         treeObj.setChkDisabled(arr[i], chkDisabled);         }   }else{// 要素服务   isServiceScale = (!layer.minScale || currentScale >= layer.maxScale && currentScale <= layer.minScale);               treeObj.setChkDisabled(arr[i], !isServiceScale);   }          } }, // 寻找所有子节点的自然序号 findAllChildren:function(treeNode, layerSeq){ // 递归寻找子节点 if(treeNode.children && treeNode.children.length > 0){ var nodes = treeNode.children; for(var i = 0, len = nodes.length; i < len; i++){ // 解密成自然序号 this.allChildrenIds.push(nodes[i].id - 1000 * (layerSeq +1)); // 加入集合 this.findAllChildren(nodes[i], layerSeq); } } }});});/*********使用方法************///  JSvar  toc = new AIMapToc(map);            map.on("layer-add-result", function(layers){            toc.createTree("toc");             }); // HTML<body class="tundra">    <div id="container">       <div id="mapDiv">                </div>       <div style="z-index:1040;width:230px;min-height:200px;position:absolute;top:10px;right:10px;background:#fff;border:1px solid #ccc;">         <div style="height:30px;line-height:29px;border-bottom:1px solid #ccc;text-align:center;font-size:13px;background:#f2f2f2;">图层控制</div>         <div id="toc" style="max-height:400px;overflow:auto;"></div>       </div>    </div>  </body>
0 0