Search in sources :

Example 1 with SpatialArgs

use of org.apache.lucene.spatial.query.SpatialArgs in project lucene-solr by apache.

the class JtsPolygonTest method q.

private SpatialArgs q(String shapeStr, double distErrPct) throws ParseException {
    Shape shape = ctx.readShapeFromWkt(shapeStr);
    SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, shape);
    args.setDistErrPct(distErrPct);
    return args;
}
Also used : SpatialArgs(org.apache.lucene.spatial.query.SpatialArgs) Shape(org.locationtech.spatial4j.shape.Shape)

Example 2 with SpatialArgs

use of org.apache.lucene.spatial.query.SpatialArgs in project lucene-solr by apache.

the class RandomSpatialOpFuzzyPrefixTreeTest method testWithinDisjointParts.

@Test
public void testWithinDisjointParts() throws IOException {
    setupQuadGrid(7, randomBoolean());
    //one shape comprised of two parts, quite separated apart
    adoc("0", new ShapePair(ctx.makeRectangle(0, 10, -120, -100), ctx.makeRectangle(220, 240, 110, 125), false));
    commit();
    //query surrounds only the second part of the indexed shape
    Query query = strategy.makeQuery(new SpatialArgs(SpatialOperation.IsWithin, ctx.makeRectangle(210, 245, 105, 128)));
    SearchResults searchResults = executeQuery(query, 1);
    //we shouldn't find it because it's not completely within
    assertTrue(searchResults.numFound == 0);
}
Also used : SpatialArgs(org.apache.lucene.spatial.query.SpatialArgs) Query(org.apache.lucene.search.Query) Test(org.junit.Test)

Example 3 with SpatialArgs

use of org.apache.lucene.spatial.query.SpatialArgs in project lucene-solr by apache.

the class RandomSpatialOpFuzzyPrefixTreeTest method testContainsPairOverlap.

/** See LUCENE-5062, {@link ContainsPrefixTreeQuery#multiOverlappingIndexedShapes}. */
@Test
public void testContainsPairOverlap() throws IOException {
    setupQuadGrid(3, randomBoolean());
    adoc("0", new ShapePair(ctx.makeRectangle(0, 33, -128, 128), ctx.makeRectangle(33, 128, -128, 128), true));
    commit();
    Query query = strategy.makeQuery(new SpatialArgs(SpatialOperation.Contains, ctx.makeRectangle(0, 128, -16, 128)));
    SearchResults searchResults = executeQuery(query, 1);
    assertEquals(1, searchResults.numFound);
}
Also used : SpatialArgs(org.apache.lucene.spatial.query.SpatialArgs) Query(org.apache.lucene.search.Query) Test(org.junit.Test)

Example 4 with SpatialArgs

use of org.apache.lucene.spatial.query.SpatialArgs in project lucene-solr by apache.

the class RandomSpatialOpFuzzyPrefixTreeTest method doTest.

@SuppressWarnings("fallthrough")
private void doTest(final SpatialOperation operation) throws IOException {
    //first show that when there's no data, a query will result in no results
    {
        Query query = strategy.makeQuery(new SpatialArgs(operation, randomRectangle()));
        SearchResults searchResults = executeQuery(query, 1);
        assertEquals(0, searchResults.numFound);
    }
    final boolean biasContains = (operation == SpatialOperation.Contains);
    //Main index loop:
    Map<String, Shape> indexedShapes = new LinkedHashMap<>();
    //grid snapped
    Map<String, Shape> indexedShapesGS = new LinkedHashMap<>();
    final int numIndexedShapes = randomIntBetween(1, 6);
    boolean indexedAtLeastOneShapePair = false;
    final boolean pointsOnly = ((PrefixTreeStrategy) strategy).isPointsOnly();
    for (int i = 0; i < numIndexedShapes; i++) {
        String id = "" + i;
        Shape indexedShape;
        int R = random().nextInt(12);
        if (R == 0) {
            //1 in 12
            indexedShape = null;
        } else if (R == 1 || pointsOnly) {
            //1 in 12
            //just one point
            indexedShape = randomPoint();
        } else if (R <= 4) {
            //3 in 12
            //comprised of more than one shape
            indexedShape = randomShapePairRect(biasContains);
            indexedAtLeastOneShapePair = true;
        } else {
            //just one rect
            indexedShape = randomRectangle();
        }
        indexedShapes.put(id, indexedShape);
        indexedShapesGS.put(id, gridSnap(indexedShape));
        adoc(id, indexedShape);
        if (random().nextInt(10) == 0)
            //intermediate commit, produces extra segments
            commit();
    }
    //delete some documents randomly
    Iterator<String> idIter = indexedShapes.keySet().iterator();
    while (idIter.hasNext()) {
        String id = idIter.next();
        if (random().nextInt(10) == 0) {
            deleteDoc(id);
            idIter.remove();
            indexedShapesGS.remove(id);
        }
    }
    commit();
    //Main query loop:
    final int numQueryShapes = atLeast(20);
    for (int i = 0; i < numQueryShapes; i++) {
        int scanLevel = randomInt(grid.getMaxLevels());
        ((RecursivePrefixTreeStrategy) strategy).setPrefixGridScanLevel(scanLevel);
        final Shape queryShape;
        switch(randomInt(10)) {
            case 0:
                queryShape = randomPoint();
                break;
            case 4:
                //choose an existing indexed shape
                if (!indexedShapes.isEmpty()) {
                    Shape tmp = indexedShapes.values().iterator().next();
                    if (tmp instanceof Point || tmp instanceof Rectangle) {
                        //avoids null and shapePair
                        queryShape = tmp;
                        break;
                    }
                }
            default:
                queryShape = randomRectangle();
        }
        final Shape queryShapeGS = gridSnap(queryShape);
        final boolean opIsDisjoint = operation == SpatialOperation.IsDisjointTo;
        //Generate truth via brute force:
        // We ensure true-positive matches (if the predicate on the raw shapes match
        //  then the search should find those same matches).
        // approximations, false-positive matches
        //true-positives
        Set<String> expectedIds = new LinkedHashSet<>();
        //false-positives (unless disjoint)
        Set<String> secondaryIds = new LinkedHashSet<>();
        for (Map.Entry<String, Shape> entry : indexedShapes.entrySet()) {
            String id = entry.getKey();
            Shape indexedShapeCompare = entry.getValue();
            if (indexedShapeCompare == null)
                continue;
            Shape queryShapeCompare = queryShape;
            if (operation.evaluate(indexedShapeCompare, queryShapeCompare)) {
                expectedIds.add(id);
                if (opIsDisjoint) {
                    //if no longer intersect after buffering them, for disjoint, remember this
                    indexedShapeCompare = indexedShapesGS.get(id);
                    queryShapeCompare = queryShapeGS;
                    if (!operation.evaluate(indexedShapeCompare, queryShapeCompare))
                        secondaryIds.add(id);
                }
            } else if (!opIsDisjoint) {
                //buffer either the indexed or query shape (via gridSnap) and try again
                if (operation == SpatialOperation.Intersects) {
                    indexedShapeCompare = indexedShapesGS.get(id);
                    queryShapeCompare = queryShapeGS;
                //TODO Unfortunately, grid-snapping both can result in intersections that otherwise
                // wouldn't happen when the grids are adjacent. Not a big deal but our test is just a
                // bit more lenient.
                } else if (operation == SpatialOperation.Contains) {
                    indexedShapeCompare = indexedShapesGS.get(id);
                } else if (operation == SpatialOperation.IsWithin) {
                    queryShapeCompare = queryShapeGS;
                }
                if (operation.evaluate(indexedShapeCompare, queryShapeCompare))
                    secondaryIds.add(id);
            }
        }
        //Search and verify results
        SpatialArgs args = new SpatialArgs(operation, queryShape);
        if (queryShape instanceof ShapePair)
            //a hack; we want to be more detailed than gridSnap(queryShape)
            args.setDistErrPct(0.0);
        Query query = strategy.makeQuery(args);
        SearchResults got = executeQuery(query, 100);
        Set<String> remainingExpectedIds = new LinkedHashSet<>(expectedIds);
        for (SearchResult result : got.results) {
            String id = result.getId();
            boolean removed = remainingExpectedIds.remove(id);
            if (!removed && (!opIsDisjoint && !secondaryIds.contains(id))) {
                fail("Shouldn't match", id, indexedShapes, indexedShapesGS, queryShape);
            }
        }
        if (opIsDisjoint)
            remainingExpectedIds.removeAll(secondaryIds);
        if (!remainingExpectedIds.isEmpty()) {
            String id = remainingExpectedIds.iterator().next();
            fail("Should have matched", id, indexedShapes, indexedShapesGS, queryShape);
        }
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) SpatialArgs(org.apache.lucene.spatial.query.SpatialArgs) Shape(org.locationtech.spatial4j.shape.Shape) Query(org.apache.lucene.search.Query) Rectangle(org.locationtech.spatial4j.shape.Rectangle) Point(org.locationtech.spatial4j.shape.Point) Point(org.locationtech.spatial4j.shape.Point) LinkedHashMap(java.util.LinkedHashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Example 5 with SpatialArgs

use of org.apache.lucene.spatial.query.SpatialArgs in project lucene-solr by apache.

the class RandomSpatialOpStrategyTestCase method testOperation.

protected void testOperation(final SpatialOperation operation, List<Shape> indexedShapes, List<Shape> queryShapes, boolean havoc) throws IOException {
    //first show that when there's no data, a query will result in no results
    {
        Query query = strategy.makeQuery(new SpatialArgs(operation, randomQueryShape()));
        SearchResults searchResults = executeQuery(query, 1);
        assertEquals(0, searchResults.numFound);
    }
    //Main index loop:
    for (int i = 0; i < indexedShapes.size(); i++) {
        Shape shape = indexedShapes.get(i);
        adoc("" + i, shape);
        if (havoc && random().nextInt(10) == 0)
            //intermediate commit, produces extra segments
            commit();
    }
    if (havoc) {
        //delete some documents randomly
        for (int id = 0; id < indexedShapes.size(); id++) {
            if (random().nextInt(10) == 0) {
                deleteDoc("" + id);
                indexedShapes.set(id, null);
            }
        }
    }
    commit();
    //Main query loop:
    for (int queryIdx = 0; queryIdx < queryShapes.size(); queryIdx++) {
        final Shape queryShape = queryShapes.get(queryIdx);
        if (havoc)
            preQueryHavoc();
        //Generate truth via brute force:
        // We ensure true-positive matches (if the predicate on the raw shapes match
        //  then the search should find those same matches).
        //true-positives
        Set<String> expectedIds = new LinkedHashSet<>();
        for (int id = 0; id < indexedShapes.size(); id++) {
            Shape indexedShape = indexedShapes.get(id);
            if (indexedShape == null)
                continue;
            if (operation.evaluate(indexedShape, queryShape)) {
                expectedIds.add("" + id);
            }
        }
        //Search and verify results
        SpatialArgs args = new SpatialArgs(operation, queryShape);
        Query query = strategy.makeQuery(args);
        SearchResults got = executeQuery(query, 100);
        Set<String> remainingExpectedIds = new LinkedHashSet<>(expectedIds);
        for (SearchResult result : got.results) {
            String id = result.getId();
            if (!remainingExpectedIds.remove(id)) {
                fail("qIdx:" + queryIdx + " Shouldn't match", id, indexedShapes, queryShape, operation);
            }
        }
        if (!remainingExpectedIds.isEmpty()) {
            String id = remainingExpectedIds.iterator().next();
            fail("qIdx:" + queryIdx + " Should have matched", id, indexedShapes, queryShape, operation);
        }
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) SpatialArgs(org.apache.lucene.spatial.query.SpatialArgs) Shape(org.locationtech.spatial4j.shape.Shape) Query(org.apache.lucene.search.Query)

Aggregations

SpatialArgs (org.apache.lucene.spatial.query.SpatialArgs)34 Query (org.apache.lucene.search.Query)16 Shape (org.locationtech.spatial4j.shape.Shape)14 Test (org.junit.Test)12 Point (org.locationtech.spatial4j.shape.Point)10 SpatialOperation (org.apache.lucene.spatial.query.SpatialOperation)6 Document (org.apache.lucene.document.Document)5 MatchAllDocsQuery (org.apache.lucene.search.MatchAllDocsQuery)5 BooleanQuery (org.apache.lucene.search.BooleanQuery)4 TopDocs (org.apache.lucene.search.TopDocs)4 SpatialPrefixTree (org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree)3 LinkedHashSet (java.util.LinkedHashSet)2 Map (java.util.Map)2 Analyzer (org.apache.lucene.analysis.Analyzer)2 StandardAnalyzer (org.apache.lucene.analysis.standard.StandardAnalyzer)2 Field (org.apache.lucene.document.Field)2 TextField (org.apache.lucene.document.TextField)2 IndexReader (org.apache.lucene.index.IndexReader)2 Term (org.apache.lucene.index.Term)2 BooleanFilter (org.apache.lucene.queries.BooleanFilter)2