Avoid VML rendering issues with zero area inner rings. We don't actually do an expensive area calculation, but just make sure that we have at least three distinct points. This version is slightly different from Tim's previous patch: it compares the VML path components rathter than the geometry components, which is less expensive and more reliable (because the VML path uses integers). p=tschaub,me r=me (closes #2876)
git-svn-id: http://svn.openlayers.org/trunk/openlayers@10837 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
@@ -164,7 +164,7 @@
|
||||
});
|
||||
draw = new OpenLayers.Control.DrawFeature(
|
||||
poly, OpenLayers.Handler.Polygon,
|
||||
{displayClass: "olControlDrawFeaturePoint", title: "Draw Features"}
|
||||
{displayClass: "olControlDrawFeaturePoint", title: "Draw Features", handlerOptions: {holeModifier: "altKey"}}
|
||||
);
|
||||
modify = new OpenLayers.Control.ModifyFeature(
|
||||
poly, {displayClass: "olControlModifyFeature", title: "Modify Features"}
|
||||
|
||||
@@ -751,21 +751,43 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
var resolution = this.getResolution();
|
||||
|
||||
var path = [];
|
||||
var linearRing, i, j, len, ilen, comp, x, y;
|
||||
for (j = 0, len=geometry.components.length; j<len; j++) {
|
||||
linearRing = geometry.components[j];
|
||||
|
||||
var j, jj, points, area, first, second, i, ii, comp, pathComp, x, y;
|
||||
for (j=0, jj=geometry.components.length; j<jj; j++) {
|
||||
path.push("m");
|
||||
for (i=0, ilen=linearRing.components.length; i<ilen; i++) {
|
||||
comp = linearRing.components[i];
|
||||
points = geometry.components[j].components;
|
||||
// we only close paths of interior rings with area
|
||||
area = (j === 0);
|
||||
first = null;
|
||||
second = null;
|
||||
for (i=0, ii=points.length; i<ii; i++) {
|
||||
comp = points[i];
|
||||
x = (comp.x / resolution - this.offset.x) | 0;
|
||||
y = (comp.y / resolution - this.offset.y) | 0;
|
||||
path.push(" " + x + "," + y);
|
||||
pathComp = " " + x + "," + y;
|
||||
path.push(pathComp)
|
||||
if (i==0) {
|
||||
path.push(" l");
|
||||
}
|
||||
if (!area) {
|
||||
// IE improperly renders sub-paths that have no area.
|
||||
// Instead of checking the area of every ring, we confirm
|
||||
// the ring has at least three distinct points. This does
|
||||
// not catch all non-zero area cases, but it greatly improves
|
||||
// interior ring digitizing and is a minor performance hit
|
||||
// when rendering rings with many points.
|
||||
if (!first) {
|
||||
first = pathComp;
|
||||
} else if (first != pathComp) {
|
||||
if (!second) {
|
||||
second = pathComp;
|
||||
} else if (second != pathComp) {
|
||||
// stop looking
|
||||
area = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
path.push(" x ");
|
||||
path.push(area ? " x " : " ");
|
||||
}
|
||||
path.push("e");
|
||||
node.path = path.join("");
|
||||
|
||||
@@ -305,7 +305,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
t.plan(2);
|
||||
t.plan(3);
|
||||
|
||||
var r = new OpenLayers.Renderer.VML(document.body);
|
||||
r.offset = {x: 0, y: 0};
|
||||
@@ -318,30 +318,16 @@
|
||||
|
||||
var node = document.createElement('div');
|
||||
|
||||
var linearRing = {
|
||||
components: [{
|
||||
x: 1,
|
||||
y: 2
|
||||
},{
|
||||
x: 3,
|
||||
y: 4
|
||||
}]
|
||||
};
|
||||
var linearRing2 = {
|
||||
components: [{
|
||||
x: 5,
|
||||
y: 6
|
||||
},{
|
||||
x: 7,
|
||||
y: 8
|
||||
}]
|
||||
};
|
||||
var geometry = {
|
||||
components: [linearRing, linearRing2]
|
||||
};
|
||||
var geometry = OpenLayers.Geometry.fromWKT(
|
||||
"POLYGON((1 2, 3 4), (5 6, 7 8))"
|
||||
);
|
||||
r.drawPolygon(node, geometry, true);
|
||||
t.ok(g_SetNodeDimension, "setNodeDimension is called");
|
||||
t.eq(node.path, "m 2,4 l 6,8 x m 10,12 l 14,16 x e", "path attribute is correct");
|
||||
t.eq(node.path, "m 2,4 l 6,8 2,4 x m 10,12 l 14,16 10,12 e", "path attribute is correct - inner ring has no area and is not closed");
|
||||
|
||||
geometry.components[1].addComponent(new OpenLayers.Geometry.Point(8, 7));
|
||||
r.drawPolygon(node, geometry, true);
|
||||
t.eq(node.path, "m 2,4 l 6,8 2,4 x m 10,12 l 14,16 16,14 10,12 x e", "path attribute is correct - inner ring has an area and is closed");
|
||||
}
|
||||
|
||||
function test_VML_drawrectangle(t) {
|
||||
|
||||
Reference in New Issue
Block a user