zoukankan      html  css  js  c++  java
  • openlayers2地图控件扩展:图例控件LegendControl

    因项目需要在地图中增加图例,以便专题地图查看或输出。

    实现思路,折线和多边形图例直接由样式属性创建,多边形直接设置div的样式;折线通过创建svg,设置polyline的样式;点要素的图例比较复杂,目前实现方式是:

    1、根据StyleMap里的Filter,找到不同Filter的要素id,这里的查找要过滤掉没有被渲染的要素;

    2、根据要素id从图层的渲染层找到对应的html元素,也就是svg标签;

    3、处理找到的svg标签即可,主要是移位;

    代码如下:

      1 OpenLayers.Control.LegendControl = OpenLayers.Class(OpenLayers.Control, {
      2     legendDiv: null,
      3     layers: [],
      4     colorDiv_w: 30,
      5     colorDiv_h: 20,
      6     /*
      7      * layers --Array
      8      * */
      9     initialize: function (layers, options) {
     10         OpenLayers.Control.prototype.initialize.apply(this, options);
     11 
     12         this.setLayers(layers);    
     13     },
     14     setMap: function(map) {
     15         var me = this;
     16         OpenLayers.Control.prototype.setMap.apply(this, arguments);
     17         if(me.map){
     18             me.map.events.register("moveend", me, me.redraw);
     19             me.map.events.register("changelayer", me, function(evt){
     20                 if(evt.property == "visibility")
     21                     this.redraw();
     22             });
     23         }
     24     },
     25     //{Array or Object}
     26     setLayers: function(layers){
     27         var me = this;
     28         if(OpenLayers.Util.isArray(layers)){
     29             me.layers = layers;
     30         }
     31     },
     32     addLayer: function(layer){
     33         this.layers.push(layer);
     34 
     35         this.redraw();
     36     },
     37     redraw: function(){
     38         if(this.div.style.display == "none"){
     39             return;
     40         }
     41         if(this.legendDiv){
     42             this.div.removeChild(this.legendDiv);
     43             this.legendDiv = null;
     44         }
     45         this.draw();
     46     },
     47     display: function(display) {
     48         this.div.style.display = (display) ? "" : "none"; 
     49     },
     50     draw: function() {
     51         OpenLayers.Control.prototype.draw.apply(this);
     52 
     53         // create layout divs
     54         this.loadContents();
     55 
     56         return this.div;
     57     },
     58     loadContents: function(){
     59         if(!this.legendDiv){
     60             this.legendDiv = document.createElement("div");
     61             this.legendDiv.id = this.id + "_legendDiv";
     62             OpenLayers.Element.addClass(this.legendDiv, "legendDiv"); 
     63             this.div.appendChild(this.legendDiv);
     64 
     65             // create span
     66             var labelSpan = document.createElement("label");
     67             labelSpan.innerHTML = "Legend";
     68             OpenLayers.Element.addClass(labelSpan, "title");
     69             this.legendDiv.appendChild(labelSpan); 
     70             var brSpan = document.createElement("br");
     71             this.legendDiv.appendChild(brSpan); 
     72 
     73             for(var i = 0; i < this.layers.length;i ++){
     74                 var layer = this.layers[i];
     75                 if(!layer.getVisibility()){
     76                     continue;
     77                 }
     78                 var geom = getLayerDefaultGeometry(layer);  //获取图层中的几何要素
     79                 if(!geom)
     80                     continue;
     81                 
     82                 //one table corresponds to a layer
     83                 var labelLyr = document.createElement("label");
     84                 labelLyr.innerHTML = layer.name;
     85                 this.legendDiv.appendChild(labelLyr);
     86                 var tableDiv = document.createElement("table");
     87                 this.legendDiv.appendChild(tableDiv);
     88                 
     89                 var featArray = layer.features;
     90                 var unrenderFeatures = layer.unrenderedFeatures;
     91                 var arr = Object.keys(unrenderFeatures);
     92                 if(arr.length == featArray.length)
     93                     continue;
     94                 
     95                 var styleRules = layer.styleMap.styles["default"].rules;
     96                 var geomType = "point";
     97                 //decide symbolizer panel from geometry type
     98                 if(geom instanceof OpenLayers.Geometry.Point ||
     99                         geom instanceof OpenLayers.Geometry.MultiPoint) {
    100                     var allFilters = [];
    101                     var bElseFilter = 2;
    102                     for(var key in styleRules) {
    103                         var filter = styleRules[key].filter;
    104                         if(filter){
    105                             allFilters.push(filter);
    106                         }
    107                         else{ //no filter
    108                             bElseFilter = styleRules[key].elseFilter;
    109                         }
    110                     }
    111                     //
    112                     if(!bElseFilter){    //no else filter --deafault
    113                         var trDiv = this.createPointLegend(geom.id, "default");
    114                         tableDiv.appendChild(trDiv);
    115                     }
    116                     else{    //find filter's geometry id
    117                         var filterIDs = [];
    118 
    119                         var findResults = {};
    120                         var findCount = 0;
    121                         for(var dex = 0; dex < featArray.length; dex ++){
    122                             if(findCount == allFilters.length + 1)
    123                                 break;
    124                             
    125                             var feat = featArray[dex];
    126                             if(arr.indexOf(feat.id) >= 0)
    127                                 continue;
    128 
    129                             var beInfilter = false;
    130                             for(var fk = 0; fk < allFilters.length; fk ++){
    131                                 var bFilter = allFilters[fk].evaluate(feat);
    132                                 if(bFilter){
    133                                     beInfilter = true;
    134                                     if(!findResults[allFilters[fk].toString()]){
    135                                         var svgId = feat.geometry.id;
    136                                         filterIDs.push({
    137                                             id:svgId,
    138                                             label: allFilters[fk].toString()
    139                                         });
    140                                         findResults[allFilters[fk].toString()] = true;
    141                                         findCount ++;                                        
    142                                     }
    143                                     break;
    144                                 }
    145 
    146                             }
    147                             if(!beInfilter && (!findResults["default"])){    //false
    148                                 var svgId = feat.geometry.id;
    149                                 filterIDs.push({
    150                                     id:svgId,
    151                                     label: "default"
    152                                 });
    153                                 findResults["default"] = true;
    154                                 findCount ++;
    155                             }
    156                         }
    157                         for(var fDex = 0; fDex < filterIDs.length; fDex ++){
    158                             var trDiv = this.createPointLegend(filterIDs[fDex].id, filterIDs[fDex].label);
    159                             tableDiv.appendChild(trDiv);                        
    160                         }
    161                     }
    162 
    163                     continue;    //skip next code
    164                 } else if(geom instanceof OpenLayers.Geometry.LineString ||
    165                         geom instanceof OpenLayers.Geometry.MultiLineString) {
    166                     geomType = "line";
    167 
    168                 } else if(geom instanceof OpenLayers.Geometry.LinearRing ||
    169                         geom instanceof OpenLayers.Geometry.Polygon ||
    170                         geom instanceof OpenLayers.Geometry.MultiPolygon) {
    171                     geomType = "polygon";
    172                 }
    173 
    174                 for(var key in styleRules) {
    175                     var filter = styleRules[key].filter;
    176                     var sybol = styleRules[key].symbolizer;
    177                     var labelTxt = "";
    178                     if(filter) {
    179                         labelTxt = filter.toString();
    180                     }
    181                     else{
    182                         labelTxt = "default";
    183                     }
    184 
    185                     var trDiv = document.createElement("tr");
    186                     tableDiv.appendChild(trDiv);
    187                     var colorTd = document.createElement("td");
    188                     trDiv.appendChild(colorTd);
    189 
    190                     var labelTd = document.createElement("td");
    191                     trDiv.appendChild(labelTd);
    192 
    193                     var itemLabel = document.createElement("label");
    194                     itemLabel.style = "margin-left:5px;position:relative;top:3px;";
    195                     itemLabel.innerHTML = labelTxt;
    196                     labelTd.appendChild(itemLabel);
    197 
    198                     if(geomType == "line"){
    199                         if(sybol.Line){
    200                             var colorDiv = this.createLineLegend(sybol.Line);
    201                             colorTd.appendChild(colorDiv);
    202                         }
    203                     }
    204                     else if(geomType == "polygon"){
    205                         if(sybol.Polygon){
    206                             var colorDiv = this.createPolygonLegend(sybol.Polygon);
    207                             colorTd.appendChild(colorDiv);                        
    208                         }
    209                     }
    210                 }
    211             }
    212 
    213         }
    214     },
    215     createPolygonLegend: function(polygonSybol){
    216         var colorDiv = document.createElement("div");
    217         if(polygonSybol.fill){
    218             var color = this.parseColor(polygonSybol.fillColor, polygonSybol.fillOpacity);
    219             colorDiv.style.background = color;
    220         }
    221         if(polygonSybol.stroke){
    222             var dashStyle = polygonSybol.strokeDashstyle;
    223             var color = this.parseColor(polygonSybol.strokeColor, polygonSybol.strokeOpacity);
    224             var width = polygonSybol.strokeWidth + "px";
    225             colorDiv.style.border = width + " " + dashStyle + " " + color;
    226         }
    227         colorDiv.style.height = this.colorDiv_h + "px";
    228         colorDiv.style.width = this.colorDiv_w + "px";
    230         return colorDiv;
    231     },
    232     /*
    233      * <svg><polyline points="20,27,34,21" fill="none" stroke="#550000" stroke-opacity="1" stroke-width="3"
    234      * stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="none"></polyline></svg>
    235      * */
    236     createLineLegend: function(lineSybol){
    237         var colorDiv = document.createElement("div");
    238         colorDiv.style.height = this.colorDiv_h + "px";
    239         colorDiv.style.width = this.colorDiv_w + "px";
    240 
    241         var lineHtml = '<svg width="100%" height="100%">';
    242         lineHtml += '<polyline points="2,2,28,18" fill="none" stroke="' + lineSybol.strokeColor 
    243         + '" stroke-opacity="'+ lineSybol.strokeOpacity +'" stroke-width="'+ lineSybol.strokeWidth + '"';
    244         lineHtml += ' stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="none"></polyline></svg>';
    245         colorDiv.innerHTML = lineHtml;
    246 
    247         return colorDiv;
    248     },
    249     createPointLegend: function(svgId, label){
    250         var trDiv = document.createElement("tr");
    251         var svgEle = document.getElementById(svgId);
    252         if(!svgEle){
    253             return trDiv;
    254         }
    255         var colorTd = document.createElement("td");
    256         trDiv.appendChild(colorTd);
    257 
    258         var labelTd = document.createElement("td");
    259         trDiv.appendChild(labelTd);
    260         var itemLabel = document.createElement("label");
    261         itemLabel.style = "margin-left:5px;position:relative;top:3px;";
    262         itemLabel.innerHTML = label;
    263         labelTd.appendChild(itemLabel);
    264 
    265         var colorDiv = document.createElement("div");
    266         colorTd.appendChild(colorDiv);
    267         var divHeight = this.colorDiv_h;
    268         var divWidth = this.colorDiv_w;
    269 
    270         var cln = svgEle.cloneNode(true);
    271         if(cln.nodeName.toLowerCase() != "svg"){    //circle,image
    272             var rVal = cln.getAttribute("r");
    273             if(cln.hasAttribute("x") && cln.hasAttribute("y")){
    274                 cln.setAttribute("x", rVal);
    275                 cln.setAttribute("y", rVal);                
    276             }
    277             if(cln.hasAttribute("cx") && cln.hasAttribute("cy")){
    278                 cln.setAttribute("cx", rVal);
    279                 cln.setAttribute("cy", rVal);
    280             }
    281             if(cln.hasAttribute("transform")){
    282                 var transform = cln.getAttribute("transform");
    283                 if(transform.indexOf('rotate(') >= 0){
    284                     var transValues = transform.split('rotate(');
    285                     var kk = null;
    286                     if(transValues.length == 1){
    287                         kk = 0;
    288                     }
    289                     else if(transValues.length > 1){
    290                         kk = 1;
    291                     }
    292                     if(kk != null){
    293                         var str = transValues[kk];
    294                         var sp = str.indexOf(')');
    295                         var rotString = str.substring(0, sp);
    296 
    297                         var ww = parseFloat(cln.getAttribute('width'));
    298                         var hh = parseFloat(cln.getAttribute('height'));
    299                         if(ww >= divWidth)
    300                             divWidth = ww + 2;
    301                         if(hh >= divWidth)
    302                             divHeight = hh + 2;
    303 
    304                         var rotValues = rotString.split(' ');
    305                         rotValues[1] = ww / 2;
    306                         rotValues[2] = hh / 2;
    307 
    308                         transValues[kk] = rotValues.join(' ') + str.substring(sp);
    309                         cln.setAttribute('transform',transValues.join('rotate('));                            
    310                     }
    311                 }
    312 
    313             }
    314             //innerHTML
    315             colorDiv.innerHTML = '<svg width="100%" height="100%"></svg>';
    316             var svgNode = colorDiv.firstChild;
    317             svgNode.appendChild(cln);
    318             colorDiv.appendChild(svgNode);
    319         }
    320         else{
    321             //change viewBox --from(0,0)
    322             var viewBox = cln.getAttribute('viewBox');    // Grab the object representing the SVG element's viewBox attribute.
    323             var viewBoxValues = viewBox.split(' ');                // Create an array and insert each individual view box attribute value (assume they're seperated by a single whitespace character).
    324 
    325             /* The array is filled with strings, convert the first two viewBox values to floats: */
    326             viewBoxValues[0] = parseFloat(viewBoxValues[0]);    // Represent the x-coordinate on the viewBox attribute.
    327             viewBoxValues[1] = parseFloat(viewBoxValues[1]);    // Represent the y coordinate on the viewBox attribute.
    328             viewBoxValues[2] = parseFloat(viewBoxValues[2]);    // Represent the y coordinate on the viewBox attribute.
    329 
    330             if(viewBoxValues[2] > 300){    //star
    331                 viewBoxValues[0] = 250;
    332                 viewBoxValues[1] = 75;
    333             }
    334             else{
    335                 viewBoxValues[0] = 0;
    336                 viewBoxValues[1] = 0;                
    337             }
    338 
    339             cln.setAttribute('viewBox', viewBoxValues.join(' '));
    340             colorDiv.appendChild(cln);                                    
    341         }
    342 
    343         colorDiv.style.height = divHeight + "px";
    344         colorDiv.style.width = divWidth + "px";
    345         return trDiv;        
    346     },
    347     parseColor: function(value, opacity){
    348         if(value.length == 7){
    349             var str = value.substr(1,6);
    350             var rgb1 = parseInt(str.substr(0, 2), 16);              
    351             var rgb2 = parseInt(str.substr(2, 2), 16);
    352             var rgb3 = parseInt(str.substr(4, 2), 16);
    353             return "rgba("+rgb1+","+rgb2+","+rgb3+","+opacity+")";
    354         }
    355         else{
    356             return value;
    357         }
    358     },
    359     CLASS_NAME: "OpenLayers.Control.LegendControl"
    360 });

    LegendControl的样式设置如下:

     1 /*
     2  * olControlLegendControl
     3 */
     4 .olControlLegendControl {
     5     position: absolute;
     6     left: 0px;
     7     bottom: 0px;
     8     width: 18em;
     9     font-family: sans-serif;
    10     font-size: smaller;
    11     margin-top: 3px;
    12     margin-left: 0px;
    13     margin-bottom: 0px;
    14     color: darkblue;
    15     background-color: transparent;    
    16 }
    17 .olControlLegendControl .legendDiv {
    18     padding-top: 5px;
    19     padding-left: 10px;
    20     padding-bottom: 5px;
    21     padding-right: 10px;
    22     background-color: rgba(200, 200, 200, 0.5);
    23 }
    24 .olControlLegendControl .legendDiv .title{
    25     margin-top: 3px;
    26     margin-left: 40px;
    27     margin-bottom: 3px;
    28     display: inline-block;
    29     height: 30px;
    30     font-family: sans-serif;
    31     font-weight: bold;
    32     font-size: 20px;
    33 }
    34 .olControlLegendControl .legendDiv .item{
    35     margin-top: 3px;
    36     margin-left: 3px;
    37     margin-bottom: 3px;
    38 }

     效果图

  • 相关阅读:
    struts2 + ajax(从后台获取json格式的数据返回到前端,然后前端用jquery对json数据进行解析)
    request 中文乱码问题
    Eclipse 支持jQuery 自动提示
    基于按annotation的hibernate主键生成策略
    微信创建菜单操作
    百度转换经纬度为地址
    微信工具类(常用接口)的整理
    微信URL有效性验证
    原型模式 (原型管理器)
    发送邮件 Email(java实现)
  • 原文地址:https://www.cnblogs.com/HandyLi/p/7698396.html
Copyright © 2011-2022 走看看