• 【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

  • 相关阅读:
    浏览器操作API
    自动化测试简介
    常用元素操作API
    Selenium环境搭建
    等待操作
    IOS OpenGL ES GPUImage 图像镜像 GPUImageTransformFilter
    IOS OpenGL ES GPUImage 图像源混合 GPUImageSourceOverBlendFilter
    IOS OpenGL ES GPUImage 图像加深混合 GPUImageDarkenBlendFilter
    IOS OpenGL ES GPUImage 图像透明混合 GPUImageAlphaBlendFilter
    IOS OpenGL ES GPUImage 图像平移 GPUImageTransformFilter
  • 原文地址:https://www.cnblogs.com/shitao/p/2636874.html
Copyright © 2020-2023  润新知