/** Create a predicate that checks whether points are within a distance of a given point. * It works by computing the bounding box around the circle that is defined * by the given points/distance and splitting it into between 1024 and 4096 * smaller boxes (4096*0.75^2=2304 on average). Then for each sub box, it * computes the relation between this box and the distance query. Finally at * search time, it first computes the sub box that the point belongs to, * most of the time, no distance computation will need to be performed since * all points from the sub box will either be in or out of the circle. * @lucene.internal */ public static DistancePredicate createDistancePredicate(double lat, double lon, double radiusMeters) { final Rectangle boundingBox = Rectangle.fromPointDistance(lat, lon, radiusMeters); final double axisLat = Rectangle.axisLat(lat, radiusMeters); final double distanceSortKey = GeoUtils.distanceQuerySortKey(radiusMeters); final Function<Rectangle, Relation> boxToRelation = box -> GeoUtils.relate( box.minLat, box.maxLat, box.minLon, box.maxLon, lat, lon, distanceSortKey, axisLat); final Grid subBoxes = createSubBoxes(boundingBox, boxToRelation); return new DistancePredicate( subBoxes.latShift, subBoxes.lonShift, subBoxes.latBase, subBoxes.lonBase, subBoxes.maxLatDelta, subBoxes.maxLonDelta, subBoxes.relations, lat, lon, distanceSortKey); }
@Override public void setBottom(int slot) { bottom = values[slot]; // make bounding box(es) to exclude non-competitive hits, but start // sampling if we get called way too much: don't make gobs of bounding // boxes if comparator hits a worst case order (e.g. backwards distance order) if (setBottomCounter < 1024 || (setBottomCounter & 0x3F) == 0x3F) { Rectangle box = Rectangle.fromPointDistance(latitude, longitude, haversin2(bottom)); // pre-encode our box to our integer encoding, so we don't have to decode // to double values for uncompetitive hits. This has some cost! minLat = encodeLatitude(box.minLat); maxLat = encodeLatitude(box.maxLat); if (box.crossesDateline()) { // box1 minLon = Integer.MIN_VALUE; maxLon = encodeLongitude(box.maxLon); // box2 minLon2 = encodeLongitude(box.minLon); } else { minLon = encodeLongitude(box.minLon); maxLon = encodeLongitude(box.maxLon); // disable box2 minLon2 = Integer.MAX_VALUE; } } setBottomCounter++; }
@Override public Weight createWeight(IndexSearcher searcher, boolean needsScores, float boost) throws IOException { Rectangle box = Rectangle.fromPointDistance(latitude, longitude, radiusMeters);
private void maybeUpdateBBox() { if (setBottomCounter < 1024 || (setBottomCounter & 0x3F) == 0x3F) { NearestHit hit = hitQueue.peek(); Rectangle box = Rectangle.fromPointDistance(pointLat, pointLon, hit.distanceMeters); //System.out.println(" update bbox to " + box); minLat = box.minLat; maxLat = box.maxLat; if (box.crossesDateline()) { // box1 minLon = Double.NEGATIVE_INFINITY; maxLon = box.maxLon; // box2 minLon2 = box.minLon; } else { minLon = box.minLon; maxLon = box.maxLon; // disable box2 minLon2 = Double.POSITIVE_INFINITY; } } setBottomCounter++; }
bbox = Rectangle.fromPointDistance(lat, lon, inclusiveUpperPoint); if ("memory".equals(optimizeBbox)) { boundingBoxFilter = null;
/** Create a predicate that checks whether points are within a distance of a given point. * It works by computing the bounding box around the circle that is defined * by the given points/distance and splitting it into between 1024 and 4096 * smaller boxes (4096*0.75^2=2304 on average). Then for each sub box, it * computes the relation between this box and the distance query. Finally at * search time, it first computes the sub box that the point belongs to, * most of the time, no distance computation will need to be performed since * all points from the sub box will either be in or out of the circle. * @lucene.internal */ public static DistancePredicate createDistancePredicate(double lat, double lon, double radiusMeters) { final Rectangle boundingBox = Rectangle.fromPointDistance(lat, lon, radiusMeters); final double axisLat = Rectangle.axisLat(lat, radiusMeters); final double distanceSortKey = GeoUtils.distanceQuerySortKey(radiusMeters); final Function<Rectangle, Relation> boxToRelation = box -> GeoUtils.relate( box.minLat, box.maxLat, box.minLon, box.maxLon, lat, lon, distanceSortKey, axisLat); final Grid subBoxes = createSubBoxes(boundingBox, boxToRelation); return new DistancePredicate( subBoxes.latShift, subBoxes.lonShift, subBoxes.latBase, subBoxes.lonBase, subBoxes.maxLatDelta, subBoxes.maxLonDelta, subBoxes.relations, lat, lon, distanceSortKey); }
@Override public void setBottom(int slot) { bottom = values[slot]; // make bounding box(es) to exclude non-competitive hits, but start // sampling if we get called way too much: don't make gobs of bounding // boxes if comparator hits a worst case order (e.g. backwards distance order) if (setBottomCounter < 1024 || (setBottomCounter & 0x3F) == 0x3F) { Rectangle box = Rectangle.fromPointDistance(latitude, longitude, haversin2(bottom)); // pre-encode our box to our integer encoding, so we don't have to decode // to double values for uncompetitive hits. This has some cost! minLat = encodeLatitude(box.minLat); maxLat = encodeLatitude(box.maxLat); if (box.crossesDateline()) { // box1 minLon = Integer.MIN_VALUE; maxLon = encodeLongitude(box.maxLon); // box2 minLon2 = encodeLongitude(box.minLon); } else { minLon = encodeLongitude(box.minLon); maxLon = encodeLongitude(box.maxLon); // disable box2 minLon2 = Integer.MAX_VALUE; } } setBottomCounter++; }
@Override public Weight createWeight(IndexSearcher searcher, boolean needsScores, float boost) throws IOException { Rectangle box = Rectangle.fromPointDistance(latitude, longitude, radiusMeters);