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;
}
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);
}
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);
}
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);
}
}
}
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);
}
}
}
Aggregations