use of org.locationtech.spatial4j.shape.Point in project lucene-solr by apache.
the class TestSolr4Spatial method checkHits.
private void checkHits(String fieldName, boolean exact, String ptStr, double distKM, double sphereRadius, int count, int... docIds) throws ParseException {
if (exact && fieldName.equalsIgnoreCase("bbox")) {
// bbox field only supports rectangular query
return;
}
String[] tests = new String[docIds != null && docIds.length > 0 ? docIds.length + 1 : 1];
//test for presence of required ids first
int i = 0;
if (docIds != null && docIds.length > 0) {
for (int docId : docIds) {
tests[i++] = "//result/doc/*[@name='id'][.='" + docId + "']";
}
}
//check total length last; maybe response includes ids it shouldn't. Nicer to check this last instead of first so
// that there may be a more specific detailed id to investigate.
tests[i++] = "*[count(//doc)=" + count + "]";
//Test using the Lucene spatial syntax
{
//never actually need the score but lets test
String score = randomScoreMode();
double distDEG = DistanceUtils.dist2Degrees(distKM, DistanceUtils.EARTH_MEAN_RADIUS_KM);
Point point = SpatialUtils.parsePoint(ptStr, SpatialContext.GEO);
String circleStr = "BUFFER(POINT(" + point.getX() + " " + point.getY() + ")," + distDEG + ")";
String shapeStr;
if (exact) {
shapeStr = circleStr;
} else {
//bbox
//the GEO is an assumption
SpatialContext ctx = SpatialContext.GEO;
Rectangle bbox = ctx.readShapeFromWkt(circleStr).getBoundingBox();
shapeStr = "ENVELOPE(" + bbox.getMinX() + ", " + bbox.getMaxX() + ", " + bbox.getMaxY() + ", " + bbox.getMinY() + ")";
}
//FYI default distErrPct=0.025 works with the tests in this file
assertQ(req("fl", "id", "q", "*:*", "rows", "1000", "fq", "{!field f=" + fieldName + (score == null ? "" : " score=" + score) + "}Intersects(" + shapeStr + ")"), tests);
}
//Test using geofilt
{
assertQ(req("fl", "id", "q", "*:*", "rows", "1000", "fq", "{!" + (exact ? "geofilt" : "bbox") + " sfield=" + fieldName + " pt='" + ptStr + "' d=" + distKM + " sphere_radius=" + sphereRadius + "}"), tests);
}
}
use of org.locationtech.spatial4j.shape.Point in project lucene-solr by apache.
the class LegacyPrefixTree method getTreeCellIterator.
@Override
public CellIterator getTreeCellIterator(Shape shape, int detailLevel) {
if (!(shape instanceof Point))
return super.getTreeCellIterator(shape, detailLevel);
//This specialization is here because the legacy implementations don't have a fast implementation of
// cell.getSubCells(point). It's fastest here to encode the full bytes for detailLevel, and create
// subcells from the bytesRef in a loop. This avoids an O(N^2) encode, and we have O(N) instead.
Cell cell = getCell((Point) shape, detailLevel);
assert cell instanceof LegacyCell;
BytesRef fullBytes = cell.getTokenBytesNoLeaf(null);
//fill in reverse order to be sorted
Cell[] cells = new Cell[detailLevel];
for (int i = 1; i < detailLevel; i++) {
fullBytes.length = i;
Cell parentCell = readCell(fullBytes, null);
cells[i - 1] = parentCell;
}
cells[detailLevel - 1] = cell;
//null filter
return new FilterCellIterator(Arrays.asList(cells).iterator(), null);
}
use of org.locationtech.spatial4j.shape.Point in project lucene-solr by apache.
the class PackedQuadPrefixTree method checkBattenberg.
protected void checkBattenberg(byte quad, double cx, double cy, int level, List<Cell> matches, long term, Shape shape, int maxLevel) {
// short-circuit if we find a match for the point (no need to continue recursion)
if (shape instanceof Point && !matches.isEmpty())
return;
double w = levelW[level] / 2;
double h = levelH[level] / 2;
SpatialRelation v = shape.relate(ctx.makeRectangle(cx - w, cx + w, cy - h, cy + h));
if (SpatialRelation.DISJOINT == v) {
return;
}
// set bits for next level
term |= (((long) (quad)) << (64 - (++level << 1)));
// increment level
term = ((term >>> 1) + 1) << 1;
if (SpatialRelation.CONTAINS == v || (level >= maxLevel)) {
matches.add(new PackedQuadCell(term, v.transpose()));
} else {
// SpatialRelation.WITHIN, SpatialRelation.INTERSECTS
build(cx, cy, level, matches, term, shape, maxLevel);
}
}
use of org.locationtech.spatial4j.shape.Point in project lucene-solr by apache.
the class SpatialArgs method calcDistanceFromErrPct.
/**
* Computes the distance given a shape and the {@code distErrPct}. The
* algorithm is the fraction of the distance from the center of the query
* shape to its closest bounding box corner.
*
* @param shape Mandatory.
* @param distErrPct 0 to 0.5
* @param ctx Mandatory
* @return A distance (in degrees).
*/
public static double calcDistanceFromErrPct(Shape shape, double distErrPct, SpatialContext ctx) {
if (distErrPct < 0 || distErrPct > 0.5) {
throw new IllegalArgumentException("distErrPct " + distErrPct + " must be between [0 to 0.5]");
}
if (distErrPct == 0 || shape instanceof Point) {
return 0;
}
Rectangle bbox = shape.getBoundingBox();
//Compute the distance from the center to a corner. Because the distance
// to a bottom corner vs a top corner can vary in a geospatial scenario,
// take the closest one (greater precision).
Point ctr = bbox.getCenter();
double y = (ctr.getY() >= 0 ? bbox.getMaxY() : bbox.getMinY());
double diagonalDist = ctx.getDistCalc().distance(ctr, bbox.getMaxX(), y);
return diagonalDist * distErrPct;
}
use of org.locationtech.spatial4j.shape.Point in project lucene-solr by apache.
the class SpatialDistanceQuery method getFieldQuery.
@Override
public Query getFieldQuery(QParser parser, SchemaField field, String externalVal) {
Point p1 = SpatialUtils.parsePointSolrException(externalVal, SpatialContext.GEO);
SchemaField latSF = subField(field, LAT, parser.getReq().getSchema());
SchemaField lonSF = subField(field, LON, parser.getReq().getSchema());
BooleanQuery.Builder result = new BooleanQuery.Builder();
result.add(latSF.getType().getFieldQuery(parser, latSF, Double.toString(p1.getY())), BooleanClause.Occur.MUST);
result.add(lonSF.getType().getFieldQuery(parser, lonSF, Double.toString(p1.getX())), BooleanClause.Occur.MUST);
return result.build();
}
Aggregations