• 【openlayers】修改源码支持SLD的graphicfill属性


    前段时间一群友有这样一个需求:在ol中画面,但面的填充物为图片,在使用sld样式时ol无法识别图片,经几番搜索原来官方版本暂不支持,可按如下方法解决

    需要修改如下三个源码文件:

    openlayers/lib/OpenLayers/Renderer/SVG.js
    openlayers/lib/OpenLayers/Renderer/VML.js  
    openlayers/lib/OpenLayers/Format/SLD/v1.js
    详情如下:‘+’后面是新增代码  ‘-’后面是删除代码
    openlayers/lib/OpenLayers/Renderer/SVG.js    
      
       
       /**
        * @requires OpenLayers/Renderer/Elements.js
      + * @requires OpenLayers/Console.js
        */
       
      
           setStyle: function(node, style, options) {
      -        style = style  || node._style;
      +        style = style || node._style;
               options = options || node._options;
               var r = parseFloat(node.getAttributeNS(null, "r"));
               var widthFactor = 1;
               }
               
               if (options.isFilled) {
      -            node.setAttributeNS(null, "fill", style.fillColor);
      -            node.setAttributeNS(null, "fill-opacity", style.fillOpacity);
      +            if (style.externalGraphic) {
      +                var pid = this.createImagePattern(style);
      +                node.setAttributeNS(null, "fill", "url(#" + pid + ")");
      +                node.setAttributeNS(null, "fill-opacity", 1);
      +            } else if (style.graphicName && node._geometryClass !== "OpenLayers.Geometry.Point") {
      +                //this can also happen if a rule based style applies to both points and other types of geometries. TODO: better handling of rule based styles!
      +                OpenLayers.Console.error('WellKnownName is not yet supported as GraphicFill by the SVG renderer!');
      +                //var pid = this.createMarkPattern(style);
      +                //node.setAttributeNS(null, "fill", "url(#" + pid + ")");
      +                //node.setAttributeNS(null, "fill-opacity", 1);
      +            } else {
      +                node.setAttributeNS(null, "fill", style.fillColor);
      +                node.setAttributeNS(null, "fill-opacity", style.fillOpacity);
      +            }
               } else {
                   node.setAttributeNS(null, "fill", "none");
               }
               this.rendererRoot.appendChild(defs);
               return defs;
           },
      +    
      +    /**
      +     * Method: createImagePattern
      +     *
      +     * Returns:
      +     * {String} The id of the created pattern
      +     */
      +    createImagePattern: function(style) {
      +        // reuse the pattern if the same externalGraphic with the same size has already been used
      +        var id = this.container.id + "-" + style.externalGraphic + ((style.pointRadius) ? "-" + style.pointRadius : "");
      +        var patternNode = OpenLayers.Util.getElement(id);
       
      +        if (!patternNode) {
      +            // to follow SLD spec we need to know image size
      +            // to get the image size we must load the image
      +            var img = new Image();
      +
      +            img.onload = OpenLayers.Function.bind(function() {
      +                if (!this.defs) {
      +                    // create svg defs tag
      +                    this.defs = this.createDefs();
      +                }
      +                
      +                // according to SLD specification image should be scaled by its inherent dimensions if no Size is given
      +                var height = img.height * 72 / 96;
      +                var width = img.width * 72 / 96;
      +                
      +                // if Size is given, it is used as height and width is scaled to original aspect
      +                if (style.pointRadius) {
      +                    var aspect = width / height;
      +                    height = (style.pointRadius * 2) * 72 / 96;
      +                    width = height * aspect;
      +                }
      +                
      +                height = height + "pt";
      +                width = width + "pt";
      +                
      +                patternNode = this.nodeFactory(id, "pattern");
      +                patternNode.setAttributeNS(null, "x", "0");
      +                patternNode.setAttributeNS(null, "y", "0");
      +                patternNode.setAttributeNS(null, "height", height);
      +                patternNode.setAttributeNS(null, "width", width);
      +                patternNode.setAttributeNS(null, "patternUnits", "userSpaceOnUse");
      +                
      +                var imageNode = this.nodeFactory(null, "image");
      +                patternNode.appendChild(imageNode);
      +                imageNode.setAttributeNS(this.xlinkns, "href", style.externalGraphic);
      +                imageNode.setAttributeNS(null, "height", height);
      +                imageNode.setAttributeNS(null, "width", width);
      +                imageNode.setAttributeNS(null, "style", "opacity: " + (style.graphicOpacity || style.fillOpacity || 1));
      +                if (typeof style.rotation != "undefined") {
      +                    var rotation = OpenLayers.String.format("rotate(${0})", [style.rotation]);
      +                    imageNode.setAttributeNS(null, "transform", rotation);
      +                }
      +                this.defs.appendChild(patternNode);
      +            }, this);
      +
      +            img.src = style.externalGraphic;
    +        }
    +
    +        return id;
    +    },
    +
    
    openlayers/lib/OpenLayers/Renderer/VML.js /** * @requires OpenLayers/Renderer/Elements.js + * @requires OpenLayers/Console.js */ // fill if (options.isFilled) { - node.fillcolor = fillColor; + if (!style.externalGraphic) { + node.fillcolor = fillColor; + } else { + node.fillcolor = "none"; + } } else { node.filled = "false"; } } fill.opacity = style.fillOpacity; - if (node._geometryClass === "OpenLayers.Geometry.Point" && - style.externalGraphic) { - - // override fillOpacity - if (style.graphicOpacity) { - fill.opacity = style.graphicOpacity; - } - - fill.src = style.externalGraphic; - fill.type = "frame"; - - if (!(style.graphicWidth && style.graphicHeight)) { - fill.aspect = "atmost"; - } - } + if (style.externalGraphic) { + // reuse the fill node if the same externalGraphic with the same size has already been used + if (fill.src != style.externalGraphic || + ((fill.size) ? parseFloat(fill.size.value.split(",")[1]): 0) != (style.pointRadius * 2) * 72 / 96) { + // override fillOpacity + if (style.graphicOpacity) { + fill.opacity = style.graphicOpacity; + } + + fill.src = style.externalGraphic; + fill.type = (node._geometryClass === "OpenLayers.Geometry.Point") ? "frame" : "tile"; + + // to follow SLD spec we need to know image size + // to get the image size we must load the image + var img = new Image(); + + img.onload = OpenLayers.Function.bind(function() { + var height = img.height * 72 / 96; + var width = img.width * 72 / 96; + if (style.pointRadius) { + var aspect = width / height; + height = (style.pointRadius * 2) * 72 / 96; + width = height * aspect; + } + fill.size = width + "pt," + height + "pt"; + }); + + // load the image + img.src = style.externalGraphic; + + if (!(style.graphicWidth && style.graphicHeight)) { + fill.aspect = "atmost"; + } + } + } else if (style.graphicName && node._geometryClass !== "OpenLayers.Geometry.Point") { + //this can also happen if a rule based style applies to both points and other types of geometries. TODO: better handling of rule based styles! + OpenLayers.Console.error('WellKnownName is not yet supported as GraphicFill by the VML renderer!'); + } if (fill.parentNode != node) { node.appendChild(fill); } openlayers/lib/OpenLayers/Format/SLD/v1.js } } }, + "GraphicFill": function(node, symbolizer) { + symbolizer.pointRadius = null; + this.readChildNodes(node, symbolizer); + }, "Graphic": function(node, symbolizer) { symbolizer.graphic = true; var graphic = {}; "Fill": function(symbolizer) { var node = this.createElementNSPlus("sld:Fill"); - // GraphicFill here - - // add in CssParameters - if(symbolizer.fillColor) { - this.writeNode( - "CssParameter", - {symbolizer: symbolizer, key: "fillColor"}, - node - ); - } - if(symbolizer.fillOpacity != null) { - this.writeNode( - "CssParameter", - {symbolizer: symbolizer, key: "fillOpacity"}, - node - ); - } + // if externalGraphic write a GraphicFill node to the Fill node + if (symbolizer.externalGraphic) { + this.writeNode("GraphicFill", symbolizer, node); + } else { + // add in CssParameters + if(symbolizer.fillColor) { + this.writeNode( + "CssParameter", + {symbolizer: symbolizer, key: "fillColor"}, + node + ); + } + if(symbolizer.fillOpacity != null) { + this.writeNode( + "CssParameter", + {symbolizer: symbolizer, key: "fillOpacity"}, + node + ); + } + } return node; }, "PointSymbolizer": function(symbolizer) { this.writeNode("Graphic", symbolizer, node); return node; }, + "GraphicFill": function(symbolizer) { + var node = this.createElementNSPlus("sld:GraphicFill"); + this.writeNode("Graphic", symbolizer, node); + return node; + }, "Graphic": function(symbolizer) { var node = this.createElementNSPlus("sld:Graphic"); if(symbolizer.externalGraphic != undefined) {

     详细示例见:http://dev.openlayers.org/sandbox/ossipoff/openlayers/examples/graphicfill.html

  • 相关阅读:
    思蕊防静电地板
    一个老站长的22条军规
    百度天天快照知识宝典
    搜索引擎常用搜索技巧
    网站运营工作流程
    关于线程间通信
    VS2012 EF5 连接oracle11.2
    ArcSde for Oracle服务注册
    NHibernate composite-id联合主键配置
    NHibernate 的 ID 标识选择器
  • 原文地址:https://www.cnblogs.com/shitao/p/2636874.html
Copyright © 2020-2023  润新知