diff options
Diffstat (limited to 'misc/openlayers/tests/Geometry/LinearRing.html')
-rw-r--r-- | misc/openlayers/tests/Geometry/LinearRing.html | 362 |
1 files changed, 362 insertions, 0 deletions
diff --git a/misc/openlayers/tests/Geometry/LinearRing.html b/misc/openlayers/tests/Geometry/LinearRing.html new file mode 100644 index 0000000..cbbba2a --- /dev/null +++ b/misc/openlayers/tests/Geometry/LinearRing.html @@ -0,0 +1,362 @@ +<html> +<head> + <script src="../OLLoader.js"></script> + <script type="text/javascript"> + var line; + var components = [new OpenLayers.Geometry.Point(10,10), + new OpenLayers.Geometry.Point(0,0)]; + + function test_LinearRing_constructor (t) { + t.plan( 6 ); + + //null + ring = new OpenLayers.Geometry.LinearRing(); + t.ok( ring instanceof OpenLayers.Geometry.LinearRing, "new OpenLayers.Geometry.LinearRing returns ring object" ); + t.eq( ring.CLASS_NAME, "OpenLayers.Geometry.LinearRing", "ring.CLASS_NAME is set correctly"); + t.eq( ring.components, [], "ring.components is set correctly"); + + //valid components + ring = new OpenLayers.Geometry.LinearRing(components); + t.ok( ring instanceof OpenLayers.Geometry.LinearRing, "new OpenLayers.Geometry.LinearRing returns ring object" ); + t.eq( ring.CLASS_NAME, "OpenLayers.Geometry.LinearRing", "ring.CLASS_NAME is set correctly"); + t.eq( ring.components.length, 3, "ring.components.length is set correctly"); + } + + function test_LinearRing_addComponent(t) { + t.plan(13); + + var ring = new OpenLayers.Geometry.LinearRing(); + + var point = new OpenLayers.Geometry.Point(0,0); + t.ok(ring.addComponent(point), + "addComponent returns true for 1st point"); + t.eq(ring.components.length, 2, "add first point, correct length"); + t.ok(ring.components[0].equals(point), "point one correct"); + t.ok(ring.components[0] === ring.components[ring.components.length - 1], + "first and last point are the same"); + + newPoint = new OpenLayers.Geometry.Point(10,10); + t.ok(ring.addComponent( newPoint ), + "addComponent returns true for unique point"); + t.eq(ring.components.length, 3, "correctly adds 3rd point"); + t.ok(ring.components[0].equals(point), "point one correct"); + t.ok(ring.components[1].equals(newPoint), "point one correct"); + t.ok(ring.components[0] === ring.components[ring.components.length - 1], + "first and last point are the same"); + + var length = ring.components.length; + var clone = ring.components[length - 1].clone(); + t.ok(!ring.addComponent(clone), + "addComponent returns false for adding a duplicate last point"); + t.eq(ring.components.length, length, + "components remains unchanged after trying to add duplicate point"); + t.ok(ring.addComponent(clone, length - 1), + "addComponent returns true when adding a duplicate with an index"); + t.eq(ring.components.length, length + 1, + "components increase in length after adding a duplicate point with index"); + + } + + function test_LinearRing_removeComponent(t) { + t.plan(10); + + var components = [new OpenLayers.Geometry.Point(0,0), + new OpenLayers.Geometry.Point(0,10), + new OpenLayers.Geometry.Point(15,15), + new OpenLayers.Geometry.Point(10,0) + ]; + var ring = new OpenLayers.Geometry.LinearRing(components); + + ring.removeComponent( ring.components[2] ); + t.eq(ring.components.length, 4, "removing from linear ring with 5 points: length ok"); + t.ok(ring.components[0].equals(components[0]), "point one correct"); + t.ok(ring.components[1].equals(components[1]), "point two correct"); + t.ok(ring.components[2].equals(components[3]), "point three correct"); + t.ok(ring.components[0] === ring.components[ring.components.length - 1], + "first and last point are the same"); + + var testBounds = new OpenLayers.Bounds(0,0,10,10); + var ringBounds = ring.getBounds(); + t.ok(ringBounds.equals(testBounds), "bounds correctly recalculated"); + + ring.removeComponent( ring.components[2] ); + ring.removeComponent( ring.components[1] ); + t.eq(ring.components.length, 3, "cant remove from linear ring with only 3 points. new length ok"); + t.ok(ring.components[0].equals(components[0]), "point one correct"); + t.ok(ring.components[1].equals(components[1]), "point two correct"); + t.ok(ring.components[0] === ring.components[ring.components.length - 1], + "first and last point are the same"); + + } + + function test_LinearRing_getArea(t) { + t.plan(1); + var components = [new OpenLayers.Geometry.Point(0,0), + new OpenLayers.Geometry.Point(0,10), + new OpenLayers.Geometry.Point(10,10), + new OpenLayers.Geometry.Point(10,0) + ]; + var ring = new OpenLayers.Geometry.LinearRing(components); + + t.eq(ring.getArea(), 100, "getArea works lovely"); + } + + function test_LinearRing_getLength(t) { + t.plan(1); + var components = [ + new OpenLayers.Geometry.Point(0,0), + new OpenLayers.Geometry.Point(0,10), + new OpenLayers.Geometry.Point(10,10), + new OpenLayers.Geometry.Point(10,0) + ]; + var ring = new OpenLayers.Geometry.LinearRing(components); + t.eq(ring.getLength(), 40, "getLength returns the correct perimiter"); + } + + function test_LinearRing_getCentroid(t) { + t.plan(2); + var components = [ + new OpenLayers.Geometry.Point(0,0), + new OpenLayers.Geometry.Point(0,10), + new OpenLayers.Geometry.Point(10,10), + new OpenLayers.Geometry.Point(10,0) + ]; + var ring = new OpenLayers.Geometry.LinearRing(components); + var centroid = ring.getCentroid(); + t.ok(centroid.x === 5 && centroid.y === 5, "getCentroid returns the correct centroid"); + ring.destroy(); + + ring = new OpenLayers.Geometry.LinearRing(); + t.eq(ring.getCentroid(), null, "getCentroid returns null if no components"); + } + + function test_LinearRing_move(t) { + + var nvert = 4, + x = new Array(nvert), + y = new Array(nvert), + components = new Array(nvert); + + t.plan(2 * (nvert + 1)); + + for(var i=0; i<nvert; ++i) { + x[i] = Math.random(); + y[i] = Math.random(); + components[i] = new OpenLayers.Geometry.Point(x[i], y[i]); + } + x.push(x[0]); + y.push(y[0]); + + var ring = new OpenLayers.Geometry.LinearRing(components); + + var dx = Math.random(); + var dy = Math.random(); + + ring.move(dx, dy); + + for(var j=0; j<nvert + 1; ++j) { + t.eq(ring.components[j].x, x[j] + dx, + "move correctly adjust x coord of " + j + " component"); + t.eq(ring.components[j].y, y[j] + dy, + "move correctly adjust y coord of " + j + " component"); + } + } + + function test_LinearRing_rotate(t) { + t.plan(10); + + var components = [ + new OpenLayers.Geometry.Point(10,10), + new OpenLayers.Geometry.Point(11,10), + new OpenLayers.Geometry.Point(11,11), + new OpenLayers.Geometry.Point(10,11) + ]; + + var ring = new OpenLayers.Geometry.LinearRing(components); + + // rotate a quarter turn around the origin + var origin = new OpenLayers.Geometry.Point(0, 0); + var angle = 90; + + ring.rotate(angle, origin); + + function withinTolerance(i, j) { + return Math.abs(i - j) < 1e-9; + } + + t.ok(withinTolerance(ring.components[0].x , -10), + "rotate correctly adjusts x of component 0"); + t.ok(withinTolerance(ring.components[0].y, 10), + "rotate correctly adjusts y of component 0"); + t.ok(withinTolerance(ring.components[1].x, -10), + "rotate correctly adjusts x of component 1"); + t.ok(withinTolerance(ring.components[1].y, 11), + "rotate correctly adjusts y of component 1"); + t.ok(withinTolerance(ring.components[2].x, -11), + "rotate correctly adjusts x of component 2"); + t.ok(withinTolerance(ring.components[2].y, 11), + "rotate correctly adjusts y of component 2"); + t.ok(withinTolerance(ring.components[3].x, -11), + "rotate correctly adjusts x of component 3"); + t.ok(withinTolerance(ring.components[3].y, 10), + "rotate correctly adjusts y of component 3"); + t.ok(withinTolerance(ring.components[4].x, -10), + "rotate correctly adjusts x of component 4"); + t.ok(withinTolerance(ring.components[4].y, 10), + "rotate correctly adjusts y of component 4"); + } + + function test_LinearRing_resize(t) { + t.plan(10); + + var components = [ + new OpenLayers.Geometry.Point(10,10), + new OpenLayers.Geometry.Point(11,10), + new OpenLayers.Geometry.Point(11,11), + new OpenLayers.Geometry.Point(10,11) + ]; + + var ring = new OpenLayers.Geometry.LinearRing(components); + + // rotate a quarter turn around the origin + var origin = new OpenLayers.Geometry.Point(0, 0); + var scale = Math.random(); + + ring.resize(scale, origin); + + function withinTolerance(i, j) { + return Math.abs(i - j) < 1e-9; + } + + t.ok(withinTolerance(ring.components[0].x , 10 * scale), + "resize correctly adjusts x of component 0"); + t.ok(withinTolerance(ring.components[0].y, 10 * scale), + "resize correctly adjusts y of component 0"); + t.ok(withinTolerance(ring.components[1].x, 11 * scale), + "resize correctly adjusts x of component 1"); + t.ok(withinTolerance(ring.components[1].y, 10 * scale), + "resize correctly adjusts y of component 1"); + t.ok(withinTolerance(ring.components[2].x, 11 * scale), + "resize correctly adjusts x of component 2"); + t.ok(withinTolerance(ring.components[2].y, 11 * scale), + "resize correctly adjusts y of component 2"); + t.ok(withinTolerance(ring.components[3].x, 10 * scale), + "resize correctly adjusts x of component 3"); + t.ok(withinTolerance(ring.components[3].y, 11 * scale), + "resize correctly adjusts y of component 3"); + t.ok(withinTolerance(ring.components[4].x, 10 * scale), + "resize correctly adjusts x of component 4"); + t.ok(withinTolerance(ring.components[4].y, 10 * scale), + "resize correctly adjusts y of component 4"); + } + + function test_containsPoint(t) { + + /** + * The ring: + * edge 3 + * (5, 10) __________ (15, 10) + * / / + * edge 4 / / edge 2 + * / / + * (0, 0) /_________/ (10, 0) + * edge 1 + */ + var components = [ + new OpenLayers.Geometry.Point(0, 0), + new OpenLayers.Geometry.Point(10, 0), + new OpenLayers.Geometry.Point(15, 10), + new OpenLayers.Geometry.Point(5, 10) + ]; + + var ring = new OpenLayers.Geometry.LinearRing(components); + + function p(x, y) { + return new OpenLayers.Geometry.Point(x, y); + } + + // contains: 1 (touches), true (within), false (outside) + var cases = [{ + point: p(5, 5), contains: true + }, { + point: p(20, 20), contains: false + }, { + point: p(15, 15), contains: false + }, { + point: p(0, 0), contains: 1 // lower left corner + }, { + point: p(10, 0), contains: 1 // lower right corner + }, { + point: p(15, 10), contains: 1 // upper right corner + }, { + point: p(5, 10), contains: 1 // upper left corner + }, { + point: p(5, 0), contains: 1 // on edge 1 + }, { + point: p(5, -0.1), contains: false // below edge 1 + }, { + point: p(5, 0.1), contains: true // above edge 1 + }, { + point: p(12.5, 5), contains: 1 // on edge 2 + }, { + point: p(12.4, 5), contains: true // left of edge 2 + }, { + point: p(12.6, 5), contains: false // right of edge 2 + }, { + point: p(10, 10), contains: 1 // on edge 3 + }, { + point: p(10, 9.9), contains: true // below edge 3 + }, { + point: p(10, 10.1), contains: false // above edge 3 + }, { + point: p(2.5, 5), contains: 1 // on edge 4 + }, { + point: p(2.4, 5), contains: false // left of edge 4 + }, { + point: p(2.6, 5), contains: true // right of edge 4 + }]; + + var len = cases.length; + t.plan(len); + var c; + for (var i=0; i<len; ++i) { + c = cases[i]; + t.eq(ring.containsPoint(c.point), c.contains, "case " + i + ": " + c.point); + } + } + + function test_containsPoint_precision(t) { + + /** + * The test for linear ring containment was sensitive to failure when + * looking for ray crossings on nearly vertical edges. With a loss + * of precision in calculating the x-coordinate for the crossing, + * the method would erronously determine that the x-coordinate was + * not within the (very narrow) x-range of the nearly vertical edge. + * + * The test below creates a polygon whose first vertical edge is + * nearly horizontal. The test point lies "far" outside the polygon + * and we expect the containsPoint method to return false. + */ + + t.plan(1); + + var components = [ + new OpenLayers.Geometry.Point(10000020.000001, 1000000), + new OpenLayers.Geometry.Point(10000020.000002, 1000010), // nearly vertical + new OpenLayers.Geometry.Point(10000030, 1000010), + new OpenLayers.Geometry.Point(10000030, 1000000) + ]; + + var ring = new OpenLayers.Geometry.LinearRing(components); + var point = new OpenLayers.Geometry.Point(10000000, 1000001); + + t.eq(ring.containsPoint(point), false, "false for point outside polygon with nearly vertical edge"); + + } + + </script> +</head> +<body> +</body> +</html> |