/**
*
*/
package com.browseengine.bobo.facets.impl;
import java.io.IOException;
import java.util.Properties;
import org.apache.lucene.search.Filter;
import org.apache.lucene.spatial.SpatialStrategy;
import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
import org.apache.lucene.spatial.query.SpatialArgs;
import org.apache.lucene.spatial.query.SpatialOperation;
import com.browseengine.bobo.api.BoboSegmentReader;
import com.browseengine.bobo.api.BrowseSelection;
import com.browseengine.bobo.api.FacetSpec;
import com.browseengine.bobo.facets.FacetCountCollectorSource;
import com.browseengine.bobo.facets.FacetHandler;
import com.browseengine.bobo.facets.data.FacetDataCache;
import com.browseengine.bobo.facets.data.TermValueList;
import com.browseengine.bobo.facets.filter.RandomAccessFilter;
import com.browseengine.bobo.facets.filter.SpatialFacetFilter;
import com.browseengine.bobo.facets.impl.GeoFacetCountCollector.GeoRange;
import com.browseengine.bobo.sort.DocComparatorSource;
import com.browseengine.bobo.util.BigSegmentedArray;
import com.spatial4j.core.context.SpatialContext;
import com.spatial4j.core.distance.DistanceUtils;
/** Constructor for SpatialFacetHandler
* @param name - name of the Spatial facet
*
*/
public class SpatialFacetHandler extends FacetHandler<FacetDataCache<?>> {
private final String longitude;
private final String latitude;
private final SpatialStrategy spatialStrategy;
public SpatialFacetHandler(String name, String lonFieldName, String latFieldName,
String geoFieldName, int geoHashPrefixTreeMaxLevels) {
super(name);
longitude = lonFieldName;
latitude = latFieldName;
SpatialPrefixTree grid = new GeohashPrefixTree(SpatialContext.GEO, geoHashPrefixTreeMaxLevels);
spatialStrategy = new RecursivePrefixTreeStrategy(grid, geoFieldName);
}
@Override
public FacetDataCache<?> load(BoboSegmentReader reader) throws IOException {
// No need to load any data
return null;
}
/**
* Builds a random access filter.
* @param value Should be of the form: lat, lon: rad
* @param selectionProperty
*/
@Override
public RandomAccessFilter buildRandomAccessFilter(String value, Properties selectionProperty)
throws IOException {
GeoRange range = GeoFacetCountCollector.parse(value);
SpatialArgs spatialArgs = new SpatialArgs(SpatialOperation.Intersects,
SpatialContext.GEO.makeCircle(range.getLon(), range.getLat(),
DistanceUtils.dist2Degrees(range.getRad(), DistanceUtils.EARTH_MEAN_RADIUS_KM)));
Filter filter = spatialStrategy.makeFilter(spatialArgs);
if (filter == null) {
return null;
}
return new SpatialFacetFilter(filter);
}
@Override
public DocComparatorSource getDocComparatorSource() {
throw new UnsupportedOperationException("Doc comparator is not yet supported for spatial facet");
}
@Override
public FacetCountCollectorSource getFacetCountCollectorSource(final BrowseSelection sel,
final FacetSpec fspec) {
throw new UnsupportedOperationException(
"Facet count collector is not yet supported for spatial facet");
}
@Override
public String[] getFieldValues(BoboSegmentReader reader, int id) {
FacetDataCache<?> latCache = (FacetDataCache<?>) reader.getFacetData(latitude);
FacetDataCache<?> lonCache = (FacetDataCache<?>) reader.getFacetData(longitude);
BigSegmentedArray latOrderArray = latCache.orderArray;
TermValueList<?> latValList = latCache.valArray;
BigSegmentedArray lonOrderArray = lonCache.orderArray;
TermValueList<?> lonValList = lonCache.valArray;
String docLatString = latValList.get(latOrderArray.get(id));
String docLonString = lonValList.get(lonOrderArray.get(id));
String[] fieldValues = new String[] { docLatString, docLonString };
return fieldValues;
}
}