public static double decodeLon(int x) {
return x / LON_SCALE;
}
<<<<<<< HEAD
// nocommit newSetQuery
=======
/** Turns quantized value from byte array back into a double. */
public static double decodeLon(byte[] src, int offset) {
return decodeLon(NumericUtils.bytesToInt(src, offset));
}
/** sugar encodes a single point as a 2D byte array */
private static byte[][] encode(double lat, double lon) {
byte[][] bytes = new byte[2][];
bytes[0] = new byte[4];
NumericUtils.intToBytes(encodeLat(lat), bytes[0], 0);
bytes[1] = new byte[4];
NumericUtils.intToBytes(encodeLon(lon), bytes[1], 0);
return bytes;
}
// static methods for generating queries
/**
* Create a query for matching a bounding box.
*
* The box may cross over the dateline.
*/
public static Query newBoxQuery(String field, double minLat, double maxLat, double minLon, double maxLon) {
if (GeoUtils.isValidLat(minLat) == false) {
throw new IllegalArgumentException("minLat=" + minLat + " is not a valid latitude");
}
if (GeoUtils.isValidLat(maxLat) == false) {
throw new IllegalArgumentException("maxLat=" + maxLat + " is not a valid latitude");
}
if (GeoUtils.isValidLon(minLon) == false) {
throw new IllegalArgumentException("minLon=" + minLon + " is not a valid longitude");
}
if (GeoUtils.isValidLon(maxLon) == false) {
throw new IllegalArgumentException("maxLon=" + maxLon + " is not a valid longitude");
}
byte[][] lower = encode(minLat, minLon);
byte[][] upper = encode(maxLat, maxLon);
// Crosses date line: we just rewrite into OR of two bboxes, with longitude as an open range:
if (maxLon < minLon) {
// Disable coord here because a multi-valued doc could match both rects and get unfairly boosted:
BooleanQuery.Builder q = new BooleanQuery.Builder();
q.setDisableCoord(true);
// E.g.: maxLon = -179, minLon = 179
byte[][] leftOpen = new byte[2][];
leftOpen[0] = lower[0];
// leave longitude open (null)
Query left = newBoxInternal(field, leftOpen, upper);
q.add(new BooleanClause(left, BooleanClause.Occur.SHOULD));
byte[][] rightOpen = new byte[2][];
rightOpen[0] = upper[0];
// leave longitude open (null)
Query right = newBoxInternal(field, lower, rightOpen);
q.add(new BooleanClause(right, BooleanClause.Occur.SHOULD));
return new ConstantScoreQuery(q.build());
} else {
return newBoxInternal(field, lower, upper);
}
}
private static Query newBoxInternal(String field, byte[][] min, byte[][] max) {
return new PointRangeQuery(field, min, new boolean[] { true, true }, max, new boolean[] { false, false }) {
@Override
protected String toString(int dimension, byte[] value) {
if (dimension == 0) {
return Double.toString(decodeLat(value, 0));
} else if (dimension == 1) {
return Double.toString(decodeLon(value, 0));
} else {
throw new AssertionError();
}
}
};
}
/**
* Create a query for matching a polygon.
*
* The supplied {@code polyLats}/{@code polyLons} must be clockwise or counter-clockwise.
*/
public static Query newPolygonQuery(String field, double[] polyLats, double[] polyLons) {
return new PointInPolygonQuery(field, polyLats, polyLons);
}
>>>>>>> 77e62276f99d3d525aa2ee8681de4ff0f78e6c2a
} |