summaryrefslogtreecommitdiff
path: root/misc/openlayers/tests/Geometry
diff options
context:
space:
mode:
authorChris Schlaeger <chris@linux.com>2014-08-12 21:56:44 +0200
committerChris Schlaeger <chris@linux.com>2014-08-12 21:56:44 +0200
commitea346a785dc1b3f7c156f6fc33da634e1f1a627b (patch)
treeaf67530553d20b6e82ad60fd79593e9c4abf5565 /misc/openlayers/tests/Geometry
parent59741cd535c47f25971bf8c32b25da25ceadc6d5 (diff)
downloadpostrunner-fb1989bda5d3e0a5472ba7644d57cae197733a8f.zip
Adding jquery, flot and openlayers to be included with the GEM.v0.0.4
Diffstat (limited to 'misc/openlayers/tests/Geometry')
-rw-r--r--misc/openlayers/tests/Geometry/Collection.html431
-rw-r--r--misc/openlayers/tests/Geometry/Curve.html157
-rw-r--r--misc/openlayers/tests/Geometry/LineString.html443
-rw-r--r--misc/openlayers/tests/Geometry/LinearRing.html362
-rw-r--r--misc/openlayers/tests/Geometry/MultiLineString.html267
-rw-r--r--misc/openlayers/tests/Geometry/MultiPoint.html130
-rw-r--r--misc/openlayers/tests/Geometry/MultiPolygon.html34
-rw-r--r--misc/openlayers/tests/Geometry/Point.html244
-rw-r--r--misc/openlayers/tests/Geometry/Polygon.html420
9 files changed, 2488 insertions, 0 deletions
diff --git a/misc/openlayers/tests/Geometry/Collection.html b/misc/openlayers/tests/Geometry/Collection.html
new file mode 100644
index 0000000..7c9fd62
--- /dev/null
+++ b/misc/openlayers/tests/Geometry/Collection.html
@@ -0,0 +1,431 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ var coll;
+
+ function test_Collection_constructor (t) {
+ t.plan( 4 );
+
+ //null param
+ coll = new OpenLayers.Geometry.Collection();
+ t.ok( coll instanceof OpenLayers.Geometry.Collection, "new OpenLayers.Geometry.Collection returns coll object" );
+ t.eq( coll.CLASS_NAME, "OpenLayers.Geometry.Collection", "coll.CLASS_NAME is set correctly");
+ t.eq( coll.components.length, 0, "coll.components is set correctly");
+
+ OpenLayers.Geometry.Collection.prototype._addComponents =
+ OpenLayers.Geometry.Collection.prototype.addComponents;
+ OpenLayers.Geometry.Collection.prototype.addComponents =
+ function(comps) { g_addcomponents = comps; };
+
+ //valid param
+ g_addcomponents = null;
+ var components = {};
+ coll = new OpenLayers.Geometry.Collection(components);
+ t.ok(g_addcomponents, components, "addcomponents called on non-null param")
+
+ OpenLayers.Geometry.Collection.prototype.addComponents =
+ OpenLayers.Geometry.Collection.prototype._addComponents;
+ }
+
+ function test_Collection_addComponents (t) {
+ t.plan( 10 );
+
+ coll = new OpenLayers.Geometry.Collection();
+
+ //null
+ coll.addComponents(null);
+ t.ok(true, "doesn't break on add null components");
+
+ OpenLayers.Geometry.Collection.prototype._addComponent =
+ OpenLayers.Geometry.Collection.prototype.addComponent;
+
+ OpenLayers.Geometry.Collection.prototype.addComponent =
+ function(comp) { g_addComp = comp; g_added++};
+
+
+ //nonarray argument
+ var g_added = 0;
+ var g_addComp = 0;
+ var component = {};
+ coll.addComponents(component);
+ t.eq(g_added, 1, "added once");
+ t.eq(g_addComp, component, "added component");
+
+ //array arg
+ var g_added = 0;
+ var g_addComp = 0;
+ var component1 = {};
+ var component2 = {};
+ coll.addComponents([component1, component2]);
+ t.eq(g_added, 2, "added twice");
+ t.eq(g_addComp, component2, "added component");
+
+ OpenLayers.Geometry.Collection.prototype.addComponent =
+ OpenLayers.Geometry.Collection.prototype._addComponent;
+
+
+
+ coll.addComponents(new OpenLayers.Geometry.Point(0,0));
+ coll.addComponents(new OpenLayers.Geometry.Point(10,10));
+ t.eq( coll.components.length, 2, "added two components to collection" );
+ bounds = coll.getBounds();
+ t.eq( bounds.left, 0, "left bound is 0" );
+ t.eq( bounds.bottom, 0, "bottom bound is 0" );
+ t.eq( bounds.right, 10, "right bound is 10" );
+ t.eq( bounds.top, 10, "top bound is 10" );
+ }
+
+ function test_Collection_clone (t) {
+ t.plan( 3 );
+ coll = new OpenLayers.Geometry.Collection();
+ coll.addComponents(new OpenLayers.Geometry.Point(0,0));
+ coll.addComponents(new OpenLayers.Geometry.Point(10,10));
+ coll2 = coll.clone();
+ t.ok( coll2 instanceof OpenLayers.Geometry.Collection, "coll.clone() returns collection object" );
+ t.eq( coll2.components.length, 2, "coll2.components.length is set correctly");
+ t.ok( coll2.components[0] instanceof OpenLayers.Geometry.Point,
+ "coll2.components.length is set correctly");
+ }
+
+ function test_Collection_removeComponents (t) {
+ t.plan( 5 );
+ coll = new OpenLayers.Geometry.Collection();
+ point = new OpenLayers.Geometry.Point(0,0);
+ coll.addComponents(point);
+ coll.addComponents(new OpenLayers.Geometry.Point(10,10));
+ coll.removeComponents(coll.components[0]);
+ t.eq( coll.components.length, 1, "coll.components.length is smaller after removeComponent" );
+ t.ok( coll.bounds == null, "bounds are nullified after call to remove (to trigger recalc on getBounds()");
+ bounds = coll.getBounds();
+ t.eq( bounds.left, 10, "left bound is 10 after removeComponent" );
+ t.eq( bounds.bottom, 10, "bottom bound is 10 after removeComponent" );
+
+ coll = new OpenLayers.Geometry.Collection();
+ for(var i=0; i<5; ++i) {
+ coll.addComponents(
+ new OpenLayers.Geometry.Point(Math.random(), Math.random())
+ );
+ }
+ coll.removeComponents(coll.components);
+ t.eq(coll.components.length, 0,
+ "remove components even works with multiple components");
+
+ }
+
+ function test_Collection_calculateBounds(t) {
+ t.plan( 9 );
+
+ var coll = new OpenLayers.Geometry.Collection();
+ coll.calculateBounds();
+ t.eq(coll.bounds, null, "null components list gives null bounds on calculation()");
+
+ var p1 = new OpenLayers.Geometry.Point(10,20);
+ var p2 = new OpenLayers.Geometry.Point(30,40);
+
+ var components = [p1, p2];
+ coll = new OpenLayers.Geometry.Collection(components);
+
+ coll.calculateBounds();
+
+ t.eq(coll.bounds.left, 10, "good left bounds");
+ t.eq(coll.bounds.bottom, 20, "good bottom bounds");
+ t.eq(coll.bounds.right, 30, "good right bounds");
+ t.eq(coll.bounds.top, 40, "good top bounds");
+
+ var newPoint = new OpenLayers.Geometry.Point(60,70);
+ coll.addComponent(newPoint);
+ coll.calculateBounds();
+
+ t.eq(coll.bounds.left, 10, "good left bounds");
+ t.eq(coll.bounds.bottom, 20, "good bottom bounds");
+ t.eq(coll.bounds.right, 60, "good right bounds");
+ t.eq(coll.bounds.top, 70, "good top bounds");
+ }
+
+ function test_Collection_equals(t) {
+ t.plan(1);
+ var geom = new OpenLayers.Geometry.Collection();
+ t.ok(!geom.equals(), "collection.equals() returns false for undefined");
+ }
+
+ function test_Collection_addComponent(t) {
+ t.plan(10);
+
+ var coll = new OpenLayers.Geometry.Collection();
+
+ //null
+ coll.addComponent(null);
+ t.ok(!coll.addComponent(null),
+ "addComponent returns false for bad component")
+
+ //good component
+ var component = new OpenLayers.Geometry.Point(3,4);
+ t.ok(coll.addComponent(component),
+ "addComponent returns true for good component");
+ t.ok(coll.bounds == null, "bounds cache correctly cleared");
+
+ var foundComponent = false;
+ for(var i=0; i< coll.components.length; i++) {
+ if (coll.components[i].equals(component)) {
+ foundComponent = true;
+ }
+ }
+ t.ok(foundComponent, "component added to internal array");
+
+ // restricted components
+ coll.componentTypes = ["OpenLayers.Geometry.Point",
+ "OpenLayers.Geometry.LineString"];
+ var point1 = new OpenLayers.Geometry.Point(0,0);
+ var point2 = new OpenLayers.Geometry.Point(1,1);
+ var line = new OpenLayers.Geometry.LineString([point1, point2]);
+ var multipoint = new OpenLayers.Geometry.MultiPoint([point1, point2]);
+
+ t.ok(coll.addComponent(point1),
+ "addComponent returns true for 1st geometry type in componentTypes");
+ t.ok(OpenLayers.Util.indexOf(coll.components, point1) > -1,
+ "addComponent adds 1st restricted type to components array");
+ t.ok(coll.addComponent(line),
+ "addComponent returns true for 2nd geometry type in componentTypes");
+ t.ok(OpenLayers.Util.indexOf(coll.components, point1) > -1,
+ "addComponent adds 2nd restricted type to components array");
+ t.ok(!coll.addComponent(multipoint),
+ "addComponent returns false for geometry type not in componentTypes");
+ t.ok(OpenLayers.Util.indexOf(coll.components, multipoint) == -1,
+ "addComponent doesn't add restricted type to component array");
+
+ }
+
+ function test_collection_getLength(t) {
+ t.plan(2);
+
+ //null
+ var coll = new OpenLayers.Geometry.Collection();
+ t.eq( coll.getLength(), 0, "null coll has 0 getlength");
+
+ //valid
+ coll.components = [
+ { 'getLength': function() { return 50; } },
+ { 'getLength': function() { return 15; } }
+ ];
+ t.eq( coll.getLength(), 65, "coll with valid components correctly sums getlength");
+ }
+
+ function test_collection_getArea(t) {
+ t.plan(2);
+
+ //null
+ var coll = new OpenLayers.Geometry.Collection();
+ t.eq( coll.getArea(), 0, "null coll has 0 getArea");
+
+ //valid
+ coll.components = [
+ { 'getArea': function() { return 50; } },
+ { 'getArea': function() { return 15; } }
+ ];
+ t.eq( coll.getArea(), 65, "coll with valid components correctly sums getArea");
+ }
+
+ function test_transform(t) {
+ t.plan(5);
+ var p1 = new OpenLayers.Geometry.Point(0,0);
+ p1.bounds = "foo";
+ var p2 = new OpenLayers.Geometry.Point(1,1);
+ p2.bounds = "foo";
+ var line = new OpenLayers.Geometry.LineString([p1, p2]);
+ var multipoint = new OpenLayers.Geometry.MultiPoint([p1, p2]);
+ var coll = new OpenLayers.Geometry.Collection([
+ p1, p2, line, multipoint
+ ]);
+ coll.bounds = "foo";
+
+ var wgs84 = new OpenLayers.Projection("EPSG:4326");
+ var sm = new OpenLayers.Projection("EPSG:900913");
+ coll.transform(wgs84, sm);
+
+ t.eq(coll.bounds, null, "coll bounds cleared");
+ t.eq(p1.bounds, null, "p1 component bounds cleared");
+ t.eq(p2.bounds, null, "p2 component bounds cleared");
+ t.eq(line.bounds, null, "line component bounds cleared");
+ t.eq(multipoint.bounds, null, "multipoint component bounds cleared");
+
+ }
+
+ function test_getCentroid_pts_only(t) {
+ t.plan(3);
+
+ coll = new OpenLayers.Geometry.Collection();
+ coll.addComponent(new OpenLayers.Geometry.Point(0,0));
+ coll.addComponent(new OpenLayers.Geometry.Point(1,1));
+
+ centroid = coll.getCentroid(true);
+ t.ok(centroid != null, 'The centroid is not null.');
+ t.eq(centroid.x, 0.5, 'The centroid x coordinate is good.');
+ t.eq(centroid.y, 0.5, 'The centroid y coordinate is good.');
+
+ coll.destroy();
+ }
+
+ function test_getCentroid_poly_nonrecursive(t) {
+ t.plan(3);
+
+ coll = new OpenLayers.Geometry.Collection();
+ coll.addComponent(
+ new OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(0,0),
+ new OpenLayers.Geometry.Point(0,1),
+ new OpenLayers.Geometry.Point(1,1),
+ new OpenLayers.Geometry.Point(1,0)
+ ])
+ ])
+ );
+ // performing non-recursive getCentroid means this next polygon
+ // is excluded from the centroid computation
+ coll.addComponent(
+ new OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(2,2),
+ new OpenLayers.Geometry.Point(2,3),
+ new OpenLayers.Geometry.Point(3,3),
+ new OpenLayers.Geometry.Point(3,2)
+ ])
+ ])
+ );
+
+ centroid = coll.getCentroid();
+ t.ok(centroid != null, 'The centroid is not null.');
+ t.eq(centroid.x, 0.5, 'The centroid x coordinate is good.');
+ t.eq(centroid.y, 0.5, 'The centroid y coordinate is good.');
+
+ coll.destroy();
+ }
+
+ function test_getCentroid_poly_only(t) {
+ t.plan(3);
+
+ coll = new OpenLayers.Geometry.Collection();
+ coll.addComponent(
+ new OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(0,0),
+ new OpenLayers.Geometry.Point(0,1),
+ new OpenLayers.Geometry.Point(1,1),
+ new OpenLayers.Geometry.Point(1,0)
+ ])
+ ])
+ );
+
+ centroid = coll.getCentroid(true);
+ t.ok(centroid != null, 'The centroid is not null.');
+ t.eq(centroid.x, 0.5, 'The centroid x coordinate is good.');
+ t.eq(centroid.y, 0.5, 'The centroid y coordinate is good.');
+
+ coll.destroy();
+ }
+
+ function test_getCentroid_poly_and_pts(t) {
+ t.plan(3);
+
+ coll = new OpenLayers.Geometry.Collection();
+ coll.addComponent(
+ new OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(0,0),
+ new OpenLayers.Geometry.Point(0,1),
+ new OpenLayers.Geometry.Point(1,1),
+ new OpenLayers.Geometry.Point(1,0)
+ ])
+ ])
+ );
+
+ // since the polygon above has an area of 1 and these
+ // points have an area of 0, they should not change the centroid
+ coll.addComponent( new OpenLayers.Geometry.Point(2,2) );
+ coll.addComponent( new OpenLayers.Geometry.Point(4,4) );
+
+ centroid = coll.getCentroid(true);
+ t.ok(centroid != null, 'The centroid is not null.');
+ t.eq(centroid.x, 0.5, 'The centroid x coordinate is good.');
+ t.eq(centroid.y, 0.5, 'The centroid y coordinate is good.');
+
+ coll.destroy();
+ }
+
+ function test_getCentroid_poly_big_and_small(t) {
+ t.plan(3);
+
+ coll = new OpenLayers.Geometry.Collection();
+ // polygon w/area=1, centroid=0.5,0.5
+ coll.addComponent(
+ new OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(0,0),
+ new OpenLayers.Geometry.Point(0,1),
+ new OpenLayers.Geometry.Point(1,1),
+ new OpenLayers.Geometry.Point(1,0)
+ ])
+ ])
+ );
+
+ // since the polygon above has an area of 1 and this
+ // polygon has an area of 4, the center is weighted 20% toward
+ // the first polygon
+
+ // polygon w/area=4, centroid=5.5,5.5
+ coll.addComponent(
+ new OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(4.5,-0.5),
+ new OpenLayers.Geometry.Point(4.5,1.5),
+ new OpenLayers.Geometry.Point(6.5,1.5),
+ new OpenLayers.Geometry.Point(6.5,-0.5)
+ ])
+ ])
+ );
+
+ centroid = coll.getCentroid(true);
+ t.ok(centroid != null, 'The centroid is not null.');
+ t.eq(centroid.x, 4.5, 'The centroid x coordinate is good.');
+ t.eq(centroid.y, 0.5, 'The centroid y coordinate is good.');
+
+ coll.destroy();
+ }
+
+ function test_avoid_infinite_recursion(t) {
+ t.plan(1);
+
+ var g = new OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing(),
+ new OpenLayers.Geometry.LinearRing()
+ ]);
+ var bounds;
+ try {
+ bounds = g.getBounds();
+ t.eq(bounds, null, "Polygon with empty linear ring has null bounds");
+ } catch (err) {
+ t.fail("Failed to get bounds of polygon with empty linear ring: " + err.message);
+ }
+
+ }
+
+
+ function test_Collection_destroy(t) {
+ t.plan( 3 );
+ coll = new OpenLayers.Geometry.Collection();
+ coll.addComponents(new OpenLayers.Geometry.Point(0,0));
+ coll.addComponents(new OpenLayers.Geometry.Point(10,10));
+ coll.getBounds();
+ coll.destroy();
+
+ t.ok(coll.components == null, "components array cleared");
+ t.ok(coll.getBounds() == null, "bounds is cleared");
+ t.ok(coll.id == null, "id is cleared");
+
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Geometry/Curve.html b/misc/openlayers/tests/Geometry/Curve.html
new file mode 100644
index 0000000..5afebdf
--- /dev/null
+++ b/misc/openlayers/tests/Geometry/Curve.html
@@ -0,0 +1,157 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ var curve;
+ var components = [new OpenLayers.Geometry.Point(10,10),
+ new OpenLayers.Geometry.Point(0,0)];
+
+ function test_Curve_constructor (t) {
+ t.plan( 3 );
+ curve = new OpenLayers.Geometry.Curve();
+ t.ok( curve instanceof OpenLayers.Geometry.Curve, "new OpenLayers.Geometry.Curve returns curve object" );
+ t.eq( curve.CLASS_NAME, "OpenLayers.Geometry.Curve", "curve.CLASS_NAME is set correctly");
+ t.eq( curve.components, [], "curve.components is set correctly");
+ }
+
+ function test_Curve_constructor (t) {
+ t.plan( 2 );
+ curve = new OpenLayers.Geometry.Curve(components);
+ t.ok( curve instanceof OpenLayers.Geometry.Curve, "new OpenLayers.Geometry.Curve returns curve object" );
+ t.eq( curve.components.length, 2, "curve.components.length is set correctly");
+ }
+
+ function test_Curve_clone (t) {
+ t.plan( 2 );
+ curve = new OpenLayers.Geometry.Curve(components);
+ curve2 = curve.clone();
+ t.ok( curve2 instanceof OpenLayers.Geometry.Curve, "curve.clone() returns curve object" );
+ t.eq( curve2.components.length, 2, "curve2.components.length is set correctly");
+ }
+
+ function test_Curve_calculateBounds(t) {
+ t.plan( 17 );
+
+
+ var curve = new OpenLayers.Geometry.Curve();
+ curve.calculateBounds();
+ t.eq(curve.bounds, null, "bounds null when no components");
+
+ var p1 = new OpenLayers.Geometry.Point(10,20);
+ var p2 = new OpenLayers.Geometry.Point(30,40);
+
+ var components = [p1, p2];
+ var curve = new OpenLayers.Geometry.Curve(components);
+
+ curve.calculateBounds();
+
+ t.eq(curve.bounds.left, 10, "good left bounds");
+ t.eq(curve.bounds.bottom, 20, "good bottom bounds");
+ t.eq(curve.bounds.right, 30, "good right bounds");
+ t.eq(curve.bounds.top, 40, "good top bounds");
+
+ var newPoint = new OpenLayers.Geometry.Point(60,70);
+ curve.addComponent(newPoint);
+ curve.calculateBounds();
+
+ t.eq(curve.bounds.left, 10, "good left bounds");
+ t.eq(curve.bounds.bottom, 20, "good bottom bounds");
+ t.eq(curve.bounds.right, 60, "good right bounds");
+ t.eq(curve.bounds.top, 70, "good top bounds");
+
+ //nullifying the bounds
+
+ //before calculation
+ curve = new OpenLayers.Geometry.Curve(components);
+ curve.bounds = null;
+ curve.calculateBounds();
+
+ t.eq(curve.bounds.left, 10, "good left bounds");
+ t.eq(curve.bounds.bottom, 20, "good bottom bounds");
+ t.eq(curve.bounds.right, 30, "good right bounds");
+ t.eq(curve.bounds.top, 40, "good top bounds");
+
+ //before addComponent
+ curve.bounds = null;
+ curve.addComponent(newPoint);
+ curve.calculateBounds();
+
+ t.eq(curve.bounds.left, 10, "good left bounds");
+ t.eq(curve.bounds.bottom, 20, "good bottom bounds");
+ t.eq(curve.bounds.right, 60, "good right bounds");
+ t.eq(curve.bounds.top, 70, "good top bounds");
+
+ }
+
+ function test_Curve_addComponent (t) {
+ t.plan( 8 );
+ curve = new OpenLayers.Geometry.Curve(components);
+ curve.addComponent(new OpenLayers.Geometry.Point(20,30));
+ bounds = curve.getBounds();
+ t.eq( curve.components.length, 3, "new point added to array" );
+ t.eq( bounds.top, 30, "top bound is 30 after addComponent" );
+ t.eq( bounds.right, 20, "right bound is 20 after addComponent" );
+ curve.addComponent(new OpenLayers.Geometry.Point(-20,-30), 1);
+ bounds = curve.getBounds();
+ t.eq( curve.components.length, 4, "new point added to array" );
+ t.eq( bounds.bottom, -30, "bottom bound is -30 after 2nd addComponent" );
+ t.eq( bounds.left, -20, "left bound is 20 after 2nd addComponent" );
+ t.eq( curve.components[1].x, -20, "new point.lon is -20 (index worked)" );
+ t.eq( curve.components[1].y, -30, "new point.lat is -30 (index worked)" );
+ }
+
+ function test_Curve_removeComponent (t) {
+ t.plan( 4 );
+ curve = new OpenLayers.Geometry.Curve(components);
+ curve.removeComponent(curve.components[1]);
+ t.eq( curve.components.length, 1, "curve.components.length is smaller after removeComponent" );
+ t.eq( curve.bounds, null, "curve.bounds nullified after removeComponent (for recalculation)" );
+ bounds = curve.getBounds();
+ t.eq( bounds.left, 10, "left bound is 10 after removeComponent" );
+ t.eq( bounds.bottom, 10, "bottom bound is 10 after removeComponent" );
+ }
+
+ function test_Curve_getLength (t) {
+ t.plan( 4 );
+
+ //no components
+ curve = new OpenLayers.Geometry.Curve();
+ curve.components = null;
+ t.eq(curve.getLength(), 0, "curve with no components has length 0");
+
+ //empty components
+ curve.components = [];
+ t.eq(curve.getLength(), 0, "curve with empty components has length 0");
+
+ //single point curve
+ curve.components = [ new OpenLayers.Geometry.Point(0,0) ];
+ t.eq(curve.getLength(), 0, "curve with only one point has length 0");
+
+ //multipoint
+ var newcomponents = [ new OpenLayers.Geometry.Point(0,0),
+ new OpenLayers.Geometry.Point(0,10),
+ new OpenLayers.Geometry.Point(20,10),
+ new OpenLayers.Geometry.Point(20,-10)
+ ];
+
+ curve = new OpenLayers.Geometry.Curve(newcomponents);
+ t.eq(curve.getLength(), 50, "curve.getLength returns a reasonably accurate length" );
+ }
+
+ function test_Curve_destroy(t) {
+ t.plan(1);
+
+ var curve = new OpenLayers.Geometry.Curve();
+ curve.components = {};
+
+ curve.destroy();
+
+ t.ok( curve.components == null, "components is cleared well in destruction");
+ }
+
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Geometry/LineString.html b/misc/openlayers/tests/Geometry/LineString.html
new file mode 100644
index 0000000..4b2ec0e
--- /dev/null
+++ b/misc/openlayers/tests/Geometry/LineString.html
@@ -0,0 +1,443 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ var line;
+ var components = [new OpenLayers.Geometry.Point(10,15),
+ new OpenLayers.Geometry.Point(0,0)];
+
+ function test_LineString_constructor (t) {
+ t.plan( 3 );
+ line = new OpenLayers.Geometry.LineString();
+ t.ok( line instanceof OpenLayers.Geometry.LineString, "new OpenLayers.Geometry.LineString returns line object" );
+ t.eq( line.CLASS_NAME, "OpenLayers.Geometry.LineString", "line.CLASS_NAME is set correctly");
+ t.eq( line.components, [], "line.components is set correctly");
+ }
+
+ function test_LineString_constructor (t) {
+ t.plan( 3 );
+ line = new OpenLayers.Geometry.LineString(components);
+ t.ok( line instanceof OpenLayers.Geometry.LineString, "new OpenLayers.Geometry.LineString returns line object" );
+ t.eq( line.CLASS_NAME, "OpenLayers.Geometry.LineString", "line.CLASS_NAME is set correctly");
+ // TBD FIXME, recursion
+ // t.eq( line.components, components, "line.components is set correctly");
+ t.eq( line.components.length, 2, "line.components.length is set correctly");
+ }
+
+ function test_LineString_toString(t) {
+ t.plan(1);
+
+ line = new OpenLayers.Geometry.LineString(components);
+ t.eq(line.toString(),
+ "LINESTRING(10 15,0 0)",
+ "toString() returns WKT");
+ }
+
+ function test_LineString_removeComponent(t) {
+ t.plan(2);
+
+ OpenLayers.Geometry.Collection.prototype._removeComponent =
+ OpenLayers.Geometry.Collection.prototype.removeComponent;
+ OpenLayers.Geometry.Collection.prototype.removeComponent =
+ function(point) { g_removeComponent = point; };
+
+ line = new OpenLayers.Geometry.LineString(components);
+
+ g_removeComponent = null;
+ line.removeComponent(components[0]);
+ t.ok(g_removeComponent == null, "point not removed if only 2 points in components");
+
+ line.components.push(new OpenLayers.Geometry.Point(4,4));
+ line.removeComponent(components[0]);
+ t.ok(g_removeComponent, components[0], "point removed if 3 points in components");
+
+ OpenLayers.Geometry.Collection.prototype.removeComponent =
+ OpenLayers.Geometry.Collection.prototype._removeComponent;
+ }
+
+ function test_LineString_move(t) {
+ t.plan(4);
+
+ var components = [new OpenLayers.Geometry.Point(10,15),
+ new OpenLayers.Geometry.Point(0,0)];
+ var line = new OpenLayers.Geometry.LineString(components);
+
+ var x0 = components[0].x;
+ var y0 = components[0].y;
+ var x1 = components[1].x;
+ var y1 = components[1].y;
+
+ var dx = 10 * Math.random();
+ var dy = 10 * Math.random();
+ line.move(dx, dy);
+
+ t.eq(line.components[0].x, x0 + dx, "move() correctly modifies first x");
+ t.eq(line.components[0].y, y0 + dy, "move() correctly modifies first y");
+ t.eq(line.components[1].x, x1 + dx, "move() correctly modifies second x");
+ t.eq(line.components[1].y, y1 + dy, "move() correctly modifies second y");
+ }
+
+ function test_LineString_rotate(t) {
+ t.plan(6);
+
+ var components = [new OpenLayers.Geometry.Point(10,15),
+ new OpenLayers.Geometry.Point(0,0)];
+ var geometry = new OpenLayers.Geometry.LineString(components);
+
+ var originals = [];
+ var comp;
+ var angle = 2 * Math.PI * Math.random();
+ var origin = new OpenLayers.Geometry.Point(10 * Math.random(),
+ 10 * Math.random());
+ for(var i=0; i<geometry.components.length; ++i) {
+ comp = geometry.components[i];
+ originals[i] = comp.rotate;
+ comp.rotate = function(a, o) {
+ t.ok(true, "rotate called for component " + i);
+ t.ok(a == angle, "rotate called with correct angle");
+ t.ok(o == origin, "rotate called with correct origin");
+ }
+ }
+ geometry.rotate(angle, origin);
+
+ // restore the original rotate defs
+ for(var i=0; i<geometry.components.length; ++i) {
+ comp.rotate = originals[i];
+ }
+ }
+
+ function test_LineString_resize(t) {
+ t.plan(8);
+
+ var tolerance = 1e-10;
+
+ var components = [new OpenLayers.Geometry.Point(10 * Math.random(),
+ 10 * Math.random()),
+ new OpenLayers.Geometry.Point(10 * Math.random(),
+ 10 * Math.random())];
+ var geometry = new OpenLayers.Geometry.LineString(components);
+
+ var origin = new OpenLayers.Geometry.Point(10 * Math.random(),
+ 10 * Math.random());
+
+ var scale = 10 * Math.random();
+
+ var oldLength = geometry.getLength();
+ var ret = geometry.resize(scale, origin);
+ t.ok(ret === geometry, "resize returns geometry");
+ var newLength = geometry.getLength();
+ t.ok((((newLength / oldLength) - scale) / scale) < tolerance,
+ "resize correctly changes the length of a linestring")
+
+ var originals = [];
+ var comp;
+ for(var i=0; i<geometry.components.length; ++i) {
+ comp = geometry.components[i];
+ originals[i] = comp.resize;
+ comp.resize = function(s, o) {
+ t.ok(true, "resize called for component " + i);
+ t.ok(s == scale, "resize called with correct scale");
+ t.ok(o == origin, "resize called with correct origin");
+ }
+ }
+ geometry.resize(scale, origin);
+
+ // restore the original resize defs
+ for(var i=0; i<geometry.components.length; ++i) {
+ comp.resize = originals[i];
+ }
+
+ }
+
+ function test_split(t) {
+ var wkt = OpenLayers.Geometry.fromWKT;
+
+ var cases = [{
+ msg: "no intersection",
+ g1: "LINESTRING(0 0, 0 1)",
+ g2: "LINESTRING(1 0, 1 1)",
+ exp: null
+ } , {
+ msg: "intersection at midpoint",
+ g1: "LINESTRING(0 0, 1 1)",
+ g2: "LINESTRING(1 0, 0 1)",
+ exp: ["LINESTRING(1 0, 0.5 0.5)", "LINESTRING(0.5 0.5, 0 1)"]
+ }, {
+ msg: "intersection at midpoint (reverse source/target)",
+ g1: "LINESTRING(1 0, 0 1)",
+ g2: "LINESTRING(0 0, 1 1)",
+ exp: ["LINESTRING(0 0, 0.5 0.5)", "LINESTRING(0.5 0.5, 1 1)"]
+ }, {
+ msg: "intersection at endpoint",
+ g1: "LINESTRING(0 0, 1 1)",
+ g2: "LINESTRING(1 0, 1 1)",
+ exp: null
+ }, {
+ msg: "midpoint intersection, no options",
+ g1: "LINESTRING(0 0, 2 2)",
+ g2: "LINESTRING(0 2, 2 0)",
+ exp: ["LINESTRING(0 2, 1 1)", "LINESTRING(1 1, 2 0)"]
+ }, {
+ msg: "midpoint intersection, edge false",
+ opt: {edge: false},
+ g1: "LINESTRING(0 0, 2 2)",
+ g2: "LINESTRING(0 2, 2 0)",
+ exp: null
+ }, {
+ msg: "midpoint intersection, mutual",
+ opt: {mutual: true},
+ g1: "LINESTRING(0 0, 2 2)",
+ g2: "LINESTRING(0 2, 2 0)",
+ exp: [["LINESTRING(0 0, 1 1)", "LINESTRING(1 1, 2 2)"], ["LINESTRING(0 2, 1 1)", "LINESTRING(1 1, 2 0)"]]
+ }, {
+ msg: "close intersection, no tolerance",
+ g1: "LINESTRING(0 0, 0.9 0.9)",
+ g2: "LINESTRING(0 2, 2 0)",
+ exp: null
+ }, {
+ msg: "close intersection, within tolerance",
+ opt: {tolerance: 0.2},
+ g1: "LINESTRING(0 0, 0.9 0.9)",
+ g2: "LINESTRING(0 2, 2 0)",
+ exp: ["LINESTRING(0 2, 0.9 0.9)", "LINESTRING(0.9 0.9, 2 0)"]
+ }];
+
+ t.plan(cases.length);
+ var c, parts, part, midparts;
+ for(var i=0; i<cases.length; ++i) {
+ c = cases[i];
+ var g1 = wkt(c.g1);
+ var g2 = wkt(c.g2);
+ var got = g1.split(g2, c.opt);
+ var exp = c.exp;
+ if(got instanceof Array) {
+ parts = [];
+ for(var j=0; j<got.length; ++j) {
+ part = got[j];
+ if(part instanceof Array) {
+ midparts = [];
+ for(var k=0; k<part.length; ++k) {
+ midparts.push(part[k].toString());
+ }
+ parts.push("[" + midparts.join(", ") + "]");
+ } else {
+ parts.push(got[j].toString());
+ }
+ }
+ got = parts.join(", ");
+ }
+ if(exp instanceof Array) {
+ parts = [];
+ for(var j=0; j<exp.length; ++j) {
+ part = exp[j];
+ if(part instanceof Array) {
+ midparts = [];
+ for(var k=0; k<part.length; ++k) {
+ midparts.push(wkt(part[k]).toString());
+ }
+ parts.push("[" + midparts.join(", ") + "]");
+ } else {
+ parts.push(wkt(exp[j]).toString());
+ }
+ }
+ exp = parts.join(", ");
+ }
+ t.eq(got, exp, "case " + i + ": " + c.msg);
+ }
+
+ }
+
+
+ function test_distanceTo(t) {
+ var wkt = OpenLayers.Geometry.fromWKT;
+ var geoms = [
+ wkt("POINT(0 0)"),
+ wkt("LINESTRING(-2 0, 0 -2, 2 -1, 2 0)")
+ ];
+
+ var cases = [{
+ got: geoms[1].distanceTo(geoms[0]),
+ expected: Math.sqrt(2)
+ }, {
+ got: geoms[1].distanceTo(geoms[0], {details: true}),
+ expected: {
+ distance: Math.sqrt(2),
+ x0: -1, y0: -1,
+ x1: 0, y1: 0
+ }
+ }];
+
+ t.plan(cases.length);
+ for(var i=0; i<cases.length; ++i) {
+ t.eq(cases[i].got, cases[i].expected, "case " + i);
+ }
+
+ }
+
+ function test_LineString_equals(t) {
+ t.plan(3);
+
+ var x0 = Math.random() * 100;
+ var y0 = Math.random() * 100;
+ var x1 = Math.random() * 100;
+ var y1 = Math.random() * 100;
+ var point0 = new OpenLayers.Geometry.Point(x0, y0);
+ var point1 = new OpenLayers.Geometry.Point(x1, y1);
+ var geometry = new OpenLayers.Geometry.LineString([point0, point1]);
+ var equal = new OpenLayers.Geometry.LineString([point0, point1]);
+ var offX = new OpenLayers.Geometry.LineString([
+ new OpenLayers.Geometry.Point(x0 + 1, y0),
+ new OpenLayers.Geometry.Point(x1 + 1, y1)]);
+ var offY = new OpenLayers.Geometry.LineString([
+ new OpenLayers.Geometry.Point(x0, y0 + 1),
+ new OpenLayers.Geometry.Point(x1, y1 + 1)]);
+ t.ok(geometry.equals(equal),
+ "equals() returns true for a geometry with equivalent coordinates");
+ t.ok(!geometry.equals(offX),
+ "equals() returns false for a geometry with offset x");
+ t.ok(!geometry.equals(offY),
+ "equals() returns false for a geometry with offset y");
+ }
+
+
+ function test_getVertices(t) {
+ t.plan(14);
+
+ var points = [
+ new OpenLayers.Geometry.Point(10, 20),
+ new OpenLayers.Geometry.Point(20, 30),
+ new OpenLayers.Geometry.Point(30, 40),
+ new OpenLayers.Geometry.Point(40, 50)
+ ];
+ var line = new OpenLayers.Geometry.LineString(points);
+
+ var verts = line.getVertices();
+ t.ok(verts instanceof Array, "got back an array");
+ t.eq(verts.length, points.length, "of correct length length");
+ t.geom_eq(verts[0], points[0], "0: correct geometry");
+ t.geom_eq(verts[1], points[1], "1: correct geometry");
+ t.geom_eq(verts[2], points[2], "2: correct geometry");
+ t.geom_eq(verts[3], points[3], "3: correct geometry");
+
+ // get nodes only
+ var nodes = line.getVertices(true);
+ t.ok(nodes instanceof Array, "[nodes only] got back an array");
+ t.eq(nodes.length, 2, "[nodes only] of correct length length");
+ t.geom_eq(nodes[0], points[0], "[nodes only] first: correct geometry");
+ t.geom_eq(nodes[1], points[points.length-1], "[nodes only] last: correct geometry");
+
+ // no nodes
+ var nodes = line.getVertices(false);
+ t.ok(nodes instanceof Array, "[no nodes] got back an array");
+ t.eq(nodes.length, 2, "[no nodes] of correct length length");
+ t.geom_eq(nodes[0], points[1], "[no nodes] first: correct geometry");
+ t.geom_eq(nodes[1], points[2], "[no nodes] last: correct geometry");
+
+ }
+
+
+ function test_LineString_clone(t) {
+ t.plan(2);
+
+ var x0 = Math.random() * 100;
+ var y0 = Math.random() * 100;
+ var x1 = Math.random() * 100;
+ var y1 = Math.random() * 100;
+ var point0 = new OpenLayers.Geometry.Point(x0, y0);
+ var point1 = new OpenLayers.Geometry.Point(x1, y1);
+ var geometry = new OpenLayers.Geometry.LineString([point0, point1]);
+ var clone = geometry.clone();
+ t.ok(clone instanceof OpenLayers.Geometry.LineString,
+ "clone() creates an OpenLayers.Geometry.LineString");
+ t.ok(geometry.equals(clone), "clone has equivalent coordinates");
+ }
+
+ function test_getGeodesicLength(t) {
+
+ // expected values from http://www.movable-type.co.uk/scripts/latlong-vincenty.html
+ var cases = [{
+ wkt: "LINESTRING(0 0, -10 45)",
+ exp: 5081689.690
+ }, {
+ wkt: "LINESTRING(-10 45, 0 0)",
+ exp: 5081689.690
+ }, {
+ wkt: "LINESTRING(0 0, -10 45, -20 50)",
+ exp: 5081689.690 + 935018.062
+ }];
+ t.plan(cases.length);
+
+ var geom, got;
+ for(var i=0; i<cases.length; ++i) {
+ geom = new OpenLayers.Geometry.fromWKT(cases[i].wkt);
+ got = geom.getGeodesicLength();
+ t.eq(Math.round(got), Math.round(cases[i].exp), "[case " + i + "] length calculated");
+ }
+
+ }
+
+ function test_LineString_simplify(t){
+ t.plan(8);
+ var ls1 = new OpenLayers.Geometry.LineString([
+ new OpenLayers.Geometry.Point(0,0),
+ new OpenLayers.Geometry.Point(1,2.1),
+ new OpenLayers.Geometry.Point(1.8,3.8),
+ new OpenLayers.Geometry.Point(2,4),
+ new OpenLayers.Geometry.Point(3,4),
+ new OpenLayers.Geometry.Point(4,4.5),
+ new OpenLayers.Geometry.Point(5,5)
+
+ ]);
+ var ls2 = new OpenLayers.Geometry.LineString([
+ new OpenLayers.Geometry.Point(0,0),
+ new OpenLayers.Geometry.Point(1,2.1),
+ new OpenLayers.Geometry.Point(1.8,3.8),
+ new OpenLayers.Geometry.Point(2,4),
+ new OpenLayers.Geometry.Point(3,4),
+ new OpenLayers.Geometry.Point(4,4.5),
+ new OpenLayers.Geometry.Point(5,5),
+ new OpenLayers.Geometry.Point(0,0)
+
+ ]);
+ var ls3 = new OpenLayers.Geometry.LineString([
+ new OpenLayers.Geometry.Point(0,0),
+ new OpenLayers.Geometry.Point(1,1)
+ ]);
+ var ls5 = new OpenLayers.Geometry.LineString([
+ new OpenLayers.Geometry.Point(0,0),
+ new OpenLayers.Geometry.Point(1,1),
+ new OpenLayers.Geometry.Point(2,2),
+ new OpenLayers.Geometry.Point(3,3),
+ new OpenLayers.Geometry.Point(4,4),
+ new OpenLayers.Geometry.Point(5,5)
+
+ ]);
+ var ls6 = new OpenLayers.Geometry.LineString([
+ new OpenLayers.Geometry.Point(0,0),
+ new OpenLayers.Geometry.Point(1,1),
+ new OpenLayers.Geometry.Point(1,1),
+ new OpenLayers.Geometry.Point(3,2)
+ ]);
+
+ t.ok(ls1 instanceof OpenLayers.Geometry.LineString, 'LineString is instance of OpenLayers.Geometry.LineString');
+ var simplified1 = ls1.simplify(0.5);
+ t.ok(simplified1 instanceof OpenLayers.Geometry.LineString, 'Simplified LineString is instance of OpenLayers.Geometry.LineString');
+ t.ok(simplified1.getVertices().length <= ls1.getVertices().length, 'Simplified LineString has less or equal number of vertices');
+ // The simplified version is derived from PostGIS function ST_SIMPLIFY()
+ t.ok(simplified1.toString() === 'LINESTRING(0 0,1.8 3.8,5 5)', 'LineString 1 was simplified correctly');
+ var simplified2 = ls2.simplify(0.5);
+ // The simplified version is derived from PostGIS function ST_SIMPLIFY()
+ t.ok(simplified2.toString() === 'LINESTRING(0 0,1.8 3.8,5 5,0 0)', 'LineString 2 was simplified correctly');
+ var simplified3 = ls3.simplify(0.5);
+ t.ok(simplified3.toString() === ls3.toString(), 'LineString with 2 vertices is left untouched');
+ var simplified5 = ls5.simplify(0.0);
+ t.ok(simplified5.toString() === 'LINESTRING(0 0,5 5)', 'A tolerance of 0 returns the optimized version needless vertices');
+ var simplified6 = ls6.simplify(0.0);
+ t.ok(simplified6.toString() === 'LINESTRING(0 0,1 1,3 2)', 'A tolerance of 0 returns the optimized version without doubled vertices');
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
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>
diff --git a/misc/openlayers/tests/Geometry/MultiLineString.html b/misc/openlayers/tests/Geometry/MultiLineString.html
new file mode 100644
index 0000000..34a6e65
--- /dev/null
+++ b/misc/openlayers/tests/Geometry/MultiLineString.html
@@ -0,0 +1,267 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ var line;
+
+ function test_MultiLineString_constructor (t) {
+ t.plan( 3 );
+ mline = new OpenLayers.Geometry.MultiLineString();
+ t.ok( mline instanceof OpenLayers.Geometry.MultiLineString, "new OpenLayers.Geometry.MultiLineString returns mline object" );
+ t.eq( mline.CLASS_NAME, "OpenLayers.Geometry.MultiLineString", "mline.CLASS_NAME is set correctly");
+ t.eq( mline.components, [], "line.components is set correctly");
+ }
+
+ function test_MultiLineString_constructor (t) {
+ t.plan( 3 );
+ line = new OpenLayers.Geometry.LineString();
+ mline = new OpenLayers.Geometry.MultiLineString(line);
+ t.ok( mline instanceof OpenLayers.Geometry.MultiLineString, "new OpenLayers.Geometry.MultiLineString returns mline object" );
+ t.eq( mline.CLASS_NAME, "OpenLayers.Geometry.MultiLineString", "mline.CLASS_NAME is set correctly");
+ t.eq( mline.components.length, 1, "mline.components.length is set correctly");
+ }
+
+ function test_split(t) {
+ var wkt = OpenLayers.Geometry.fromWKT;
+
+ var cases = [{
+ msg: "no intersection",
+ g1: "MULTILINESTRING((0 0, 0 1), (2 2, 3 3))",
+ g2: "MULTILINESTRING((1 0, 1 1), (2 2, 3 2))",
+ exp: null
+ } , {
+ msg: "intersection at midpoint",
+ g1: "MULTILINESTRING((0 0, 1 1))",
+ g2: "MULTILINESTRING((1 0, 0 1))",
+ exp: ["MULTILINESTRING((1 0, 0.5 0.5))", "MULTILINESTRING((0.5 0.5, 0 1))"]
+ }, {
+ msg: "intersection at midpoint (reverse source/target)",
+ g1: "MULTILINESTRING((1 0, 0 1))",
+ g2: "MULTILINESTRING((0 0, 1 1))",
+ exp: ["MULTILINESTRING((0 0, 0.5 0.5))", "MULTILINESTRING((0.5 0.5, 1 1))"]
+ }, {
+ msg: "intersection at endpoint",
+ g1: "MULTILINESTRING((0 0, 1 1))",
+ g2: "MULTILINESTRING((1 0, 1 1))",
+ exp: null
+ }, {
+ msg: "midpoint intersection, no options",
+ g1: "MULTILINESTRING((0 0, 2 2))",
+ g2: "MULTILINESTRING((0 2, 2 0))",
+ exp: ["MULTILINESTRING((0 2, 1 1))", "MULTILINESTRING((1 1, 2 0))"]
+ }, {
+ msg: "midpoint intersection, edge false",
+ opt: {edge: false},
+ g1: "MULTILINESTRING((0 0, 2 2))",
+ g2: "MULTILINESTRING((0 2, 2 0))",
+ exp: null
+ }, {
+ msg: "midpoint intersection, mutual",
+ opt: {mutual: true},
+ g1: "MULTILINESTRING((0 0, 2 2))",
+ g2: "MULTILINESTRING((0 2, 2 0))",
+ exp: [["MULTILINESTRING((0 0, 1 1))", "MULTILINESTRING((1 1, 2 2))"], ["MULTILINESTRING((0 2, 1 1))", "MULTILINESTRING((1 1, 2 0))"]]
+ }, {
+ msg: "close intersection, no tolerance",
+ g1: "MULTILINESTRING((0 0, 0.9 0.9))",
+ g2: "MULTILINESTRING((0 2, 2 0))",
+ exp: null
+ }, {
+ msg: "close intersection, within tolerance",
+ opt: {tolerance: 0.2},
+ g1: "MULTILINESTRING((0 0, 0.9 0.9))",
+ g2: "MULTILINESTRING((0 2, 2 0))",
+ exp: ["MULTILINESTRING((0 2, 0.9 0.9))", "MULTILINESTRING((0.9 0.9, 2 0))"]
+ }, {
+ msg: "multi source, single target",
+ g1: "MULTILINESTRING((0 0, 2 2))",
+ g2: "LINESTRING(0 2, 2 0)",
+ exp: ["LINESTRING(0 2, 1 1)", "LINESTRING(1 1, 2 0)"]
+ }, {
+ msg: "multi source, single target, mutual split",
+ opt: {mutual: true},
+ g1: "MULTILINESTRING((0 0, 2 2))",
+ g2: "LINESTRING(0 2, 2 0)",
+ exp: [["MULTILINESTRING((0 0, 1 1))", "MULTILINESTRING((1 1, 2 2))"], ["LINESTRING(0 2, 1 1)", "LINESTRING(1 1, 2 0)"]]
+ }, {
+ msg: "single source, multi target",
+ g1: "LINESTRING(0 2, 2 0)",
+ g2: "MULTILINESTRING((0 0, 2 2))",
+ exp: ["MULTILINESTRING((0 0, 1 1))", "MULTILINESTRING((1 1, 2 2))"]
+ }, {
+ msg: "partial target split",
+ g1: "MULTILINESTRING((2 0, 0 2))",
+ g2: "MULTILINESTRING((0 0, 2 2), (3 3, 4 4))",
+ exp: ["MULTILINESTRING((0 0, 1 1))", "MULTILINESTRING((1 1, 2 2), (3 3, 4 4))"]
+ }, {
+ msg: "partial target split, mutual true",
+ opt: {mutual: true},
+ g1: "MULTILINESTRING((2 0, 0 2))",
+ g2: "MULTILINESTRING((0 0, 2 2), (3 3, 4 4))",
+ exp: [["MULTILINESTRING((2 0, 1 1))", "MULTILINESTRING((1 1, 0 2))"], ["MULTILINESTRING((0 0, 1 1))", "MULTILINESTRING((1 1, 2 2), (3 3, 4 4))"]]
+ }, {
+ msg: "partial source split, mutual true",
+ opt: {mutual: true},
+ g1: "MULTILINESTRING((0 0, 2 2), (3 3, 4 4))",
+ g2: "MULTILINESTRING((2 0, 0 2))",
+ exp: [["MULTILINESTRING((0 0, 1 1))", "MULTILINESTRING((1 1, 2 2), (3 3, 4 4))"], ["MULTILINESTRING((2 0, 1 1))", "MULTILINESTRING((1 1, 0 2))"]]
+ }, {
+ msg: "partial target split with source endpoint",
+ g1: "MULTILINESTRING((1 0, 1 1))",
+ g2: "MULTILINESTRING((0 0, 2 2), (3 3, 4 4))",
+ exp: ["MULTILINESTRING((0 0, 1 1))", "MULTILINESTRING((1 1, 2 2), (3 3, 4 4))"]
+ }, {
+ msg: "partial target split with source endpoint, mutual true",
+ opt: {mutual: true},
+ g1: "MULTILINESTRING((5 5, 6 6), (1 0, 1 1))",
+ g2: "MULTILINESTRING((0 0, 2 2), (3 3, 4 4))",
+ exp: [[], ["MULTILINESTRING((0 0, 1 1))", "MULTILINESTRING((1 1, 2 2), (3 3, 4 4))"]]
+ }, {
+ msg: "partial source split with target endpoint",
+ g1: "MULTILINESTRING((0 0, 2 2), (3 3, 4 4))",
+ g2: "MULTILINESTRING((1 0, 1 1))",
+ exp: null
+ }, {
+ msg: "partial source split with target endpoint, mutual true",
+ opt: {mutual: true},
+ g1: "MULTILINESTRING((0 0, 2 2), (3 3, 4 4), (5 5, 6 6))",
+ g2: "MULTILINESTRING((1 0, 1 1))",
+ exp: [["MULTILINESTRING((0 0, 1 1))", "MULTILINESTRING((1 1, 2 2), (3 3, 4 4), (5 5, 6 6))"], []]
+ }, {
+ msg: "partial target and source split",
+ g1: "MULTILINESTRING((0 5, 2 5), (4 5, 6 5), (8 5, 10 5))",
+ g2: "MULTILINESTRING((5 0, 5 2), (5 4, 5 6), (5 8, 5 10))",
+ exp: ["MULTILINESTRING((5 0, 5 2), (5 4, 5 5))", "MULTILINESTRING((5 5, 5 6), (5 8, 5 10))"]
+ }, {
+ msg: "partial target and source split, mutual true",
+ opt: {mutual: true},
+ g1: "MULTILINESTRING((0 5, 2 5), (4 5, 6 5), (8 5, 10 5))",
+ g2: "MULTILINESTRING((5 0, 5 2), (5 4, 5 6), (5 8, 5 10))",
+ exp: [["MULTILINESTRING((0 5, 2 5), (4 5, 5 5))", "MULTILINESTRING((5 5, 6 5), (8 5, 10 5))"],
+ ["MULTILINESTRING((5 0, 5 2), (5 4, 5 5))", "MULTILINESTRING((5 5, 5 6), (5 8, 5 10))"]]
+ }, {
+ msg: "partial target and source split with source endpoint, mutual true",
+ opt: {mutual: true},
+ g1: "MULTILINESTRING((0 5, 2 5), (4 5, 6 5), (8 5, 10 5))",
+ g2: "MULTILINESTRING((4 0, 4 2), (4 4, 4 6), (4 8, 4 10))",
+ exp: [[], ["MULTILINESTRING((4 0, 4 2), (4 4, 4 5))", "MULTILINESTRING((4 5, 4 6), (4 8, 4 10))"]]
+ }, {
+ msg: "partial target and source split with target endpoint, mutual true",
+ opt: {mutual: true},
+ g1: "MULTILINESTRING((4 0, 4 2), (4 4, 4 6), (4 8, 4 10))",
+ g2: "MULTILINESTRING((0 5, 2 5), (4 5, 6 5), (8 5, 10 5))",
+ exp: [["MULTILINESTRING((4 0, 4 2), (4 4, 4 5))", "MULTILINESTRING((4 5, 4 6), (4 8, 4 10))"], []]
+ }, {
+ msg: "partial target and source split with source vertex, mutual true",
+ opt: {mutual: true},
+ g1: "MULTILINESTRING((0 5, 2 5), (4 5, 5 5, 6 5), (8 5, 10 5))",
+ g2: "MULTILINESTRING((5 0, 5 2), (5 4, 5 6), (5 8, 5 10))",
+ exp: [["MULTILINESTRING((0 5, 2 5), (4 5, 5 5))", "MULTILINESTRING((5 5, 6 5), (8 5, 10 5))"], ["MULTILINESTRING((5 0, 5 2), (5 4, 5 5))", "MULTILINESTRING((5 5, 5 6), (5 8, 5 10))"]]
+ }, {
+ msg: "partial target and source split with target vertex, mutual true",
+ opt: {mutual: true},
+ g1: "MULTILINESTRING((5 0, 5 2), (5 4, 5 6), (5 8, 5 10))",
+ g2: "MULTILINESTRING((0 5, 2 5), (4 5, 5 5, 6 5), (8 5, 10 5))",
+ exp: [["MULTILINESTRING((5 0, 5 2), (5 4, 5 5))", "MULTILINESTRING((5 5, 5 6), (5 8, 5 10))"], ["MULTILINESTRING((0 5, 2 5), (4 5, 5 5))", "MULTILINESTRING((5 5, 6 5), (8 5, 10 5))"]]
+ }];
+
+
+ t.plan(cases.length);
+ var c, parts, part, midparts;
+ for(var i=0; i<cases.length; ++i) {
+ c = cases[i];
+ var g1 = wkt(c.g1);
+ var g2 = wkt(c.g2);
+ var got = g1.split(g2, c.opt);
+ var exp = c.exp;
+ if(got instanceof Array) {
+ parts = [];
+ for(var j=0; j<got.length; ++j) {
+ part = got[j];
+ if(part instanceof Array) {
+ midparts = [];
+ for(var k=0; k<part.length; ++k) {
+ midparts.push(part[k].toString());
+ }
+ parts.push("[" + midparts.join(", ") + "]");
+ } else {
+ parts.push(got[j].toString());
+ }
+ }
+ got = parts.join(", ");
+ }
+ if(exp instanceof Array) {
+ parts = [];
+ for(var j=0; j<exp.length; ++j) {
+ part = exp[j];
+ if(part instanceof Array) {
+ midparts = [];
+ for(var k=0; k<part.length; ++k) {
+ midparts.push(wkt(part[k]).toString());
+ }
+ parts.push("[" + midparts.join(", ") + "]");
+ } else {
+ parts.push(wkt(exp[j]).toString());
+ }
+ }
+ exp = parts.join(", ");
+ }
+ t.eq(got, exp, "case " + i + ": " + c.msg);
+ }
+
+ }
+
+ function test_getVertices(t) {
+ t.plan(22);
+
+ var points = [
+ new OpenLayers.Geometry.Point(10, 20),
+ new OpenLayers.Geometry.Point(20, 30),
+ new OpenLayers.Geometry.Point(30, 40),
+ new OpenLayers.Geometry.Point(40, 50)
+ ];
+
+ var multi = new OpenLayers.Geometry.MultiLineString([
+ new OpenLayers.Geometry.LineString(points),
+ new OpenLayers.Geometry.LineString(points)
+ ]);
+
+ var verts = multi.getVertices();
+ t.ok(verts instanceof Array, "got back an array");
+ t.eq(verts.length, 2 * points.length, "of correct length length");
+ t.geom_eq(verts[0], points[0], "0: correct geometry");
+ t.geom_eq(verts[1], points[1], "1: correct geometry");
+ t.geom_eq(verts[2], points[2], "2: correct geometry");
+ t.geom_eq(verts[3], points[3], "3: correct geometry");
+ t.geom_eq(verts[4], points[0], "4: correct geometry");
+ t.geom_eq(verts[5], points[1], "5: correct geometry");
+ t.geom_eq(verts[6], points[2], "6: correct geometry");
+ t.geom_eq(verts[7], points[3], "7: correct geometry");
+
+ // nodes only
+ var nodes = multi.getVertices(true);
+ t.ok(nodes instanceof Array, "[nodes only] got back an array");
+ t.eq(nodes.length, 4, "[nodes only] of correct length length");
+ t.geom_eq(nodes[0], points[0], "[nodes only] 0: correct geometry");
+ t.geom_eq(nodes[1], points[3], "[nodes only] 1: correct geometry");
+ t.geom_eq(nodes[2], points[0], "[nodes only] 2: correct geometry");
+ t.geom_eq(nodes[3], points[3], "[nodes only] 3: correct geometry");
+
+ // no nodes
+ var nodes = multi.getVertices(false);
+ t.ok(nodes instanceof Array, "[no nodes] got back an array");
+ t.eq(nodes.length, 4, "[no nodes] of correct length length");
+ t.geom_eq(nodes[0], points[1], "[no nodes] 0: correct geometry");
+ t.geom_eq(nodes[1], points[2], "[no nodes] 1: correct geometry");
+ t.geom_eq(nodes[2], points[1], "[no nodes] 2: correct geometry");
+ t.geom_eq(nodes[3], points[2], "[no nodes] 3: correct geometry");
+
+
+ }
+
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Geometry/MultiPoint.html b/misc/openlayers/tests/Geometry/MultiPoint.html
new file mode 100644
index 0000000..47ce430
--- /dev/null
+++ b/misc/openlayers/tests/Geometry/MultiPoint.html
@@ -0,0 +1,130 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ var point = new OpenLayers.Geometry.Point(10, 15);
+
+
+ function test_MultiPoint_constructor (t) {
+ t.plan( 2 );
+ var multipoint = new OpenLayers.Geometry.MultiPoint();
+ t.ok( multipoint instanceof OpenLayers.Geometry.MultiPoint, "new OpenLayers.Geometry.MultiPoint returns multipoint object" );
+ t.eq( multipoint.CLASS_NAME, "OpenLayers.Geometry.MultiPoint", "multipoint.CLASS_NAME is set correctly");
+ }
+
+ function test_MultiPoint_constructor (t) {
+ t.plan( 3 );
+ var multipoint = new OpenLayers.Geometry.MultiPoint([point]);
+ t.ok( multipoint instanceof OpenLayers.Geometry.MultiPoint, "new OpenLayers.Geometry.MultiPoint returns multipoint object" );
+ t.eq( multipoint.CLASS_NAME, "OpenLayers.Geometry.MultiPoint", "multipoint.CLASS_NAME is set correctly");
+ t.eq( multipoint.components.length, 1, "multipolygon.components.length is set correctly");
+ }
+
+ function test_MultiPoint_move(t) {
+ t.plan(2);
+
+ var multipoint = new OpenLayers.Geometry.MultiPoint([point]);
+ var x = point.x;
+ var y = point.y;
+
+ var dx = 10 * Math.random();
+ var dy = 10 * Math.random();
+ multipoint.move(dx, dy);
+ t.eq(multipoint.components[0].x, x + dx, "move() correctly modifies x");
+ t.eq(multipoint.components[0].y, y + dy, "move() correctly modifies y");
+ }
+
+ function test_distanceTo(t) {
+ var points = [
+ new OpenLayers.Geometry.Point(0, 0),
+ new OpenLayers.Geometry.Point(10, 0),
+ new OpenLayers.Geometry.Point(0, 9),
+ new OpenLayers.Geometry.Point(-5, 0),
+ new OpenLayers.Geometry.Point(-5, 4)
+ ];
+
+ var geoms = [
+ new OpenLayers.Geometry.MultiPoint([points[0], points[1]]),
+ new OpenLayers.Geometry.MultiPoint([points[2], points[3]]),
+ points[4]
+ ];
+
+ var cases = [{
+ got: geoms[0].distanceTo(geoms[0]),
+ expected: 0
+ }, {
+ got: geoms[0].distanceTo(geoms[1]),
+ expected: 5
+ }, {
+ got: geoms[1].distanceTo(geoms[2]),
+ expected: 4
+ }, {
+ got: geoms[0].distanceTo(geoms[1], {details: true}),
+ expected: {
+ distance: 5,
+ x0: 0, y0: 0,
+ x1: -5, y1: 0
+ }
+ }, {
+ got: geoms[1].distanceTo(geoms[0], {details: true}),
+ expected: {
+ distance: 5,
+ x0: -5, y0: 0,
+ x1: 0, y1: 0
+ }
+ }, {
+ got: geoms[1].distanceTo(geoms[2], {details: true}),
+ expected: {
+ distance: 4,
+ x0: -5, y0: 0,
+ x1: -5, y1: 4
+ }
+ }];
+
+ t.plan(cases.length);
+ for(var i=0; i<cases.length; ++i) {
+ t.eq(cases[i].got, cases[i].expected, "case " + i);
+ }
+
+ }
+
+ function test_MultiPoint_equals(t) {
+ t.plan(3);
+
+ var x = Math.random() * 100;
+ var y = Math.random() * 100;
+ var geometry = new OpenLayers.Geometry.MultiPoint(
+ [new OpenLayers.Geometry.Point(x, y)]);
+ var equal = new OpenLayers.Geometry.MultiPoint(
+ [new OpenLayers.Geometry.Point(x, y)]);
+ var offX = new OpenLayers.Geometry.MultiPoint(
+ [new OpenLayers.Geometry.Point(x + 1, y)]);
+ var offY = new OpenLayers.Geometry.MultiPoint(
+ [new OpenLayers.Geometry.Point(x, y + 1)]);
+ t.ok(geometry.equals(equal),
+ "equals() returns true for a geometry with equivalent coordinates");
+ t.ok(!geometry.equals(offX),
+ "equals() returns false for a geometry with offset x");
+ t.ok(!geometry.equals(offY),
+ "equals() returns false for a geometry with offset y");
+ }
+
+ function test_MultiPoint_clone(t) {
+ t.plan(2);
+
+ var x = Math.random() * 100;
+ var y = Math.random() * 100;
+ var geometry = new OpenLayers.Geometry.MultiPoint(
+ [new OpenLayers.Geometry.Point(x, y)]);
+ var clone = geometry.clone();
+ t.ok(clone instanceof OpenLayers.Geometry.MultiPoint,
+ "clone() creates an OpenLayers.Geometry.MultiPoint");
+ t.ok(geometry.equals(clone), "clone has equivalent coordinates");
+ }
+
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Geometry/MultiPolygon.html b/misc/openlayers/tests/Geometry/MultiPolygon.html
new file mode 100644
index 0000000..f44de93
--- /dev/null
+++ b/misc/openlayers/tests/Geometry/MultiPolygon.html
@@ -0,0 +1,34 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ var polygon;
+ var components = [new OpenLayers.Geometry.Point(10,10), new OpenLayers.Geometry.Point(0,0)];
+ var components2 = [new OpenLayers.Geometry.Point(10,10), new OpenLayers.Geometry.Point(0,0), new OpenLayers.Geometry.Point(10,0), new OpenLayers.Geometry.Point(10,10)];
+ var linearRing = new OpenLayers.Geometry.LinearRing(components);
+ var linearRing2 = new OpenLayers.Geometry.LinearRing(components2);
+
+ var polygon = new OpenLayers.Geometry.Polygon([linearRing]);
+ var polygon2 = new OpenLayers.Geometry.Polygon([linearRing2]);
+
+ function test_MultiPolygon_constructor (t) {
+ t.plan( 2 );
+ multipolygon = new OpenLayers.Geometry.MultiPolygon();
+ t.ok( multipolygon instanceof OpenLayers.Geometry.MultiPolygon, "new OpenLayers.Geometry.MultiPolygon returns multipolygon object" );
+ t.eq( multipolygon.CLASS_NAME, "OpenLayers.Geometry.MultiPolygon", "multipolygon.CLASS_NAME is set correctly");
+ }
+
+ function test_MultiPolygon_constructor (t) {
+ t.plan( 3 );
+ multipolygon = new OpenLayers.Geometry.MultiPolygon([polygon, polygon2]);
+ t.ok( multipolygon instanceof OpenLayers.Geometry.MultiPolygon, "new OpenLayers.Geometry.MultiPolygon returns multipolygon object" );
+ t.eq( multipolygon.CLASS_NAME, "OpenLayers.Geometry.MultiPolygon", "multipolygon.CLASS_NAME is set correctly");
+ t.eq( multipolygon.components.length, 2, "multipolygon.components.length is set correctly");
+ }
+
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Geometry/Point.html b/misc/openlayers/tests/Geometry/Point.html
new file mode 100644
index 0000000..e688250
--- /dev/null
+++ b/misc/openlayers/tests/Geometry/Point.html
@@ -0,0 +1,244 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ var point;
+
+ function test_Point_constructor (t) {
+ t.plan( 8 );
+
+ //empty
+ point = new OpenLayers.Geometry.Point();
+ t.ok( point instanceof OpenLayers.Geometry.Point, "new OpenLayers.Geometry.Point returns point object" );
+ t.eq( point.CLASS_NAME, "OpenLayers.Geometry.Point", "point.CLASS_NAME is set correctly");
+
+ //valid
+ var x = 10;
+ var y = 20;
+ point = new OpenLayers.Geometry.Point(x, y);
+ t.ok( point instanceof OpenLayers.Geometry.Point, "new OpenLayers.Geometry.Point returns point object" );
+ t.eq( point.CLASS_NAME, "OpenLayers.Geometry.Point", "point.CLASS_NAME is set correctly");
+ t.eq( point.x, x, "point.x is set correctly");
+ t.eq( point.y, y, "point.y is set correctly");
+ t.eq( point.lon, null, "point.lon is not set");
+ t.eq( point.lat, null, "point.lat is not set");
+ }
+
+ function test_Point_calculateBounds (t) {
+ t.plan(4);
+
+ var x = 10;
+ var y = 20;
+ point = new OpenLayers.Geometry.Point(x, y);
+ point.calculateBounds();
+ t.eq( point.bounds.left, x, "bounds.left is 10" );
+ t.eq( point.bounds.right, x, "bounds.right is 10" );
+ t.eq( point.bounds.top, y, "bounds.top is 20" );
+ t.eq( point.bounds.bottom, y, "bounds.bottom is 20" );
+ }
+
+
+ function test_Point_transform_getBounds (t) {
+ t.plan(2);
+
+ var x = 10;
+ var y = 20;
+ point = new OpenLayers.Geometry.Point(x, y);
+ point.calculateBounds();
+ t.ok( point.bounds != null, "bounds calculated by calcBounds" );
+ point.transform(new OpenLayers.Projection("EPSG:4326"),
+ new OpenLayers.Projection("EPSG:900913"));
+ t.eq(point.bounds, null, "Point bounds cleared after transform");
+ }
+
+ function test_Point_transform_string(t) {
+ t.plan(4);
+
+ var x = 10;
+ var y = 20;
+ point = new OpenLayers.Geometry.Point(x, y);
+ point.calculateBounds();
+ t.ok( point.bounds != null, "bounds calculated by calcBounds" );
+ point.transform("EPSG:4326", "EPSG:900913");
+ t.eq(point.bounds, null, "Point bounds cleared after transform");
+ t.eq(point.x.toFixed(2), "1113194.91", "transformed x");
+ t.eq(point.y.toFixed(2), "2273030.93", "transformed y");
+
+ }
+
+ function test_Point_distanceTo(t) {
+ t.plan(7);
+
+ var x1 = 10;
+ var y1 = 20;
+ point1 = new OpenLayers.Geometry.Point(x1, y1);
+
+ var x2 = 100;
+ var y2 = 200;
+ point2 = new OpenLayers.Geometry.Point(x2, y2);
+
+ var dist = point1.distanceTo(point2)
+ t.eq( dist, 201.24611797498107267682563018581, "distances calculating correctly");
+ t.eq( dist, Math.sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)), "distance calculation correct");
+
+ // test that details are returned (though trivial in this case)
+ var result = point1.distanceTo(point2, {details: true});
+ t.eq(result.distance, point1.distanceTo(point2), "[details] distance property is same as return without details");
+ t.eq(result.x0, x1, "[details] x0 property is correct");
+ t.eq(result.y0, y1, "[details] y0 property is correct");
+ t.eq(result.x1, x2, "[details] x1 property is correct");
+ t.eq(result.y1, y2, "[details] y1 property is correct");
+
+ }
+
+ function test_Point_toString(t) {
+ t.plan(1);
+
+ var x = 10;
+ var y = 20;
+ point = new OpenLayers.Geometry.Point(x, y);
+ t.eq(point.toString(), "POINT(" + x + " " + y + ")",
+ "toString() returns WKT" );
+
+ }
+
+ function test_Point_toString_no_wkt(t) {
+ t.plan(1);
+
+ var WKT = OpenLayers.Format.WKT;
+ OpenLayers.Format.WKT = null;
+
+ var x = 10;
+ var y = 20;
+ point = new OpenLayers.Geometry.Point(x, y);
+ t.eq(point.toString(), "[object Object]", "default string representation");
+
+ OpenLayers.Format.WKT = WKT;
+
+ }
+
+ function test_Point_move(t) {
+ t.plan(3);
+
+ var x = 10;
+ var y = 20;
+ point = new OpenLayers.Geometry.Point(x, y);
+
+ var dx = 10 * Math.random();
+ var dy = 10 * Math.random();
+ point.bounds = "foo";
+ point.move(dx, dy);
+ t.eq(point.x, x + dx, "move() correctly modifies x");
+ t.eq(point.y, y + dy, "move() correctly modifies y");
+
+ t.ok(point.bounds == null, "bounds is cleared after a move()");
+ }
+
+ function test_Point_rotate(t) {
+ t.plan(5);
+
+ var tolerance = 1e-10;
+ var x = 10;
+ var y = 20;
+ var point = new OpenLayers.Geometry.Point(x, y);
+ var origin = new OpenLayers.Geometry.Point(5, 10);
+
+ // rotate a full revolution
+ point.bounds = "foo";
+ point.rotate(360, origin);
+ t.ok(((point.x - x) / x) < tolerance,
+ "rotate by 360 returns to the same y");
+ t.ok(((point.y - y) / y) < tolerance,
+ "rotate by 360 returns to the same y");
+
+ t.ok(point.bounds == null, "bounds is cleared after a rotate()");
+
+ // rotate an 1/8 turn
+ point.rotate(45, origin);
+ t.ok(((point.x - 1.4644660940672636) / 1.4644660940672636) < tolerance,
+ "rotate 1/8 turn correctly");
+ t.ok(((point.y - 20.606601717798213) / 20.606601717798213) < tolerance,
+ "rotate 1/8 turn correctly");
+ }
+
+ function test_Point_resize(t) {
+ t.plan(6);
+
+ var tolerance = 1e-10;
+ var x = 100 * Math.random();
+ var y = 100 * Math.random();
+ var point = new OpenLayers.Geometry.Point(x, y);
+ point.bounds = "foo";
+
+ var i = 100 * Math.random();
+ var j = 100 * Math.random();
+ var origin = new OpenLayers.Geometry.Point(i, j);
+
+ var scale = 10 * Math.random();
+ var oldDistance = origin.distanceTo(point);
+
+ var ret = point.resize(scale, origin);
+ var newDistance = origin.distanceTo(point);
+
+ t.ok(ret === point, "resize returns geometry");
+ t.ok((origin.x == i) && (origin.y == j),
+ "resize leaves the origin untouched");
+ t.ok((((newDistance / oldDistance) - scale) / scale) < tolerance,
+ "resize moves points the correct distance from the origin");
+
+ t.ok(point.bounds == null, "bounds is correctly cleared after a resize()");
+
+ // resize with non uniform scaling (ratio != 1)
+ point = new OpenLayers.Geometry.Point(10, 10);
+ origin = new OpenLayers.Geometry.Point(0, 0);
+ point.resize(2, origin, 4);
+ t.eq(point.x, 80, "non-uniform scaling correctly applied in x dim");
+ t.eq(point.y, 20, "non-uniform scaling correctly applied in y dim");
+
+ }
+
+ function test_Point_equals(t) {
+ t.plan(3);
+
+ var x = Math.random() * 100;
+ var y = Math.random() * 100;
+ var geometry = new OpenLayers.Geometry.Point(x, y);
+ var equal = new OpenLayers.Geometry.Point(x, y);
+ var offX = new OpenLayers.Geometry.Point(x + 1, y);
+ var offY = new OpenLayers.Geometry.Point(x, y + 1);
+ t.ok(geometry.equals(equal),
+ "equals() returns true for a geometry with equivalent coordinates");
+ t.ok(!geometry.equals(offX),
+ "equals() returns false for a geometry with offset x");
+ t.ok(!geometry.equals(offY),
+ "equals() returns false for a geometry with offset y");
+ }
+
+ function test_getVertices(t) {
+ t.plan(3);
+
+ var point = new OpenLayers.Geometry.Point(10, 20);
+ var verts = point.getVertices();
+ t.ok(verts instanceof Array, "got back an array");
+ t.eq(verts.length, 1, "of length 1");
+ t.geom_eq(verts[0], point, "with correct geometry");
+ }
+
+ function test_Point_clone(t) {
+ t.plan(2);
+
+ var x = Math.random() * 100;
+ var y = Math.random() * 100;
+ var geometry = new OpenLayers.Geometry.Point(x, y);
+ var clone = geometry.clone();
+ t.ok(clone instanceof OpenLayers.Geometry.Point,
+ "clone() creates an OpenLayers.Geometry.Point");
+ t.ok(geometry.equals(clone), "clone has equivalent coordinates");
+ }
+
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Geometry/Polygon.html b/misc/openlayers/tests/Geometry/Polygon.html
new file mode 100644
index 0000000..0df0295
--- /dev/null
+++ b/misc/openlayers/tests/Geometry/Polygon.html
@@ -0,0 +1,420 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ var polygon;
+ var components = [new OpenLayers.Geometry.Point(10,14), new OpenLayers.Geometry.Point(5,3)];
+ var components2 = [new OpenLayers.Geometry.Point(12,15), new OpenLayers.Geometry.Point(2,3), new OpenLayers.Geometry.Point(10,0), new OpenLayers.Geometry.Point(10,10)];
+ var linearRing = new OpenLayers.Geometry.LinearRing(components);
+ var linearRing2 = new OpenLayers.Geometry.LinearRing(components2);
+
+ function test_Polygon_constructor (t) {
+ t.plan( 3 );
+ polygon = new OpenLayers.Geometry.Polygon();
+ t.ok( polygon instanceof OpenLayers.Geometry.Polygon, "new OpenLayers.Geometry.Polygon returns polygon object" );
+ t.eq( polygon.CLASS_NAME, "OpenLayers.Geometry.Polygon", "polygon.CLASS_NAME is set correctly");
+ t.eq( polygon.components.length, 0, "polygon.components is set correctly");
+ }
+
+ function test_Polygon_constructor (t) {
+ t.plan( 3 );
+ polygon = new OpenLayers.Geometry.Polygon([linearRing]);
+ t.ok( polygon instanceof OpenLayers.Geometry.Polygon, "new OpenLayers.Geometry.Polygon returns polygon object" );
+ t.eq( polygon.CLASS_NAME, "OpenLayers.Geometry.Polygon", "polygon.CLASS_NAME is set correctly");
+ t.eq( polygon.components.length, 1, "polygon.components.length is set correctly");
+ }
+
+ function test_Polygon_constructor (t) {
+ t.plan( 3 );
+ polygon = new OpenLayers.Geometry.Polygon([linearRing, linearRing2]);
+ t.ok( polygon instanceof OpenLayers.Geometry.Polygon, "new OpenLayers.Geometry.Polygon returns polygon object" );
+ t.eq( polygon.CLASS_NAME, "OpenLayers.Geometry.Polygon", "polygon.CLASS_NAME is set correctly");
+ t.eq( polygon.components.length, 2, "polygon.components.length is set correctly");
+ }
+
+ function test_Polygon_transform_getBounds (t) {
+ t.plan(3);
+
+ var components = [new OpenLayers.Geometry.Point(10,14), new OpenLayers.Geometry.Point(5,3)];
+ var linearRing = new OpenLayers.Geometry.LinearRing(components);
+ polygon = new OpenLayers.Geometry.Polygon([linearRing.clone()]);
+ polygon.calculateBounds();
+ t.ok( polygon.bounds != null, "bounds calculated by calcBounds" );
+ polygon.transform(new OpenLayers.Projection("EPSG:4326"),
+ new OpenLayers.Projection("EPSG:900913"));
+ t.eq(polygon.bounds, null, "Point bounds cleared after transform");
+ t.eq(polygon.getBounds().toBBOX(), "556597.453889,334111.171355,1113194.907778,1574216.547942", "Bounds are correct")
+ }
+
+ function test_Polygon_transform_string (t) {
+ t.plan(3);
+
+ var components = [new OpenLayers.Geometry.Point(10,14), new OpenLayers.Geometry.Point(5,3)];
+ var linearRing = new OpenLayers.Geometry.LinearRing(components);
+ polygon = new OpenLayers.Geometry.Polygon([linearRing.clone()]);
+ polygon.calculateBounds();
+ t.ok( polygon.bounds != null, "bounds calculated by calcBounds" );
+ polygon.transform("EPSG:4326", "EPSG:900913");
+ t.eq(polygon.bounds, null, "Point bounds cleared after transform");
+ t.eq(polygon.getBounds().toBBOX(), "556597.453889,334111.171355,1113194.907778,1574216.547942", "Bounds are correct")
+ }
+
+ function test_Polygon_getArea(t) {
+ t.plan( 5 );
+
+ //no components
+ var polygon = new OpenLayers.Geometry.Polygon();
+ t.eq(polygon.getArea(), 0, "getArea empty polygon is 0");
+
+ var createSquareRing = function(area) {
+ var points = [
+ new OpenLayers.Geometry.Point(0, 0),
+ new OpenLayers.Geometry.Point(0, area),
+ new OpenLayers.Geometry.Point(area, area),
+ new OpenLayers.Geometry.Point(area, 0)
+ ];
+ var ring = new OpenLayers.Geometry.LinearRing(points);
+ return ring;
+ };
+
+
+ //simple polygon
+ var comps = [ createSquareRing(2) ];
+
+ var polygon = new OpenLayers.Geometry.Polygon(comps);
+ t.eq(polygon.getArea(), 4, "getArea simple polygon works lovely");
+
+ //polygon with holes
+ comps = [ createSquareRing(10),
+ createSquareRing(2),
+ createSquareRing(3),
+ createSquareRing(4)
+ ];
+
+ var polygon = new OpenLayers.Geometry.Polygon(comps);
+ t.eq(polygon.getArea(), 71, "getArea polygon with holes works lovely");
+
+ //simple polygon negative
+ comps = [ createSquareRing(-2) ];
+
+ var polygon = new OpenLayers.Geometry.Polygon(comps);
+ t.eq(polygon.getArea(), 4, "getArea simple polygon negative works lovely");
+
+ //polygon with holes negative
+ comps = [ createSquareRing(-10),
+ createSquareRing(-2),
+ createSquareRing(-3),
+ createSquareRing(-4)
+ ];
+
+ var polygon = new OpenLayers.Geometry.Polygon(comps);
+ t.eq(polygon.getArea(), 71, "getArea negative polygon with holes works lovely");
+
+ }
+
+ function test_Polygon_move(t) {
+ t.plan(4);
+
+ polygon = new OpenLayers.Geometry.Polygon([linearRing, linearRing2]);
+
+ var x = linearRing.components[0].x;
+ var y = linearRing.components[0].y;
+ var x2 = linearRing2.components[0].x;
+ var y2 = linearRing2.components[0].y;
+
+ var dx = 10 * Math.random();
+ var dy = 10 * Math.random();
+
+ polygon.move(dx, dy);
+
+ t.eq(polygon.components[0].components[0].x, x + dx, "move() correctly modifies first x");
+ t.eq(polygon.components[0].components[0].y, y + dy, "move() correctly modifies first y");
+ t.eq(polygon.components[1].components[0].x, x2 + dx, "move() correctly modifies second x");
+ t.eq(polygon.components[1].components[0].y, y2 + dy, "move() correctly modifies second y");
+ }
+
+ function test_Polygon_rotate(t) {
+ t.plan(6);
+
+ var geometry = new OpenLayers.Geometry.Polygon([linearRing, linearRing2]);
+
+ var originals = [];
+ var comp;
+ var angle = 2 * Math.PI * Math.random();
+ var origin = new OpenLayers.Geometry.Point(10 * Math.random(),
+ 10 * Math.random());
+ for(var i=0; i<geometry.components.length; ++i) {
+ comp = geometry.components[i];
+ originals[i] = comp.rotate;
+ comp.rotate = function(a, o) {
+ t.ok(true, "rotate called for component " + i);
+ t.ok(a == angle, "rotate called with correct angle");
+ t.ok(o == origin, "rotate called with correct origin");
+ }
+ }
+ geometry.rotate(angle, origin);
+
+ // restore the original rotate defs
+ for(var i=0; i<geometry.components.length; ++i) {
+ comp.rotate = originals[i];
+ }
+ }
+
+ function test_Polygon_resize(t) {
+ t.plan(8);
+
+ var tolerance = 1e-10;
+ var geometry = new OpenLayers.Geometry.Polygon([linearRing, linearRing2]);
+ var origin = new OpenLayers.Geometry.Point(10 * Math.random(),
+ 10 * Math.random());
+ var scale = 10 * Math.random();
+
+ var oldArea = geometry.getArea();
+ var oldPerimeter = geometry.getLength();
+ geometry.resize(scale, origin);
+ var newArea = geometry.getArea();
+ var newPerimeter = geometry.getLength();
+
+ t.ok((((newArea / oldArea) - (scale * scale)) / (scale * scale)) < tolerance,
+ "resize correctly changes the area of a polygon")
+ t.ok((((newPerimeter / oldPerimeter) - scale) / scale) < tolerance,
+ "resize correctly changes the perimeter of a polygon")
+
+ var originals = [];
+ var comp;
+ for(var i=0; i<geometry.components.length; ++i) {
+ comp = geometry.components[i];
+ originals[i] = comp.resize;
+ comp.resize = function(s, o) {
+ t.ok(true, "resize called for component " + i);
+ t.ok(s == scale, "resize called with correct scale");
+ t.ok(o == origin, "resize called with correct origin");
+ }
+ }
+ geometry.resize(scale, origin);
+
+ // restore the original resize defs
+ for(var i=0; i<geometry.components.length; ++i) {
+ comp.resize = originals[i];
+ }
+
+ }
+
+ function test_Polygon_createRegular(t) {
+ t.plan(22);
+ var sides = 40;
+ var poly = OpenLayers.Geometry.Polygon.createRegularPolygon(new OpenLayers.Geometry.Point(5,0), 6, sides);
+ var polyBounds = poly.getBounds();
+ t.eq(polyBounds.toBBOX(), "-0.981504,-5.981504,10.981504,5.981504", sides + " sided figure generates correct bbox.");
+ t.eq(poly.components.length, 1, "Poly has one linear ring");
+ t.eq(poly.components[0].components.length, sides + 1, "ring has 41 components");
+ t.eq(poly.components[0].components[0].id, poly.components[0].components[sides].id, "ring starts and ends with same geom");
+ t.eq(Math.round(poly.getArea()), Math.round(Math.PI * 36), "area of "+sides+" sided poly rounds to same area as a circle.");
+
+ var sides = 3;
+ var poly = OpenLayers.Geometry.Polygon.createRegularPolygon(new OpenLayers.Geometry.Point(5,0), 6, sides);
+ var polyBounds = poly.getBounds();
+ t.eq(polyBounds.toBBOX(), "-0.196152,-3,10.196152,6", sides + " sided figure generates correct bbox.");
+ t.eq(poly.components.length, 1, "Poly has one linear ring");
+ t.eq(poly.components[0].components.length, sides + 1, "ring has correct count of components");
+ t.eq(poly.components[0].components[0].id, poly.components[0].components[sides].id, "ring starts and ends with same geom");
+ t.eq(Math.round(poly.getArea()), 47, "area of 3 sided poly is correct");
+
+ var sides = 3;
+ var poly3 = OpenLayers.Geometry.Polygon.createRegularPolygon(new OpenLayers.Geometry.Point(10,0), 15, sides);
+ var polyBounds = poly3.getBounds();
+ t.eq(polyBounds.toBBOX(), "-2.990381,-7.5,22.990381,15", sides + " sided figure generates correct bbox.");
+ t.eq(Math.round(polyBounds.getCenterLonLat().lon), 10, "longitude of center of bounds is same as origin");
+ t.eq(poly3.components.length, 1, "Poly has one linear ring");
+ t.eq(poly3.components[0].components.length, sides + 1, "ring has correct count of components");
+ t.eq(poly3.components[0].components[0].id, poly3.components[0].components[sides].id, "ring starts and ends with same geom");
+ t.ok(poly3.getArea() > poly.getArea(), "area with radius 15 > poly with radius 6");
+
+ var sides = 4;
+ var poly4 = OpenLayers.Geometry.Polygon.createRegularPolygon(new OpenLayers.Geometry.Point(10,0), 15, sides);
+ var polyBounds = poly4.getBounds();
+ t.eq(polyBounds.toBBOX(), "-0.606602,-10.606602,20.606602,10.606602", sides + " sided figure generates correct bbox.");
+ t.eq(Math.round(polyBounds.getCenterLonLat().lon), 10, "longitude of center of bounds is same as origin");
+ t.eq(poly4.components.length, 1, "Poly has one linear ring");
+ t.eq(poly4.components[0].components.length, sides + 1, "ring has correct count of components");
+ t.eq(poly4.components[0].components[0].id, poly4.components[0].components[sides].id, "ring starts and ends with same geom");
+ t.ok(poly4.getArea() > poly3.getArea(), "square with radius 15 > triangle with radius 15");
+ }
+
+ function test_Polygon_equals(t) {
+ t.plan(3);
+
+ var x0 = Math.random() * 100;
+ var y0 = Math.random() * 100;
+ var x1 = Math.random() * 100;
+ var y1 = Math.random() * 100;
+ var x2 = Math.random() * 100;
+ var y2 = Math.random() * 100;
+ var point0 = new OpenLayers.Geometry.Point(x0, y0);
+ var point1 = new OpenLayers.Geometry.Point(x1, y1);
+ var point2 = new OpenLayers.Geometry.Point(x2, y2);
+ var pointX = new OpenLayers.Geometry.Point(x0 + 1, y0);
+ var pointY = new OpenLayers.Geometry.Point(x0, y0 + 1);
+ var geometry = new OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([point0, point1, point2])]);
+ var equal = new OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([point0, point1, point2])]);
+ var offX = new OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([pointX, point1, point2])]);
+ var offY = new OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([pointY, point1, point2])]);
+ t.ok(geometry.equals(equal),
+ "equals() returns true for a geometry with equivalent coordinates");
+ t.ok(!geometry.equals(offX),
+ "equals() returns false for a geometry with offset x");
+ t.ok(!geometry.equals(offY),
+ "equals() returns false for a geometry with offset y");
+ }
+
+ function test_distanceTo(t) {
+ var wkt = OpenLayers.Geometry.fromWKT;
+ var geoms = [
+ wkt("POLYGON((0 3, 1 4, 2 3, 1 2, 0 3))"),
+ wkt("POINT(0 0)"),
+ wkt("LINESTRING(-2 0, 0 -2, 2 -1, 2 0)"),
+ wkt("LINESTRING(0 2, 1 3)"),
+ wkt("POINT(1 3)")
+ ];
+
+ var cases = [{
+ got: geoms[0].distanceTo(geoms[1]),
+ expected: Math.sqrt(5)
+ }, {
+ got: geoms[0].distanceTo(geoms[1], {details: true}),
+ expected: {
+ distance: Math.sqrt(5),
+ x0: 1, y0: 2,
+ x1: 0, y1: 0
+ }
+ }, {
+ got: geoms[0].distanceTo(geoms[2], {details: true}),
+ expected: {
+ distance: Math.sqrt(5),
+ x0: 1, y0: 2,
+ x1: 2, y1: 0
+ }
+ }, {
+ got: geoms[0].distanceTo(geoms[3], {details: true}),
+ expected: {
+ distance: 0,
+ x0: 0.5, y0: 2.5,
+ x1: 0.5, y1: 2.5
+ }
+ }, {
+ got: geoms[0].distanceTo(geoms[4]),
+ expected: Math.sqrt(0.5)
+ }, {
+ got: geoms[0].distanceTo(geoms[4], {edge: false}),
+ expected: 0
+ }];
+
+ t.plan(cases.length);
+ for(var i=0; i<cases.length; ++i) {
+ t.eq(cases[i].got, cases[i].expected, "case " + i);
+ }
+
+ }
+
+ function test_getVertices(t) {
+ t.plan(6);
+
+ var points = [
+ new OpenLayers.Geometry.Point(10, 20),
+ new OpenLayers.Geometry.Point(20, 30),
+ new OpenLayers.Geometry.Point(30, 40),
+ new OpenLayers.Geometry.Point(40, 50)
+ ];
+ var polygon = new OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing(points)
+ ]);
+
+ var verts = polygon.getVertices();
+ t.ok(verts instanceof Array, "got back an array");
+ t.eq(verts.length, points.length, "of correct length length");
+ t.geom_eq(verts[0], points[0], "0: correct geometry");
+ t.geom_eq(verts[1], points[1], "1: correct geometry");
+ t.geom_eq(verts[2], points[2], "2: correct geometry");
+ t.geom_eq(verts[3], points[3], "3: correct geometry");
+
+ }
+
+ function test_Polygon_clone(t) {
+ t.plan(2);
+
+ var x0 = Math.random() * 100;
+ var y0 = Math.random() * 100;
+ var x1 = Math.random() * 100;
+ var y1 = Math.random() * 100;
+ var x2 = Math.random() * 100;
+ var y2 = Math.random() * 100;
+ var point0 = new OpenLayers.Geometry.Point(x0, y0);
+ var point1 = new OpenLayers.Geometry.Point(x1, y1);
+ var point2 = new OpenLayers.Geometry.Point(x2, y2);
+ var geometry = new OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([point0, point1, point2])]);
+ var clone = geometry.clone();
+ t.ok(clone instanceof OpenLayers.Geometry.Polygon,
+ "clone() creates an OpenLayers.Geometry.Polygon");
+ t.ok(geometry.equals(clone), "clone has equivalent coordinates");
+ }
+
+ function test_getGeodesicArea(t) {
+
+ t.plan(1);
+
+ // from the wfs-states.html example
+ var illinois = OpenLayers.Geometry.fromWKT(
+ "MULTIPOLYGON(((-88.071564 37.51099,-88.087883 37.476273,-88.311707 37.442852,-88.359177 37.409309,-88.419853 37.420292,-88.467644 37.400757,-88.511322 37.296852,-88.501427 37.257782,-88.450699 37.205669,-88.422516 37.15691,-88.45047 37.098671,-88.476799 37.072144,-88.4907 37.06818,-88.517273 37.06477,-88.559273 37.072815,-88.61422 37.109047,-88.68837 37.13541,-88.739113 37.141182,-88.746506 37.152107,-88.863289 37.202194,-88.932503 37.218407,-88.993172 37.220036,-89.065033 37.18586,-89.116821 37.112137,-89.146347 37.093185,-89.169548 37.064236,-89.174332 37.025711,-89.150246 36.99844,-89.12986 36.988113,-89.193512 36.986771,-89.210052 37.028973,-89.237679 37.041733,-89.264053 37.087124,-89.284233 37.091244,-89.303291 37.085384,-89.3097 37.060909,-89.264244 37.027733,-89.262001 37.008686,-89.282768 36.999207,-89.310982 37.009682,-89.38295 37.049213,-89.37999 37.099083,-89.423798 37.137203,-89.440521 37.165318,-89.468216 37.224266,-89.465309 37.253731,-89.489594 37.256001,-89.513885 37.276402,-89.513885 37.304962,-89.50058 37.329441,-89.468742 37.339409,-89.435738 37.355717,-89.427574 37.411018,-89.453621 37.453186,-89.494781 37.491726,-89.524971 37.571957,-89.513367 37.615929,-89.51918 37.650375,-89.513374 37.67984,-89.521523 37.694798,-89.581436 37.706104,-89.666458 37.745453,-89.675858 37.78397,-89.691055 37.804794,-89.728447 37.840992,-89.851715 37.905064,-89.861046 37.905487,-89.866814 37.891876,-89.900551 37.875904,-89.937874 37.878044,-89.978912 37.911884,-89.958229 37.963634,-90.010811 37.969318,-90.041924 37.993206,-90.119339 38.032272,-90.134712 38.053951,-90.207527 38.088905,-90.254059 38.122169,-90.289635 38.166817,-90.336716 38.188713,-90.364769 38.234299,-90.369347 38.323559,-90.358688 38.36533,-90.339607 38.390846,-90.301842 38.427357,-90.265785 38.518688,-90.26123 38.532768,-90.240944 38.562805,-90.183708 38.610271,-90.183578 38.658772,-90.20224 38.700363,-90.196571 38.723965,-90.163399 38.773098,-90.135178 38.785484,-90.121727 38.80051,-90.113121 38.830467,-90.132812 38.853031,-90.243927 38.914509,-90.278931 38.924717,-90.31974 38.924908,-90.413071 38.96233,-90.469841 38.959179,-90.530426 38.891609,-90.570328 38.871326,-90.627213 38.880795,-90.668877 38.935253,-90.70607 39.037792,-90.707588 39.058178,-90.690399 39.0937,-90.716736 39.144211,-90.718193 39.195873,-90.732338 39.224747,-90.738083 39.24781,-90.779343 39.296803,-90.850494 39.350452,-90.947891 39.400585,-91.036339 39.444412,-91.064384 39.473984,-91.093613 39.528927,-91.156189 39.552593,-91.203247 39.600021,-91.317665 39.685917,-91.367088 39.72464,-91.373421 39.761272,-91.381714 39.803772,-91.449188 39.863049,-91.450989 39.885242,-91.434052 39.901829,-91.430389 39.921837,-91.447243 39.946064,-91.487289 40.005753,-91.504005 40.066711,-91.516129 40.134544,-91.506546 40.200459,-91.498932 40.251377,-91.486694 40.309624,-91.448593 40.371902,-91.418816 40.386875,-91.385757 40.392361,-91.372757 40.402988,-91.385399 40.44725,-91.374794 40.503654,-91.382103 40.528496,-91.412872 40.547993,-91.411118 40.572971,-91.37561 40.603439,-91.262062 40.639545,-91.214912 40.643818,-91.162498 40.656311,-91.129158 40.682148,-91.119987 40.705402,-91.092751 40.761547,-91.088905 40.833729,-91.04921 40.879585,-90.983276 40.923927,-90.960709 40.950504,-90.954651 41.070362,-90.957787 41.104359,-90.990341 41.144371,-91.018257 41.165825,-91.05632 41.176258,-91.101524 41.231522,-91.102348 41.267818,-91.07328 41.334896,-91.055786 41.401379,-91.027489 41.423508,-91.000694 41.431084,-90.949654 41.421234,-90.844139 41.444622,-90.7799 41.449821,-90.708214 41.450062,-90.658791 41.462318,-90.6007 41.509586,-90.54084 41.52597,-90.454994 41.527546,-90.434967 41.543579,-90.423004 41.567272,-90.348366 41.586849,-90.339348 41.602798,-90.341133 41.64909,-90.326027 41.722736,-90.304886 41.756466,-90.25531 41.781738,-90.195839 41.806137,-90.154518 41.930775,-90.14267 41.983963,-90.150536 42.033428,-90.168098 42.061043,-90.166649 42.103745,-90.176086 42.120502,-90.191574 42.122688,-90.230934 42.159721,-90.323601 42.197319,-90.367729 42.210209,-90.407173 42.242645,-90.417984 42.263924,-90.427681 42.340633,-90.441597 42.360073,-90.491043 42.388783,-90.563583 42.421837,-90.605827 42.46056,-90.648346 42.475643,-90.651772 42.494698,-90.638329 42.509361,-90.419975 42.508362,-89.923569 42.504108,-89.834618 42.50346,-89.400497 42.49749,-89.359444 42.497906,-88.939079 42.490864,-88.764954 42.490906,-88.70652 42.489655,-88.297897 42.49197,-88.194702 42.489613,-87.79731 42.489132,-87.836945 42.314213,-87.760239 42.156456,-87.670547 42.059822,-87.612625 41.847332,-87.529861 41.723591,-87.532646 41.469715,-87.532448 41.301304,-87.531731 41.173756,-87.532021 41.00993,-87.532669 40.745411,-87.53717 40.49461,-87.535675 40.483246,-87.535339 40.166195,-87.535774 39.887302,-87.535576 39.609341,-87.538567 39.477448,-87.540215 39.350525,-87.597664 39.338268,-87.625237 39.307404,-87.610619 39.297661,-87.615799 39.281418,-87.606895 39.258163,-87.584564 39.248753,-87.588593 39.208466,-87.594208 39.198128,-87.607925 39.196068,-87.644257 39.168507,-87.670326 39.146679,-87.659454 39.130653,-87.662262 39.113468,-87.631668 39.103943,-87.630867 39.088974,-87.612007 39.084606,-87.58532 39.062435,-87.581749 38.995743,-87.591858 38.994083,-87.547905 38.977077,-87.53347 38.963703,-87.530182 38.931919,-87.5392 38.904861,-87.559059 38.869812,-87.550507 38.857891,-87.507889 38.795559,-87.519028 38.776699,-87.508003 38.769722,-87.508316 38.736633,-87.543892 38.685974,-87.588478 38.672169,-87.625191 38.642811,-87.628647 38.622917,-87.619827 38.599209,-87.640594 38.593178,-87.652855 38.573872,-87.672943 38.547424,-87.65139 38.515369,-87.653534 38.500443,-87.679909 38.504005,-87.692818 38.481533,-87.756096 38.466125,-87.758659 38.457096,-87.738953 38.44548,-87.748428 38.417965,-87.784019 38.378124,-87.834503 38.352524,-87.850082 38.286098,-87.863007 38.285362,-87.874039 38.316788,-87.883446 38.315552,-87.888466 38.300659,-87.914108 38.281048,-87.913651 38.302345,-87.925919 38.304771,-87.980019 38.241085,-87.986008 38.234814,-87.977928 38.200714,-87.932289 38.171131,-87.931992 38.157528,-87.950569 38.136913,-87.973503 38.13176,-88.018547 38.103302,-88.012329 38.092346,-87.964867 38.096748,-87.975296 38.073307,-88.034729 38.054085,-88.043091 38.04512,-88.041473 38.038303,-88.021698 38.033531,-88.029213 38.008236,-88.021706 37.975056,-88.042511 37.956264,-88.041771 37.934498,-88.064621 37.929783,-88.078941 37.944,-88.084 37.92366,-88.030441 37.917591,-88.026588 37.905758,-88.044868 37.896004,-88.100082 37.90617,-88.101456 37.895306,-88.075737 37.867809,-88.034241 37.843746,-88.042137 37.827522,-88.089264 37.831249,-88.086029 37.817612,-88.035576 37.805683,-88.072472 37.735401,-88.133636 37.700745,-88.15937 37.660686,-88.157631 37.628479,-88.134171 37.583572,-88.071564 37.51099)))"
+ );
+
+ // two calculations of the area (in square meters)
+ var planar = illinois.getArea() * Math.pow(OpenLayers.INCHES_PER_UNIT['dd'] / OpenLayers.INCHES_PER_UNIT['m'], 2);
+ var geodesic = illinois.getGeodesicArea();
+
+ // from http://en.wikipedia.org/wiki/Illinois
+ var expected = 1.40998e11; // square meters
+
+ var planarErr = Math.abs(planar - expected) / expected;
+ var geodesicErr = Math.abs(geodesic - expected) / expected;
+
+ t.ok(geodesicErr < planarErr, "geodesic measure is better (" + geodesicErr.toFixed(3) + " vs. " + planarErr.toFixed(3) + ")");
+
+ }
+
+ function test_getCentroid(t) {
+ t.plan(5);
+ var bounds = new OpenLayers.Bounds(5, 10, 5, 10);
+ var geometry = bounds.toGeometry();
+ var centroid = geometry.getCentroid();
+ t.eq(geometry.components[0].components.length, 2, "only two vertices since the box has left=right and bottom=top");
+ t.ok(centroid && centroid.x === 5 && centroid.y === 10, "getCentroid returns a point geometry even if the ring of the polygon has only 2 vertices");
+ bounds = new OpenLayers.Bounds(123456789.0, 123456789.0, 123456789.1, 123456789.1);
+ geometry = bounds.toGeometry();
+ centroid = geometry.getCentroid();
+ t.eq(geometry.components[0].components.length, 5, "five vertices expected");
+ var dX = Math.abs(centroid.x - 123456789.05);
+ var dY = Math.abs(centroid.y - 123456789.05);
+ t.ok(centroid && dX < 0.0001 && dY < 0.0001, " getCentroid returns the correct point geometry dX = " + dX + ", dY = " + dY);
+
+ var components = [
+ new OpenLayers.Geometry.Point(0,0), new OpenLayers.Geometry.Point(1,1),
+ new OpenLayers.Geometry.Point(0,1), new OpenLayers.Geometry.Point(1,0)];
+ var linearRing = new OpenLayers.Geometry.LinearRing(components);
+ polygon = new OpenLayers.Geometry.Polygon([linearRing.clone()]);
+ centroid = polygon.getCentroid();
+ var tX = centroid.x;
+ var tY = centroid.y;
+ t.ok( !isNaN(tX) && !isNaN(tY) && tX !== Infinity && tY !== Infinity, " getCentroid for wrong polygon works x = " + tX + ", y = " + tY);
+ }
+
+
+ </script>
+</head>
+<body>
+</body>
+</html>