Index: lucene/spatial/src/test/org/apache/lucene/spatial/vector/TestTwoDoublesStrategy.java =================================================================== --- lucene/spatial/src/test/org/apache/lucene/spatial/vector/TestTwoDoublesStrategy.java (revision 1354804) +++ lucene/spatial/src/test/org/apache/lucene/spatial/vector/TestTwoDoublesStrategy.java (working copy) @@ -50,8 +50,7 @@ @Test public void testCircleShapeSupport() { Circle circle = new CircleImpl(new PointImpl(0, 0), 10, this.ctx); - SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, circle); - Query query = this.strategy.makeQuery(args, this.fieldInfo); + Query query = this.strategy.makeIntersectsQuery(circle, 0, this.fieldInfo); assertNotNull(query); } @@ -60,7 +59,7 @@ public void testInvalidQueryShape() { Point point = new PointImpl(0, 0); SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, point); - this.strategy.makeQuery(args, this.fieldInfo); + this.strategy.makeIntersectsQuery(point, 0, this.fieldInfo); } @Test Index: lucene/spatial/src/test/org/apache/lucene/spatial/prefix/TestRecursivePrefixTreeStrategy.java =================================================================== --- lucene/spatial/src/test/org/apache/lucene/spatial/prefix/TestRecursivePrefixTreeStrategy.java (revision 1354804) +++ lucene/spatial/src/test/org/apache/lucene/spatial/prefix/TestRecursivePrefixTreeStrategy.java (working copy) @@ -132,9 +132,7 @@ //TODO can we use super.runTestQueries() ? private void checkHits(Point pt, double dist, int assertNumFound, int[] assertIds) { Shape shape = ctx.makeCircle(pt,dist); - SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects,shape); - args.setDistPrecision(0.0); - SearchResults got = executeQuery(strategy.makeQuery(args, fieldInfo), 100); + SearchResults got = executeQuery(strategy.makeIntersectsQuery(shape, 0, fieldInfo), 100); assertEquals(""+shape,assertNumFound,got.numFound); if (assertIds != null) { Set gotIds = new HashSet(); Index: lucene/spatial/src/test/org/apache/lucene/spatial/StrategyTestCase.java =================================================================== --- lucene/spatial/src/test/org/apache/lucene/spatial/StrategyTestCase.java (revision 1354804) +++ lucene/spatial/src/test/org/apache/lucene/spatial/StrategyTestCase.java (working copy) @@ -107,7 +107,8 @@ SpatialTestQuery q = queries.next(); String msg = q.line; //"Query: " + q.args.toString(ctx); - SearchResults got = executeQuery(strategy.makeQuery(q.args, fieldInfo), 100); + SearchResults got = executeQuery(strategy.makeIntersectsQuery( + q.args.getShape(), q.args.getDistPrecision(), fieldInfo), 100); if (concern.orderIsImportant) { Iterator ids = q.ids.iterator(); for (SearchResult r : got.results) { Index: lucene/spatial/src/java/org/apache/lucene/spatial/SpatialStrategy.java =================================================================== --- lucene/spatial/src/java/org/apache/lucene/spatial/SpatialStrategy.java (revision 1354804) +++ lucene/spatial/src/java/org/apache/lucene/spatial/SpatialStrategy.java (working copy) @@ -60,17 +60,17 @@ return new IndexableField[] { createField(fieldInfo, shape, index, store) }; } - public abstract ValueSource makeValueSource(SpatialArgs args, T fieldInfo); + public abstract ValueSource makeValueSource(Shape shape, double distancePrecision, T fieldInfo); /** * Make a query */ - public abstract Query makeQuery(SpatialArgs args, T fieldInfo); + public abstract Query makeIntersectsQuery(Shape shape, double distancePrecision, T fieldInfo); /** * Make a Filter */ - public abstract Filter makeFilter(SpatialArgs args, T fieldInfo); + public abstract Filter makeIntersectsFilter(Shape shape, double distancePrecision, T fieldInfo); public boolean isIgnoreIncompatibleGeometry() { return ignoreIncompatibleGeometry; Index: lucene/spatial/src/java/org/apache/lucene/spatial/vector/TwoDoublesStrategy.java =================================================================== --- lucene/spatial/src/java/org/apache/lucene/spatial/vector/TwoDoublesStrategy.java (revision 1354804) +++ lucene/spatial/src/java/org/apache/lucene/spatial/vector/TwoDoublesStrategy.java (working copy) @@ -85,34 +85,30 @@ } @Override - public ValueSource makeValueSource(SpatialArgs args, TwoDoublesFieldInfo fieldInfo) { - Point p = args.getShape().getCenter(); + public ValueSource makeValueSource(Shape shape, double distancePrecision, TwoDoublesFieldInfo fieldInfo) { + Point p = shape.getCenter(); return new DistanceValueSource(p, ctx.getDistCalc(), fieldInfo, parser); } @Override - public Filter makeFilter(SpatialArgs args, TwoDoublesFieldInfo fieldInfo) { - if( args.getShape() instanceof Circle) { - if( SpatialOperation.is( args.getOperation(), - SpatialOperation.Intersects, - SpatialOperation.IsWithin )) { - Circle circle = (Circle)args.getShape(); - Query bbox = makeWithin(circle.getBoundingBox(), fieldInfo); + public Filter makeIntersectsFilter(Shape shape, double distancePrecision, TwoDoublesFieldInfo fieldInfo) { + if (shape instanceof Rectangle) { + return new QueryWrapperFilter(makeIntersectsQuery(shape, distancePrecision, fieldInfo)); + } - // Make the ValueSource - ValueSource valueSource = makeValueSource(args, fieldInfo); + Circle circle = (Circle) shape; + Query bbox = makeWithin(circle.getBoundingBox(), fieldInfo); - return new ValueSourceFilter( - new QueryWrapperFilter( bbox ), valueSource, 0, circle.getDistance() ); - } - } - return new QueryWrapperFilter( makeQuery(args, fieldInfo) ); + // Make the ValueSource + ValueSource valueSource = makeValueSource(shape, distancePrecision, fieldInfo); + + return new ValueSourceFilter( + new QueryWrapperFilter(bbox), valueSource, 0, circle.getDistance()); } @Override - public Query makeQuery(SpatialArgs args, TwoDoublesFieldInfo fieldInfo) { + public Query makeIntersectsQuery(Shape shape, double distancePrecision, TwoDoublesFieldInfo fieldInfo) { // For starters, just limit the bbox - Shape shape = args.getShape(); if (!(shape instanceof Rectangle || shape instanceof Circle)) { throw new InvalidShapeException("Only Rectangles and Circles are currently supported, " + "found [" + shape.getClass() + "]");//TODO @@ -124,46 +120,19 @@ throw new UnsupportedOperationException( "Crossing dateline not yet supported" ); } - ValueSource valueSource = null; + ValueSource valueSource = makeValueSource(shape, distancePrecision, fieldInfo); - Query spatial = null; - SpatialOperation op = args.getOperation(); + Query spatial = makeWithin(bbox, fieldInfo); - if( SpatialOperation.is( op, - SpatialOperation.BBoxWithin, - SpatialOperation.BBoxIntersects ) ) { - spatial = makeWithin(bbox, fieldInfo); - } - else if( SpatialOperation.is( op, - SpatialOperation.Intersects, - SpatialOperation.IsWithin ) ) { - spatial = makeWithin(bbox, fieldInfo); - if( args.getShape() instanceof Circle) { - Circle circle = (Circle)args.getShape(); + if (shape instanceof Circle) { + Circle circle = (Circle) shape; + ValueSourceFilter vsf = new ValueSourceFilter( + new QueryWrapperFilter(spatial), valueSource, 0, circle.getDistance()); - // Make the ValueSource - valueSource = makeValueSource(args, fieldInfo); - - ValueSourceFilter vsf = new ValueSourceFilter( - new QueryWrapperFilter( spatial ), valueSource, 0, circle.getDistance() ); - - spatial = new FilteredQuery( new MatchAllDocsQuery(), vsf ); - } - } - else if( op == SpatialOperation.IsDisjointTo ) { - spatial = makeDisjoint(bbox, fieldInfo); - } - - if( spatial == null ) { - throw new UnsupportedSpatialOperation(args.getOperation()); - } - - if( valueSource != null ) { valueSource = new CachingDoubleValueSource(valueSource); + spatial = new FilteredQuery(new MatchAllDocsQuery(), vsf); } - else { - valueSource = makeValueSource(args, fieldInfo); - } + Query spatialRankingQuery = new FunctionQuery(valueSource); BooleanQuery bq = new BooleanQuery(); bq.add(spatial,BooleanClause.Occur.MUST); @@ -171,6 +140,25 @@ return bq; } + public Query makeDisjointToQuery(Shape shape, double distancePrecision, TwoDoublesFieldInfo fieldInfo) { + if (!(shape instanceof Rectangle || shape instanceof Circle)) { + throw new InvalidShapeException("Only Rectangles and Circles are currently supported, " + + "found [" + shape.getClass() + "]"); + } + + Rectangle bbox = shape.getBoundingBox(); + + Query disjointQuery = makeDisjoint(bbox, fieldInfo); + ValueSource valueSource = makeValueSource(shape, distancePrecision, fieldInfo); + Query rankingQuery = new FunctionQuery(valueSource); + + BooleanQuery query = new BooleanQuery(); + query.add(disjointQuery, BooleanClause.Occur.MUST); + query.add(rankingQuery, BooleanClause.Occur.MUST); + + return query; + } + /** * Constructs a query to retrieve documents that fully contain the input envelope. * @return the spatial query Index: lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java =================================================================== --- lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java (revision 1354804) +++ lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java (working copy) @@ -148,12 +148,16 @@ } @Override - public ValueSource makeValueSource(SpatialArgs args, SimpleSpatialFieldInfo fieldInfo) { + public ValueSource makeValueSource(Shape shape, double distancePrecision, SimpleSpatialFieldInfo fieldInfo) { DistanceCalculator calc = grid.getSpatialContext().getDistCalc(); - return makeValueSource(args, fieldInfo, calc); + return makeValueSource(shape, distancePrecision, fieldInfo, calc); } - public ValueSource makeValueSource(SpatialArgs args, SimpleSpatialFieldInfo fieldInfo, DistanceCalculator calc) { + public ValueSource makeValueSource( + Shape shape, + double distancePrecision, + SimpleSpatialFieldInfo fieldInfo, + DistanceCalculator calc) { PointPrefixTreeFieldCacheProvider p = provider.get( fieldInfo.getFieldName() ); if( p == null ) { synchronized (this) {//double checked locking idiom is okay since provider is threadsafe @@ -164,7 +168,7 @@ } } } - Point point = args.getShape().getCenter(); + Point point = shape.getCenter(); return new CachedDistanceValueSource(point, calc, p); } Index: lucene/spatial/src/java/org/apache/lucene/spatial/prefix/RecursivePrefixTreeStrategy.java =================================================================== --- lucene/spatial/src/java/org/apache/lucene/spatial/prefix/RecursivePrefixTreeStrategy.java (revision 1354804) +++ lucene/spatial/src/java/org/apache/lucene/spatial/prefix/RecursivePrefixTreeStrategy.java (working copy) @@ -49,25 +49,19 @@ } @Override - public Query makeQuery(SpatialArgs args, SimpleSpatialFieldInfo fieldInfo) { - Filter f = makeFilter(args, fieldInfo); + public Query makeIntersectsQuery(Shape shape, double distancePrecision, SimpleSpatialFieldInfo fieldInfo) { + Filter f = makeIntersectsFilter(shape, distancePrecision, fieldInfo); - ValueSource vs = makeValueSource(args, fieldInfo); + ValueSource vs = makeValueSource(shape, distancePrecision, fieldInfo); return new FilteredQuery( new FunctionQuery(vs), f ); } @Override - public Filter makeFilter(SpatialArgs args, SimpleSpatialFieldInfo fieldInfo) { - final SpatialOperation op = args.getOperation(); - if (! SpatialOperation.is(op, SpatialOperation.IsWithin, SpatialOperation.Intersects, SpatialOperation.BBoxWithin)) - throw new UnsupportedSpatialOperation(op); + public Filter makeIntersectsFilter(Shape shape, double distancePrecision, SimpleSpatialFieldInfo fieldInfo) { + int detailLevel = grid.getMaxLevelForPrecision(shape, distancePrecision); - Shape qshape = args.getShape(); - - int detailLevel = grid.getMaxLevelForPrecision(qshape,args.getDistPrecision()); - return new RecursivePrefixTreeFilter( - fieldInfo.getFieldName(), grid,qshape, prefixGridScanLevel, detailLevel); + fieldInfo.getFieldName(), grid, shape, prefixGridScanLevel, detailLevel); } } Index: lucene/spatial/src/java/org/apache/lucene/spatial/prefix/TermQueryPrefixTreeStrategy.java =================================================================== --- lucene/spatial/src/java/org/apache/lucene/spatial/prefix/TermQueryPrefixTreeStrategy.java (revision 1354804) +++ lucene/spatial/src/java/org/apache/lucene/spatial/prefix/TermQueryPrefixTreeStrategy.java (working copy) @@ -36,21 +36,14 @@ } @Override - public Filter makeFilter(SpatialArgs args, SimpleSpatialFieldInfo fieldInfo) { - return new QueryWrapperFilter( makeQuery(args, fieldInfo) ); + public Filter makeIntersectsFilter(Shape shape, double distancePrecision, SimpleSpatialFieldInfo fieldInfo) { + return new QueryWrapperFilter(makeIntersectsQuery(shape, distancePrecision, fieldInfo)); } @Override - public Query makeQuery(SpatialArgs args, SimpleSpatialFieldInfo fieldInfo) { - if (args.getOperation() != SpatialOperation.Intersects && - args.getOperation() != SpatialOperation.IsWithin && - args.getOperation() != SpatialOperation.Overlaps ){ - // TODO -- can translate these other query types - throw new UnsupportedSpatialOperation(args.getOperation()); - } - Shape qshape = args.getShape(); - int detailLevel = grid.getMaxLevelForPrecision(qshape, args.getDistPrecision()); - List cells = grid.getNodes(qshape, detailLevel, false); + public Query makeIntersectsQuery(Shape shape, double distancePrecision, SimpleSpatialFieldInfo fieldInfo) { + int detailLevel = grid.getMaxLevelForPrecision(shape, distancePrecision); + List cells = grid.getNodes(shape, detailLevel, false); BooleanQuery booleanQuery = new BooleanQuery(); for (Node cell : cells) {