summaryrefslogtreecommitdiff
path: root/jstests/core/geo_big_polygon2.js
diff options
context:
space:
mode:
authorJonathan Abrahams <jonathan@mongodb.com>2014-12-03 14:30:55 -0500
committerMatt Kangas <matt.kangas@mongodb.com>2014-12-23 12:31:57 -0500
commit94b1781bcdfb70156fb3b5f6978400007279cc0d (patch)
tree1548cff84c5a3f079243a57af54aa7663991e169 /jstests/core/geo_big_polygon2.js
parentc4691732d3a7cdcdff2a28c970f89c06d3c428b6 (diff)
downloadmongo-94b1781bcdfb70156fb3b5f6978400007279cc0d.tar.gz
SERVER-16406 Big poly tests
Includes: Reduce N-polygon test to 25000 from 100000 Closes #887 Signed-off-by: Matt Kangas <matt.kangas@mongodb.com>
Diffstat (limited to 'jstests/core/geo_big_polygon2.js')
-rw-r--r--jstests/core/geo_big_polygon2.js867
1 files changed, 867 insertions, 0 deletions
diff --git a/jstests/core/geo_big_polygon2.js b/jstests/core/geo_big_polygon2.js
new file mode 100644
index 00000000000..9fb9ffead3d
--- /dev/null
+++ b/jstests/core/geo_big_polygon2.js
@@ -0,0 +1,867 @@
+//
+// Big Polygon related tests
+// - Tests the capability for a geo query with a big polygon object (strictCRS)
+// $geoWithin & $geoIntersects
+// - Big polygon objects cannot be stored
+// Try all different shapes queries against various stored geo points, line & polygons
+
+var crs84CRS = {
+ type: "name",
+ properties: {
+ name: "urn:ogc:def:crs:OGC:1.3:CRS84"
+ }
+};
+var epsg4326CRS = {
+ type: "name",
+ properties: {
+ name: "EPSG:4326"
+ }
+};
+var strictCRS = {
+ type: "name",
+ properties: {
+ name: "urn:x-mongodb:crs:strictwinding:EPSG:4326"
+ }
+};
+// invalid CRS name
+var badCRS = {
+ type: "name",
+ properties: {
+ name: "urn:x-mongodb:crs:invalid:EPSG:4326"
+ }
+};
+
+// helper to generate a line along a longitudinal
+function genLonLine(lon, startLat, endLat, latStep) {
+ var line = [];
+ for (var lat = startLat; lat <= endLat; lat += latStep) {
+ line.push( [ lon, lat ] );
+ }
+ return line;
+}
+
+// Main program
+// Clear out collection
+var coll = db.geo_bigpoly;
+coll.drop();
+
+// GeoJson Objects to be inserted into collection
+// coordinates are longitude, latitude
+// strictCRS (big polygon) cannot be stored in the collection
+var objects = [
+ {
+ name: "boat ramp",
+ geo: {
+ type: "Point",
+ coordinates: [ -97.927117, 30.327376 ]
+ }
+ },
+ {
+ name: "on equator",
+ geo: {
+ type: "Point",
+ coordinates: [ -97.9 , 0 ]
+ }
+ },
+ {
+ name: "just north of equator",
+ geo: {
+ type: "Point",
+ coordinates: [ -97.9 , 0.1 ]
+ }
+ },
+ {
+ name: "just south of equator",
+ geo: {
+ type: "Point",
+ coordinates: [ -97.9 , -0.1 ]
+ }
+ },
+ {
+ name: "north pole - crs84CRS",
+ geo: {
+ type: "Point",
+ coordinates: [ -97.9 , 90.0 ],
+ crs: crs84CRS
+ }
+ },
+ {
+ name: "south pole - epsg4326CRS",
+ geo: {
+ type: "Point",
+ coordinates: [ -97.9 , -90.0 ],
+ crs: epsg4326CRS
+ }
+ },
+ {
+ name: "short line string: PA, LA, 4corners, ATX, Mansfield, FL, Reston, NYC",
+ geo: {
+ type: "LineString",
+ coordinates: [
+ [ -122.1611953, 37.4420407 ],
+ [ -118.283638, 34.028517 ],
+ [ -109.045223, 36.9990835 ],
+ [ -97.850404, 30.3921555 ],
+ [ -97.904187, 30.395457 ],
+ [ -86.600836, 30.398147 ],
+ [ -77.357837, 38.9589935 ],
+ [ -73.987723, 40.7575074 ]
+ ]
+ }
+ },
+ {
+ name: "1024 point long line string from south pole to north pole",
+ geo: {
+ type: "LineString",
+ coordinates: genLonLine(2.349902, -90.0, 90.0, 180.0 / 1024)
+ }
+ },
+ {
+ name: "line crossing equator - epsg4326CRS",
+ geo: {
+ type: "LineString",
+ coordinates: [
+ [ -77.0451853, -12.0553442 ],
+ [ -76.7784557, 18.0098528 ]
+ ],
+ crs: epsg4326CRS
+ }
+ },
+ {
+ name: "GeoJson polygon",
+ geo: {
+ type: "Polygon",
+ coordinates: [
+ [ [ -80.0, 30.0 ],
+ [ -40.0, 30.0 ],
+ [ -40.0, 60.0 ],
+ [ -80.0, 60.0 ],
+ [ -80.0, 30.0 ] ]
+ ]
+ }
+ },
+ {
+ name: "polygon w/ hole",
+ geo: {
+ type: "Polygon",
+ coordinates: [
+ [ [ -80.0, 30.0 ],
+ [ -40.0, 30.0 ],
+ [ -40.0, 60.0 ],
+ [-80.0, 60.0 ],
+ [ -80.0, 30.0 ] ],
+ [ [ -70.0, 40.0 ],
+ [ -60.0, 40.0 ],
+ [ -60.0, 50.0 ],
+ [ -70.0, 50.0 ],
+ [ -70.0, 40.0 ] ]
+ ]
+ }
+ },
+ {
+ name: "polygon w/ two holes",
+ geo: {
+ type: "Polygon",
+ coordinates: [
+ [ [ -80.0, 30.0 ],
+ [ -40.0, 30.0 ],
+ [ -40.0, 60.0 ],
+ [ -80.0, 60.0 ],
+ [ -80.0, 30.0 ] ],
+ [ [ -70.0, 40.0 ],
+ [ -60.0, 40.0 ],
+ [ -60.0, 50.0 ],
+ [ -70.0, 50.0 ],
+ [ -70.0, 40.0 ] ],
+ [ [ -55.0, 40.0 ],
+ [ -45.0, 40.0 ],
+ [ -45.0, 50.0 ],
+ [ -55.0, 50.0 ],
+ [ -55.0, 40.0 ] ]
+ ]
+ }
+ },
+ {
+ name: "polygon covering North pole",
+ geo: {
+ type: "Polygon",
+ coordinates: [
+ [ [ -120.0, 89.0 ],
+ [ 0.0, 89.0 ],
+ [ 120.0, 89.0 ],
+ [ -120.0, 89.0 ] ]
+ ]
+ }
+ },
+ {
+ name: "polygon covering South pole",
+ geo: {
+ type: "Polygon",
+ coordinates: [
+ [ [ -120.0, -89.0 ],
+ [ 0.0, -89.0 ],
+ [ 120.0, -89.0 ],
+ [ -120.0, -89.0 ] ]
+ ]
+ }
+ },
+ {
+ name: "big polygon/rectangle covering both poles",
+ geo: {
+ type: "Polygon",
+ coordinates: [
+ [ [ -130.0, 89.0 ],
+ [ -120.0, 89.0 ],
+ [ -120.0, -89.0 ],
+ [ -130.0, -89.0 ],
+ [ -130.0, 89.0 ] ]
+ ],
+ crs: strictCRS
+ }
+ },
+ {
+ name: "polygon (triangle) w/ hole at North pole",
+ geo: {
+ type: "Polygon",
+ coordinates: [
+ [ [ -120.0, 80.0 ],
+ [ 0.0, 80.0 ],
+ [ 120.0, 80.0 ],
+ [-120.0, 80.0 ] ],
+ [ [ -120.0, 88.0 ],
+ [ 0.0, 88.0 ],
+ [ 120.0, 88.0 ],
+ [-120.0, 88.0 ] ]
+ ]
+ }
+ },
+ {
+ name: "polygon with edge on equator",
+ geo: {
+ type: "Polygon",
+ coordinates: [
+ [ [ -120.0, 0.0 ],
+ [ 120.0, 0.0 ],
+ [ 0.0, 90.0 ],
+ [ -120.0, 0.0 ] ]
+ ]
+ }
+ },
+ {
+ name: "polygon just inside single hemisphere (Northern) - China, California, Europe",
+ geo: {
+ type: "Polygon",
+ coordinates: [
+ [ [ 120.0, 0.000001 ],
+ [ -120.0, 0.000001 ],
+ [ 0.0, 0.000001 ],
+ [ 120.0, 0.000001 ] ]
+ ]
+ }
+ },
+ {
+ name: "polygon inside Northern hemisphere",
+ geo: {
+ type: "Polygon",
+ coordinates: [
+ [ [ 120.0, 80.0 ],
+ [ -120.0, 80.0 ],
+ [ 0.0, 80.0 ],
+ [ 120.0, 80.0 ] ]
+ ]
+ }
+ },
+ {
+ name: "polygon just inside a single hemisphere (Southern) - Pacific, Indonesia, Africa",
+ geo: {
+ type: "Polygon",
+ coordinates: [
+ [ [ -120.0, -0.000001 ],
+ [ 120.0, -0.000001 ],
+ [ 0.0, -0.000001 ],
+ [ -120.0, -0.000001 ] ]
+ ]
+ }
+ },
+ {
+ name: "polygon inside Southern hemisphere",
+ geo: {
+ type: "Polygon",
+ coordinates: [
+ [ [ -120.0, -80.0 ],
+ [ 120.0, -80.0 ],
+ [ 0.0, -80.0 ],
+ [ -120.0, -80.0 ] ]
+ ]
+ }
+ },
+ {
+ name: "single point (MultiPoint): Palo Alto",
+ geo: {
+ type: "MultiPoint",
+ coordinates: [
+ [ -122.1611953, 37.4420407 ]
+ ]
+ }
+ },
+ {
+ name: "multiple points(MultiPoint): PA, LA, 4corners, ATX, Mansfield, FL, Reston, NYC",
+ geo: {
+ type: "MultiPoint",
+ coordinates: [
+ [ -122.1611953, 37.4420407 ],
+ [ -118.283638, 34.028517 ],
+ [ -109.045223, 36.9990835 ],
+ [ -97.850404, 30.3921555 ],
+ [ -97.904187, 30.395457 ],
+ [ -86.600836, 30.398147 ],
+ [ -77.357837, 38.9589935 ],
+ [ -73.987723, 40.7575074 ]
+ ]
+ }
+ },
+ {
+ name: "two points (MultiPoint): Shenzhen, Guangdong, China",
+ geo: {
+ type: "MultiPoint",
+ coordinates: [
+ [ 114.0538788, 22.5551603 ],
+ [ 114.022837, 22.44395 ]
+ ]
+ }
+ },
+ {
+ name: "two points (MultiPoint) but only one in: Shenzhen, Guangdong, China",
+ geo: {
+ type: "MultiPoint",
+ coordinates: [
+ [ 114.0538788, 22.5551603 ],
+ [ 113.743858, 23.025815 ]
+ ]
+ }
+ },
+ {
+ name: "multi line string: new zealand bays",
+ geo: {
+ type: "MultiLineString",
+ coordinates: [
+ [ [ 172.803869, -43.592789 ],
+ [ 172.659335, -43.620348 ],
+ [ 172.684038, -43.636528 ],
+ [ 172.820922, -43.605325 ] ],
+ [ [ 172.830497, -43.607768 ],
+ [ 172.813263, -43.656319 ],
+ [ 172.823096, -43.660996 ],
+ [ 172.850943, -43.607609 ] ],
+ [ [ 172.912056, -43.623148 ],
+ [ 172.887696, -43.670897 ],
+ [ 172.900469, -43.676178 ],
+ [ 172.931735, -43.622839 ] ]
+ ]
+ }
+ },
+ {
+ name: "multi polygon: new zealand north and south islands",
+ geo: {
+ type: "MultiPolygon",
+ coordinates: [
+ [
+ [ [ 165.773255, -45.902933 ],
+ [ 169.398419, -47.261538 ],
+ [ 174.672744, -41.767722 ],
+ [ 172.288845, -39.897992 ],
+ [ 165.773255, -45.902933 ] ]
+ ],
+ [
+ [ [ 173.166448, -39.778262 ],
+ [ 175.342744, -42.677333 ],
+ [ 179.913373, -37.224362 ],
+ [ 171.475953, -32.688871 ],
+ [ 173.166448, -39.778262 ] ]
+ ]
+ ]
+ }
+ },
+ {
+ name: "geometry collection: point in Australia and triangle around Australia",
+ geo: {
+ type: "GeometryCollection",
+ geometries: [
+ {
+ name: "center of Australia",
+ type: "Point",
+ coordinates: [ 133.985885, -27.240790 ]
+ },
+ {
+ name: "Triangle around Australia",
+ type: "Polygon",
+ coordinates: [
+ [ [ 97.423178, -44.735405 ],
+ [ 169.845050, -38.432287 ],
+ [ 143.824366, 15.966509 ],
+ [ 97.423178, -44.735405 ] ]
+ ]
+ }
+ ]
+ }
+ }
+];
+
+
+// Test various polygons which are not queryable
+var badPolys = [
+ {
+ name: "Polygon with bad CRS",
+ type: "Polygon",
+ coordinates: [
+ [ [ 114.0834046, 22.6648202 ],
+ [ 113.8293457, 22.3819359 ],
+ [ 114.2736054, 22.4047911 ],
+ [ 114.0834046, 22.6648202 ] ]
+ ],
+ crs: badCRS
+ },
+ {
+ name: "Open polygon < 3 sides",
+ type: "Polygon",
+ coordinates: [
+ [ [ 114.0834046, 22.6648202 ],
+ [ 113.8293457, 22.3819359 ] ]
+ ],
+ crs: strictCRS
+ },
+ {
+ name: "Open polygon > 3 sides",
+ type: "Polygon",
+ coordinates: [
+ [ [ 114.0834046, 22.6648202 ],
+ [ 113.8293457, 22.3819359 ],
+ [ 114.2736054, 22.4047911 ],
+ [ 114.1, 22.5 ] ]
+ ],
+ crs: strictCRS
+ },
+ {
+ name: "duplicate non-adjacent points",
+ type: "Polygon",
+ coordinates: [
+ [ [ 114.0834046, 22.6648202 ],
+ [ 113.8293457, 22.3819359 ],
+ [ 114.2736054, 22.4047911 ],
+ [ 113.8293457, 22.3819359 ],
+ [ -65.9165954, 22.6648202 ],
+ [ 114.0834046, 22.6648202 ] ]
+ ],
+ crs: strictCRS
+ },
+ {
+ name: "One hole in polygon",
+ type: "Polygon",
+ coordinates: [
+ [ [ -80.0, 30.0 ],
+ [ -40.0, 30.0 ],
+ [ -40.0, 60.0 ],
+ [ -80.0, 60.0 ],
+ [ -80.0, 30.0 ] ],
+ [ [ -70.0, 40.0 ],
+ [ -60.0, 40.0 ],
+ [ -60.0, 50.0 ],
+ [ -70.0, 50.0 ],
+ [ -70.0, 40.0 ] ]
+ ],
+ crs: strictCRS
+ },
+ {
+ name: "2 holes in polygon",
+ type: "Polygon",
+ coordinates: [
+ [ [ -80.0, 30.0 ],
+ [ -40.0, 30.0 ],
+ [ -40.0, 60.0 ],
+ [ -80.0, 60.0 ],
+ [ -80.0, 30.0 ] ],
+ [ [ -70.0, 40.0 ],
+ [ -60.0, 40.0 ],
+ [ -60.0, 50.0 ],
+ [ -70.0, 50.0 ],
+ [ -70.0, 40.0 ] ],
+ [ [ -55.0, 40.0 ],
+ [ -45.0, 40.0 ],
+ [ -45.0, 50.0 ],
+ [ -55.0, 50.0 ],
+ [ -55.0, 40.0 ] ]
+ ],
+ crs: strictCRS
+ },
+ {
+ name: "complex polygon (edges cross)",
+ type: "Polygon",
+ coordinates: [
+ [ [ 10.0, 10.0 ],
+ [ 20.0, 10.0 ],
+ [ 10.0, 20.0 ],
+ [ 20.0, 20.0 ],
+ [ 10.0, 10.0 ] ]
+ ],
+ crs: strictCRS
+ }
+];
+
+
+// Closed polygons used in query (3, 4, 5, 6-sided)
+var polys = [
+ {
+ name: "3 sided closed polygon",
+ type: "Polygon", // triangle
+ coordinates: [ [
+ [ 10.0, 10.0 ],
+ [ 20.0, 10.0 ],
+ [ 15.0, 17.0 ],
+ [ 10.0, 10.0 ]
+ ] ],
+ crs: strictCRS,
+ nW: 0, nI: 1
+ },
+ {
+ name: "3 sided closed polygon (non-big)",
+ type: "Polygon", // triangle
+ coordinates: [ [
+ [ 10.0, 10.0 ],
+ [ 20.0, 10.0 ],
+ [ 15.0, 17.0 ],
+ [ 10.0, 10.0 ]
+ ] ],
+ nW: 0, nI: 1
+ },
+ {
+ name: "4 sided closed polygon",
+ type: "Polygon", // rectangle
+ coordinates: [ [
+ [ 10.0, 10.0 ],
+ [ 20.0, 10.0 ],
+ [ 20.0, 20.0 ],
+ [ 10.0, 20.0 ],
+ [ 10.0, 10.0 ]
+ ] ],
+ crs: strictCRS,
+ nW: 0, nI: 1
+ },
+ {
+ name: "4 sided closed polygon (non-big)",
+ type: "Polygon", // rectangle
+ coordinates: [
+ [ [ 10.0, 10.0 ],
+ [ 20.0, 10.0 ],
+ [ 20.0, 20.0 ],
+ [ 10.0, 20.0 ],
+ [ 10.0, 10.0 ] ]
+ ],
+ nW: 0, nI: 1
+ },
+ {
+ name: "5 sided closed polygon",
+ type: "Polygon", // pentagon
+ coordinates: [ [
+ [ 10.0, 10.0 ],
+ [ 20.0, 10.0 ],
+ [ 25.0, 18.0 ],
+ [ 15.0, 25.0 ],
+ [ 5.0, 18.0 ],
+ [ 10.0, 10.0 ]
+ ] ],
+ crs: strictCRS,
+ nW: 0, nI: 1
+ },
+ {
+ name: "5 sided closed polygon (non-big)",
+ type: "Polygon", // pentagon
+ coordinates: [ [
+ [ 10.0, 10.0 ],
+ [ 20.0, 10.0 ],
+ [ 25.0, 18.0 ],
+ [ 15.0, 25.0 ],
+ [ 5.0, 18.0 ],
+ [ 10.0, 10.0 ]
+ ] ],
+ nW: 0, nI: 1
+ },
+ {
+ name: "6 sided closed polygon",
+ type: "Polygon", // hexagon
+ coordinates: [ [
+ [ 10.0, 10.0 ],
+ [ 15.0, 10.0 ],
+ [ 22.0, 15.0 ],
+ [ 15.0, 20.0 ],
+ [ 10.0, 20.0 ],
+ [ 7.0, 15.0 ],
+ [ 10.0, 10.0 ]
+ ] ],
+ crs: strictCRS,
+ nW: 0, nI: 1
+ },
+ {
+ name: "6 sided closed polygon (non-big)",
+ type: "Polygon", // hexagon
+ coordinates: [ [
+ [ 10.0, 10.0 ],
+ [ 15.0, 10.0 ],
+ [ 22.0, 15.0 ],
+ [ 15.0, 20.0 ],
+ [ 10.0, 20.0 ],
+ [ 7.0, 15.0 ],
+ [ 10.0, 10.0 ]
+ ] ],
+ nW: 0, nI: 1
+ }
+];
+
+// helper function to create n-sided polygon
+function nGonGenerator(N, D, clockwise, LON, LAT) {
+ // compute N points on a circle centered at LAT,LON
+ // with diameter = D
+ // and lat*lat + lon*lon = (D/2)*(D/2)
+ // lat range is -10 to +10
+ // lon = sqrt( (D/2)*(D/2) - lat*lat )
+ // N = number of edges
+ // N must be even!
+ // edge lengths will be uneven with this quick & dirty approach
+ N = (N % 2 == 1) ? N + 1 : N;
+ var eps = 2 * D / N;
+ var lat=0;
+ var lon=0;
+ var pts = [];
+ var i = 0;
+ // produce longitude values in pairs
+ // traverse with left foot outside the circle (clockwise) to define the big polygon
+ for (i = 0, lat = D / 2; i <= N / 2; ++i, lat -= eps) {
+ if ( lat < (-D / 2) ) {
+ // set fixing lat
+ lat = (-D / 2);
+ }
+ lon = Math.sqrt( (D / 2) * (D / 2) - (lat * lat) );
+ newlat = lat + LAT;
+ newlon = lon + LON;
+ conjugateLon = LON - lon;
+ pts[i] = [ newlon, newlat ];
+ pts[N-i] = [ conjugateLon, newlat ];
+ }
+ // Reverse points if counterclockwise
+ if (!clockwise) {
+ pts = pts.reverse();
+ }
+ // ensure we connected the dots
+ assert(tojson(pts[0]) == tojson(pts[N]));
+ return pts;
+}
+
+// helper function to return number of valid objects
+function getNumberOfValidObjects(objects) {
+ var i = 0;
+ objects.forEach(function(o) {
+ // strictCRS cannot be stored
+ if (!o.geo.crs || o.geo.crs != strictCRS) {
+ i++;
+ }
+ });
+ return i;
+}
+
+var totalObjects = getNumberOfValidObjects(objects);
+
+// test various n-sided polygons in query, (n: <number of sides>, d: <diameter>)
+// Try them in both clockwise & counterclockwise order
+var nsidedPolys = [
+ // Big Polygon centered on 0, 0
+ {
+ name: "4 sided polygon centered on 0, 0",
+ type: "Polygon",
+ coordinates: [
+ nGonGenerator(4, 30, true, 0, 0)
+ ],
+ crs: strictCRS,
+ nW: totalObjects - 3,
+ nI: totalObjects
+ },
+ // Non-big polygons have counterclockwise coordinates
+ {
+ name: "4 sided polygon centered on 0, 0 (non-big)",
+ type: "Polygon",
+ coordinates: [
+ nGonGenerator(4, 30, false, 0, 0)
+ ],
+ nW: 0,
+ nI: 3
+ },
+ {
+ name: "100 sided polygon centered on 0, 0",
+ type: "Polygon",
+ coordinates: [
+ nGonGenerator(100, 20, true, 0, 0)
+ ],
+ crs: strictCRS,
+ nW: totalObjects - 3,
+ nI: totalObjects
+ },
+ {
+ name: "100 sided polygon centered on 0, 0 (non-big)",
+ type: "Polygon",
+ coordinates: [
+ nGonGenerator(100, 20, false, 0, 0)
+ ],
+ nW: 0,
+ nI: 3
+ },
+ {
+ name: "5000 sided polygon centered on 0, 0 (non-big)",
+ type: "Polygon",
+ coordinates: [
+ nGonGenerator(5000, 89.99, false, 0, 0)
+ ],
+ nW: 0,
+ nI: 3
+ },
+ {
+ name: "25000 sided polygon centered on 0, 0",
+ type: "Polygon",
+ coordinates: [
+ nGonGenerator(25000, 89.99, true, 0, 0)
+ ],
+ crs: strictCRS,
+ nW: totalObjects - 3,
+ nI: totalObjects
+ },
+ // Big polygon centered on Shenzen
+ {
+ name: "4 sided polygon centered on Shenzen",
+ type: "Polygon",
+ coordinates: [
+ nGonGenerator(4, 5, true, 114.1, 22.55)
+ ],
+ crs: strictCRS,
+ nW: totalObjects - 3,
+ nI: totalObjects - 2
+ },
+ {
+ name: "4 sided polygon centered on Shenzen (non-big)",
+ type: "Polygon",
+ coordinates: [
+ nGonGenerator(4, 5, false, 114.1, 22.55)
+ ],
+ crs: strictCRS,
+ nW: 2,
+ nI: 3
+ }
+];
+
+// Populate with 2dsphere index
+assert.commandWorked(coll.ensureIndex({geo: "2dsphere"}), "create 2dsphere index");
+
+// Insert objects into collection
+objects.forEach(function(o) {
+ // strictCRS objects cannot be stored
+ if (o.geo.crs && o.geo.crs == strictCRS) {
+ assert.writeError(coll.insert(o), "insert " + o.name);
+ } else {
+ assert.writeOK(coll.insert(o), "insert " + o.name);
+ }
+});
+
+// Try creating other index types
+assert.commandWorked(
+ coll.ensureIndex({geo: "2dsphere", a: 1}),
+ "compound index, geo");
+// These other index types will fail because of the GeoJSON documents
+assert.commandFailed(
+ coll.ensureIndex({geo: "2dsphere", a: "text"}),
+ "compound index, geo & text");
+assert.commandFailed(
+ coll.ensureIndex({geo: "geoHaystack" }, {bucketSize:1}),
+ "geoHaystack index");
+assert.commandFailed(
+ coll.ensureIndex({geo: "2d"}),
+ "2d index");
+
+totalObjects = coll.count();
+
+// Test with none & 2dsphere index
+var indexes = ["none", "2dsphere"];
+
+indexes.forEach(function(index) {
+
+ // Reset indexes on collection
+ assert.commandWorked(coll.dropIndexes(), "drop indexes");
+
+ if (index != "none") {
+ // Create index
+ assert.commandWorked(coll.ensureIndex({geo: index}), "create " + index + " index");
+ }
+
+ // These polygons should not be queryable
+ badPolys.forEach(function(p) {
+
+ // within
+ assert.throws(function() {
+ coll.count({geo: {$geoWithin: {$geometry: p}}});},
+ null,
+ "within " + p.name);
+
+ // intersection
+ assert.throws(function() {
+ coll.count({geo: {$geoIntersects: {$geometry: p}}});},
+ null,
+ "intersects " + p.name);
+ });
+
+
+ // Tests for closed polygons
+ polys.forEach(function(p) {
+
+ // geoWithin query
+ var docArray = [];
+ var q = {geo: {$geoWithin: {$geometry: p}}};
+ // Test query in aggregate
+ docArray = coll.aggregate({$match: q}).toArray();
+ assert.eq(p.nW, docArray.length, "aggregate within " + p.name);
+ docArray = coll.find(q).toArray();
+ assert.eq(p.nW, docArray.length, "within " + p.name);
+
+ // geoIntersects query
+ q = {geo: {$geoIntersects: {$geometry: p}}};
+ // Test query in aggregate
+ docArray = coll.aggregate({$match: q}).toArray();
+ assert.eq(p.nI, docArray.length, "aggregate intersects " + p.name);
+ docArray = coll.find(q).toArray();
+ assert.eq(p.nI, docArray.length, p.name + " intersects");
+ // Update on matching docs
+ var result = coll.update(q, {$set: {stored: ObjectId()}}, {multi: true});
+ // only check nModified if write commands are enabled
+ if ( coll.getMongo().writeMode() == "commands" ) {
+ assert.eq(p.nI, result.nModified, "update " + p.name);
+ }
+ // Remove & restore matching docs
+ assert.eq(p.nI, coll.remove(q).nRemoved, "remove " + p.name);
+ var bulk = coll.initializeUnorderedBulkOp();
+ docArray.forEach(function(doc) {
+ bulk.insert(doc);
+ });
+ assert.eq(docArray.length, bulk.execute().nInserted, "reinsert " + p.name);
+
+ });
+
+ // test the n-sided closed polygons
+ nsidedPolys.forEach(function(p) {
+
+ // within
+ assert.eq(p.nW,
+ coll.count({geo: {$geoWithin: {$geometry: p}}}),
+ "within " + p.name);
+
+ // intersects
+ assert.eq(p.nI,
+ coll.count({geo: {$geoIntersects: {$geometry: p}}}),
+ "intersection " + p.name);
+
+ });
+
+});