Firefox SVG does not support drawing points with values more than something
between 10,000 and 40,000. (It's hard to tell, since it crashes the browser when you try.) The resulting behavior is that the browser crashes. This wraps these values into Pixel regions, and doesn't draw features which fall outside of them. (This sucks, but the result is the browser not crashing.) This closes #669, and should be improved as described in #670 for 2.5. If for some reason you know that the browser you're on can support larger maxPixel values, you can adjust the maxPixel private variable on the renderer. I believe that Opera and WebKit nightlies will work fine with a larger maxPixel value. Changing this is encouraged *only* if you are developer working on the code, because it can totally crash browsers in a production environment. git-svn-id: http://svn.openlayers.org/trunk/openlayers@3071 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
@@ -13,7 +13,17 @@ OpenLayers.Renderer.SVG.prototype =
|
||||
|
||||
/** @type String */
|
||||
xmlns: "http://www.w3.org/2000/svg",
|
||||
|
||||
// Firefox has a limitation where values larger or smaller than about
|
||||
// this.localResolution in an SVG document lock the browser up. This works around it.
|
||||
/** @type Integer */
|
||||
maxPixel: this.localResolution,
|
||||
|
||||
|
||||
/** @type Float
|
||||
@private */
|
||||
localResolution: null,
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
@@ -54,8 +64,33 @@ OpenLayers.Renderer.SVG.prototype =
|
||||
|
||||
var resolution = this.getResolution();
|
||||
|
||||
var extentString = extent.left / resolution + " " + -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 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 + " " +
|
||||
extent.getWidth() / resolution + " " + extent.getHeight() / resolution;
|
||||
//var extentString = extent.left / resolution + " " + -extent.top / resolution + " " +
|
||||
this.rendererRoot.setAttributeNS(null, "viewBox", extentString);
|
||||
},
|
||||
|
||||
@@ -236,9 +271,22 @@ OpenLayers.Renderer.SVG.prototype =
|
||||
*/
|
||||
drawCircle: function(node, geometry, radius) {
|
||||
var resolution = this.getResolution();
|
||||
node.setAttributeNS(null, "cx", geometry.x / resolution);
|
||||
node.setAttributeNS(null, "cy", geometry.y / resolution);
|
||||
node.setAttributeNS(null, "r", radius);
|
||||
var x = (geometry.x / resolution + this.left);
|
||||
var y = (geometry.y / resolution - this.top);
|
||||
var draw = true;
|
||||
if (x < -this.maxPixel || x > this.maxPixel) { draw = false; }
|
||||
if (y < -this.maxPixel || y > this.maxPixel) { draw = false; }
|
||||
|
||||
if (draw) {
|
||||
node.setAttributeNS(null, "cx", x);
|
||||
node.setAttributeNS(null, "cy", y);
|
||||
node.setAttributeNS(null, "r", radius);
|
||||
} else {
|
||||
node.setAttributeNS(null, "cx", "");
|
||||
node.setAttributeNS(null, "cy", "");
|
||||
node.setAttributeNS(null, "r", 0);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -266,17 +314,26 @@ OpenLayers.Renderer.SVG.prototype =
|
||||
*/
|
||||
drawPolygon: function(node, geometry) {
|
||||
var d = "";
|
||||
var draw = true;
|
||||
for (var j = 0; j < geometry.components.length; j++) {
|
||||
var linearRing = geometry.components[j];
|
||||
d += " M";
|
||||
for (var i = 0; i < linearRing.components.length; i++) {
|
||||
d += " " + this.getShortString(linearRing.components[i]);
|
||||
var component = this.getShortString(linearRing.components[i])
|
||||
if (component) {
|
||||
d += " " + component;
|
||||
} else {
|
||||
draw = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
d += " z";
|
||||
|
||||
node.setAttributeNS(null, "d", d);
|
||||
node.setAttributeNS(null, "fill-rule", "evenodd");
|
||||
if (draw) {
|
||||
node.setAttributeNS(null, "d", d);
|
||||
node.setAttributeNS(null, "fill-rule", "evenodd");
|
||||
} else {
|
||||
node.setAttributeNS(null, "d", "");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -285,10 +342,24 @@ OpenLayers.Renderer.SVG.prototype =
|
||||
* @private
|
||||
*/
|
||||
drawRectangle: function(node, geometry) {
|
||||
node.setAttributeNS(null, "x", geometry.x / resolution);
|
||||
node.setAttributeNS(null, "y", geometry.y / resolution);
|
||||
node.setAttributeNS(null, "width", geometry.width);
|
||||
node.setAttributeNS(null, "height", geometry.height);
|
||||
// This needs to be reworked
|
||||
var x = (geometry.x / resolution + this.left);
|
||||
var y = (geometry.y / resolution - this.top);
|
||||
var draw = true;
|
||||
if (x < -this.maxPixel || x > this.maxPixel) { draw = false; }
|
||||
if (y < -this.maxPixel || y > this.maxPixel) { draw = false; }
|
||||
if (draw) {
|
||||
node.setAttributeNS(null, "x", x);
|
||||
node.setAttributeNS(null, "y", y);
|
||||
node.setAttributeNS(null, "width", geometry.width);
|
||||
node.setAttributeNS(null, "height", geometry.height);
|
||||
} else {
|
||||
node.setAttributeNS(null, "x", "");
|
||||
node.setAttributeNS(null, "y", "");
|
||||
node.setAttributeNS(null, "width", 0);
|
||||
node.setAttributeNS(null, "height", 0);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
|
||||
@@ -299,16 +370,27 @@ OpenLayers.Renderer.SVG.prototype =
|
||||
*/
|
||||
drawCurve: function(node, geometry) {
|
||||
var d = null;
|
||||
var draw = true;
|
||||
for (var i = 0; i < geometry.components.length; i++) {
|
||||
if ((i%3) == 0 && (i/3) == 0) {
|
||||
d = "M " + this.getShortString(geometry.components[i]);
|
||||
var component = this.getShortString(geometry.components[i]);
|
||||
if (!component) { draw = false; }
|
||||
d = "M " + component;
|
||||
} else if ((i%3) == 1) {
|
||||
d += " C " + this.getShortString(geometry.components[i]);
|
||||
var component = this.getShortString(geometry.components[i]);
|
||||
if (!component) { draw = false; }
|
||||
d += " C " + component;
|
||||
} else {
|
||||
d += " " + this.getShortString(geometry.components[i]);
|
||||
var component = this.getShortString(geometry.components[i]);
|
||||
if (!component) { draw = false; }
|
||||
d += " " + component;
|
||||
}
|
||||
}
|
||||
node.setAttributeNS(null, "d", d);
|
||||
if (draw) {
|
||||
node.setAttributeNS(null, "d", d);
|
||||
} else {
|
||||
node.setAttributeNS(null, "d", "");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -320,17 +402,28 @@ OpenLayers.Renderer.SVG.prototype =
|
||||
|
||||
// create the svg path string representation
|
||||
var d = null;
|
||||
var draw = true;
|
||||
for (var i = 0; i < geometry.components.length; i++) {
|
||||
if ((i%3) == 0 && (i/3) == 0) {
|
||||
d = "M " + this.getShortString(geometry.components[i]);
|
||||
var component = this.getShortString(geometry.components[i]);
|
||||
if (!component) { draw = false; }
|
||||
d = "M " + component;
|
||||
} else if ((i%3) == 1) {
|
||||
d += " C " + this.getShortString(geometry.components[i]);
|
||||
var component = this.getShortString(geometry.components[i]);
|
||||
if (!component) { draw = false; }
|
||||
d += " C " + component;
|
||||
} else {
|
||||
d += " " + this.getShortString(geometry.components[i]);
|
||||
var component = this.getShortString(geometry.components[i]);
|
||||
if (!component) { draw = false; }
|
||||
d += " " + component;
|
||||
}
|
||||
}
|
||||
d += " Z";
|
||||
node.setAttributeNS(null, "d", d);
|
||||
if (draw) {
|
||||
node.setAttributeNS(null, "d", d);
|
||||
} else {
|
||||
node.setAttributeNS(null, "d", "");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -340,7 +433,9 @@ OpenLayers.Renderer.SVG.prototype =
|
||||
getComponentsString: function(components) {
|
||||
var strings = [];
|
||||
for(var i = 0; i < components.length; i++) {
|
||||
strings.push(this.getShortString(components[i]));
|
||||
var component = this.getShortString(components[i]);
|
||||
if (!component) { return false; }
|
||||
strings.push(component);
|
||||
}
|
||||
return strings.join(",");
|
||||
},
|
||||
@@ -352,7 +447,12 @@ OpenLayers.Renderer.SVG.prototype =
|
||||
*/
|
||||
getShortString: function(point) {
|
||||
var resolution = this.getResolution();
|
||||
return point.x / resolution + "," + point.y / resolution;
|
||||
var x = (point.x / resolution + this.left);
|
||||
var y = (point.y / resolution - this.top);
|
||||
if (x < -this.maxPixel || x > this.maxPixel) { return false; }
|
||||
if (y < -this.maxPixel || y > this.maxPixel) { return false; }
|
||||
var string = x + "," + y;
|
||||
return string;
|
||||
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user