3 <script src="../../lib/OpenLayers.js"></script>
4 <script type="text/javascript">
6 var components = [new OpenLayers.Geometry.Point(10,14), new OpenLayers.Geometry.Point(5,3)];
7 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)];
8 var linearRing = new OpenLayers.Geometry.LinearRing(components);
9 var linearRing2 = new OpenLayers.Geometry.LinearRing(components2);
11 function test_Polygon_constructor (t) {
13 polygon = new OpenLayers.Geometry.Polygon();
14 t.ok( polygon instanceof OpenLayers.Geometry.Polygon, "new OpenLayers.Geometry.Polygon returns polygon object" );
15 t.eq( polygon.CLASS_NAME, "OpenLayers.Geometry.Polygon", "polygon.CLASS_NAME is set correctly");
16 t.eq( polygon.components.length, 0, "polygon.components is set correctly");
19 function test_Polygon_constructor (t) {
21 polygon = new OpenLayers.Geometry.Polygon([linearRing]);
22 t.ok( polygon instanceof OpenLayers.Geometry.Polygon, "new OpenLayers.Geometry.Polygon returns polygon object" );
23 t.eq( polygon.CLASS_NAME, "OpenLayers.Geometry.Polygon", "polygon.CLASS_NAME is set correctly");
24 t.eq( polygon.components.length, 1, "polygon.components.length is set correctly");
27 function test_Polygon_constructor (t) {
29 polygon = new OpenLayers.Geometry.Polygon([linearRing, linearRing2]);
30 t.ok( polygon instanceof OpenLayers.Geometry.Polygon, "new OpenLayers.Geometry.Polygon returns polygon object" );
31 t.eq( polygon.CLASS_NAME, "OpenLayers.Geometry.Polygon", "polygon.CLASS_NAME is set correctly");
32 t.eq( polygon.components.length, 2, "polygon.components.length is set correctly");
35 function test_Polygon_transform_getBounds (t) {
38 var components = [new OpenLayers.Geometry.Point(10,14), new OpenLayers.Geometry.Point(5,3)];
39 var linearRing = new OpenLayers.Geometry.LinearRing(components);
40 polygon = new OpenLayers.Geometry.Polygon([linearRing.clone()]);
41 polygon.calculateBounds();
42 t.ok( polygon.bounds != null, "bounds calculated by calcBounds" );
43 polygon.transform(new OpenLayers.Projection("EPSG:4326"),
44 new OpenLayers.Projection("EPSG:900913"));
45 t.eq(polygon.bounds, null, "Point bounds cleared after transform");
46 t.eq(polygon.getBounds().toBBOX(), "556597.453889,334111.171355,1113194.907778,1574216.547942", "Bounds are correct")
49 function test_Polygon_getArea(t) {
53 var polygon = new OpenLayers.Geometry.Polygon();
54 t.eq(polygon.getArea(), 0, "getArea empty polygon is 0");
56 var createSquareRing = function(area) {
58 new OpenLayers.Geometry.Point(0, 0),
59 new OpenLayers.Geometry.Point(0, area),
60 new OpenLayers.Geometry.Point(area, area),
61 new OpenLayers.Geometry.Point(area, 0)
63 var ring = new OpenLayers.Geometry.LinearRing(points);
69 var comps = [ createSquareRing(2) ];
71 var polygon = new OpenLayers.Geometry.Polygon(comps);
72 t.eq(polygon.getArea(), 4, "getArea simple polygon works lovely");
75 comps = [ createSquareRing(10),
81 var polygon = new OpenLayers.Geometry.Polygon(comps);
82 t.eq(polygon.getArea(), 71, "getArea polygon with holes works lovely");
84 //simple polygon negative
85 comps = [ createSquareRing(-2) ];
87 var polygon = new OpenLayers.Geometry.Polygon(comps);
88 t.eq(polygon.getArea(), 4, "getArea simple polygon negative works lovely");
90 //polygon with holes negative
91 comps = [ createSquareRing(-10),
97 var polygon = new OpenLayers.Geometry.Polygon(comps);
98 t.eq(polygon.getArea(), 71, "getArea negative polygon with holes works lovely");
102 function test_Polygon_move(t) {
105 polygon = new OpenLayers.Geometry.Polygon([linearRing, linearRing2]);
107 var x = linearRing.components[0].x;
108 var y = linearRing.components[0].y;
109 var x2 = linearRing2.components[0].x;
110 var y2 = linearRing2.components[0].y;
112 var dx = 10 * Math.random();
113 var dy = 10 * Math.random();
115 polygon.move(dx, dy);
117 t.eq(polygon.components[0].components[0].x, x + dx, "move() correctly modifies first x");
118 t.eq(polygon.components[0].components[0].y, y + dy, "move() correctly modifies first y");
119 t.eq(polygon.components[1].components[0].x, x2 + dx, "move() correctly modifies second x");
120 t.eq(polygon.components[1].components[0].y, y2 + dy, "move() correctly modifies second y");
123 function test_Polygon_rotate(t) {
126 var geometry = new OpenLayers.Geometry.Polygon([linearRing, linearRing2]);
130 var angle = 2 * Math.PI * Math.random();
131 var origin = new OpenLayers.Geometry.Point(10 * Math.random(),
133 for(var i=0; i<geometry.components.length; ++i) {
134 comp = geometry.components[i];
135 originals[i] = comp.rotate;
136 comp.rotate = function(a, o) {
137 t.ok(true, "rotate called for component " + i);
138 t.ok(a == angle, "rotate called with correct angle");
139 t.ok(o == origin, "rotate called with correct origin");
142 geometry.rotate(angle, origin);
144 // restore the original rotate defs
145 for(var i=0; i<geometry.components.length; ++i) {
146 comp.rotate = originals[i];
150 function test_Polygon_resize(t) {
153 var tolerance = 1e-10;
154 var geometry = new OpenLayers.Geometry.Polygon([linearRing, linearRing2]);
155 var origin = new OpenLayers.Geometry.Point(10 * Math.random(),
157 var scale = 10 * Math.random();
159 var oldArea = geometry.getArea();
160 var oldPerimeter = geometry.getLength();
161 geometry.resize(scale, origin);
162 var newArea = geometry.getArea();
163 var newPerimeter = geometry.getLength();
165 t.ok((((newArea / oldArea) - (scale * scale)) / (scale * scale)) < tolerance,
166 "resize correctly changes the area of a polygon")
167 t.ok((((newPerimeter / oldPerimeter) - scale) / scale) < tolerance,
168 "resize correctly changes the perimeter of a polygon")
172 for(var i=0; i<geometry.components.length; ++i) {
173 comp = geometry.components[i];
174 originals[i] = comp.resize;
175 comp.resize = function(s, o) {
176 t.ok(true, "resize called for component " + i);
177 t.ok(s == scale, "resize called with correct scale");
178 t.ok(o == origin, "resize called with correct origin");
181 geometry.resize(scale, origin);
183 // restore the original resize defs
184 for(var i=0; i<geometry.components.length; ++i) {
185 comp.resize = originals[i];
190 function test_Polygon_createRegular(t) {
193 var poly = OpenLayers.Geometry.Polygon.createRegularPolygon(new OpenLayers.Geometry.Point(5,0), 6, sides);
194 var polyBounds = poly.getBounds();
195 t.eq(polyBounds.toBBOX(), "-0.981504,-5.981504,10.981504,5.981504", sides + " sided figure generates correct bbox.");
196 t.eq(poly.components.length, 1, "Poly has one linear ring");
197 t.eq(poly.components[0].components.length, sides + 1, "ring has 41 components");
198 t.eq(poly.components[0].components[0].id, poly.components[0].components[sides].id, "ring starts and ends with same geom");
199 t.eq(Math.round(poly.getArea()), Math.round(Math.PI * 36), "area of "+sides+" sided poly rounds to same area as a circle.");
202 var poly = OpenLayers.Geometry.Polygon.createRegularPolygon(new OpenLayers.Geometry.Point(5,0), 6, sides);
203 var polyBounds = poly.getBounds();
204 t.eq(polyBounds.toBBOX(), "-0.196152,-3,10.196152,6", sides + " sided figure generates correct bbox.");
205 t.eq(poly.components.length, 1, "Poly has one linear ring");
206 t.eq(poly.components[0].components.length, sides + 1, "ring has correct count of components");
207 t.eq(poly.components[0].components[0].id, poly.components[0].components[sides].id, "ring starts and ends with same geom");
208 t.eq(Math.round(poly.getArea()), 47, "area of 3 sided poly is correct");
211 var poly3 = OpenLayers.Geometry.Polygon.createRegularPolygon(new OpenLayers.Geometry.Point(10,0), 15, sides);
212 var polyBounds = poly3.getBounds();
213 t.eq(polyBounds.toBBOX(), "-2.990381,-7.5,22.990381,15", sides + " sided figure generates correct bbox.");
214 t.eq(Math.round(polyBounds.getCenterLonLat().lon), 10, "longitude of center of bounds is same as origin");
215 t.eq(poly3.components.length, 1, "Poly has one linear ring");
216 t.eq(poly3.components[0].components.length, sides + 1, "ring has correct count of components");
217 t.eq(poly3.components[0].components[0].id, poly3.components[0].components[sides].id, "ring starts and ends with same geom");
218 t.ok(poly3.getArea() > poly.getArea(), "area with radius 15 > poly with radius 6");
221 var poly4 = OpenLayers.Geometry.Polygon.createRegularPolygon(new OpenLayers.Geometry.Point(10,0), 15, sides);
222 var polyBounds = poly4.getBounds();
223 t.eq(polyBounds.toBBOX(), "-0.606602,-10.606602,20.606602,10.606602", sides + " sided figure generates correct bbox.");
224 t.eq(Math.round(polyBounds.getCenterLonLat().lon), 10, "longitude of center of bounds is same as origin");
225 t.eq(poly4.components.length, 1, "Poly has one linear ring");
226 t.eq(poly4.components[0].components.length, sides + 1, "ring has correct count of components");
227 t.eq(poly4.components[0].components[0].id, poly4.components[0].components[sides].id, "ring starts and ends with same geom");
228 t.ok(poly4.getArea() > poly3.getArea(), "square with radius 15 > triangle with radius 15");
231 function test_Polygon_equals(t) {
234 var x0 = Math.random() * 100;
235 var y0 = Math.random() * 100;
236 var x1 = Math.random() * 100;
237 var y1 = Math.random() * 100;
238 var x2 = Math.random() * 100;
239 var y2 = Math.random() * 100;
240 var point0 = new OpenLayers.Geometry.Point(x0, y0);
241 var point1 = new OpenLayers.Geometry.Point(x1, y1);
242 var point2 = new OpenLayers.Geometry.Point(x2, y2);
243 var pointX = new OpenLayers.Geometry.Point(x0 + 1, y0);
244 var pointY = new OpenLayers.Geometry.Point(x0, y0 + 1);
245 var geometry = new OpenLayers.Geometry.Polygon([
246 new OpenLayers.Geometry.LinearRing([point0, point1, point2])]);
247 var equal = new OpenLayers.Geometry.Polygon([
248 new OpenLayers.Geometry.LinearRing([point0, point1, point2])]);
249 var offX = new OpenLayers.Geometry.Polygon([
250 new OpenLayers.Geometry.LinearRing([pointX, point1, point2])]);
251 var offY = new OpenLayers.Geometry.Polygon([
252 new OpenLayers.Geometry.LinearRing([pointY, point1, point2])]);
253 t.ok(geometry.equals(equal),
254 "equals() returns true for a geometry with equivalent coordinates");
255 t.ok(!geometry.equals(offX),
256 "equals() returns false for a geometry with offset x");
257 t.ok(!geometry.equals(offY),
258 "equals() returns false for a geometry with offset y");
261 function test_distanceTo(t) {
262 var wkt = OpenLayers.Geometry.fromWKT;
264 wkt("POLYGON((0 3, 1 4, 2 3, 1 2, 0 3))"),
266 wkt("LINESTRING(-2 0, 0 -2, 2 -1, 2 0)"),
267 wkt("LINESTRING(0 2, 1 3)"),
272 got: geoms[0].distanceTo(geoms[1]),
273 expected: Math.sqrt(5)
275 got: geoms[0].distanceTo(geoms[1], {details: true}),
277 distance: Math.sqrt(5),
282 got: geoms[0].distanceTo(geoms[2], {details: true}),
284 distance: Math.sqrt(5),
289 got: geoms[0].distanceTo(geoms[3], {details: true}),
296 got: geoms[0].distanceTo(geoms[4]),
297 expected: Math.sqrt(0.5)
299 got: geoms[0].distanceTo(geoms[4], {edge: false}),
303 t.plan(cases.length);
304 for(var i=0; i<cases.length; ++i) {
305 t.eq(cases[i].got, cases[i].expected, "case " + i);
310 function test_getVertices(t) {
314 new OpenLayers.Geometry.Point(10, 20),
315 new OpenLayers.Geometry.Point(20, 30),
316 new OpenLayers.Geometry.Point(30, 40),
317 new OpenLayers.Geometry.Point(40, 50)
319 var polygon = new OpenLayers.Geometry.Polygon([
320 new OpenLayers.Geometry.LinearRing(points)
323 var verts = polygon.getVertices();
324 t.ok(verts instanceof Array, "got back an array");
325 t.eq(verts.length, points.length, "of correct length length");
326 t.geom_eq(verts[0], points[0], "0: correct geometry");
327 t.geom_eq(verts[1], points[1], "1: correct geometry");
328 t.geom_eq(verts[2], points[2], "2: correct geometry");
329 t.geom_eq(verts[3], points[3], "3: correct geometry");
333 function test_Polygon_clone(t) {
336 var x0 = Math.random() * 100;
337 var y0 = Math.random() * 100;
338 var x1 = Math.random() * 100;
339 var y1 = Math.random() * 100;
340 var x2 = Math.random() * 100;
341 var y2 = Math.random() * 100;
342 var point0 = new OpenLayers.Geometry.Point(x0, y0);
343 var point1 = new OpenLayers.Geometry.Point(x1, y1);
344 var point2 = new OpenLayers.Geometry.Point(x2, y2);
345 var geometry = new OpenLayers.Geometry.Polygon([
346 new OpenLayers.Geometry.LinearRing([point0, point1, point2])]);
347 var clone = geometry.clone();
348 t.ok(clone instanceof OpenLayers.Geometry.Polygon,
349 "clone() creates an OpenLayers.Geometry.Polygon");
350 t.ok(geometry.equals(clone), "clone has equivalent coordinates");
353 function test_getGeodesicArea(t) {
357 // from the wfs-states.html example
358 var illinois = OpenLayers.Geometry.fromWKT(
359 "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)))"
362 // two calculations of the area (in square meters)
363 var planar = illinois.getArea() * Math.pow(OpenLayers.INCHES_PER_UNIT['dd'] / OpenLayers.INCHES_PER_UNIT['m'], 2);
364 var geodesic = illinois.getGeodesicArea();
366 // from http://en.wikipedia.org/wiki/Illinois
367 var expected = 1.40998e11; // square meters
369 var planarErr = Math.abs(planar - expected) / expected;
370 var geodesicErr = Math.abs(geodesic - expected) / expected;
372 t.ok(geodesicErr < planarErr, "geodesic measure is better (" + geodesicErr.toFixed(3) + " vs. " + planarErr.toFixed(3) + ")");