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:
crschmidt
2007-04-13 12:40:22 +00:00
parent 0d2b12c7cd
commit ba5b664a2f

View File

@@ -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;
},