【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详情如下:&lsquo;+&rsquo;后面是新增代码&lsquo;-&rsquo;后面是删除代码<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]