Search in sources :

Example 16 with Point

use of org.locationtech.spatial4j.shape.Point in project lucene-solr by apache.

the class TermQueryPrefixTreeStrategy method makeQuery.

@Override
public Query makeQuery(SpatialArgs args) {
    final SpatialOperation op = args.getOperation();
    if (op != SpatialOperation.Intersects)
        throw new UnsupportedSpatialOperation(op);
    Shape shape = args.getShape();
    int detailLevel = grid.getLevelForDistance(args.resolveDistErr(ctx, distErrPct));
    //--get a List of BytesRef for each term we want (no parents, no leaf bytes))
    final int GUESS_NUM_TERMS;
    if (shape instanceof Point)
        //perfect guess
        GUESS_NUM_TERMS = detailLevel;
    else
        //should this be a method on SpatialPrefixTree?
        GUESS_NUM_TERMS = 4096;
    //shared byte array for all terms
    BytesRefBuilder masterBytes = new BytesRefBuilder();
    List<BytesRef> terms = new ArrayList<>(GUESS_NUM_TERMS);
    CellIterator cells = grid.getTreeCellIterator(shape, detailLevel);
    while (cells.hasNext()) {
        Cell cell = cells.next();
        if (!cell.isLeaf())
            continue;
        //null because we want a new BytesRef
        BytesRef term = cell.getTokenBytesNoLeaf(null);
        //We copy out the bytes because it may be re-used across the iteration. This also gives us the opportunity
        // to use one contiguous block of memory for the bytes of all terms we need.
        masterBytes.grow(masterBytes.length() + term.length);
        masterBytes.append(term);
        //don't need; will reset later
        term.bytes = null;
        term.offset = masterBytes.length() - term.length;
        terms.add(term);
    }
    //doing this now because if we did earlier, it's possible the bytes needed to grow()
    for (BytesRef byteRef : terms) {
        byteRef.bytes = masterBytes.bytes();
    }
    //TODO an automatonQuery might be faster?
    return new TermInSetQuery(getFieldName(), terms);
}
Also used : UnsupportedSpatialOperation(org.apache.lucene.spatial.query.UnsupportedSpatialOperation) BytesRefBuilder(org.apache.lucene.util.BytesRefBuilder) Shape(org.locationtech.spatial4j.shape.Shape) TermInSetQuery(org.apache.lucene.search.TermInSetQuery) ArrayList(java.util.ArrayList) CellIterator(org.apache.lucene.spatial.prefix.tree.CellIterator) Point(org.locationtech.spatial4j.shape.Point) UnsupportedSpatialOperation(org.apache.lucene.spatial.query.UnsupportedSpatialOperation) SpatialOperation(org.apache.lucene.spatial.query.SpatialOperation) Cell(org.apache.lucene.spatial.prefix.tree.Cell) Point(org.locationtech.spatial4j.shape.Point) BytesRef(org.apache.lucene.util.BytesRef)

Example 17 with Point

use of org.locationtech.spatial4j.shape.Point in project lucene-solr by apache.

the class CompositeStrategyTest method randomCircle.

//TODO move up
private Shape randomCircle() {
    final Point point = randomPoint();
    //TODO pick using gaussian
    double radius;
    if (ctx.isGeo()) {
        radius = randomDouble() * 100;
    } else {
        //find distance to closest edge
        final Rectangle worldBounds = ctx.getWorldBounds();
        double maxRad = point.getX() - worldBounds.getMinX();
        maxRad = Math.min(maxRad, worldBounds.getMaxX() - point.getX());
        maxRad = Math.min(maxRad, point.getY() - worldBounds.getMinY());
        maxRad = Math.min(maxRad, worldBounds.getMaxY() - point.getY());
        radius = randomDouble() * maxRad;
    }
    return ctx.makeCircle(point, radius);
}
Also used : Rectangle(org.locationtech.spatial4j.shape.Rectangle) Point(org.locationtech.spatial4j.shape.Point)

Example 18 with Point

use of org.locationtech.spatial4j.shape.Point in project lucene-solr by apache.

the class SpatialExample method search.

private void search() throws Exception {
    IndexReader indexReader = DirectoryReader.open(directory);
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    Sort idSort = new Sort(new SortField("id", SortField.Type.INT));
    //--Filter by circle (<= distance from a point)
    {
        //Search with circle
        //note: SpatialArgs can be parsed from a string
        SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, ctx.makeCircle(-80.0, 33.0, DistanceUtils.dist2Degrees(200, DistanceUtils.EARTH_MEAN_RADIUS_KM)));
        Query query = strategy.makeQuery(args);
        TopDocs docs = indexSearcher.search(query, 10, idSort);
        assertDocMatchedIds(indexSearcher, docs, 2);
        //Now, lets get the distance for the 1st doc via computing from stored point value:
        // (this computation is usually not redundant)
        Document doc1 = indexSearcher.doc(docs.scoreDocs[0].doc);
        String doc1Str = doc1.getField(strategy.getFieldName()).stringValue();
        //assume doc1Str is "x y" as written in newSampleDocument()
        int spaceIdx = doc1Str.indexOf(' ');
        double x = Double.parseDouble(doc1Str.substring(0, spaceIdx));
        double y = Double.parseDouble(doc1Str.substring(spaceIdx + 1));
        double doc1DistDEG = ctx.calcDistance(args.getShape().getCenter(), x, y);
        assertEquals(121.6d, DistanceUtils.degrees2Dist(doc1DistDEG, DistanceUtils.EARTH_MEAN_RADIUS_KM), 0.1);
        //or more simply:
        assertEquals(121.6d, doc1DistDEG * DistanceUtils.DEG_TO_KM, 0.1);
    }
    //--Match all, order by distance ascending
    {
        Point pt = ctx.makePoint(60, -50);
        //the distance (in km)
        ValueSource valueSource = strategy.makeDistanceValueSource(pt, DistanceUtils.DEG_TO_KM);
        //false=asc dist
        Sort distSort = new Sort(valueSource.getSortField(false)).rewrite(indexSearcher);
        TopDocs docs = indexSearcher.search(new MatchAllDocsQuery(), 10, distSort);
        assertDocMatchedIds(indexSearcher, docs, 4, 20, 2);
    //To get the distance, we could compute from stored values like earlier.
    // However in this example we sorted on it, and the distance will get
    // computed redundantly.  If the distance is only needed for the top-X
    // search results then that's not a big deal. Alternatively, try wrapping
    // the ValueSource with CachingDoubleValueSource then retrieve the value
    // from the ValueSource now. See LUCENE-4541 for an example.
    }
    //demo arg parsing
    {
        SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, ctx.makeCircle(-80.0, 33.0, 1));
        SpatialArgs args2 = new SpatialArgsParser().parse("Intersects(BUFFER(POINT(-80 33),1))", ctx);
        assertEquals(args.toString(), args2.toString());
    }
    indexReader.close();
}
Also used : IndexSearcher(org.apache.lucene.search.IndexSearcher) SpatialArgs(org.apache.lucene.spatial.query.SpatialArgs) Query(org.apache.lucene.search.Query) MatchAllDocsQuery(org.apache.lucene.search.MatchAllDocsQuery) SpatialArgsParser(org.apache.lucene.spatial.query.SpatialArgsParser) SortField(org.apache.lucene.search.SortField) Point(org.locationtech.spatial4j.shape.Point) Document(org.apache.lucene.document.Document) MatchAllDocsQuery(org.apache.lucene.search.MatchAllDocsQuery) TopDocs(org.apache.lucene.search.TopDocs) ValueSource(org.apache.lucene.queries.function.ValueSource) IndexReader(org.apache.lucene.index.IndexReader) Sort(org.apache.lucene.search.Sort)

Example 19 with Point

use of org.locationtech.spatial4j.shape.Point in project lucene-solr by apache.

the class DistanceValueSource method getValues.

/**
   * Returns the FunctionValues used by the function query.
   */
@Override
public FunctionValues getValues(Map context, LeafReaderContext readerContext) throws IOException {
    LeafReader reader = readerContext.reader();
    final NumericDocValues ptX = DocValues.getNumeric(reader, strategy.getFieldNameX());
    final NumericDocValues ptY = DocValues.getNumeric(reader, strategy.getFieldNameY());
    return new FunctionValues() {

        private int lastDocID = -1;

        private final Point from = DistanceValueSource.this.from;

        private final DistanceCalculator calculator = strategy.getSpatialContext().getDistCalc();

        private final double nullValue = (strategy.getSpatialContext().isGeo() ? 180 * multiplier : Double.MAX_VALUE);

        private double getDocValue(NumericDocValues values, int doc) throws IOException {
            int curDocID = values.docID();
            if (doc > curDocID) {
                curDocID = values.advance(doc);
            }
            if (doc == curDocID) {
                return Double.longBitsToDouble(values.longValue());
            } else {
                return 0.0;
            }
        }

        @Override
        public float floatVal(int doc) throws IOException {
            return (float) doubleVal(doc);
        }

        @Override
        public double doubleVal(int doc) throws IOException {
            // make sure it has minX and area
            double x = getDocValue(ptX, doc);
            if (ptX.docID() == doc) {
                double y = getDocValue(ptY, doc);
                assert ptY.docID() == doc;
                return calculator.distance(from, x, y) * multiplier;
            }
            return nullValue;
        }

        @Override
        public String toString(int doc) throws IOException {
            return description() + "=" + floatVal(doc);
        }
    };
}
Also used : DistanceCalculator(org.locationtech.spatial4j.distance.DistanceCalculator) NumericDocValues(org.apache.lucene.index.NumericDocValues) LeafReader(org.apache.lucene.index.LeafReader) FunctionValues(org.apache.lucene.queries.function.FunctionValues) Point(org.locationtech.spatial4j.shape.Point) Point(org.locationtech.spatial4j.shape.Point)

Example 20 with Point

use of org.locationtech.spatial4j.shape.Point in project lucene-solr by apache.

the class DistanceStrategyTest method checkDistValueSource.

void checkDistValueSource(Point pt, float... distances) throws IOException {
    float multiplier = random().nextFloat() * 100f;
    float[] dists2 = Arrays.copyOf(distances, distances.length);
    for (int i = 0; i < dists2.length; i++) {
        dists2[i] *= multiplier;
    }
    checkValueSource(strategy.makeDistanceValueSource(pt, multiplier), dists2, 1.0e-3f);
}
Also used : Point(org.locationtech.spatial4j.shape.Point)

Aggregations

Point (org.locationtech.spatial4j.shape.Point)71 Test (org.junit.Test)21 Shape (org.locationtech.spatial4j.shape.Shape)15 Query (org.apache.lucene.search.Query)9 SpatialArgs (org.apache.lucene.spatial.query.SpatialArgs)9 Rectangle (org.locationtech.spatial4j.shape.Rectangle)9 ArrayList (java.util.ArrayList)7 Field (org.apache.lucene.document.Field)6 PointImpl (org.locationtech.spatial4j.shape.impl.PointImpl)6 BooleanQuery (org.apache.lucene.search.BooleanQuery)5 TopDocs (org.apache.lucene.search.TopDocs)5 IOException (java.io.IOException)4 SpatialContext (org.locationtech.spatial4j.context.SpatialContext)4 Document (org.apache.lucene.document.Document)3 StoredField (org.apache.lucene.document.StoredField)3 IndexReader (org.apache.lucene.index.IndexReader)3 IndexSearcher (org.apache.lucene.search.IndexSearcher)3 ScoreDoc (org.apache.lucene.search.ScoreDoc)3 Cell (org.apache.lucene.spatial.prefix.tree.Cell)3 CellIterator (org.apache.lucene.spatial.prefix.tree.CellIterator)3