openlayers入门开发系列之图层控制

本篇的重点内容是利用openlayers实现地图图层控制功能,效果图如下:

部分核心代码如下:

  • 页面引用ztree插件
<!-- Ztree控件css以及js -->
<link href="${pageContext.request.contextPath}/js/plugins/ztree/zTreeStyle/img/zTreeStyle.css" rel="stylesheet" />
<script src="${pageContext.request.contextPath}/js/plugins/ztree/jquery.ztree.min.js"></script>
  • 图层管理器界面布局
DCI.Catalog = {
    Html: "<div></div>"
    + "<div style=' height:5px;'></div>"
    + "<div id='CatalogTree'style='height:98%;'><ul id='ztreeThemeServerOfCatalog' class='ztree'><ul></div>"
}
  • 图层配置
    "layers": [
        {"layer_id":"anjiHXMap","server":"geoserver","level":0,"name":"anjiHXMap","visible":true,"format":"image/png","tile_grid":"grid_GDImage","url":"/gwc/service/wms"},
        {"layer_id":"anjiGNMap","server":"geoserver","level":0,"name":"anjiGNMap","visible":true,"format":"image/png","tile_grid":"grid_GDImage","url":"/gwc/service/wms"},
    ],
    "maps":[
        {
            "map_id":"map_1",
            "description":"地图",
            "layer_groups":[
               {
                   "group_id":"tdtmap_img",
                                "layers":[
                                    {"id":"map_1","pid":"root","title":"安吉县","tip":"安吉县"},
                                    //{"id":"g-1","pid":"map_1","title":"影像图","tip":"影像图","visible":true,"inswitcher":false,"layers":["GISSERVER_AnJiMapImg"]},
                                    {"id":"g-1","pid":"map_1","title":"影像图","tip":"影像图","visible":true,"inswitcher":false,"layers":["tmap_img_w","tmap_cia_w"]},
                                    {"id":"g-10","pid":"map_1","title":"功能区划","tip":"功能区划","visible":true,"layers":["anjiGNMap"]},
                                    {"id":"g-11","pid":"map_1","title":"红线数据","tip":"红线数据","visible":true,"layers":["anjiHXMap"]}
                   ]
                },
                {
                   "group_id":"tdtmap_vec",
                                "layers":[
                                    {"id":"map_1","pid":"root","title":"安吉县","tip":"安吉县"},
                                    //{"id":"g-1","pid":"map_1","title":"街道图","tip":"街道图","visible":true,"inswitcher":false,"layers":["GISSERVER_AnJiMapVec"]},
                                    {"id":"g-1","pid":"map_1","title":"街道图","tip":"街道图","visible":true,"inswitcher":false,"layers":["tmap_vec_c","tmap_cva_w"]},
                                    {"id":"g-10","pid":"map_1","title":"功能区划","tip":"功能区划","visible":true,"layers":["anjiGNMap"]},
                                    {"id":"g-11","pid":"map_1","title":"红线数据","tip":"红线数据","visible":true,"layers":["anjiHXMap"]}
                                ]
                }
            ],
            "olview":"id_view_1"
        }
    ]

 

  • 图层管理器初始化js
//初始化图层管理器
intiLayerManagerWindow();
//初始化图层管理器
function intiLayerManagerWindow(){
    var layerSwitcherCtrl = new bxmap.control.LayerSwitcher({
        className:"ol-layer-switcher-nobutton",
        shownButton:false
    });
    layerSwitcherCtrl.showPanel();
    layerSwitcherCtrl.setMap(bmap.getMap());
    $("#ztreeThemeServerOfCatalog").append(layerSwitcherCtrl.panel);
}
  • LayerSwitcher类定义
/*----------图层控制器{bxmap.control.LayerSwitcher}---------*/
/**
 * @classdesc 图层控制器控件,依赖ztree.js
 * @constructor
 * @extends {bxmap.control.Control}
 * @param options
 * @param options.shownButton {Boolean} 是否显示button,默认为true,由button控制图层管理器
 * @param options.className {String|undefined} DOM element.className,默认为ol-layer-switcher
 */
bxmap.control.LayerSwitcher = function (options) {
	var opt_options = options || {};
	
    //创建图层控制器dom
    var element = this.panel = document.createElement("div");
    this.hiddenClassName = element.className = opt_options.className || "ol-layer-switcher";
    this.shownClassName = this.hiddenClassName + " shown";
    
    var shownButton = opt_options.shownButton == null ? true : opt_options.shownButton;
    if(shownButton){
    	var button = document.createElement("button");
        button.setAttribute("title", "图层控制");
        element.appendChild(button);
    }
    
    var treeElement = this._treeElement = document.createElement("ul");
    treeElement.id = "ol-layer-switcher-ztree";
    treeElement.className="ztree";
    element.appendChild(treeElement);
    
    if(shownButton){
	    var _this = this;
	    button.onclick = function(e) {
	        e = e || window.event;
	        _this.showPanel();
	        e.preventDefault();
	    };
	    
	    treeElement.onmouseout = function(e) {
	        e = e || window.event;
	        if (!treeElement.contains(e.toElement || e.relatedTarget)) {
	        	_this.hidePanel();
	        }
	    };
    }
    
	this.tree = null;//图层控制树
	this.setting = null;
	this._initTreeSetting();
	
	bxmap.control.Control.call(this, {
        element: element
    });
}
ol.inherits(bxmap.control.LayerSwitcher, bxmap.control.Control);

/**
 * @description 显示控件
 */
bxmap.control.LayerSwitcher.prototype.showPanel = function() {
	this.panel.className = this.shownClassName;
};

/**
 * @description 隐藏控件
 */
bxmap.control.LayerSwitcher.prototype.hidePanel = function() {
	this.panel.className = this.hiddenClassName;
};

/**
 * @description 获取显示状态
 * @returns {Boolean} true-可见;false-不可见
 */
bxmap.control.LayerSwitcher.prototype.getVisible = function() {
	var visible = this.panel.className == this.shownClassName? true:false;
	return visible;
};

/**
 * @inheritdoc
 * @description 设置控件关联的地图
 * @param {ol.CanvasMap} map 地图对象
 */
bxmap.control.LayerSwitcher.prototype.setMap = function (map) {
	if(this.getMap()){
		var bmap = this.getMap().get("wrap");
		 //切换地图时,自动切换图层控制
        var updateBaseLayer = bmap.getBaseLayerGroup();
        updateBaseLayer.un("change:layers", this._handleInitializeMap, this);
        updateBaseLayer.getLayers().un("change:length", this._handleInitializeMap, this);
	}
    bxmap.control.Control.prototype.setMap.call(this, map);
    if (map) {
        var bmap = map.get("wrap");
        this.initialize(bmap);
        //切换地图时,自动切换图层控制
        var updateBaseLayer = bmap.getBaseLayerGroup();
        updateBaseLayer.on("change:layers", this._handleInitializeMap, this);
        updateBaseLayer.getLayers().on("change:length", this._handleInitializeMap, this);
    }
};

/**
 * @private
 * @description 初始化地图
 * @param evt
 */
bxmap.control.LayerSwitcher.prototype._handleInitializeMap = function(evt){
	var map = this.getMap();
	var bmap = map.get("wrap");
	this.initialize(bmap);
}

/**
 * @description 初始化图层控制
 * @param bxmap {bxmap.Map}
 */
bxmap.control.LayerSwitcher.prototype.initialize = function(bmap){
	var container = bmap.getLayerContainer();
	var layers = container.getCurrentLayers();
	var nodes = this._getNodesFromLayers(layers);
	var setting = this.setting;
	
	var _this = this;
  	$(document).ready(function() {
  		var tmp = _this.tree;
  		_this.tree = $.fn.zTree.init($(_this._treeElement), setting, nodes);
  	});
}

/**
 * @private
 * @description 初始化树节点设置
 */
bxmap.control.LayerSwitcher.prototype._initTreeSetting = function () {
	//ztree的设置
    var setting = this.setting = {
        check: {
            chkboxType: { "Y": "ps", "N": "ps" },
            enable: true,
            autoCheckTrigger: false//true
        },
        data: {
            simpleData: {
                enable: true,
                idKey: "id",
                pIdKey: "pid",
                rootPId: bxmap.LAYER_SWITCHER_ROOT//"root"
            },
            key: {
                name: "title",
                title: "tip"
            }
        },
        view: {
            selectedMulti: false
        },
        callback: {}
    };

    var _this = this;
    //勾选事件
    setting.callback.onCheck = function (event, treeid, treenode) {
        var bmap = _this.getMap().get("wrap");
        var container = bmap.getLayerContainer();
        var sellayer = _this.getBindingLayer(treenode.id);
        if (sellayer) {
            sellayer.setVisible(treenode.checked);
        }
    }
}

/**
 * @private
 * @description 根据图层获取树节点
 * @param layers
 * @returns {Array}
 */
bxmap.control.LayerSwitcher.prototype._getNodesFromLayers = function(layers){
	var nodes = [];
	//如果pid为"root",nocheck选项
	var rootId = bxmap.LAYER_SWITCHER_ROOT;
	var category_map = bxmap.LAYER_SWITCHER_CATEGORY_MAP;//图层控制器根节点地图
	var category_group = bxmap.LAYER_SWITCHER_CATEGORY_GROUP;//图层控制器图层组节点
	var category_layer = bxmap.LAYER_SWITCHER_CATEGORY_LAYER;//图层控制器图层节点
	var _this = this;
	layers.forEach(function(elem,index,array){
        var switcherSetting = elem.switcherSetting;
        if(switcherSetting == null) return;
		var layerid = switcherSetting["id"];
        if(layerid == null) return;

        _this.getBindingLayer(layerid);
        //是否显示在图层控制器中
        var displayInSwitcher = switcherSetting["inswitcher"];
        if(!displayInSwitcher) return;

        //ztree node节点设置
        var node = {
       		"id":switcherSetting["id"],
        	"pid":switcherSetting["pid"],
        	"title":switcherSetting["title"],
        	"tip":switcherSetting["tip"],
        	"open":true,
        	"icon":bxmap.Resource.LayerSwitcherLayerPng
        };
        var checked = elem.getVisible();
        var category = switcherSetting["bxmap.LAYER_SWITCHER_CATEGORY"];
		switch(category){
			case category_map://地图节点
				node["nocheck"] = true;
				node["open"] = true;
				node["icon"] = bxmap.Resource.LayerSwitcherMapPng;
				break;
			case category_group://图层组节点
				node["icon"] = bxmap.Resource.LayerSwitcherGroupPng;
				node["checked"] = checked;
				break;
			default://图层节点
				node["icon"] = bxmap.Resource.LayerSwitcherLayerPng;
				node["checked"] = checked;
				break;
		}
		nodes.push(node);
  	});
	return nodes;
}

/**
 * @private
 * @description 根据图层id获取基础底图图层
 * @param {String} layerid 图层id
 * @returns {ol.layer.Layer}
 */
bxmap.control.LayerSwitcher.prototype.getBindingLayer = function (layerid) {
    var bmap = this.getMap().get("wrap");
    var container = bmap.getLayerContainer();

    //地图hash
    if (this[container.mapId] == null) {
        this[container.mapId] = {};
    }

    //图层组hash
    var mapHash = this[container.mapId];
    var groupId = container.getCurrentBaseLayerGroup().get(bxmap.CONFIG_GROUP_ID);
    if (mapHash[groupId] == null) {
        mapHash[groupId] = {};
    }

    //图层hash
    var groupHash = mapHash[groupId];
    if (groupHash[layerid] == null) {
        var layer = this.getCurrentLayerById(layerid);
        //控制图层是否显示在控制器中,如果根图层不显示在控制器中,则改图层不显示
        var rootLayer = this.getRootLayer(layer);
        if(rootLayer){
        	var displayInSwitcher = rootLayer.switcherSetting["inswitcher"];
            layer.switcherSetting["inswitcher"] = displayInSwitcher;
        }
        
        groupHash[layerid] = layer;
    }
    return groupHash[layerid];
}

/**
 * @description 获取图层所属的根图层,根图层是指root节点下的图层
 * @param layer {ol.layer.Layer} 图层
 * @returns {ol.layer.Layer}
 */
bxmap.control.LayerSwitcher.prototype.getRootLayer = function(layer){
	//pid == root则该图层为root节点
	var pid = layer.switcherSetting["pid"];
	if(!pid || pid == bxmap.LAYER_SWITCHER_ROOT){
		return null;
	}
	//若layer的pid -> pid == root,则该图层为根图层
    var pLayer = this.getCurrentLayerById(pid);
    pid = pLayer.switcherSetting["pid"];
    if(pid == bxmap.LAYER_SWITCHER_ROOT){
    	return layer;
    }
    return this.getRootLayer(pLayer);
}

/**
 * @description 从当前基础底图中获取指定图层id的图层
 * @param {String} layerid 图层id
 * @returns {ol.layer.Layer}
 */
bxmap.control.LayerSwitcher.prototype.getCurrentLayerById = function (layerid) {
    var output = null;
    var bmap = this.getMap().get("wrap");
    var container = bmap.getLayerContainer();
    var currentGroup = container.getCurrentBaseLayerGroup();
    var layersArray = currentGroup.getLayers().getArray();
    var layer;
    for (var i = 0, length = layersArray.length; i < length; i++) {
        layer = layersArray[i];
        if (layer.switcherSetting["id"] === layerid) {
            output = layer;
            break;
        }
    }
    return output;
}

 

作者: GIS之家

GIS之家微信号:gishome;GIS之家拥有自己的GIS开发团队,均是高校GIS研究生,具备丰富的webgis开发项目工作经验,专注以及热爱研究webgis技术的团队

发表评论

电子邮件地址不会被公开。