Skip to content

Commit 333e027

Browse files
author
gregs
committed
need to add error value to bounding boxes on polygons + boxes SERVER-3725
1 parent 0ad6185 commit 333e027

File tree

3 files changed

+54
-21
lines changed

3 files changed

+54
-21
lines changed

db/geo/2d.cpp

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,13 @@ namespace mongo {
529529
if( _max._y > g->_max ) _max._y = g->_max;
530530
}
531531

532+
void fudge( const Geo2dType* g ) {
533+
_min._x -= g->_error;
534+
_min._y -= g->_error;
535+
_max._x += g->_error;
536+
_max._y += g->_error;
537+
}
538+
532539
bool onBoundary( Point p, double fudge = 0 ) {
533540
return onBoundary( _min._x, p._x, fudge ) ||
534541
onBoundary( _max._x, p._x, fudge ) ||
@@ -2305,6 +2312,9 @@ namespace mongo {
23052312
_want._min = Point( i.next() );
23062313
_want._max = Point( i.next() );
23072314

2315+
_wantRegion = _want;
2316+
_wantRegion.fudge( g ); // Need to make sure we're checking regions within error bounds of where we want
2317+
fixBox( g, _wantRegion );
23082318
fixBox( g, _want );
23092319

23102320
uassert( 13064 , "need an area > 0 " , _want.area() > 0 );
@@ -2323,18 +2333,18 @@ namespace mongo {
23232333
}
23242334

23252335
void fixBox( const Geo2dType* g, Box& box ) {
2326-
if( _want._min._x > _want._max._x )
2327-
swap( _want._min._x, _want._max._x );
2328-
if( _want._min._y > _want._max._y )
2329-
swap( _want._min._y, _want._max._y );
2336+
if( box._min._x > box._max._x )
2337+
swap( box._min._x, box._max._x );
2338+
if( box._min._y > box._max._y )
2339+
swap( box._min._y, box._max._y );
23302340

23312341
double gMin = g->_min;
23322342
double gMax = g->_max;
23332343

2334-
if( _want._min._x < gMin ) _want._min._x = gMin;
2335-
if( _want._min._y < gMin ) _want._min._y = gMin;
2336-
if( _want._max._x > gMax) _want._max._x = gMax;
2337-
if( _want._max._y > gMax ) _want._max._y = gMax;
2344+
if( box._min._x < gMin ) box._min._x = gMin;
2345+
if( box._min._y < gMin ) box._min._y = gMin;
2346+
if( box._max._x > gMax) box._max._x = gMax;
2347+
if( box._max._y > gMax ) box._max._y = gMax;
23382348
}
23392349

23402350
void swap( double& a, double& b ) {
@@ -2352,7 +2362,7 @@ namespace mongo {
23522362
}
23532363

23542364
virtual double intersectsBox( Box& cur ) {
2355-
return cur.intersects( _want );
2365+
return cur.intersects( _wantRegion );
23562366
}
23572367

23582368
virtual KeyResult approxKeyCheck( const Point& p, double& d ) {
@@ -2366,6 +2376,7 @@ namespace mongo {
23662376
}
23672377

23682378
Box _want;
2379+
Box _wantRegion;
23692380
double _wantLen;
23702381
double _fudge;
23712382

@@ -2392,7 +2403,8 @@ namespace mongo {
23922403
uassert( 14030, "polygon must be defined by three points or more", _poly.size() >= 3 );
23932404

23942405
_bounds = _poly.bounds();
2395-
_bounds.truncate( g );
2406+
_bounds.fudge( g ); // We need to check regions within the error bounds of these bounds
2407+
_bounds.truncate( g ); // We don't need to look anywhere outside the space
23962408

23972409
_maxDim = _g->_error + _bounds.maxDim() / 2;
23982410

jstests/geo_poly_line.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Test that weird polygons work SERVER-3725
2+
3+
t = db.geo_polygon5;
4+
t.drop();
5+
6+
t.insert({loc:[0,0]})
7+
t.insert({loc:[1,0]})
8+
t.insert({loc:[2,0]})
9+
t.insert({loc:[3,0]})
10+
t.insert({loc:[4,0]})
11+
12+
t.ensureIndex( { loc : "2d" } );
13+
14+
printjson( t.find({ loc: { "$within": { "$polygon" : [[0,0], [2,0], [4,0]] } } }).toArray() )
15+
16+
assert.eq( 5, t.find({ loc: { "$within": { "$polygon" : [[0,0], [2,0], [4,0]] } } }).itcount() )
17+

jstests/slowNightly/geo_polygon.js

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,24 +26,28 @@ if ( shouldRun ) {
2626
for( var n = 0; n < numTests; n++ ){
2727
t.dropIndexes()
2828
t.ensureIndex( { loc : "2d" }, { bits : 2 + n } );
29-
30-
29+
3130
assert.eq( 9 , t.find( { loc: { "$within": { "$polygon" : [[0,0], [1,1], [0,2]] }}} ).count() , "Triangle Test" );
3231
assert.eq( num , t.find( { loc : { "$within" : { "$polygon" : [ [-180,-180], [-180,180], [180,180], [180,-180] ] } } } ).count() , "Bounding Box Test" );
33-
32+
3433
assert.eq( 441 , t.find( { loc : { "$within" : { "$polygon" : [ [0,0], [0,10], [10,10], [10,0] ] } } } ).count() , "Square Test" );
3534
assert.eq( 25 , t.find( { loc : { "$within" : { "$polygon" : [ [0,0], [0,2], [2,2], [2,0] ] } } } ).count() , "Square Test 2" );
36-
if(0){ // SERVER-3726
37-
assert.eq( 331 , t.find( { loc : { "$within" : { "$polygon" : [ [0,0], [0,10], [10,10], [10,0], [5,5] ] } } } ).count() , "Square Missing Chunk Test" );
38-
assert.eq( 21 , t.find( { loc : { "$within" : { "$polygon" : [ [0,0], [0,2], [2,2], [2,0], [1,1] ] } } } ).count() , "Square Missing Chunk Test 2" );
35+
36+
if(1){ // SERVER-3726
37+
// Points exactly on diagonals may be in or out, depending on how the error calculating the slope falls.
38+
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 );
39+
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 );
3940
}
40-
41+
4142
assert.eq( 1 , t.find( { loc: { "$within": { "$polygon" : [[0,0], [0,0], [0,0]] }}} ).count() , "Point Test" );
42-
if(0){ // SERVER-3725
43-
assert.eq( 5 , t.find( { loc: { "$within": { "$polygon" : [[0,0], [1,0], [2,0]] }}} ).count() , "Line Test 1" );
44-
assert.eq( 3 , t.find( { loc: { "$within": { "$polygon" : [[0,0], [0,0], [1,0]] }}} ).count() , "Line Test 2" );
45-
assert.eq( 5 , t.find( { loc: { "$within": { "$polygon" : [[0,2], [0,1], [0,0]] }}} ).count() , "Line Test 3" );
43+
44+
// SERVER-3725
45+
{
46+
assert.eq( 5 , t.find( { loc: { "$within": { "$polygon" : [[0,0], [1,0], [2,0]] }}} ).count() , "Line Test 1" );
47+
assert.eq( 3 , t.find( { loc: { "$within": { "$polygon" : [[0,0], [0,0], [1,0]] }}} ).count() , "Line Test 2" );
48+
assert.eq( 5 , t.find( { loc: { "$within": { "$polygon" : [[0,2], [0,1], [0,0]] }}} ).count() , "Line Test 3" );
4649
}
50+
4751
assert.eq( 3 , t.find( { loc: { "$within": { "$polygon" : [[0,1], [0,0], [0,0]] }}} ).count() , "Line Test 4" );
4852
}
4953
}

0 commit comments

Comments
 (0)