Tobby 发表于 2012-12-29 11:06:54

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

<div id="cnblogs_post_body">前段时间一群友有这样一个需求:在ol中画面,但面的填充物为图片,在使用sld样式时ol无法识别图片,经几番搜索原来官方版本暂不支持,可按如下方法解决
需要修改如下三个源码文件:
openlayers/lib/OpenLayers/Renderer/SVG.js
openlayers/lib/OpenLayers/Renderer/VML.jsopenlayers/lib/OpenLayers/Format/SLD/v1.js详情如下:‘+’后面是新增代码‘-’后面是删除代码<div class="cnblogs_code">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})", );+                  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(",")): 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) {
页: [1]
查看完整版本: 【openlayers】修改源码支持SLD的graphicfill属性