LUCENE-3795: re-optimize degrees-radians conversions

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1300457 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yonik Seeley 2012-03-14 04:05:51 +00:00
parent 8854531251
commit d8fff9b873
5 changed files with 24 additions and 20 deletions

View File

@ -36,6 +36,7 @@ import org.apache.lucene.util.Bits;
import org.apache.solr.common.SolrException;
import org.apache.solr.response.TextResponseWriter;
import org.apache.solr.search.*;
import org.apache.solr.search.function.distance.HaversineConstFunction;
import java.io.IOException;
import java.util.ArrayList;
@ -49,7 +50,7 @@ import java.util.Set;
*/
public class LatLonType extends AbstractSubTypeFieldType implements SpatialQueryable {
protected static final int LAT = 0;
protected static final int LONG = 1;
protected static final int LON = 1;
@Override
protected void init(IndexSchema schema, Map<String, String> args) {
@ -75,7 +76,7 @@ public class LatLonType extends AbstractSubTypeFieldType implements SpatialQuery
f[i] = subField(field, i).createField(String.valueOf(latLon[LAT]), boost);
i++;
//longitude
f[i] = subField(field, i).createField(String.valueOf(latLon[LONG]), boost);
f[i] = subField(field, i).createField(String.valueOf(latLon[LON]), boost);
}
@ -142,7 +143,7 @@ public class LatLonType extends AbstractSubTypeFieldType implements SpatialQuery
// lat & lon in degrees
double latCenter = point[LAT];
double lonCenter = point[LONG];
double lonCenter = point[LON];
DistanceCalculator distCalc = new GeodesicSphereDistCalc.Haversine(options.units.earthRadius());
SpatialContext ctx = new SimpleSpatialContext(options.units,distCalc,null);
@ -164,7 +165,7 @@ public class LatLonType extends AbstractSubTypeFieldType implements SpatialQuery
// Now that we've figured out the ranges, build them!
SchemaField latField = subField(options.field, LAT);
SchemaField lonField = subField(options.field, LONG);
SchemaField lonField = subField(options.field, LON);
SpatialDistanceQuery spatial = new SpatialDistanceQuery();
@ -398,8 +399,8 @@ class SpatialDistanceQuery extends ExtendedQueryBase implements PostFilter {
this.lon2 = SpatialDistanceQuery.this.lon2;
this.calcDist = SpatialDistanceQuery.this.calcDist;
this.latCenterRad = Math.toRadians(SpatialDistanceQuery.this.latCenter);
this.lonCenterRad = Math.toRadians(SpatialDistanceQuery.this.lonCenter);
this.latCenterRad = SpatialDistanceQuery.this.latCenter * HaversineConstFunction.DEGREES_TO_RADIANS;
this.lonCenterRad = SpatialDistanceQuery.this.lonCenter * HaversineConstFunction.DEGREES_TO_RADIANS;
this.latCenterRad_cos = this.calcDist ? Math.cos(latCenterRad) : 0;
this.dist = SpatialDistanceQuery.this.dist;
this.planetRadius = SpatialDistanceQuery.this.planetRadius;
@ -428,8 +429,8 @@ class SpatialDistanceQuery extends ExtendedQueryBase implements PostFilter {
}
double dist(double lat, double lon) {
double latRad = Math.toRadians(lat);
double lonRad = Math.toRadians(lon);
double latRad = lat * HaversineConstFunction.DEGREES_TO_RADIANS;
double lonRad = lon * HaversineConstFunction.DEGREES_TO_RADIANS;
// haversine, specialized to avoid a cos() call on latCenterRad
double diffX = latCenterRad - latRad;

View File

@ -362,13 +362,13 @@ public abstract class ValueSourceParser implements NamedListInitializedPlugin {
addParser(new DoubleParser("rad") {
@Override
public double func(int doc, FunctionValues vals) {
return Math.toRadians(vals.doubleVal(doc));
return vals.doubleVal(doc) * HaversineConstFunction.DEGREES_TO_RADIANS;
}
});
addParser(new DoubleParser("deg") {
@Override
public double func(int doc, FunctionValues vals) {
return Math.toDegrees(vals.doubleVal(doc));
return vals.doubleVal(doc) * HaversineConstFunction.RADIANS_TO_DEGREES;
}
});
addParser(new DoubleParser("sqrt") {

View File

@ -44,6 +44,9 @@ import java.util.Map;
* Haversine function with one point constant
*/
public class HaversineConstFunction extends ValueSource {
// TODO: these could go in spatial4j somewhere
public static final double DEGREES_TO_RADIANS = Math.PI / 180.0;
public static final double RADIANS_TO_DEGREES = 180.0 / Math.PI;
public static ValueSourceParser parser = new ValueSourceParser() {
@Override
@ -190,7 +193,7 @@ public class HaversineConstFunction extends ValueSource {
this.p2 = vs;
this.latSource = p2.getSources().get(0);
this.lonSource = p2.getSources().get(1);
this.latCenterRad_cos = Math.cos(Math.toRadians(latCenter));
this.latCenterRad_cos = Math.cos(latCenter * DEGREES_TO_RADIANS);
}
protected String name() {
@ -201,15 +204,15 @@ public class HaversineConstFunction extends ValueSource {
public FunctionValues getValues(Map context, AtomicReaderContext readerContext) throws IOException {
final FunctionValues latVals = latSource.getValues(context, readerContext);
final FunctionValues lonVals = lonSource.getValues(context, readerContext);
final double latCenterRad = Math.toRadians(this.latCenter);
final double lonCenterRad = Math.toRadians(this.lonCenter);
final double latCenterRad = this.latCenter * DEGREES_TO_RADIANS;
final double lonCenterRad = this.lonCenter * DEGREES_TO_RADIANS;
final double latCenterRad_cos = this.latCenterRad_cos;
return new DoubleDocValues(this) {
@Override
public double doubleVal(int doc) {
double latRad = Math.toRadians(latVals.doubleVal(doc));
double lonRad = Math.toRadians(lonVals.doubleVal(doc));
double latRad = latVals.doubleVal(doc) * DEGREES_TO_RADIANS;
double lonRad = lonVals.doubleVal(doc) * DEGREES_TO_RADIANS;
double diffX = latCenterRad - latRad;
double diffY = lonCenterRad - lonRad;
double hsinX = Math.sin(diffX * 0.5);

View File

@ -81,10 +81,10 @@ public class HaversineFunction extends ValueSource {
double y2;
double x2;
if (convertToRadians) {
y1 = Math.toRadians(p1D[0]);
x1 = Math.toRadians(p1D[1]);
y2 = Math.toRadians(p2D[0]);
x2 = Math.toRadians(p2D[1]);
y1 = p1D[0] * HaversineConstFunction.DEGREES_TO_RADIANS;
x1 = p1D[1] * HaversineConstFunction.DEGREES_TO_RADIANS;
y2 = p2D[0] * HaversineConstFunction.DEGREES_TO_RADIANS;
x2 = p2D[1] * HaversineConstFunction.DEGREES_TO_RADIANS;
} else {
y1 = p1D[0];
x1 = p1D[1];

View File

@ -169,7 +169,7 @@ public class SpatialFilterTest extends SolrTestCaseJ4 {
assertQ(req("fl", "id", "q","*:* OR foo_i:" + random.nextInt(100)+100, "rows", "1000", "fq", "{!"+method+" sfield=" +fieldName + " cache=false cost=150" + "}",
"pt", pt, "d", String.valueOf(distance)),
tests);
assertEquals(postFilterCount + 1, DelegatingCollector.setLastDelegateCount); // post filtering shouldn't be used
assertEquals(postFilterCount + 1, DelegatingCollector.setLastDelegateCount); // post filtering *should* have been used
}
}