Example usage for org.apache.lucene.util SloppyMath toRadians

List of usage examples for org.apache.lucene.util SloppyMath toRadians

Introduction

In this page you can find the example usage for org.apache.lucene.util SloppyMath toRadians.

Prototype

public static double toRadians(final double degrees) 

Source Link

Document

Convert to radians.

Usage

From source file:com.czw.search.lucene.example.facet.DistanceFacetsExample.java

License:Apache License

/** Given a latitude and longitude (in degrees) and the
 *  maximum great circle (surface of the earth) distance,
 *  returns a simple Filter bounding box to "fast match"
 *  candidates. *//*from ww  w.  j av  a 2s .com*/
public static Query getBoundingBoxQuery(double originLat, double originLng, double maxDistanceKM) {

    // Basic bounding box geo math from
    // http://JanMatuschek.de/LatitudeLongitudeBoundingCoordinates,
    // licensed under creative commons 3.0:
    // http://creativecommons.org/licenses/by/3.0

    // TODO: maybe switch to recursive prefix tree instead
    // (in lucene/spatial)?  It should be more efficient
    // since it's a 2D trie...

    // Degrees -> Radians:
    double originLatRadians = SloppyMath.toRadians(originLat);
    double originLngRadians = SloppyMath.toRadians(originLng);

    double angle = maxDistanceKM / EARTH_RADIUS_KM;

    double minLat = originLatRadians - angle;
    double maxLat = originLatRadians + angle;

    double minLng;
    double maxLng;
    if (minLat > SloppyMath.toRadians(-90) && maxLat < SloppyMath.toRadians(90)) {
        double delta = Math.asin(Math.sin(angle) / Math.cos(originLatRadians));
        minLng = originLngRadians - delta;
        if (minLng < SloppyMath.toRadians(-180)) {
            minLng += 2 * Math.PI;
        }
        maxLng = originLngRadians + delta;
        if (maxLng > SloppyMath.toRadians(180)) {
            maxLng -= 2 * Math.PI;
        }
    } else {
        // The query includes a pole!
        minLat = Math.max(minLat, SloppyMath.toRadians(-90));
        maxLat = Math.min(maxLat, SloppyMath.toRadians(90));
        minLng = SloppyMath.toRadians(-180);
        maxLng = SloppyMath.toRadians(180);
    }

    BooleanQuery.Builder f = new BooleanQuery.Builder();

    // Add latitude range filter:
    f.add(DoublePoint.newRangeQuery("latitude", SloppyMath.toDegrees(minLat), SloppyMath.toDegrees(maxLat)),
            BooleanClause.Occur.FILTER);

    // Add longitude range filter:
    if (minLng > maxLng) {
        // The bounding box crosses the international date
        // line:
        BooleanQuery.Builder lonF = new BooleanQuery.Builder();
        lonF.add(DoublePoint.newRangeQuery("longitude", SloppyMath.toDegrees(minLng), Double.POSITIVE_INFINITY),
                BooleanClause.Occur.SHOULD);
        lonF.add(DoublePoint.newRangeQuery("longitude", Double.NEGATIVE_INFINITY, SloppyMath.toDegrees(maxLng)),
                BooleanClause.Occur.SHOULD);
        f.add(lonF.build(), BooleanClause.Occur.MUST);
    } else {
        f.add(DoublePoint.newRangeQuery("longitude", SloppyMath.toDegrees(minLng),
                SloppyMath.toDegrees(maxLng)), BooleanClause.Occur.FILTER);
    }

    return f.build();
}