/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.lucene.spatial.tier; import org.apache.lucene.search.ConstantScoreQuery; import org.apache.lucene.search.ChainedFilter; import org.apache.lucene.search.Filter; import org.apache.lucene.search.Query; import org.apache.lucene.search.QueryWrapperFilter; import org.apache.lucene.spatial.geohash.GeoHashDistanceFilter; /** * <p><font color="red"><b>NOTE:</b> This API is still in * flux and might change in incompatible ways in the next * release.</font> */ public class DistanceQueryBuilder { private static final long serialVersionUID = 1L; private final double lat; private final double lng; private final double miles; private final Filter filter; final DistanceFilter distanceFilter; /** * Create a distance query using * a boundary box wrapper around a more precise * DistanceFilter. * * @param lat The latitude to search around * @param lng the Longitude to search around * @param miles The radius to search within * @param latField The name of the field containing the latitude * @param lngField The name of the field containing the longitude * @param tierFieldPrefix The prefix of the tier * @param needPrecise if true, then distance is calculated in addition to tier info * @param minTierIndexed The minimum tier level indexed * @param maxTierIndexed The maximum tier level indexed */ public DistanceQueryBuilder (double lat, double lng, double miles, String latField, String lngField, String tierFieldPrefix, boolean needPrecise, int minTierIndexed, int maxTierIndexed) { this.lat = lat; this.lng = lng; this.miles = miles; CartesianPolyFilterBuilder cpf = new CartesianPolyFilterBuilder(tierFieldPrefix, minTierIndexed, maxTierIndexed); Filter cartesianFilter = cpf.getBoundingArea(lat, lng, miles); /* create precise distance filter */ if (needPrecise) { filter = distanceFilter = new LatLongDistanceFilter(cartesianFilter, lat, lng, miles, latField, lngField); } else { filter = cartesianFilter; distanceFilter = null; } } /** * Create a distance query using * a boundary box wrapper around a more precise * DistanceFilter. * * @param lat * @param lng * @param miles */ public DistanceQueryBuilder (double lat, double lng, double miles, String geoHashFieldPrefix, String tierFieldPrefix, boolean needPrecise, int minTierIndexed, int maxTierIndexed){ this.lat = lat; this.lng = lng; this.miles = miles; CartesianPolyFilterBuilder cpf = new CartesianPolyFilterBuilder(tierFieldPrefix, minTierIndexed, maxTierIndexed); Filter cartesianFilter = cpf.getBoundingArea(lat, lng, miles); /* create precise distance filter */ if (needPrecise) { filter = distanceFilter = new GeoHashDistanceFilter(cartesianFilter, lat, lng, miles, geoHashFieldPrefix); } else { filter = cartesianFilter; distanceFilter = null; } } /** * Create a distance query using * a boundary box wrapper around a more precise * DistanceFilter. */ public Filter getFilter() { if (distanceFilter != null) { distanceFilter.reset(); } return filter; } public Filter getFilter(Query query) { // Chain the Query (as filter) with our distance filter if (distanceFilter != null) { distanceFilter.reset(); } QueryWrapperFilter qf = new QueryWrapperFilter(query); return new ChainedFilter(new Filter[] {qf, filter}, ChainedFilter.AND); } public DistanceFilter getDistanceFilter() { return distanceFilter; } public Query getQuery(Query query){ return new ConstantScoreQuery(getFilter(query)); } public double getLat() { return lat; } public double getLng() { return lng; } public double getMiles() { return miles; } @Override public String toString() { return "DistanceQuery lat: " + lat + " lng: " + lng + " miles: "+ miles; } }