mirror of https://github.com/apache/lucene.git
LUCENE-7430: Add some explicit delta for bounds objects that corresponds to point resolution in doc values.
This commit is contained in:
parent
8683da80ed
commit
08ca33f57e
|
@ -67,6 +67,12 @@ public class Geo3DDocValuesField extends Field {
|
|||
private final static double yFactor = 1.0 / inverseYFactor;
|
||||
private final static double zFactor = 1.0 / inverseZFactor;
|
||||
|
||||
// These values are the delta between a value and the next value in each specific dimension
|
||||
|
||||
private final static double xStep = inverseXFactor;
|
||||
private final static double yStep = inverseYFactor;
|
||||
private final static double zStep = inverseZFactor;
|
||||
|
||||
/**
|
||||
* Type for a Geo3DDocValuesField
|
||||
* <p>
|
||||
|
@ -182,6 +188,54 @@ public class Geo3DDocValuesField extends Field {
|
|||
return decodeZ(((int)(docValue)) & 0x1FFFFF);
|
||||
}
|
||||
|
||||
/** Round the provided X value down, by encoding it, decrementing it, and unencoding it.
|
||||
* @param startValue is the starting value.
|
||||
* @return the rounded value.
|
||||
*/
|
||||
public static double roundDownX(final double startValue) {
|
||||
return startValue - xStep;
|
||||
}
|
||||
|
||||
/** Round the provided X value up, by encoding it, incrementing it, and unencoding it.
|
||||
* @param startValue is the starting value.
|
||||
* @return the rounded value.
|
||||
*/
|
||||
public static double roundUpX(final double startValue) {
|
||||
return startValue + xStep;
|
||||
}
|
||||
|
||||
/** Round the provided Y value down, by encoding it, decrementing it, and unencoding it.
|
||||
* @param startValue is the starting value.
|
||||
* @return the rounded value.
|
||||
*/
|
||||
public static double roundDownY(final double startValue) {
|
||||
return startValue - yStep;
|
||||
}
|
||||
|
||||
/** Round the provided Y value up, by encoding it, incrementing it, and unencoding it.
|
||||
* @param startValue is the starting value.
|
||||
* @return the rounded value.
|
||||
*/
|
||||
public static double roundUpY(final double startValue) {
|
||||
return startValue + yStep;
|
||||
}
|
||||
|
||||
/** Round the provided Z value down, by encoding it, decrementing it, and unencoding it.
|
||||
* @param startValue is the starting value.
|
||||
* @return the rounded value.
|
||||
*/
|
||||
public static double roundDownZ(final double startValue) {
|
||||
return startValue - zStep;
|
||||
}
|
||||
|
||||
/** Round the provided Z value up, by encoding it, incrementing it, and unencoding it.
|
||||
* @param startValue is the starting value.
|
||||
* @return the rounded value.
|
||||
*/
|
||||
public static double roundUpZ(final double startValue) {
|
||||
return startValue + zStep;
|
||||
}
|
||||
|
||||
// For encoding/decoding, we generally want the following behavior:
|
||||
// (1) If you encode the maximum value or the minimum value, the resulting int fits in 21 bits.
|
||||
// (2) If you decode an encoded value, you get back the original value for both the minimum and maximum planet model values.
|
||||
|
|
|
@ -30,13 +30,25 @@ import org.apache.lucene.util.NumericUtils;
|
|||
class PointInShapeIntersectVisitor implements IntersectVisitor {
|
||||
private final DocIdSetBuilder hits;
|
||||
private final GeoShape shape;
|
||||
private final XYZBounds shapeBounds;
|
||||
private final double minimumX;
|
||||
private final double maximumX;
|
||||
private final double minimumY;
|
||||
private final double maximumY;
|
||||
private final double minimumZ;
|
||||
private final double maximumZ;
|
||||
private DocIdSetBuilder.BulkAdder adder;
|
||||
|
||||
public PointInShapeIntersectVisitor(DocIdSetBuilder hits, GeoShape shape, XYZBounds shapeBounds) {
|
||||
public PointInShapeIntersectVisitor(DocIdSetBuilder hits,
|
||||
GeoShape shape,
|
||||
XYZBounds bounds) {
|
||||
this.hits = hits;
|
||||
this.shape = shape;
|
||||
this.shapeBounds = shapeBounds;
|
||||
this.minimumX = Geo3DDocValuesField.roundDownX(bounds.getMinimumX());
|
||||
this.maximumX = Geo3DDocValuesField.roundUpX(bounds.getMaximumX());
|
||||
this.minimumY = Geo3DDocValuesField.roundDownY(bounds.getMinimumY());
|
||||
this.maximumY = Geo3DDocValuesField.roundUpY(bounds.getMaximumY());
|
||||
this.minimumZ = Geo3DDocValuesField.roundDownZ(bounds.getMinimumZ());
|
||||
this.maximumZ = Geo3DDocValuesField.roundUpZ(bounds.getMaximumZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -55,9 +67,9 @@ class PointInShapeIntersectVisitor implements IntersectVisitor {
|
|||
double x = Geo3DPoint.decodeDimension(packedValue, 0);
|
||||
double y = Geo3DPoint.decodeDimension(packedValue, Integer.BYTES);
|
||||
double z = Geo3DPoint.decodeDimension(packedValue, 2 * Integer.BYTES);
|
||||
if (x >= shapeBounds.getMinimumX() && x <= shapeBounds.getMaximumX() &&
|
||||
y >= shapeBounds.getMinimumY() && y <= shapeBounds.getMaximumY() &&
|
||||
z >= shapeBounds.getMinimumZ() && z <= shapeBounds.getMaximumZ()) {
|
||||
if (x >= minimumX && x <= maximumX &&
|
||||
y >= minimumY && y <= maximumY &&
|
||||
z >= minimumZ && z <= maximumZ) {
|
||||
if (shape.isWithin(x, y, z)) {
|
||||
adder.add(docID);
|
||||
}
|
||||
|
@ -83,9 +95,9 @@ class PointInShapeIntersectVisitor implements IntersectVisitor {
|
|||
assert zMin <= zMax;
|
||||
|
||||
// First, check bounds. If the shape is entirely contained, return CELL_CROSSES_QUERY.
|
||||
if (shapeBounds.getMinimumX() >= xMin && shapeBounds.getMaximumX() <= xMax &&
|
||||
shapeBounds.getMinimumY() >= yMin && shapeBounds.getMaximumY() <= yMax &&
|
||||
shapeBounds.getMinimumZ() >= zMin && shapeBounds.getMaximumZ() <= zMax) {
|
||||
if (minimumX >= xMin && maximumX <= xMax &&
|
||||
minimumY >= yMin && maximumY <= yMax &&
|
||||
minimumZ >= zMin && maximumZ <= zMax) {
|
||||
return Relation.CELL_CROSSES_QUERY;
|
||||
}
|
||||
|
||||
|
|
|
@ -1480,7 +1480,9 @@ public class TestGeo3DPoint extends LuceneTestCase {
|
|||
b.append("target is in leaf " + leafReader + " of full reader " + reader + "\n");
|
||||
|
||||
DocIdSetBuilder hits = new DocIdSetBuilder(leafReader.maxDoc());
|
||||
ExplainingVisitor visitor = new ExplainingVisitor(shape, targetDocPoint, scaledDocPoint, new PointInShapeIntersectVisitor(hits, shape, bounds), docID - reader.leaves().get(subIndex).docBase, 3, Integer.BYTES, b);
|
||||
ExplainingVisitor visitor = new ExplainingVisitor(shape, targetDocPoint, scaledDocPoint,
|
||||
new PointInShapeIntersectVisitor(hits, shape, bounds),
|
||||
docID - reader.leaves().get(subIndex).docBase, 3, Integer.BYTES, b);
|
||||
|
||||
// Do first phase, where we just figure out the "path" that leads to the target docID:
|
||||
leafReader.getPointValues().intersect(fieldName, visitor);
|
||||
|
|
Loading…
Reference in New Issue