0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00
mongodb/jstests/geo_center_sphere2.js
2011-04-18 16:42:59 -04:00

159 lines
4.0 KiB
JavaScript

//
// Tests the error handling of spherical queries
// along with multi-location documents.
// This is necessary since the error handling must manage
// multiple documents, and so requires simultaneous testing.
//
var numTests = 30
for ( var test = 0; test < numTests; test++ ) {
//var fixedTest = 6017
//if( fixedTest ) test = fixedTest
Random.srand( 1337 + test );
var radius = 5000 * Random.rand() // km
radius = radius / 6371 // radians
var numDocs = Math.floor( 400 * Random.rand() )
// TODO: Wrapping uses the error value to figure out what would overlap...
var bits = Math.floor( 5 + Random.rand() * 28 )
var maxPointsPerDoc = 50
t = db.sphere
var randomPoint = function() {
return [ Random.rand() * 360 - 180, Random.rand() * 180 - 90 ];
}
// Get a start point that doesn't require wrapping
// TODO: Are we a bit too aggressive with wrapping issues?
var startPoint
var ex = null
do {
t.drop()
startPoint = randomPoint()
t.ensureIndex( { loc : "2d" }, { bits : bits } )
try {
// Check for wrapping issues
t.find( { loc : { $within : { $centerSphere : [ startPoint, radius ] } } } ).toArray()
ex = null
} catch (e) {
ex = e
}
} while (ex)
var pointsIn = 0
var pointsOut = 0
var docsIn = 0
var docsOut = 0
var totalPoints = 0
//var point = randomPoint()
for ( var i = 0; i < numDocs; i++ ) {
var numPoints = Math.floor( Random.rand() * maxPointsPerDoc + 1 )
var docIn = false
var multiPoint = []
totalPoints += numPoints
for ( var p = 0; p < numPoints; p++ ) {
var point = randomPoint()
multiPoint.push( point )
if ( Geo.sphereDistance( startPoint, point ) <= radius ) {
pointsIn++
docIn = true
} else {
pointsOut++
}
}
t.insert( { loc : multiPoint } )
if ( docIn )
docsIn++
else
docsOut++
}
printjson( { test: test,
radius : radius, bits : bits, numDocs : numDocs, pointsIn : pointsIn, docsIn : docsIn, pointsOut : pointsOut,
docsOut : docsOut } )
assert.isnull( db.getLastError() )
assert.eq( docsIn + docsOut, numDocs )
assert.eq( pointsIn + pointsOut, totalPoints )
// $centerSphere
assert.eq( docsIn, t.find( { loc : { $within : { $centerSphere : [ startPoint, radius ] } } } ).count() )
// $nearSphere
var results = t.find( { loc : { $nearSphere : startPoint, $maxDistance : radius } } ).limit( 2 * pointsIn )
.toArray()
assert.eq( pointsIn, results.length )
var distance = 0;
for ( var i = 0; i < results.length; i++ ) {
var minNewDistance = radius + 1
for( var j = 0; j < results[i].loc.length; j++ ){
var newDistance = Geo.sphereDistance( startPoint, results[i].loc[j] )
if( newDistance < minNewDistance && newDistance >= distance ) minNewDistance = newDistance
}
//print( "Dist from : " + results[i].loc[j] + " to " + startPoint + " is "
// + minNewDistance + " vs " + radius )
assert.lte( minNewDistance, radius )
assert.gte( minNewDistance, distance )
distance = minNewDistance
}
// geoNear
var results = db.runCommand( {
geoNear : "sphere", near : startPoint, maxDistance : radius, num : 2 * pointsIn, spherical : true } ).results
/*
printjson( results );
for ( var j = 0; j < results[0].obj.loc.length; j++ ) {
var newDistance = Geo.sphereDistance( startPoint, results[0].obj.loc[j] )
if( newDistance <= radius ) print( results[0].obj.loc[j] + " : " + newDistance )
}
*/
assert.eq( pointsIn, results.length )
var distance = 0;
for ( var i = 0; i < results.length; i++ ) {
var retDistance = results[i].dis
// print( "Dist from : " + results[i].loc + " to " + startPoint + " is "
// + retDistance + " vs " + radius )
var distInObj = false
for ( var j = 0; j < results[i].obj.loc.length && distInObj == false; j++ ) {
var newDistance = Geo.sphereDistance( startPoint, results[i].obj.loc[j] )
distInObj = ( newDistance >= retDistance - 0.0001 && newDistance <= retDistance + 0.0001 )
}
assert( distInObj )
assert.lte( retDistance, radius )
assert.gte( retDistance, distance )
distance = retDistance
}
//break;
}