New vector rendering for better performance and less renderer specific limitations. r=elemoine (closes #1675, closes #1656, closes #1631, closes #1431, closes #1709)
git-svn-id: http://svn.openlayers.org/trunk/openlayers@7930 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
@@ -450,26 +450,36 @@ OpenLayers.Renderer.Elements = OpenLayers.Class(OpenLayers.Renderer, {
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
* style - {Object}
|
||||
* featureId - {String}
|
||||
*
|
||||
* Returns:
|
||||
* {Boolean} true if the geometry has been drawn completely; null if
|
||||
* incomplete; false otherwise
|
||||
*/
|
||||
drawGeometry: function(geometry, style, featureId) {
|
||||
var className = geometry.CLASS_NAME;
|
||||
var rendered = true;
|
||||
if ((className == "OpenLayers.Geometry.Collection") ||
|
||||
(className == "OpenLayers.Geometry.MultiPoint") ||
|
||||
(className == "OpenLayers.Geometry.MultiLineString") ||
|
||||
(className == "OpenLayers.Geometry.MultiPolygon")) {
|
||||
for (var i = 0, len=geometry.components.length; i<len; i++) {
|
||||
this.drawGeometry(geometry.components[i], style, featureId);
|
||||
rendered = rendered && this.drawGeometry(
|
||||
geometry.components[i], style, featureId);
|
||||
}
|
||||
return;
|
||||
return rendered;
|
||||
};
|
||||
|
||||
rendered = false;
|
||||
if (style.display != "none") {
|
||||
if (style.backgroundGraphic) {
|
||||
this.redrawBackgroundNode(geometry.id, geometry, style, featureId);
|
||||
this.redrawBackgroundNode(geometry.id, geometry, style,
|
||||
featureId);
|
||||
}
|
||||
this.redrawNode(geometry.id, geometry, style, featureId);
|
||||
} else {
|
||||
var node = OpenLayers.Util.getElement(geometry.id);
|
||||
rendered = this.redrawNode(geometry.id, geometry, style,
|
||||
featureId);
|
||||
}
|
||||
if (rendered == false) {
|
||||
var node = document.getElementById(geometry.id);
|
||||
if (node) {
|
||||
if (node._style.backgroundGraphic) {
|
||||
node.parentNode.removeChild(document.getElementById(
|
||||
@@ -478,6 +488,7 @@ OpenLayers.Renderer.Elements = OpenLayers.Class(OpenLayers.Renderer, {
|
||||
node.parentNode.removeChild(node);
|
||||
}
|
||||
}
|
||||
return rendered;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -488,6 +499,10 @@ OpenLayers.Renderer.Elements = OpenLayers.Class(OpenLayers.Renderer, {
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
* style - {Object}
|
||||
* featureId - {String}
|
||||
*
|
||||
* Returns:
|
||||
* {Boolean} true if the complete geometry could be drawn, null if parts of
|
||||
* the geometry could not be drawn, false otherwise
|
||||
*/
|
||||
redrawNode: function(id, geometry, style, featureId) {
|
||||
// Get the node if it's already on the map.
|
||||
@@ -508,7 +523,13 @@ OpenLayers.Renderer.Elements = OpenLayers.Class(OpenLayers.Renderer, {
|
||||
newNode._geometry = geometry;
|
||||
newNode._geometryClass = geometry.CLASS_NAME;
|
||||
newNode._style = style;
|
||||
newNode = this.drawGeometryNode(newNode, geometry, style);
|
||||
|
||||
var drawResult = this.drawGeometryNode(newNode, geometry, style);
|
||||
if(drawResult === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
newNode = drawResult.node;
|
||||
|
||||
// Insert the node into the indexer so it can show us where to
|
||||
// place it. Note that this operation is O(log(n)). If there's a
|
||||
@@ -522,7 +543,9 @@ OpenLayers.Renderer.Elements = OpenLayers.Class(OpenLayers.Renderer, {
|
||||
this.root.appendChild(newNode);
|
||||
}
|
||||
|
||||
this.postDraw(newNode);
|
||||
this.postDraw(newNode);
|
||||
|
||||
return drawResult.complete;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -540,6 +563,10 @@ OpenLayers.Renderer.Elements = OpenLayers.Class(OpenLayers.Renderer, {
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
* style - {Object}
|
||||
* featureId - {String}
|
||||
*
|
||||
* Returns:
|
||||
* {Boolean} true if the complete geometry could be drawn, null if parts of
|
||||
* the geometry could not be drawn, false otherwise
|
||||
*/
|
||||
redrawBackgroundNode: function(id, geometry, style, featureId) {
|
||||
var backgroundStyle = OpenLayers.Util.extend({}, style);
|
||||
@@ -556,7 +583,7 @@ OpenLayers.Renderer.Elements = OpenLayers.Class(OpenLayers.Renderer, {
|
||||
backgroundStyle.backgroundYOffset = null;
|
||||
backgroundStyle.backgroundGraphicZIndex = null;
|
||||
|
||||
this.redrawNode(
|
||||
return this.redrawNode(
|
||||
id + this.BACKGROUND_ID_SUFFIX,
|
||||
geometry,
|
||||
backgroundStyle,
|
||||
@@ -574,6 +601,11 @@ OpenLayers.Renderer.Elements = OpenLayers.Class(OpenLayers.Renderer, {
|
||||
* node - {DOMElement}
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
* style - {Object}
|
||||
*
|
||||
* Returns:
|
||||
* {Object} a hash with properties "node" (the drawn node) and "complete"
|
||||
* (null if parts of the geometry could not be drawn, false if nothing
|
||||
* could be drawn)
|
||||
*/
|
||||
drawGeometryNode: function(node, geometry, style) {
|
||||
style = style || node._style;
|
||||
@@ -583,25 +615,26 @@ OpenLayers.Renderer.Elements = OpenLayers.Class(OpenLayers.Renderer, {
|
||||
'isFilled': true,
|
||||
'isStroked': !!style.strokeWidth
|
||||
};
|
||||
var drawn;
|
||||
switch (geometry.CLASS_NAME) {
|
||||
case "OpenLayers.Geometry.Point":
|
||||
this.drawPoint(node, geometry);
|
||||
drawn = this.drawPoint(node, geometry);
|
||||
break;
|
||||
case "OpenLayers.Geometry.LineString":
|
||||
options.isFilled = false;
|
||||
this.drawLineString(node, geometry);
|
||||
drawn = this.drawLineString(node, geometry);
|
||||
break;
|
||||
case "OpenLayers.Geometry.LinearRing":
|
||||
this.drawLinearRing(node, geometry);
|
||||
drawn = this.drawLinearRing(node, geometry);
|
||||
break;
|
||||
case "OpenLayers.Geometry.Polygon":
|
||||
this.drawPolygon(node, geometry);
|
||||
drawn = this.drawPolygon(node, geometry);
|
||||
break;
|
||||
case "OpenLayers.Geometry.Surface":
|
||||
this.drawSurface(node, geometry);
|
||||
drawn = this.drawSurface(node, geometry);
|
||||
break;
|
||||
case "OpenLayers.Geometry.Rectangle":
|
||||
this.drawRectangle(node, geometry);
|
||||
drawn = this.drawRectangle(node, geometry);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -612,7 +645,14 @@ OpenLayers.Renderer.Elements = OpenLayers.Class(OpenLayers.Renderer, {
|
||||
|
||||
//set style
|
||||
//TBD simplify this
|
||||
return this.setStyle(node, style, options, geometry);
|
||||
if (drawn != false) {
|
||||
return {
|
||||
node: this.setStyle(node, style, options, geometry),
|
||||
complete: drawn
|
||||
};
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -634,6 +674,9 @@ OpenLayers.Renderer.Elements = OpenLayers.Class(OpenLayers.Renderer, {
|
||||
* Parameters:
|
||||
* node - {DOMElement}
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
*
|
||||
* Returns:
|
||||
* {DOMElement} or false if the renderer could not draw the point
|
||||
*/
|
||||
drawPoint: function(node, geometry) {},
|
||||
|
||||
@@ -646,6 +689,10 @@ OpenLayers.Renderer.Elements = OpenLayers.Class(OpenLayers.Renderer, {
|
||||
* Parameters:
|
||||
* node - {DOMElement}
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
*
|
||||
* Returns:
|
||||
* {DOMElement} or null if the renderer could not draw all components of
|
||||
* the linestring, or false if nothing could be drawn
|
||||
*/
|
||||
drawLineString: function(node, geometry) {},
|
||||
|
||||
@@ -658,6 +705,10 @@ OpenLayers.Renderer.Elements = OpenLayers.Class(OpenLayers.Renderer, {
|
||||
* Parameters:
|
||||
* node - {DOMElement}
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
*
|
||||
* Returns:
|
||||
* {DOMElement} or null if the renderer could not draw all components
|
||||
* of the linear ring, or false if nothing could be drawn
|
||||
*/
|
||||
drawLinearRing: function(node, geometry) {},
|
||||
|
||||
@@ -670,6 +721,10 @@ OpenLayers.Renderer.Elements = OpenLayers.Class(OpenLayers.Renderer, {
|
||||
* Parameters:
|
||||
* node - {DOMElement}
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
*
|
||||
* Returns:
|
||||
* {DOMElement} or null if the renderer could not draw all components
|
||||
* of the polygon, or false if nothing could be drawn
|
||||
*/
|
||||
drawPolygon: function(node, geometry) {},
|
||||
|
||||
@@ -682,6 +737,9 @@ OpenLayers.Renderer.Elements = OpenLayers.Class(OpenLayers.Renderer, {
|
||||
* Parameters:
|
||||
* node - {DOMElement}
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
*
|
||||
* Returns:
|
||||
* {DOMElement} or false if the renderer could not draw the rectangle
|
||||
*/
|
||||
drawRectangle: function(node, geometry) {},
|
||||
|
||||
@@ -694,6 +752,9 @@ OpenLayers.Renderer.Elements = OpenLayers.Class(OpenLayers.Renderer, {
|
||||
* Parameters:
|
||||
* node - {DOMElement}
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
*
|
||||
* Returns:
|
||||
* {DOMElement} or false if the renderer could not draw the circle
|
||||
*/
|
||||
drawCircle: function(node, geometry) {},
|
||||
|
||||
@@ -706,6 +767,9 @@ OpenLayers.Renderer.Elements = OpenLayers.Class(OpenLayers.Renderer, {
|
||||
* Parameters:
|
||||
* node - {DOMElement}
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
*
|
||||
* Returns:
|
||||
* {DOMElement} or false if the renderer could not draw the surface
|
||||
*/
|
||||
drawSurface: function(node, geometry) {},
|
||||
|
||||
|
||||
@@ -31,14 +31,14 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
* {Integer} Firefox has a limitation where values larger or smaller than
|
||||
* about 15000 in an SVG document lock the browser up. This
|
||||
* works around it.
|
||||
*/
|
||||
*/
|
||||
MAX_PIXEL: 15000,
|
||||
|
||||
/**
|
||||
* Property: localResolution
|
||||
* {Float}
|
||||
/**
|
||||
* Property: translationParameters
|
||||
* {Object} Hash with "x" and "y" properties
|
||||
*/
|
||||
localResolution: null,
|
||||
translationParameters: null,
|
||||
|
||||
/**
|
||||
* Property: symbolSize
|
||||
@@ -58,6 +58,7 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
}
|
||||
OpenLayers.Renderer.Elements.prototype.initialize.apply(this,
|
||||
arguments);
|
||||
this.translationParameters = {x: 0, y: 0};
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -86,16 +87,20 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
* See #669 for more information
|
||||
*
|
||||
* Parameters:
|
||||
* x - {Integer}
|
||||
* y - {Integer}
|
||||
* x - {Integer}
|
||||
* y - {Integer}
|
||||
* xyOnly - {Boolean} whether or not to just check for x and y, which means
|
||||
* to not take the current translation parameters into account if true.
|
||||
*
|
||||
* Returns:
|
||||
* {Boolean} Whether or not the 'x' and 'y' coordinates are in the
|
||||
* valid range.
|
||||
*/
|
||||
inValidRange: function(x, y) {
|
||||
return (x >= -this.MAX_PIXEL && x <= this.MAX_PIXEL &&
|
||||
y >= -this.MAX_PIXEL && y <= this.MAX_PIXEL);
|
||||
inValidRange: function(x, y, xyOnly) {
|
||||
var left = x + (xyOnly ? 0 : this.translationParameters.x);
|
||||
var top = y + (xyOnly ? 0 : this.translationParameters.y);
|
||||
return (left >= -this.MAX_PIXEL && left <= this.MAX_PIXEL &&
|
||||
top >= -this.MAX_PIXEL && top <= this.MAX_PIXEL);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -103,39 +108,66 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
*
|
||||
* Parameters:
|
||||
* extent - {<OpenLayers.Bounds>}
|
||||
* resolutionChanged - {Boolean}
|
||||
*
|
||||
* Returns:
|
||||
* {Boolean} true to notify the layer that the new extent does not exceed
|
||||
* the coordinate range, and the features will not need to be redrawn.
|
||||
* False otherwise.
|
||||
*/
|
||||
setExtent: function(extent) {
|
||||
setExtent: function(extent, resolutionChanged) {
|
||||
OpenLayers.Renderer.Elements.prototype.setExtent.apply(this,
|
||||
arguments);
|
||||
|
||||
var resolution = this.getResolution();
|
||||
var left = -extent.left / resolution;
|
||||
var top = extent.top / resolution;
|
||||
|
||||
// If the resolution has changed, start over changing the corner, because
|
||||
// the features will redraw.
|
||||
if (!this.localResolution || resolution != this.localResolution) {
|
||||
this.left = -extent.left / resolution;
|
||||
this.top = extent.top / resolution;
|
||||
}
|
||||
|
||||
var left = 0;
|
||||
var top = 0;
|
||||
if (resolutionChanged) {
|
||||
this.left = left;
|
||||
this.top = top;
|
||||
// Set the viewbox
|
||||
var extentString = "0 0 " + this.size.w + " " + this.size.h;
|
||||
|
||||
// If the resolution has not changed, we already have features, and we need
|
||||
// to adjust the viewbox to fit them.
|
||||
if (this.localResolution && resolution == this.localResolution) {
|
||||
left = (this.left) - (-extent.left / resolution);
|
||||
top = (this.top) - (extent.top / resolution);
|
||||
}
|
||||
|
||||
// Store resolution for use later.
|
||||
this.localResolution = resolution;
|
||||
|
||||
// Set the viewbox -- the left/top will be pixels-dragged-since-res change,
|
||||
// the width/height will be pixels.
|
||||
var extentString = left + " " + top + " " +
|
||||
this.size.w + " " + this.size.h;
|
||||
//var extentString = extent.left / resolution + " " + -extent.top / resolution + " " +
|
||||
this.rendererRoot.setAttributeNS(null, "viewBox", extentString);
|
||||
this.rendererRoot.setAttributeNS(null, "viewBox", extentString);
|
||||
this.translate(0, 0);
|
||||
return true;
|
||||
} else {
|
||||
var inRange = this.translate(left - this.left, top - this.top);
|
||||
if (!inRange) {
|
||||
// recenter the coordinate system
|
||||
this.setExtent(extent, true);
|
||||
}
|
||||
return inRange;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: translate
|
||||
* Transforms the SVG coordinate system
|
||||
*
|
||||
* Parameters:
|
||||
* x - {Float}
|
||||
* y - {Float}
|
||||
*
|
||||
* Returns:
|
||||
* {Boolean} true if the translation parameters ar in the valid coordinates
|
||||
* range, false otherwise.
|
||||
*/
|
||||
translate: function(x, y) {
|
||||
if (!this.inValidRange(x, y, true)) {
|
||||
return false;
|
||||
} else {
|
||||
var transformString = "";
|
||||
if (x || y) {
|
||||
transformString = "translate(" + x + "," + y + ")";
|
||||
}
|
||||
this.root.setAttributeNS(null, "transform", transformString);
|
||||
this.translationParameters = {x: x, y: y};
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -413,9 +445,12 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
* Parameters:
|
||||
* node - {DOMElement}
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
*
|
||||
* Returns:
|
||||
* {DOMElement} or false if the renderer could not draw the point
|
||||
*/
|
||||
drawPoint: function(node, geometry) {
|
||||
this.drawCircle(node, geometry, 1);
|
||||
return this.drawCircle(node, geometry, 1);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -426,6 +461,9 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
* node - {DOMElement}
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
* radius - {Float}
|
||||
*
|
||||
* Returns:
|
||||
* {DOMElement} or false if the renderer could not draw the circle
|
||||
*/
|
||||
drawCircle: function(node, geometry, radius) {
|
||||
var resolution = this.getResolution();
|
||||
@@ -436,10 +474,9 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
node.setAttributeNS(null, "cx", x);
|
||||
node.setAttributeNS(null, "cy", y);
|
||||
node.setAttributeNS(null, "r", radius);
|
||||
return node;
|
||||
} else {
|
||||
node.setAttributeNS(null, "cx", "");
|
||||
node.setAttributeNS(null, "cy", "");
|
||||
node.setAttributeNS(null, "r", 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
},
|
||||
@@ -451,23 +488,41 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
* Parameters:
|
||||
* node - {DOMElement}
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
*
|
||||
* Returns:
|
||||
* {DOMElement} or null if the renderer could not draw all components of
|
||||
* the linestring, or false if nothing could be drawn
|
||||
*/
|
||||
drawLineString: function(node, geometry) {
|
||||
node.setAttributeNS(null, "points",
|
||||
this.getComponentsString(geometry.components));
|
||||
var componentsResult = this.getComponentsString(geometry.components);
|
||||
if (componentsResult.path) {
|
||||
node.setAttributeNS(null, "points", componentsResult.path);
|
||||
return (componentsResult.complete ? node : null);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/**v
|
||||
/**
|
||||
* Method: drawLinearRing
|
||||
* This method is only called by the renderer itself.
|
||||
*
|
||||
* Parameters:
|
||||
* node - {DOMElement}
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
*
|
||||
* Returns:
|
||||
* {DOMElement} or null if the renderer could not draw all components
|
||||
* of the linear ring, or false if nothing could be drawn
|
||||
*/
|
||||
drawLinearRing: function(node, geometry) {
|
||||
node.setAttributeNS(null, "points",
|
||||
this.getComponentsString(geometry.components));
|
||||
var componentsResult = this.getComponentsString(geometry.components);
|
||||
if (componentsResult.path) {
|
||||
node.setAttributeNS(null, "points", componentsResult.path);
|
||||
return (componentsResult.complete ? node : null);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -477,28 +532,35 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
* Parameters:
|
||||
* node - {DOMElement}
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
*
|
||||
* Returns:
|
||||
* {DOMElement} or null if the renderer could not draw all components
|
||||
* of the polygon, or false if nothing could be drawn
|
||||
*/
|
||||
drawPolygon: function(node, geometry) {
|
||||
var d = "";
|
||||
var draw = true;
|
||||
var complete = true;
|
||||
var linearRingResult, path;
|
||||
for (var j=0, len=geometry.components.length; j<len; j++) {
|
||||
var linearRing = geometry.components[j];
|
||||
d += " M";
|
||||
for (var i=0, ilen=linearRing.components.length; i<ilen; i++) {
|
||||
var component = this.getShortString(linearRing.components[i]);
|
||||
if (component) {
|
||||
d += " " + component;
|
||||
} else {
|
||||
draw = false;
|
||||
}
|
||||
linearRingResult = this.getComponentsString(
|
||||
geometry.components[j].components, " ");
|
||||
path = linearRingResult.path;
|
||||
if (path) {
|
||||
d += " " + path;
|
||||
complete = linearRingResult.complete && complete;
|
||||
} else {
|
||||
draw = false;
|
||||
}
|
||||
}
|
||||
d += " z";
|
||||
if (draw) {
|
||||
node.setAttributeNS(null, "d", d);
|
||||
node.setAttributeNS(null, "fill-rule", "evenodd");
|
||||
return complete ? node : null;
|
||||
} else {
|
||||
node.setAttributeNS(null, "d", "");
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -509,6 +571,9 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
* Parameters:
|
||||
* node - {DOMElement}
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
*
|
||||
* Returns:
|
||||
* {DOMElement} or false if the renderer could not draw the rectangle
|
||||
*/
|
||||
drawRectangle: function(node, geometry) {
|
||||
var resolution = this.getResolution();
|
||||
@@ -520,11 +585,9 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
node.setAttributeNS(null, "y", y);
|
||||
node.setAttributeNS(null, "width", geometry.width / resolution);
|
||||
node.setAttributeNS(null, "height", geometry.height / resolution);
|
||||
return node;
|
||||
} else {
|
||||
node.setAttributeNS(null, "x", "");
|
||||
node.setAttributeNS(null, "y", "");
|
||||
node.setAttributeNS(null, "width", 0);
|
||||
node.setAttributeNS(null, "height", 0);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -535,6 +598,9 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
* Parameters:
|
||||
* node - {DOMElement}
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
*
|
||||
* Returns:
|
||||
* {DOMElement} or false if the renderer could not draw the surface
|
||||
*/
|
||||
drawSurface: function(node, geometry) {
|
||||
|
||||
@@ -559,8 +625,9 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
d += " Z";
|
||||
if (draw) {
|
||||
node.setAttributeNS(null, "d", d);
|
||||
return node;
|
||||
} else {
|
||||
node.setAttributeNS(null, "d", "");
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -569,19 +636,93 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
*
|
||||
* Parameters:
|
||||
* components - {Array(<OpenLayers.Geometry.Point>)} Array of points
|
||||
* separator - {String} character between coordinate pairs. Defaults to ","
|
||||
*
|
||||
* Returns:
|
||||
* {Object} hash with properties "path" (the string created from the
|
||||
* components and "complete" (false if the renderer was unable to
|
||||
* draw all components)
|
||||
*/
|
||||
getComponentsString: function(components) {
|
||||
getComponentsString: function(components, separator) {
|
||||
var renderCmp = [];
|
||||
var complete = true;
|
||||
var len = components.length;
|
||||
var strings = [];
|
||||
for(var i=0, len=components.length; i<len; i++) {
|
||||
var component = this.getShortString(components[i]);
|
||||
if (component) {
|
||||
strings.push(component);
|
||||
var str, component, j;
|
||||
for(var i=0; i<len; i++) {
|
||||
component = components[i];
|
||||
renderCmp.push(component);
|
||||
str = this.getShortString(component);
|
||||
if (str) {
|
||||
strings.push(str);
|
||||
} else {
|
||||
// The current component is outside the valid range. Let's
|
||||
// see if the previous or next component is inside the range.
|
||||
// If so, add the coordinate of the intersection with the
|
||||
// valid range bounds.
|
||||
if (i > 0) {
|
||||
if (this.getShortString(components[i + 1])) {
|
||||
strings.push(this.clipLine(components[i],
|
||||
components[i-1]));
|
||||
}
|
||||
}
|
||||
if (i < len - 1) {
|
||||
if (this.getShortString(components[i + 1])) {
|
||||
strings.push(this.clipLine(components[i],
|
||||
components[i+1]));
|
||||
}
|
||||
}
|
||||
complete = false;
|
||||
}
|
||||
}
|
||||
return strings.join(",");
|
||||
|
||||
return {
|
||||
path: strings.join(separator || ","),
|
||||
complete: complete
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: clipLine
|
||||
* Given two points (one inside the valid range, and one outside),
|
||||
* clips the line betweeen the two points so that the new points are both
|
||||
* inside the valid range.
|
||||
*
|
||||
* Parameters:
|
||||
* badComponent - {<OpenLayers.Geometry.Point>)} original geometry of the
|
||||
* invalid point
|
||||
* goodComponent - {<OpenLayers.Geometry.Point>)} original geometry of the
|
||||
* valid point
|
||||
* Returns
|
||||
* {String} the SVG coordinate pair of the clipped point (like
|
||||
* getShortString), or an empty string if both passed componets are at
|
||||
* the same point.
|
||||
*/
|
||||
clipLine: function(badComponent, goodComponent) {
|
||||
if (goodComponent.equals(badComponent)) {
|
||||
return "";
|
||||
}
|
||||
var resolution = this.getResolution();
|
||||
var maxX = this.MAX_PIXEL - this.translationParameters.x;
|
||||
var maxY = this.MAX_PIXEL - this.translationParameters.y;
|
||||
var x1 = goodComponent.x / resolution + this.left;
|
||||
var y1 = this.top - goodComponent.y / resolution;
|
||||
var x2 = badComponent.x / resolution + this.left;
|
||||
var y2 = this.top - badComponent.y / resolution;
|
||||
var k;
|
||||
if (x2 < -maxX || x2 > maxX) {
|
||||
k = (y2 - y1) / (x2 - x1);
|
||||
x2 = x2 < 0 ? -maxX : maxX;
|
||||
y2 = y1 + (x2 - x1) * k;
|
||||
}
|
||||
if (y2 < -maxY || y2 > maxY) {
|
||||
k = (x2 - x1) / (y2 - y1);
|
||||
y2 = y2 < 0 ? -maxY : maxY;
|
||||
x2 = x1 + (y2 - y1) * k;
|
||||
}
|
||||
return x2 + "," + y2;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Method: getShortString
|
||||
*
|
||||
@@ -589,7 +730,7 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
* point - {<OpenLayers.Geometry.Point>}
|
||||
*
|
||||
* Returns:
|
||||
* {String}
|
||||
* {String} or false if point is outside the valid range
|
||||
*/
|
||||
getShortString: function(point) {
|
||||
var resolution = this.getResolution();
|
||||
|
||||
@@ -79,8 +79,13 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
*
|
||||
* Parameters:
|
||||
* extent - {<OpenLayers.Bounds>}
|
||||
* resolutionChanged - {Boolean}
|
||||
*
|
||||
* Returns:
|
||||
* {Boolean} true to notify the layer that the new extent does not exceed
|
||||
* the coordinate range, and the features will not need to be redrawn.
|
||||
*/
|
||||
setExtent: function(extent) {
|
||||
setExtent: function(extent, resolutionChanged) {
|
||||
OpenLayers.Renderer.Elements.prototype.setExtent.apply(this,
|
||||
arguments);
|
||||
var resolution = this.getResolution();
|
||||
@@ -95,6 +100,8 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
// flip the VML display Y axis upside down so it
|
||||
// matches the display Y axis of the map
|
||||
this.root.style.flip = "y";
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
|
||||
@@ -569,23 +576,6 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
return this.nodeFactory(this.container.id + "_root", "olv:group");
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: drawFeature
|
||||
* Overrides the superclass's drawFeature method to take care of features
|
||||
* that are outside the viewport.
|
||||
*
|
||||
* Parameters:
|
||||
* feature - {<OpenLayers.Feature.Vector>}
|
||||
* style - {<Object>}
|
||||
*/
|
||||
drawFeature: function(feature, style) {
|
||||
if (!feature.geometry.getBounds().intersectsBounds(this.extent)) {
|
||||
style = {display: "none"};
|
||||
}
|
||||
OpenLayers.Renderer.Elements.prototype.drawFeature.apply(this,
|
||||
[feature, style]);
|
||||
},
|
||||
|
||||
/**************************************
|
||||
* *
|
||||
* GEOMETRY DRAWING FUNCTIONS *
|
||||
@@ -599,9 +589,12 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
* Parameters:
|
||||
* node - {DOMElement}
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
*
|
||||
* Returns:
|
||||
* {DOMElement} or false if the point could not be drawn
|
||||
*/
|
||||
drawPoint: function(node, geometry) {
|
||||
this.drawCircle(node, geometry, 1);
|
||||
return this.drawCircle(node, geometry, 1);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -613,6 +606,9 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
* node - {DOMElement}
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
* radius - {float}
|
||||
*
|
||||
* Returns:
|
||||
* {DOMElement} or false if the circle could not ne drawn
|
||||
*/
|
||||
drawCircle: function(node, geometry, radius) {
|
||||
if(!isNaN(geometry.x)&& !isNaN(geometry.y)) {
|
||||
@@ -625,7 +621,9 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
|
||||
node.style.width = diameter + "px";
|
||||
node.style.height = diameter + "px";
|
||||
return node;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
|
||||
@@ -636,9 +634,12 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
* Parameters:
|
||||
* node - {DOMElement}
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
*
|
||||
* Returns:
|
||||
* {DOMElement}
|
||||
*/
|
||||
drawLineString: function(node, geometry) {
|
||||
this.drawLine(node, geometry, false);
|
||||
return this.drawLine(node, geometry, false);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -648,9 +649,12 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
* Parameters:
|
||||
* node - {DOMElement}
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
*
|
||||
* Returns:
|
||||
* {DOMElement}
|
||||
*/
|
||||
drawLinearRing: function(node, geometry) {
|
||||
this.drawLine(node, geometry, true);
|
||||
return this.drawLine(node, geometry, true);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -661,6 +665,9 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
* node - {DOMElement}
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
* closeLine - {Boolean} Close the line? (make it a ring?)
|
||||
*
|
||||
* Returns:
|
||||
* {DOMElement}
|
||||
*/
|
||||
drawLine: function(node, geometry, closeLine) {
|
||||
|
||||
@@ -679,6 +686,7 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
}
|
||||
var end = (closeLine) ? " x e" : " e";
|
||||
node.path = "m" + parts.join("") + end;
|
||||
return node;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -688,6 +696,9 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
* Parameters:
|
||||
* node - {DOMElement}
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
*
|
||||
* Returns:
|
||||
* {DOMElement}
|
||||
*/
|
||||
drawPolygon: function(node, geometry) {
|
||||
this.setNodeDimension(node, geometry);
|
||||
@@ -713,6 +724,7 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
}
|
||||
path.push("e");
|
||||
node.path = path.join("");
|
||||
return node;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -722,6 +734,9 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
* Parameters:
|
||||
* node - {DOMElement}
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
*
|
||||
* Returns:
|
||||
* {DOMElement}
|
||||
*/
|
||||
drawRectangle: function(node, geometry) {
|
||||
var resolution = this.getResolution();
|
||||
@@ -730,6 +745,8 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
node.style.top = geometry.y/resolution + "px";
|
||||
node.style.width = geometry.width/resolution + "px";
|
||||
node.style.height = geometry.height/resolution + "px";
|
||||
|
||||
return node;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -738,6 +755,9 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
* Parameters:
|
||||
* node - {DOMElement}
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
*
|
||||
* Returns:
|
||||
* {DOMElement}
|
||||
*/
|
||||
drawSurface: function(node, geometry) {
|
||||
|
||||
@@ -761,6 +781,7 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
path.push(" x e");
|
||||
|
||||
node.path = path.join("");
|
||||
return node;
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user