Index: lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeValuesFilter.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeValuesFilter.java (revision ) +++ lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeValuesFilter.java (revision ) @@ -0,0 +1,63 @@ +package org.apache.lucene.spatial.util; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import com.spatial4j.core.shape.Shape; +import org.apache.lucene.index.AtomicReaderContext; +import org.apache.lucene.search.DocIdSet; +import org.apache.lucene.search.Filter; +import org.apache.lucene.search.FilteredDocIdSet; +import org.apache.lucene.spatial.SpatialStrategy; +import org.apache.lucene.util.Bits; + +import java.io.IOException; + +/** + * Matches indexed shapes against a Matcher + * + * @lucene.experimental + */ +public class ShapeValuesFilter extends Filter { + private SpatialStrategy strategy; + private ShapeMatcher matcher; + private Filter preFilter; + + public ShapeValuesFilter(SpatialStrategy strategy, ShapeMatcher matcher, Filter preFilter) { + this.matcher = matcher; + this.strategy = strategy; + this.preFilter = preFilter; + } + + @Override + public DocIdSet getDocIdSet(AtomicReaderContext context, Bits acceptDocs) throws IOException { + DocIdSet preFilterDocIdSet = preFilter.getDocIdSet(context, acceptDocs); + if (preFilterDocIdSet == null) + return null; + + final ShapeValues shapeValues = strategy.makeShapeValues(context); + return new FilteredDocIdSet(preFilterDocIdSet) { + @Override + protected boolean match(int docid) { + Shape indexedShape = shapeValues.shape(docid); + assert indexedShape != null : "passed preFilter thus exists"; + return matcher.match(indexedShape); + } + }; + } + +} Index: lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeValues.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeValues.java (revision ) +++ lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeValues.java (revision ) @@ -0,0 +1,40 @@ +package org.apache.lucene.spatial.util; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import com.spatial4j.core.shape.Shape; + +/** + * @lucene.experimental + */ +public interface ShapeValues { + //No point in extending FunctionValues / ValueSource ? + + public Class getShapeType(); + + public Class getInnerShapeType(); + + /** + * Returns the shape for this document. + * @param doc + * @return A transient shape object; clone it if you need to retain a copy! + * Null if none. + */ + public S shape(int doc); + +} Index: lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeMatcherFactory.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeMatcherFactory.java (revision ) +++ lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeMatcherFactory.java (revision ) @@ -0,0 +1,103 @@ +package org.apache.lucene.spatial.util; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import com.spatial4j.core.shape.Shape; +import com.spatial4j.core.shape.SpatialRelation; +import org.apache.lucene.spatial.query.SpatialOperation; +import org.apache.lucene.spatial.query.UnsupportedSpatialOperation; + +import static org.apache.lucene.spatial.query.SpatialOperation.BBoxIntersects; +import static org.apache.lucene.spatial.query.SpatialOperation.BBoxWithin; +import static org.apache.lucene.spatial.query.SpatialOperation.Contains; +import static org.apache.lucene.spatial.query.SpatialOperation.Intersects; +import static org.apache.lucene.spatial.query.SpatialOperation.IsDisjointTo; +import static org.apache.lucene.spatial.query.SpatialOperation.IsEqualTo; +import static org.apache.lucene.spatial.query.SpatialOperation.Overlaps; + +/** + * @lucene.experimental + */ +public class ShapeMatcherFactory { + + public static ShapeMatcher get(Class indexShapeType, SpatialOperation op, Shape queryShape) { + //TODO use indexShapeType + //TODO add nuances of requiring area + if (op == BBoxIntersects) + return new BBoxShapeMatcher( + new RelationShapeMatcher(SpatialRelation.INTERSECTS, queryShape)); + if (op == BBoxWithin) + return new BBoxShapeMatcher( + new RelationShapeMatcher(SpatialRelation.WITHIN, queryShape)); + if (op == Contains) + return new RelationShapeMatcher(SpatialRelation.CONTAINS, queryShape); + if (op == Intersects) + return new RelationShapeMatcher(SpatialRelation.INTERSECTS, queryShape); + if (op == IsEqualTo) + return new EqualsShapeMatcher(queryShape); + if (op == IsDisjointTo) + return new RelationShapeMatcher(SpatialRelation.DISJOINT, queryShape); + if (op == Overlaps) + return new RelationShapeMatcher(SpatialRelation.INTERSECTS, queryShape); + + throw new UnsupportedSpatialOperation(op); + } + + //TODO NOCOMMIT implement equals, hashcode, tostring for matchers + + public static class RelationShapeMatcher implements ShapeMatcher { + private final SpatialRelation rel; + private final Shape queryShape; + + public RelationShapeMatcher(SpatialRelation rel, Shape queryShape) { + this.rel = rel; + this.queryShape = queryShape; + } + + @Override + public boolean match(Shape shape) { + return shape.relate(queryShape) == rel; + } + } + + public static class BBoxShapeMatcher implements ShapeMatcher { + private final ShapeMatcher delegate; + + public BBoxShapeMatcher(ShapeMatcher delegate) { + this.delegate = delegate; + } + + @Override + public boolean match(Shape shape) { + return delegate.match(shape.getBoundingBox()); + } + } + + public static class EqualsShapeMatcher implements ShapeMatcher { + private final Shape queryShape; + + public EqualsShapeMatcher(Shape queryShape) { + this.queryShape = queryShape; + } + + @Override + public boolean match(Shape shape) { + return shape.equals(queryShape); + } + } +} Index: lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeMatcher.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeMatcher.java (revision ) +++ lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeMatcher.java (revision ) @@ -0,0 +1,28 @@ +package org.apache.lucene.spatial.util; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import com.spatial4j.core.shape.Shape; + +/** + * @lucene.experimental + */ +public interface ShapeMatcher { + + boolean match(Shape shape); +}