added new graphicName symbolizer property, which allows to render well-known graphic symbols named "square", "cross", "x" and "triangle", in addition to the existing "circle". Thanks Tim for the tweaks and the example. r=tschaub,elemoine (closes #1398)
git-svn-id: http://svn.openlayers.org/trunk/openlayers@7634 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
@@ -19,6 +19,12 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
* {String}
|
||||
*/
|
||||
xmlns: "http://www.w3.org/2000/svg",
|
||||
|
||||
/**
|
||||
* Property: xlinkns
|
||||
* {String}
|
||||
*/
|
||||
xlinkns: "http://www.w3.org/1999/xlink",
|
||||
|
||||
/**
|
||||
* Constant: MAX_PIXEL
|
||||
@@ -33,6 +39,12 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
* {Float}
|
||||
*/
|
||||
localResolution: null,
|
||||
|
||||
/**
|
||||
* Property: symbolSize
|
||||
* {Object} Cache for symbol sizes according to their svg coordinate space
|
||||
*/
|
||||
symbolSize: {},
|
||||
|
||||
/**
|
||||
* Constructor: OpenLayers.Renderer.SVG
|
||||
@@ -154,7 +166,13 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
var nodeType = null;
|
||||
switch (geometry.CLASS_NAME) {
|
||||
case "OpenLayers.Geometry.Point":
|
||||
nodeType = style.externalGraphic ? "image" : "circle";
|
||||
if (style.externalGraphic) {
|
||||
nodeType = "image";
|
||||
} else if (this.isComplexSymbol(style.graphicName)) {
|
||||
nodeType = "use";
|
||||
} else {
|
||||
nodeType = "circle";
|
||||
}
|
||||
break;
|
||||
case "OpenLayers.Geometry.Rectangle":
|
||||
nodeType = "rect";
|
||||
@@ -194,10 +212,11 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
style = style || node._style;
|
||||
options = options || node._options;
|
||||
var r = parseFloat(node.getAttributeNS(null, "r"));
|
||||
var widthFactor = 1;
|
||||
var pos;
|
||||
if (node._geometryClass == "OpenLayers.Geometry.Point" && r) {
|
||||
if (style.externalGraphic) {
|
||||
var x = parseFloat(node.getAttributeNS(null, "cx"));
|
||||
var y = parseFloat(node.getAttributeNS(null, "cy"));
|
||||
pos = this.getPosition(node);
|
||||
|
||||
if (style.graphicWidth && style.graphicHeight) {
|
||||
node.setAttributeNS(null, "preserveAspectRatio", "none");
|
||||
@@ -213,19 +232,31 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
|
||||
var opacity = style.graphicOpacity || style.fillOpacity;
|
||||
|
||||
node.setAttributeNS(null, "x", (x + xOffset).toFixed());
|
||||
node.setAttributeNS(null, "y", (y + yOffset).toFixed());
|
||||
node.setAttributeNS(null, "x", (pos.x + xOffset).toFixed());
|
||||
node.setAttributeNS(null, "y", (pos.y + yOffset).toFixed());
|
||||
node.setAttributeNS(null, "width", width);
|
||||
node.setAttributeNS(null, "height", height);
|
||||
node.setAttributeNS("http://www.w3.org/1999/xlink", "href", style.externalGraphic);
|
||||
node.setAttributeNS(this.xlinkns, "href", style.externalGraphic);
|
||||
node.setAttributeNS(null, "style", "opacity: "+opacity);
|
||||
} else if (this.isComplexSymbol(style.graphicName)) {
|
||||
// the symbol viewBox is three times as large as the symbol
|
||||
var offset = style.pointRadius * 3;
|
||||
var size = offset * 2;
|
||||
var id = this.importSymbol(style.graphicName);
|
||||
pos = this.getPosition(node);
|
||||
widthFactor = this.symbolSize[id] / size;
|
||||
node.setAttributeNS(this.xlinkns, "href", "#" + id);
|
||||
node.setAttributeNS(null, "width", size);
|
||||
node.setAttributeNS(null, "height", size);
|
||||
node.setAttributeNS(null, "x", pos.x - offset);
|
||||
node.setAttributeNS(null, "y", pos.y - offset);
|
||||
} else {
|
||||
node.setAttributeNS(null, "r", style.pointRadius);
|
||||
}
|
||||
|
||||
if (style.rotation) {
|
||||
if (style.rotation && pos) {
|
||||
var rotation = OpenLayers.String.format(
|
||||
"rotate(${0} ${1} ${2})", [style.rotation, x, y]);
|
||||
"rotate(${0} ${1} ${2})", [style.rotation, pos.x, pos.y]);
|
||||
node.setAttributeNS(null, "transform", rotation);
|
||||
}
|
||||
}
|
||||
@@ -240,7 +271,7 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
if (options.isStroked) {
|
||||
node.setAttributeNS(null, "stroke", style.strokeColor);
|
||||
node.setAttributeNS(null, "stroke-opacity", style.strokeOpacity);
|
||||
node.setAttributeNS(null, "stroke-width", style.strokeWidth);
|
||||
node.setAttributeNS(null, "stroke-width", style.strokeWidth * widthFactor);
|
||||
node.setAttributeNS(null, "stroke-linecap", style.strokeLinecap);
|
||||
} else {
|
||||
node.setAttributeNS(null, "stroke", "none");
|
||||
@@ -308,6 +339,18 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
return this.nodeFactory(this.container.id + "_root", "g");
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: createDefs
|
||||
*
|
||||
* Returns:
|
||||
* {DOMElement} The element to which we'll add the symbol definitions
|
||||
*/
|
||||
createDefs: function() {
|
||||
var defs = this.nodeFactory("ol-renderer-defs", "defs");
|
||||
this.rendererRoot.appendChild(defs);
|
||||
return defs;
|
||||
},
|
||||
|
||||
/**************************************
|
||||
* *
|
||||
* GEOMETRY DRAWING FUNCTIONS *
|
||||
@@ -510,6 +553,88 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: getPosition
|
||||
* Finds the position of an svg node.
|
||||
*
|
||||
* Parameters:
|
||||
* node - {DOMElement}
|
||||
*
|
||||
* Returns:
|
||||
* {Object} hash with x and y properties, representing the coordinates
|
||||
* within the svg coordinate system
|
||||
*/
|
||||
getPosition: function(node) {
|
||||
return({
|
||||
x: parseFloat(node.getAttributeNS(null, "cx")),
|
||||
y: parseFloat(node.getAttributeNS(null, "cy"))
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: importSymbol
|
||||
* add a new symbol definition from the rendererer's symbol hash
|
||||
*
|
||||
* Parameters:
|
||||
* graphicName - {String} name of the symbol to import
|
||||
*
|
||||
* Returns:
|
||||
* {String} - id of the imported symbol
|
||||
*/
|
||||
importSymbol: function (graphicName) {
|
||||
if (!this.defs) {
|
||||
// create svg defs tag
|
||||
this.defs = this.createDefs();
|
||||
}
|
||||
var id = this.container.id + "-" + graphicName;
|
||||
|
||||
// check if symbol already exists in the defs
|
||||
if (document.getElementById(id) != null) {
|
||||
return id;
|
||||
}
|
||||
|
||||
var symbol = OpenLayers.Renderer.symbol[graphicName];
|
||||
if (!symbol) {
|
||||
throw new Error(graphicName + ' is not a valid symbol name');
|
||||
return;
|
||||
}
|
||||
|
||||
var symbolNode = this.nodeFactory(id, "symbol");
|
||||
var node = this.nodeFactory(null, "polygon");
|
||||
symbolNode.appendChild(node);
|
||||
var symbolExtent = new OpenLayers.Bounds(
|
||||
Number.MAX_VALUE, Number.MAX_VALUE, 0, 0);
|
||||
|
||||
var points = "";
|
||||
var x,y;
|
||||
for (var i=0; i<symbol.length; i=i+2) {
|
||||
x = symbol[i];
|
||||
y = symbol[i+1];
|
||||
symbolExtent.left = Math.min(symbolExtent.left, x);
|
||||
symbolExtent.bottom = Math.min(symbolExtent.bottom, y);
|
||||
symbolExtent.right = Math.max(symbolExtent.right, x);
|
||||
symbolExtent.top = Math.max(symbolExtent.top, y);
|
||||
points += " " + x + "," + y;
|
||||
}
|
||||
|
||||
node.setAttributeNS(null, "points", points);
|
||||
// Hard-coded linejoin for now, to make it look the same as in VML.
|
||||
// There is no strokeLinejoin property yet for symbolizers.
|
||||
node.setAttributeNS(null, "stroke-linejoin", "round");
|
||||
|
||||
var width = symbolExtent.getWidth();
|
||||
var height = symbolExtent.getHeight();
|
||||
// create a viewBox three times as large as the symbol itself,
|
||||
// to allow for strokeWidth being displayed correctly at the corners.
|
||||
var viewBox = [symbolExtent.left - width,
|
||||
symbolExtent.bottom - height, width * 3, height * 3];
|
||||
symbolNode.setAttributeNS(null, "viewBox", viewBox.join(" "));
|
||||
this.symbolSize[id] = Math.max(width, height) * 3;
|
||||
|
||||
this.defs.appendChild(symbolNode);
|
||||
return symbolNode.id;
|
||||
},
|
||||
|
||||
CLASS_NAME: "OpenLayers.Renderer.SVG"
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user