openlayers2地图控件扩展:图例控件LegendControl
因项目需要在地图中增加图例,以便专题地图查看或输出。
实现思路,折线和多边形图例直接由样式属性创建,多边形直接设置div的样式;折线通过创建svg,设置polyline的样式;点要素的图例比较复杂,目前实现方式是:
1、根据StyleMap里的Filter,找到不同Filter的要素id,这里的查找要过滤掉没有被渲染的要素;
2、根据要素id从图层的渲染层找到对应的html元素,也就是svg标签;
3、处理找到的svg标签即可,主要是移位;
代码如下:
 OpenLayers.Control.LegendControl = OpenLayers.Class(OpenLayers.Control, {
     legendDiv: null,
     layers: [],
     colorDiv_w: 30,
     colorDiv_h: 20,
     /*
      * layers --Array
      * */
     initialize: function (layers, options) {
         OpenLayers.Control.prototype.initialize.apply(this, options);
         this.setLayers(layers);
     },
     setMap: function(map) {
         var me = this;
         OpenLayers.Control.prototype.setMap.apply(this, arguments);
         if(me.map){
             me.map.events.register("moveend", me, me.redraw);
             me.map.events.register("changelayer", me, function(evt){
                 if(evt.property == "visibility")
                     this.redraw();
             });
         }
     },
     //{Array or Object}
     setLayers: function(layers){
         var me = this;
         if(OpenLayers.Util.isArray(layers)){
             me.layers = layers;
         }
     },
     addLayer: function(layer){
         this.layers.push(layer);
         this.redraw();
     },
     redraw: function(){
         if(this.div.style.display == "none"){
             return;
         }
         if(this.legendDiv){
             this.div.removeChild(this.legendDiv);
             this.legendDiv = null;
         }
         this.draw();
     },
     display: function(display) {
         this.div.style.display = (display) ? "" : "none";
     },
     draw: function() {
         OpenLayers.Control.prototype.draw.apply(this);
         // create layout divs
         this.loadContents();
         return this.div;
     },
     loadContents: function(){
         if(!this.legendDiv){
             this.legendDiv = document.createElement("div");
             this.legendDiv.id = this.id + "_legendDiv";
             OpenLayers.Element.addClass(this.legendDiv, "legendDiv");
             this.div.appendChild(this.legendDiv);
             // create span
             var labelSpan = document.createElement("label");
             labelSpan.innerHTML = "Legend";
             OpenLayers.Element.addClass(labelSpan, "title");
             this.legendDiv.appendChild(labelSpan);
             var brSpan = document.createElement("br");
             this.legendDiv.appendChild(brSpan); 
             for(var i = 0; i < this.layers.length;i ++){
                 var layer = this.layers[i];
                 if(!layer.getVisibility()){
                     continue;
                 }
                 var geom = getLayerDefaultGeometry(layer);  //获取图层中的几何要素
                 if(!geom)
                     continue;
                 //one table corresponds to a layer
                 var labelLyr = document.createElement("label");
                 labelLyr.innerHTML = layer.name;
                 this.legendDiv.appendChild(labelLyr);
                 var tableDiv = document.createElement("table");
                 this.legendDiv.appendChild(tableDiv);
                 var featArray = layer.features;
                 var unrenderFeatures = layer.unrenderedFeatures;
                 var arr = Object.keys(unrenderFeatures);
                 if(arr.length == featArray.length)
                     continue;
                 var styleRules = layer.styleMap.styles["default"].rules;
                 var geomType = "point";
                 //decide symbolizer panel from geometry type
                 if(geom instanceof OpenLayers.Geometry.Point ||
                         geom instanceof OpenLayers.Geometry.MultiPoint) {
                     var allFilters = [];
                     var bElseFilter = 2;
                     for(var key in styleRules) {
                         var filter = styleRules[key].filter;
                         if(filter){
                             allFilters.push(filter);
                         }
                         else{ //no filter
                             bElseFilter = styleRules[key].elseFilter;
                         }
                     }
                     //
                     if(!bElseFilter){    //no else filter --deafault
                         var trDiv = this.createPointLegend(geom.id, "default");
                         tableDiv.appendChild(trDiv);
                     }
                     else{    //find filter's geometry id
                         var filterIDs = [];
                         var findResults = {};
                         var findCount = 0;
                         for(var dex = 0; dex < featArray.length; dex ++){
                             if(findCount == allFilters.length + 1)
                                 break;
                             var feat = featArray[dex];
                             if(arr.indexOf(feat.id) >= 0)
                                 continue;
                             var beInfilter = false;
                             for(var fk = 0; fk < allFilters.length; fk ++){
                                 var bFilter = allFilters[fk].evaluate(feat);
                                 if(bFilter){
                                     beInfilter = true;
                                     if(!findResults[allFilters[fk].toString()]){
                                         var svgId = feat.geometry.id;
                                         filterIDs.push({
                                             id:svgId,
                                             label: allFilters[fk].toString()
                                         });
                                         findResults[allFilters[fk].toString()] = true;
                                         findCount ++;
                                     }
                                     break;
                                 }
                             }
                             if(!beInfilter && (!findResults["default"])){    //false
                                 var svgId = feat.geometry.id;
                                 filterIDs.push({
                                     id:svgId,
                                     label: "default"
                                 });
                                 findResults["default"] = true;
                                 findCount ++;
                             }
                         }
                         for(var fDex = 0; fDex < filterIDs.length; fDex ++){
                             var trDiv = this.createPointLegend(filterIDs[fDex].id, filterIDs[fDex].label);
                             tableDiv.appendChild(trDiv);
                         }
                     }
                     continue;    //skip next code
                 } else if(geom instanceof OpenLayers.Geometry.LineString ||
                         geom instanceof OpenLayers.Geometry.MultiLineString) {
                     geomType = "line";
                 } else if(geom instanceof OpenLayers.Geometry.LinearRing ||
                         geom instanceof OpenLayers.Geometry.Polygon ||
                         geom instanceof OpenLayers.Geometry.MultiPolygon) {
                     geomType = "polygon";
                 }
                 for(var key in styleRules) {
                     var filter = styleRules[key].filter;
                     var sybol = styleRules[key].symbolizer;
                     var labelTxt = "";
                     if(filter) {
                         labelTxt = filter.toString();
                     }
                     else{
                         labelTxt = "default";
                     }
                     var trDiv = document.createElement("tr");
                     tableDiv.appendChild(trDiv);
                     var colorTd = document.createElement("td");
                     trDiv.appendChild(colorTd);
                     var labelTd = document.createElement("td");
                     trDiv.appendChild(labelTd);
                     var itemLabel = document.createElement("label");
                     itemLabel.style = "margin-left:5px;position:relative;top:3px;";
                     itemLabel.innerHTML = labelTxt;
                     labelTd.appendChild(itemLabel);
                     if(geomType == "line"){
                         if(sybol.Line){
                             var colorDiv = this.createLineLegend(sybol.Line);
                             colorTd.appendChild(colorDiv);
                         }
                     }
                     else if(geomType == "polygon"){
                         if(sybol.Polygon){
                             var colorDiv = this.createPolygonLegend(sybol.Polygon);
                             colorTd.appendChild(colorDiv);
                         }
                     }
                 }
             }
         }
     },
     createPolygonLegend: function(polygonSybol){
         var colorDiv = document.createElement("div");
         if(polygonSybol.fill){
             var color = this.parseColor(polygonSybol.fillColor, polygonSybol.fillOpacity);
             colorDiv.style.background = color;
         }
         if(polygonSybol.stroke){
             var dashStyle = polygonSybol.strokeDashstyle;
             var color = this.parseColor(polygonSybol.strokeColor, polygonSybol.strokeOpacity);
             var width = polygonSybol.strokeWidth + "px";
             colorDiv.style.border = width + " " + dashStyle + " " + color;
         }
         colorDiv.style.height = this.colorDiv_h + "px";
         colorDiv.style.width = this.colorDiv_w + "px";
         return colorDiv;
     },
     /*
      * <svg><polyline points="20,27,34,21" fill="none" stroke="#550000" stroke-opacity="1" stroke-width="3"
      * stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="none"></polyline></svg>
      * */
     createLineLegend: function(lineSybol){
         var colorDiv = document.createElement("div");
         colorDiv.style.height = this.colorDiv_h + "px";
         colorDiv.style.width = this.colorDiv_w + "px";
         var lineHtml = '<svg width="100%" height="100%">';
         lineHtml += '<polyline points="2,2,28,18" fill="none" stroke="' + lineSybol.strokeColor
         + '" stroke-opacity="'+ lineSybol.strokeOpacity +'" stroke-width="'+ lineSybol.strokeWidth + '"';
         lineHtml += ' stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="none"></polyline></svg>';
         colorDiv.innerHTML = lineHtml;
         return colorDiv;
     },
     createPointLegend: function(svgId, label){
         var trDiv = document.createElement("tr");
         var svgEle = document.getElementById(svgId);
         if(!svgEle){
             return trDiv;
         }
         var colorTd = document.createElement("td");
         trDiv.appendChild(colorTd);
         var labelTd = document.createElement("td");
         trDiv.appendChild(labelTd);
         var itemLabel = document.createElement("label");
         itemLabel.style = "margin-left:5px;position:relative;top:3px;";
         itemLabel.innerHTML = label;
         labelTd.appendChild(itemLabel);
         var colorDiv = document.createElement("div");
         colorTd.appendChild(colorDiv);
         var divHeight = this.colorDiv_h;
         var divWidth = this.colorDiv_w;
         var cln = svgEle.cloneNode(true);
         if(cln.nodeName.toLowerCase() != "svg"){    //circle,image
             var rVal = cln.getAttribute("r");
             if(cln.hasAttribute("x") && cln.hasAttribute("y")){
                 cln.setAttribute("x", rVal);
                 cln.setAttribute("y", rVal);
             }
             if(cln.hasAttribute("cx") && cln.hasAttribute("cy")){
                 cln.setAttribute("cx", rVal);
                 cln.setAttribute("cy", rVal);
             }
             if(cln.hasAttribute("transform")){
                 var transform = cln.getAttribute("transform");
                 if(transform.indexOf('rotate(') >= 0){
                     var transValues = transform.split('rotate(');
                     var kk = null;
                     if(transValues.length == 1){
                         kk = 0;
                     }
                     else if(transValues.length > 1){
                         kk = 1;
                     }
                     if(kk != null){
                         var str = transValues[kk];
                         var sp = str.indexOf(')');
                         var rotString = str.substring(0, sp);
                         var ww = parseFloat(cln.getAttribute('width'));
                         var hh = parseFloat(cln.getAttribute('height'));
                         if(ww >= divWidth)
                             divWidth = ww + 2;
                         if(hh >= divWidth)
                             divHeight = hh + 2;
                         var rotValues = rotString.split(' ');
                         rotValues[1] = ww / 2;
                         rotValues[2] = hh / 2;
                         transValues[kk] = rotValues.join(' ') + str.substring(sp);
                         cln.setAttribute('transform',transValues.join('rotate('));
                     }
                 }
             }
             //innerHTML
             colorDiv.innerHTML = '<svg width="100%" height="100%"></svg>';
             var svgNode = colorDiv.firstChild;
             svgNode.appendChild(cln);
             colorDiv.appendChild(svgNode);
         }
         else{
             //change viewBox --from(0,0)
             var viewBox = cln.getAttribute('viewBox');    // Grab the object representing the SVG element's viewBox attribute.
             var viewBoxValues = viewBox.split(' ');                // Create an array and insert each individual view box attribute value (assume they're seperated by a single whitespace character).
             /* The array is filled with strings, convert the first two viewBox values to floats: */
             viewBoxValues[0] = parseFloat(viewBoxValues[0]);    // Represent the x-coordinate on the viewBox attribute.
             viewBoxValues[1] = parseFloat(viewBoxValues[1]);    // Represent the y coordinate on the viewBox attribute.
             viewBoxValues[2] = parseFloat(viewBoxValues[2]);    // Represent the y coordinate on the viewBox attribute.
             if(viewBoxValues[2] > 300){    //star
                 viewBoxValues[0] = 250;
                 viewBoxValues[1] = 75;
             }
             else{
                 viewBoxValues[0] = 0;
                 viewBoxValues[1] = 0;
             }
             cln.setAttribute('viewBox', viewBoxValues.join(' '));
             colorDiv.appendChild(cln);
         }
         colorDiv.style.height = divHeight + "px";
         colorDiv.style.width = divWidth + "px";
         return trDiv;
     },
     parseColor: function(value, opacity){
         if(value.length == 7){
             var str = value.substr(1,6);
             var rgb1 = parseInt(str.substr(0, 2), 16);
             var rgb2 = parseInt(str.substr(2, 2), 16);
             var rgb3 = parseInt(str.substr(4, 2), 16);
             return "rgba("+rgb1+","+rgb2+","+rgb3+","+opacity+")";
         }
         else{
             return value;
         }
     },
     CLASS_NAME: "OpenLayers.Control.LegendControl"
 });
LegendControl的样式设置如下:
/*
* olControlLegendControl
*/
.olControlLegendControl {
position: absolute;
left: 0px;
bottom: 0px;
width: 18em;
font-family: sans-serif;
font-size: smaller;
margin-top: 3px;
margin-left: 0px;
margin-bottom: 0px;
color: darkblue;
background-color: transparent;
}
.olControlLegendControl .legendDiv {
padding-top: 5px;
padding-left: 10px;
padding-bottom: 5px;
padding-right: 10px;
background-color: rgba(200, 200, 200, 0.5);
}
.olControlLegendControl .legendDiv .title{
margin-top: 3px;
margin-left: 40px;
margin-bottom: 3px;
display: inline-block;
height: 30px;
font-family: sans-serif;
font-weight: bold;
font-size: 20px;
}
.olControlLegendControl .legendDiv .item{
margin-top: 3px;
margin-left: 3px;
margin-bottom: 3px;
}
效果图

openlayers2地图控件扩展:图例控件LegendControl的更多相关文章
- 【完全开源】百度地图Web service API C#.NET版,带地图显示控件、导航控件、POI查找控件
		目录 概述 功能 如何使用 参考帮助 概述 源代码主要包含三个项目,BMap.NET.BMap.NET.WindowsForm以及BMap.NET.WinformDemo. BMap.NET 对百度地 ... 
- 扩展GridView控件——为内容项添加拖放及分组功能
		引言 相信大家对GridView都不陌生,是非常有用的控件,用于平铺有序的显示多个内容项.打开任何WinRT应用或者是微软合作商的网站,都会在APP中发现GridView的使用.“Tiles”提供了一 ... 
- 验证控件插图扩展控件ValidatorCalloutExtender(用于扩展验证控件)和TextBoxWatermarkExtender
		<asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptMan ... 
- [转]Asp.Net MVC 扩展联想控件
		本文转自:http://www.cnblogs.com/bright-lin/archive/2013/02/06/MVC_SuggestBox.html 在web中,为改善用户体验,我们常会将一些文 ... 
- cocos2dx - 控件扩展之pageview循环显示
		接上一节内容:cocos2dx - shader实现任意动画的残影效果 本节主要讲一下扩展PageView控件功能 在实际游戏应用中,经常会碰到用原来的控件难以实现的功能.这时候就需要根据需求,通过选 ... 
- 【转】【完全开源】百度地图Web service API C#.NET版,带地图显示控件、导航控件、POI查找控件
		[转][完全开源]百度地图Web service API C#.NET版,带地图显示控件.导航控件.POI查找控件 目录 概述 功能 如何使用 参考帮助 概述 源代码主要包含三个项目,BMap.NET ... 
- 给easyui datebox时间框控件扩展一个清空的实例
		给easyui datebox扩展一个清空的实例 步骤一:拓展插件 /** * 给时间框控件扩展一个清除的按钮 */ $.fn.datebox.defaults.cleanText = '清空'; ( ... 
- 扩展GroupBox控件
		1.GroupBox的边框颜色可以自行设置: 2.GroupBox可以设置边框的为圆角: 3.设置GroupBox标题在控件中的位置. 4.设置GroupBox标题的字体和颜色. 具体实现步骤Pane ... 
- 一个动态扩展表格控件列和行的 jQuery 插件
		一个动态扩展表格控件列和行的 jQuery 插件 不过这并不影响使用鸭! 看这里:https://github.com/zhuwansu/table-ext.js 一个简单的示范 html <t ... 
- 玩转控件:扩展Dev中SimpleButton
		何为扩展,顾名思义,就是在原有控件属性.事件的基础上拓展自己需要或实用的属性.事件等等.或者可以理解为,现有的控件已经不能完全满足我(的需求)了.好的扩展会使控件更加完善,实用,好用.不好的扩展,说白 ... 
随机推荐
- iOS 将金钱变为逗号形式
			; NSNumberFormatter * formatter = [NSNumberFormatter new]; [formatter setNumberStyle:NSNumberFormatt ... 
- Golang Frameworks
			Web frameworks help developers build applications as easily and quickly as possible. Go is still rel ... 
- ubuntu jdk 1.7 安装
			1. 打开网址http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html,下载相应的JD ... 
- 常用的SQLalchemy 字段类型
			https://blog.csdn.net/weixin_41896508/article/details/80772238 常用的SQLAlchemy字段类型 类型名 python中类型 说明 In ... 
- python list中append()与extend()用法
			列表是以类的形式实现的.“创建”列表实际上是将一个类实例化.因此,列表有多种方法可以操作. 1. 列表可包含任何数据类型的元素,单个列表中的元素无须全为同一类型. 2. append() 方法向列表的 ... 
- lua53编译
			#下载lua包lua-5.3.5 #vs2017新建个空工程,删除lua.c,luac,c,设置配置类型 动态库.dll #编译完成 
- MongoDB-6: MongoDB索引
			一.简介 在MongoDB建立索引能提高查询效率,只需要扫描索引只存储的这个集合的一小部分,并只把这小部分加载到内存中,效率大大的提高,如果没有建立索引,在查询时,MongoDB必须执行全表扫描,在数 ... 
- django--admin模型层
			django amdin是django提供的一个后台管理页面,改管理页面提供完善的html和css,使得你在通过Model创建完数据库表之后,就可以对数据进行增删改查,而使用django admin ... 
- JSONObject和JSONArray 以及Mybatis传入Map类型参数
			import org.json.JSONArray;import org.json.JSONObject; 将字符串转化为JSONArray JSONArray jsonArray = new ... 
- 如何做好部门以及公司的文档管理、知识管理以及情报管理?——By Me
			之前针对部门的文档管理开发平台进行过一次需求调研分析,对于实现方案与我们的实际需求之前的满足情况系统梳理了一下,我觉得对于有类似需求的团队或者公司应该有可以借鉴的地方,发到这里供大家参考.如有不正之处 ... 
