From a46707e727845aaeec906f7adacadf034d5527de Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Mon, 26 Apr 2010 16:21:59 +0100 Subject: [PATCH 1/5] Add support for irregular transformations to TransformFeature Give the TransformFeature control an irregular mode where dragging a handle just extends that side rather than growing the shape symmetrically about the centre. --- lib/OpenLayers/Control/TransformFeature.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/OpenLayers/Control/TransformFeature.js b/lib/OpenLayers/Control/TransformFeature.js index 437124bfcf..72944228b8 100644 --- a/lib/OpenLayers/Control/TransformFeature.js +++ b/lib/OpenLayers/Control/TransformFeature.js @@ -165,7 +165,13 @@ OpenLayers.Control.TransformFeature = OpenLayers.Class(OpenLayers.Control, { * {} */ dragControl: null, - + + /** + * APIProperty: irregular + * {Boolean} + */ + irregular: false, + /** * Constructor: OpenLayers.Control.TransformFeature * Create a new transform feature control. @@ -390,6 +396,14 @@ OpenLayers.Control.TransformFeature = OpenLayers.Class(OpenLayers.Control, { var dy1 = this.y - centerGeometry.y; var dx0 = dx1 - (this.x - oldGeom.x); var dy0 = dy1 - (this.y - oldGeom.y); + if (control.irregular && !control._setfeature) { + dx1 -= (this.x - oldGeom.x) / 2; + dy1 -= (this.y - oldGeom.y) / 2; + var newCenter = centerGeometry.clone(); + newCenter.x += Math.abs(dx0) < 0.00001 ? 0 : (this.x - oldGeom.x) / 2; + newCenter.y += Math.abs(dy0) < 0.00001 ? 0 : (this.y - oldGeom.y) / 2; + control.transformFeature({center: newCenter}); + } this.x = oldX; this.y = oldY; var scale, ratio = 1; @@ -410,6 +424,7 @@ OpenLayers.Control.TransformFeature = OpenLayers.Class(OpenLayers.Control, { control.box.geometry.resize(scale, centerGeometry, ratio); control.box.geometry.rotate(control.rotation, centerGeometry); + control.box.move(control.feature.geometry.getBounds().getCenterLonLat()); control.transformFeature({scale: scale, ratio: ratio}); }; From 1b6eb38d46c77c15a66116bd191dec276b62aece Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Tue, 18 Oct 2011 09:55:25 +0100 Subject: [PATCH 2/5] Make irregular transforms work on rotated features Rework support for irregular transforms to handle features which have been rotated correctly. --- lib/OpenLayers/Control/TransformFeature.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/OpenLayers/Control/TransformFeature.js b/lib/OpenLayers/Control/TransformFeature.js index 72944228b8..a52f8d84fd 100644 --- a/lib/OpenLayers/Control/TransformFeature.js +++ b/lib/OpenLayers/Control/TransformFeature.js @@ -399,10 +399,6 @@ OpenLayers.Control.TransformFeature = OpenLayers.Class(OpenLayers.Control, { if (control.irregular && !control._setfeature) { dx1 -= (this.x - oldGeom.x) / 2; dy1 -= (this.y - oldGeom.y) / 2; - var newCenter = centerGeometry.clone(); - newCenter.x += Math.abs(dx0) < 0.00001 ? 0 : (this.x - oldGeom.x) / 2; - newCenter.y += Math.abs(dy0) < 0.00001 ? 0 : (this.y - oldGeom.y) / 2; - control.transformFeature({center: newCenter}); } this.x = oldX; this.y = oldY; @@ -424,8 +420,14 @@ OpenLayers.Control.TransformFeature = OpenLayers.Class(OpenLayers.Control, { control.box.geometry.resize(scale, centerGeometry, ratio); control.box.geometry.rotate(control.rotation, centerGeometry); - control.box.move(control.feature.geometry.getBounds().getCenterLonLat()); control.transformFeature({scale: scale, ratio: ratio}); + if (control.irregular && !control._setfeature) { + var newCenter = centerGeometry.clone(); + newCenter.x += Math.abs(oldX - centerGeometry.x) < 0.00001 ? 0 : (this.x - oldX); + newCenter.y += Math.abs(oldY - centerGeometry.y) < 0.00001 ? 0 : (this.y - oldY); + control.box.geometry.move(this.x - oldX, this.y - oldY); + control.transformFeature({center: newCenter}); + } }; // Override for rotation handle move - make sure that the box and From 93f2a31253035aa4d68460b67c203e3f54d735b7 Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Tue, 18 Oct 2011 10:43:56 +0100 Subject: [PATCH 3/5] Add tests for regular and irregular transformations --- tests/Control/TransformFeature.html | 38 +++++++++++++++++++++++++++++ tests/Test.AnotherWay.geom_eq.js | 36 ++++++++++++++++++++++++--- 2 files changed, 70 insertions(+), 4 deletions(-) diff --git a/tests/Control/TransformFeature.html b/tests/Control/TransformFeature.html index 00fb0a90b4..3279867876 100644 --- a/tests/Control/TransformFeature.html +++ b/tests/Control/TransformFeature.html @@ -82,6 +82,44 @@ control.box.move(center); t.geom_eq(control.handles[0].geometry, control.box.geometry.components[0], "handle moved with box"); } + + function test_handleMove(t) { + t.plan(16); + var map = new OpenLayers.Map("map", {allOverlays: true}); + var layer = new OpenLayers.Layer.Vector(); + var feature = new OpenLayers.Feature.Vector( + OpenLayers.Geometry.fromWKT("POLYGON((-1 -1, 1 -1, 1 1, -1 1))")); + layer.addFeatures([feature]); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0, 0), 18); + var control = new OpenLayers.Control.TransformFeature(layer); + map.addControl(control); + control.setFeature(feature); + + var bottomLeft = new OpenLayers.LonLat(-2, -2); + control.handles[0].move(bottomLeft); + t.geom_eq(control.handles[0].geometry, new OpenLayers.Geometry.Point(-2, -2), "bottom left handle at -2,-2"); + t.geom_eq(control.handles[1].geometry, new OpenLayers.Geometry.Point(0, -2), "bottom handle at 0,-2"); + t.geom_eq(control.handles[2].geometry, new OpenLayers.Geometry.Point(2, -2), "bottom right handle at 2,-2"); + t.geom_eq(control.handles[3].geometry, new OpenLayers.Geometry.Point(2, 0), "right handle at 2,0"); + t.geom_eq(control.handles[4].geometry, new OpenLayers.Geometry.Point(2, 2), "top right handle at 2,2"); + t.geom_eq(control.handles[5].geometry, new OpenLayers.Geometry.Point(0, 2), "top handle at 0,2"); + t.geom_eq(control.handles[6].geometry, new OpenLayers.Geometry.Point(-2, 2), "top left handle at -2,2"); + t.geom_eq(control.handles[7].geometry, new OpenLayers.Geometry.Point(-2, 0), "left handle at -2,0"); + + control.irregular = true; + + var bottomLeft = new OpenLayers.LonLat(-3, -3); + control.handles[0].move(bottomLeft); + t.geom_eq(control.handles[0].geometry, new OpenLayers.Geometry.Point(-3, -3), "bottom left handle at -3,-3"); + t.geom_eq(control.handles[1].geometry, new OpenLayers.Geometry.Point(-0.5, -3), "bottom handle at 0,-3"); + t.geom_eq(control.handles[2].geometry, new OpenLayers.Geometry.Point(2, -3), "bottom right handle at 2,-3"); + t.geom_eq(control.handles[3].geometry, new OpenLayers.Geometry.Point(2, -0.5), "right handle at 2,0"); + t.geom_eq(control.handles[4].geometry, new OpenLayers.Geometry.Point(2, 2), "top right handle at 2,2"); + t.geom_eq(control.handles[5].geometry, new OpenLayers.Geometry.Point(-0.5, 2), "top handle at 0,2"); + t.geom_eq(control.handles[6].geometry, new OpenLayers.Geometry.Point(-3, 2), "top left handle at -3,2"); + t.geom_eq(control.handles[7].geometry, new OpenLayers.Geometry.Point(-3, -0.5), "left handle at -3,0"); + } diff --git a/tests/Test.AnotherWay.geom_eq.js b/tests/Test.AnotherWay.geom_eq.js index 3e3ad8486f..87e40e2134 100644 --- a/tests/Test.AnotherWay.geom_eq.js +++ b/tests/Test.AnotherWay.geom_eq.js @@ -34,6 +34,34 @@ } } + /** + * Function assertFloatEqual + * Test two objects for floating point equivalence. Throw an exception + * if not equivalent. + * + * Parameters: + * got - {Object} + * expected - {Object} + * msg - {String} The message to be thrown. This message will be appended + * with ": got {got} but expected {expected}" where got and expected are + * replaced with string representations of the above arguments. + */ + function assertFloatEqual(got, expected, msg) { + if(got === undefined) { + got = "undefined"; + } else if (got === null) { + got = "null"; + } + if(expected === undefined) { + expected = "undefined"; + } else if (expected === null) { + expected = "null"; + } + if(Math.abs(got - expected) > 0.000000001) { + throw msg + ": got '" + got + "' but expected '" + expected + "'"; + } + } + /** * Function assertGeometryEqual * Test two geometries for equivalence. Geometries are considered @@ -58,9 +86,9 @@ if(got instanceof OpenLayers.Geometry.Point) { // compare points - assertEqual(got.x, expected.x, "x mismatch"); - assertEqual(got.y, expected.y, "y mismatch"); - assertEqual(got.z, expected.z, "z mismatch"); + assertFloatEqual(got.x, expected.x, "x mismatch"); + assertFloatEqual(got.y, expected.y, "y mismatch"); + assertFloatEqual(got.z, expected.z, "z mismatch"); } else { // compare components assertEqual( @@ -107,4 +135,4 @@ } } -})(); \ No newline at end of file +})(); From 533ee475ee91b6edea3ba0bc09cadfa7202527bb Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Tue, 18 Oct 2011 10:50:18 +0100 Subject: [PATCH 4/5] Improve documentation of regular versus irregular transformation --- lib/OpenLayers/Control/TransformFeature.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/OpenLayers/Control/TransformFeature.js b/lib/OpenLayers/Control/TransformFeature.js index a52f8d84fd..571963146c 100644 --- a/lib/OpenLayers/Control/TransformFeature.js +++ b/lib/OpenLayers/Control/TransformFeature.js @@ -165,13 +165,16 @@ OpenLayers.Control.TransformFeature = OpenLayers.Class(OpenLayers.Control, { * {} */ dragControl: null, - + /** * APIProperty: irregular - * {Boolean} + * {Boolean} Make scaling/resizing work irregularly. If true then + * dragging a handle causes the feature to resize in the direction + * of movement. If false then the feature resizes symetrically + * about it's center. */ irregular: false, - + /** * Constructor: OpenLayers.Control.TransformFeature * Create a new transform feature control. From dd103ebf821297a916e4bddec9c76225f1ab5852 Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Sat, 31 Dec 2011 14:00:25 +0000 Subject: [PATCH 5/5] Use OpenLayers.Util.DEFAULT_PRECISION for geometry comparisons --- tests/Test.AnotherWay.geom_eq.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Test.AnotherWay.geom_eq.js b/tests/Test.AnotherWay.geom_eq.js index 87e40e2134..893c5b5a2f 100644 --- a/tests/Test.AnotherWay.geom_eq.js +++ b/tests/Test.AnotherWay.geom_eq.js @@ -47,6 +47,7 @@ * replaced with string representations of the above arguments. */ function assertFloatEqual(got, expected, msg) { + var OpenLayers = Test.AnotherWay._g_test_iframe.OpenLayers; if(got === undefined) { got = "undefined"; } else if (got === null) { @@ -57,7 +58,7 @@ } else if (expected === null) { expected = "null"; } - if(Math.abs(got - expected) > 0.000000001) { + if(Math.abs(got - expected) > Math.pow(10, -OpenLayers.Util.DEFAULT_PRECISION)) { throw msg + ": got '" + got + "' but expected '" + expected + "'"; } }