Skip to content

Commit

Permalink
apache#1596 'BBox_within' is not working in 'lucene.spatial' filter
Browse files Browse the repository at this point in the history
  • Loading branch information
navis committed Mar 7, 2019
1 parent 5c7ccd7 commit 34f934e
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
import org.apache.lucene.spatial.query.SpatialArgs;
import org.apache.lucene.spatial.query.SpatialOperation;
import org.locationtech.spatial4j.context.SpatialContext;
import org.locationtech.spatial4j.context.jts.JtsSpatialContext;
import org.locationtech.spatial4j.io.GeohashUtils;
Expand Down Expand Up @@ -99,7 +100,7 @@ public LuceneSpatialFilter(
{
this.field = Preconditions.checkNotNull(field, "field can not be null");
this.operation = Preconditions.checkNotNull(operation, "operation can not be null");
this.shapeFormat = Preconditions.checkNotNull(shapeFormat, "shapeFormat can not be null");
this.shapeFormat = shapeFormat == null ? ShapeFormat.WKT : shapeFormat;
this.shapeString = Preconditions.checkNotNull(shapeString, "shapeString can not be null");
}

Expand Down Expand Up @@ -205,10 +206,9 @@ public ImmutableBitmap getBitmapIndex(
);
JtsSpatialContext ctx = JtsSpatialContext.GEO;
try {
SpatialArgs args = new SpatialArgs(operation.op(), shapeFormat.newReader(ctx).read(shapeString));
SpatialPrefixTree grid = new GeohashPrefixTree(ctx, GeohashUtils.MAX_PRECISION);
SpatialStrategy strategy = new RecursivePrefixTreeStrategy(grid, fieldName);
return lucene.filterFor(strategy.makeQuery(args), baseBitmap);
return lucene.filterFor(strategy.makeQuery(makeSpatialArgs(ctx)), baseBitmap);
}
catch (Exception e) {
throw Throwables.propagate(e);
Expand All @@ -229,6 +229,23 @@ public String toString()
};
}

private SpatialArgs makeSpatialArgs(JtsSpatialContext ctx) throws IOException, ParseException
{
final Shape shape = shapeFormat.newReader(ctx).read(shapeString);
if (operation.isLuceneNative()) {
return new SpatialArgs(operation.op(), shape);
}
switch (operation) {
case BBOX_INTERSECTS:
return new SpatialArgs(SpatialOperation.Intersects, shape.getBoundingBox());
case BBOX_WINTHIN:
return new SpatialArgs(SpatialOperation.IsWithin, shape.getBoundingBox());
case EQUALTO:
case OVERLAPS:
}
throw new UnsupportedOperationException(operation + " is not supported yet");
}

@Override
public String toString()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,31 +58,48 @@ public SpatialOperation op()
{
return SpatialOperation.IsEqualTo;
}

@Override
public boolean isLuceneNative() { return false;}
},
OVERLAPS {
@Override
public SpatialOperation op()
{
return SpatialOperation.Overlaps;
}

@Override
public boolean isLuceneNative() { return false;}
},
BBOX_INTERSECTS {
@Override
public SpatialOperation op()
{
return SpatialOperation.BBoxIntersects;
}

@Override
public boolean isLuceneNative() { return false;}
},
BBOX_WINTHIN {
@Override
public SpatialOperation op()
{
return SpatialOperation.BBoxWithin;
}

@Override
public boolean isLuceneNative() { return false;}
};

public abstract SpatialOperation op();

public boolean isLuceneNative()
{
return true;
}

@JsonValue
public String getName()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,30 @@ public void testSimpleFilter()
new Object[]{"서초대로", "LINESTRING (127.007656 37.491764, 127.027648 37.497879)"}
);
Assert.assertEquals(expected, runQuery(builder.streaming()));

builder.filters(new LuceneSpatialFilter(
"geom",
SpatialOperations.BBOX_WINTHIN,
ShapeFormat.WKT,
"MULTIPOINT ((127.017827 37.484505), (127.034182 37.521752))"
));
expected = createExpectedMaps(
columns,
new Object[]{"강남대로", "LINESTRING (127.034182 37.484505, 127.021399 37.511051, 127.017827 37.521752)"}
);
Assert.assertEquals(expected, runQuery(builder.streaming()));

builder.filters(new LuceneSpatialFilter(
"geom",
SpatialOperations.BBOX_INTERSECTS,
ShapeFormat.WKT,
"MULTIPOINT ((127.007656 37.491764), (127.034182 37.497879))"
));
expected = createExpectedMaps(
columns,
new Object[]{"강남대로", "LINESTRING (127.034182 37.484505, 127.021399 37.511051, 127.017827 37.521752)"},
new Object[]{"서초대로", "LINESTRING (127.007656 37.491764, 127.027648 37.497879)"}
);
Assert.assertEquals(expected, runQuery(builder.streaming()));
}
}

0 comments on commit 34f934e

Please sign in to comment.