From d8fff9b873687b452fd3575c15a2e4dc75a08f5b Mon Sep 17 00:00:00 2001 From: Yonik Seeley Date: Wed, 14 Mar 2012 04:05:51 +0000 Subject: [PATCH] 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 --- .../java/org/apache/solr/schema/LatLonType.java | 17 +++++++++-------- .../apache/solr/search/ValueSourceParser.java | 4 ++-- .../distance/HaversineConstFunction.java | 13 ++++++++----- .../function/distance/HaversineFunction.java | 8 ++++---- .../apache/solr/search/SpatialFilterTest.java | 2 +- 5 files changed, 24 insertions(+), 20 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/schema/LatLonType.java b/solr/core/src/java/org/apache/solr/schema/LatLonType.java index b2f4f2bb3f7..5e2c4f25ce6 100644 --- a/solr/core/src/java/org/apache/solr/schema/LatLonType.java +++ b/solr/core/src/java/org/apache/solr/schema/LatLonType.java @@ -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 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; diff --git a/solr/core/src/java/org/apache/solr/search/ValueSourceParser.java b/solr/core/src/java/org/apache/solr/search/ValueSourceParser.java index c8c21be73b0..d7051ed8483 100755 --- a/solr/core/src/java/org/apache/solr/search/ValueSourceParser.java +++ b/solr/core/src/java/org/apache/solr/search/ValueSourceParser.java @@ -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") { diff --git a/solr/core/src/java/org/apache/solr/search/function/distance/HaversineConstFunction.java b/solr/core/src/java/org/apache/solr/search/function/distance/HaversineConstFunction.java index 1c6bbcce169..5e22eb3e114 100755 --- a/solr/core/src/java/org/apache/solr/search/function/distance/HaversineConstFunction.java +++ b/solr/core/src/java/org/apache/solr/search/function/distance/HaversineConstFunction.java @@ -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); diff --git a/solr/core/src/java/org/apache/solr/search/function/distance/HaversineFunction.java b/solr/core/src/java/org/apache/solr/search/function/distance/HaversineFunction.java index f2a537d8cc1..2cc8d068e40 100644 --- a/solr/core/src/java/org/apache/solr/search/function/distance/HaversineFunction.java +++ b/solr/core/src/java/org/apache/solr/search/function/distance/HaversineFunction.java @@ -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]; diff --git a/solr/core/src/test/org/apache/solr/search/SpatialFilterTest.java b/solr/core/src/test/org/apache/solr/search/SpatialFilterTest.java index 20b65e20d66..9f7c8ccf52a 100644 --- a/solr/core/src/test/org/apache/solr/search/SpatialFilterTest.java +++ b/solr/core/src/test/org/apache/solr/search/SpatialFilterTest.java @@ -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 } }