Index: lucene/spatial/src/java/org/apache/lucene/spatial/vector/TwoDoublesStrategy.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- lucene/spatial/src/java/org/apache/lucene/spatial/vector/TwoDoublesStrategy.java (revision Local version) +++ lucene/spatial/src/java/org/apache/lucene/spatial/vector/TwoDoublesStrategy.java (revision Shelved version) @@ -26,6 +26,7 @@ import org.apache.lucene.document.DoubleField; import org.apache.lucene.document.Field; import org.apache.lucene.document.FieldType; +import org.apache.lucene.queries.ChainedFilter; import org.apache.lucene.queries.function.FunctionQuery; import org.apache.lucene.queries.function.ValueSource; import org.apache.lucene.search.BooleanClause; @@ -101,22 +102,21 @@ @Override public Filter makeFilter(SpatialArgs args) { - if( args.getShape() instanceof Circle) { - if( SpatialOperation.is( args.getOperation(), + if( ! SpatialOperation.is( args.getOperation(), - SpatialOperation.Intersects, + SpatialOperation.Intersects, - SpatialOperation.IsWithin )) { - Circle circle = (Circle)args.getShape(); - Query bbox = makeWithin(circle.getBoundingBox()); - - // Make the ValueSource - ValueSource valueSource = makeValueSource(args); - - return new ValueSourceFilter( - new QueryWrapperFilter( bbox ), valueSource, 0, circle.getRadius() ); + SpatialOperation.IsWithin )) + throw new UnsupportedSpatialOperation(args.getOperation()); + Shape shape = args.getShape(); + Filter bboxFilter = new QueryWrapperFilter(makeWithin(shape.getBoundingBox())); + if (shape instanceof Rectangle || shape instanceof Point) { + return bboxFilter; + } else { + Filter[] filters = new Filter[2]; + filters[0] = bboxFilter; + filters[1] = new FieldCachePointShapeFilter(this, args); + return new ChainedFilter(filters, ChainedFilter.AND); - } - } + } + } - return new QueryWrapperFilter( makeQuery(args) ); - } @Override public Query makeQuery(SpatialArgs args) { @@ -182,49 +182,38 @@ /** * Constructs a query to retrieve documents that fully contain the input envelope. - * @return the spatial query */ private Query makeWithin(Rectangle bbox) { - Query qX = NumericRangeQuery.newDoubleRange( - fieldNameX, - precisionStep, - bbox.getMinX(), - bbox.getMaxX(), - true, - true); - Query qY = NumericRangeQuery.newDoubleRange( - fieldNameY, - precisionStep, - bbox.getMinY(), - bbox.getMaxY(), - true, - true); - BooleanQuery bq = new BooleanQuery(); - bq.add(qX,BooleanClause.Occur.MUST); - bq.add(qY,BooleanClause.Occur.MUST); + BooleanClause.Occur MUST = BooleanClause.Occur.MUST; + if (bbox.getCrossesDateLine()) { + //use null as performance trick since no data will be beyond the world bounds + bq.add(rangeQuery(fieldNameX, null/*-180*/, bbox.getMaxX()), MUST); + bq.add(rangeQuery(fieldNameX, bbox.getMinX(), null/*+180*/), MUST); + } else { + bq.add(rangeQuery(fieldNameX, bbox.getMinX(), bbox.getMaxX()), MUST); + } + bq.add(rangeQuery(fieldNameY, bbox.getMinY(), bbox.getMaxY()), MUST); return bq; } + private NumericRangeQuery rangeQuery(String fieldName, Double min, Double max) { + return NumericRangeQuery.newDoubleRange( + fieldName, + precisionStep, + min, + max, + true, + true);//inclusive + } + /** * Constructs a query to retrieve documents that fully contain the input envelope. * @return the spatial query */ Query makeDisjoint(Rectangle bbox) { - Query qX = NumericRangeQuery.newDoubleRange( - fieldNameX, - precisionStep, - bbox.getMinX(), - bbox.getMaxX(), - true, - true); - Query qY = NumericRangeQuery.newDoubleRange( - fieldNameY, - precisionStep, - bbox.getMinY(), - bbox.getMaxY(), - true, - true); + Query qX = rangeQuery(fieldNameX, bbox.getMinX(), bbox.getMaxX()); + Query qY = rangeQuery(fieldNameY, bbox.getMinY(), bbox.getMaxY()); BooleanQuery bq = new BooleanQuery(); bq.add(qX,BooleanClause.Occur.MUST_NOT);