Skip to content
Browse files

need to add error value to bounding boxes on polygons + boxes SERVER-…

…3725
  • Loading branch information...
1 parent 0ad6185 commit 333e0276374e229764277053ea4be6b92c6fe3ed gregs committed Sep 6, 2011
Showing with 54 additions and 21 deletions.
  1. +22 −10 db/geo/2d.cpp
  2. +17 −0 jstests/geo_poly_line.js
  3. +15 −11 jstests/slowNightly/geo_polygon.js
View
32 db/geo/2d.cpp
@@ -529,6 +529,13 @@ namespace mongo {
if( _max._y > g->_max ) _max._y = g->_max;
}
+ void fudge( const Geo2dType* g ) {
+ _min._x -= g->_error;
+ _min._y -= g->_error;
+ _max._x += g->_error;
+ _max._y += g->_error;
+ }
+
bool onBoundary( Point p, double fudge = 0 ) {
return onBoundary( _min._x, p._x, fudge ) ||
onBoundary( _max._x, p._x, fudge ) ||
@@ -2305,6 +2312,9 @@ namespace mongo {
_want._min = Point( i.next() );
_want._max = Point( i.next() );
+ _wantRegion = _want;
+ _wantRegion.fudge( g ); // Need to make sure we're checking regions within error bounds of where we want
+ fixBox( g, _wantRegion );
fixBox( g, _want );
uassert( 13064 , "need an area > 0 " , _want.area() > 0 );
@@ -2323,18 +2333,18 @@ namespace mongo {
}
void fixBox( const Geo2dType* g, Box& box ) {
- if( _want._min._x > _want._max._x )
- swap( _want._min._x, _want._max._x );
- if( _want._min._y > _want._max._y )
- swap( _want._min._y, _want._max._y );
+ if( box._min._x > box._max._x )
+ swap( box._min._x, box._max._x );
+ if( box._min._y > box._max._y )
+ swap( box._min._y, box._max._y );
double gMin = g->_min;
double gMax = g->_max;
- if( _want._min._x < gMin ) _want._min._x = gMin;
- if( _want._min._y < gMin ) _want._min._y = gMin;
- if( _want._max._x > gMax) _want._max._x = gMax;
- if( _want._max._y > gMax ) _want._max._y = gMax;
+ if( box._min._x < gMin ) box._min._x = gMin;
+ if( box._min._y < gMin ) box._min._y = gMin;
+ if( box._max._x > gMax) box._max._x = gMax;
+ if( box._max._y > gMax ) box._max._y = gMax;
}
void swap( double& a, double& b ) {
@@ -2352,7 +2362,7 @@ namespace mongo {
}
virtual double intersectsBox( Box& cur ) {
- return cur.intersects( _want );
+ return cur.intersects( _wantRegion );
}
virtual KeyResult approxKeyCheck( const Point& p, double& d ) {
@@ -2366,6 +2376,7 @@ namespace mongo {
}
Box _want;
+ Box _wantRegion;
double _wantLen;
double _fudge;
@@ -2392,7 +2403,8 @@ namespace mongo {
uassert( 14030, "polygon must be defined by three points or more", _poly.size() >= 3 );
_bounds = _poly.bounds();
- _bounds.truncate( g );
+ _bounds.fudge( g ); // We need to check regions within the error bounds of these bounds
+ _bounds.truncate( g ); // We don't need to look anywhere outside the space
_maxDim = _g->_error + _bounds.maxDim() / 2;
View
17 jstests/geo_poly_line.js
@@ -0,0 +1,17 @@
+// Test that weird polygons work SERVER-3725
+
+t = db.geo_polygon5;
+t.drop();
+
+t.insert({loc:[0,0]})
+t.insert({loc:[1,0]})
+t.insert({loc:[2,0]})
+t.insert({loc:[3,0]})
+t.insert({loc:[4,0]})
+
+t.ensureIndex( { loc : "2d" } );
+
+printjson( t.find({ loc: { "$within": { "$polygon" : [[0,0], [2,0], [4,0]] } } }).toArray() )
+
+assert.eq( 5, t.find({ loc: { "$within": { "$polygon" : [[0,0], [2,0], [4,0]] } } }).itcount() )
+
View
26 jstests/slowNightly/geo_polygon.js
@@ -26,24 +26,28 @@ if ( shouldRun ) {
for( var n = 0; n < numTests; n++ ){
t.dropIndexes()
t.ensureIndex( { loc : "2d" }, { bits : 2 + n } );
-
-
+
assert.eq( 9 , t.find( { loc: { "$within": { "$polygon" : [[0,0], [1,1], [0,2]] }}} ).count() , "Triangle Test" );
assert.eq( num , t.find( { loc : { "$within" : { "$polygon" : [ [-180,-180], [-180,180], [180,180], [180,-180] ] } } } ).count() , "Bounding Box Test" );
-
+
assert.eq( 441 , t.find( { loc : { "$within" : { "$polygon" : [ [0,0], [0,10], [10,10], [10,0] ] } } } ).count() , "Square Test" );
assert.eq( 25 , t.find( { loc : { "$within" : { "$polygon" : [ [0,0], [0,2], [2,2], [2,0] ] } } } ).count() , "Square Test 2" );
- if(0){ // SERVER-3726
- assert.eq( 331 , t.find( { loc : { "$within" : { "$polygon" : [ [0,0], [0,10], [10,10], [10,0], [5,5] ] } } } ).count() , "Square Missing Chunk Test" );
- assert.eq( 21 , t.find( { loc : { "$within" : { "$polygon" : [ [0,0], [0,2], [2,2], [2,0], [1,1] ] } } } ).count() , "Square Missing Chunk Test 2" );
+
+ if(1){ // SERVER-3726
+ // Points exactly on diagonals may be in or out, depending on how the error calculating the slope falls.
+ assert.between( 341 - 18 , t.find( { loc : { "$within" : { "$polygon" : [ [0,0], [0,10], [10,10], [10,0], [5,5] ] } } } ).count(), 341, "Square Missing Chunk Test", true );
+ assert.between( 21 - 2 , t.find( { loc : { "$within" : { "$polygon" : [ [0,0], [0,2], [2,2], [2,0], [1,1] ] } } } ).count(), 21 , "Square Missing Chunk Test 2", true );
}
-
+
assert.eq( 1 , t.find( { loc: { "$within": { "$polygon" : [[0,0], [0,0], [0,0]] }}} ).count() , "Point Test" );
- if(0){ // SERVER-3725
- assert.eq( 5 , t.find( { loc: { "$within": { "$polygon" : [[0,0], [1,0], [2,0]] }}} ).count() , "Line Test 1" );
- assert.eq( 3 , t.find( { loc: { "$within": { "$polygon" : [[0,0], [0,0], [1,0]] }}} ).count() , "Line Test 2" );
- assert.eq( 5 , t.find( { loc: { "$within": { "$polygon" : [[0,2], [0,1], [0,0]] }}} ).count() , "Line Test 3" );
+
+ // SERVER-3725
+ {
+ assert.eq( 5 , t.find( { loc: { "$within": { "$polygon" : [[0,0], [1,0], [2,0]] }}} ).count() , "Line Test 1" );
+ assert.eq( 3 , t.find( { loc: { "$within": { "$polygon" : [[0,0], [0,0], [1,0]] }}} ).count() , "Line Test 2" );
+ assert.eq( 5 , t.find( { loc: { "$within": { "$polygon" : [[0,2], [0,1], [0,0]] }}} ).count() , "Line Test 3" );
}
+
assert.eq( 3 , t.find( { loc: { "$within": { "$polygon" : [[0,1], [0,0], [0,0]] }}} ).count() , "Line Test 4" );
}
}

0 comments on commit 333e027

Please sign in to comment.
Something went wrong with that request. Please try again.