diff options
author | Chris Schlaeger <chris@linux.com> | 2014-08-12 21:56:44 +0200 |
---|---|---|
committer | Chris Schlaeger <chris@linux.com> | 2014-08-12 21:56:44 +0200 |
commit | ea346a785dc1b3f7c156f6fc33da634e1f1a627b (patch) | |
tree | af67530553d20b6e82ad60fd79593e9c4abf5565 /misc/openlayers/tests/Geometry | |
parent | 59741cd535c47f25971bf8c32b25da25ceadc6d5 (diff) | |
download | postrunner-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.html | 431 | ||||
-rw-r--r-- | misc/openlayers/tests/Geometry/Curve.html | 157 | ||||
-rw-r--r-- | misc/openlayers/tests/Geometry/LineString.html | 443 | ||||
-rw-r--r-- | misc/openlayers/tests/Geometry/LinearRing.html | 362 | ||||
-rw-r--r-- | misc/openlayers/tests/Geometry/MultiLineString.html | 267 | ||||
-rw-r--r-- | misc/openlayers/tests/Geometry/MultiPoint.html | 130 | ||||
-rw-r--r-- | misc/openlayers/tests/Geometry/MultiPolygon.html | 34 | ||||
-rw-r--r-- | misc/openlayers/tests/Geometry/Point.html | 244 | ||||
-rw-r--r-- | misc/openlayers/tests/Geometry/Polygon.html | 420 |
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> |