summaryrefslogtreecommitdiff
path: root/misc/openlayers/tests/Geometry/LinearRing.html
diff options
context:
space:
mode:
Diffstat (limited to 'misc/openlayers/tests/Geometry/LinearRing.html')
-rw-r--r--misc/openlayers/tests/Geometry/LinearRing.html362
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>