mirror of https://github.com/apache/lucene.git
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:
parent
8854531251
commit
d8fff9b873
|
@ -36,6 +36,7 @@ import org.apache.lucene.util.Bits;
|
||||||
import org.apache.solr.common.SolrException;
|
import org.apache.solr.common.SolrException;
|
||||||
import org.apache.solr.response.TextResponseWriter;
|
import org.apache.solr.response.TextResponseWriter;
|
||||||
import org.apache.solr.search.*;
|
import org.apache.solr.search.*;
|
||||||
|
import org.apache.solr.search.function.distance.HaversineConstFunction;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -49,7 +50,7 @@ import java.util.Set;
|
||||||
*/
|
*/
|
||||||
public class LatLonType extends AbstractSubTypeFieldType implements SpatialQueryable {
|
public class LatLonType extends AbstractSubTypeFieldType implements SpatialQueryable {
|
||||||
protected static final int LAT = 0;
|
protected static final int LAT = 0;
|
||||||
protected static final int LONG = 1;
|
protected static final int LON = 1;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void init(IndexSchema schema, Map<String, String> args) {
|
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);
|
f[i] = subField(field, i).createField(String.valueOf(latLon[LAT]), boost);
|
||||||
i++;
|
i++;
|
||||||
//longitude
|
//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
|
// lat & lon in degrees
|
||||||
double latCenter = point[LAT];
|
double latCenter = point[LAT];
|
||||||
double lonCenter = point[LONG];
|
double lonCenter = point[LON];
|
||||||
|
|
||||||
DistanceCalculator distCalc = new GeodesicSphereDistCalc.Haversine(options.units.earthRadius());
|
DistanceCalculator distCalc = new GeodesicSphereDistCalc.Haversine(options.units.earthRadius());
|
||||||
SpatialContext ctx = new SimpleSpatialContext(options.units,distCalc,null);
|
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!
|
// Now that we've figured out the ranges, build them!
|
||||||
SchemaField latField = subField(options.field, LAT);
|
SchemaField latField = subField(options.field, LAT);
|
||||||
SchemaField lonField = subField(options.field, LONG);
|
SchemaField lonField = subField(options.field, LON);
|
||||||
|
|
||||||
SpatialDistanceQuery spatial = new SpatialDistanceQuery();
|
SpatialDistanceQuery spatial = new SpatialDistanceQuery();
|
||||||
|
|
||||||
|
@ -398,8 +399,8 @@ class SpatialDistanceQuery extends ExtendedQueryBase implements PostFilter {
|
||||||
this.lon2 = SpatialDistanceQuery.this.lon2;
|
this.lon2 = SpatialDistanceQuery.this.lon2;
|
||||||
this.calcDist = SpatialDistanceQuery.this.calcDist;
|
this.calcDist = SpatialDistanceQuery.this.calcDist;
|
||||||
|
|
||||||
this.latCenterRad = Math.toRadians(SpatialDistanceQuery.this.latCenter);
|
this.latCenterRad = SpatialDistanceQuery.this.latCenter * HaversineConstFunction.DEGREES_TO_RADIANS;
|
||||||
this.lonCenterRad = Math.toRadians(SpatialDistanceQuery.this.lonCenter);
|
this.lonCenterRad = SpatialDistanceQuery.this.lonCenter * HaversineConstFunction.DEGREES_TO_RADIANS;
|
||||||
this.latCenterRad_cos = this.calcDist ? Math.cos(latCenterRad) : 0;
|
this.latCenterRad_cos = this.calcDist ? Math.cos(latCenterRad) : 0;
|
||||||
this.dist = SpatialDistanceQuery.this.dist;
|
this.dist = SpatialDistanceQuery.this.dist;
|
||||||
this.planetRadius = SpatialDistanceQuery.this.planetRadius;
|
this.planetRadius = SpatialDistanceQuery.this.planetRadius;
|
||||||
|
@ -428,8 +429,8 @@ class SpatialDistanceQuery extends ExtendedQueryBase implements PostFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
double dist(double lat, double lon) {
|
double dist(double lat, double lon) {
|
||||||
double latRad = Math.toRadians(lat);
|
double latRad = lat * HaversineConstFunction.DEGREES_TO_RADIANS;
|
||||||
double lonRad = Math.toRadians(lon);
|
double lonRad = lon * HaversineConstFunction.DEGREES_TO_RADIANS;
|
||||||
|
|
||||||
// haversine, specialized to avoid a cos() call on latCenterRad
|
// haversine, specialized to avoid a cos() call on latCenterRad
|
||||||
double diffX = latCenterRad - latRad;
|
double diffX = latCenterRad - latRad;
|
||||||
|
|
|
@ -362,13 +362,13 @@ public abstract class ValueSourceParser implements NamedListInitializedPlugin {
|
||||||
addParser(new DoubleParser("rad") {
|
addParser(new DoubleParser("rad") {
|
||||||
@Override
|
@Override
|
||||||
public double func(int doc, FunctionValues vals) {
|
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") {
|
addParser(new DoubleParser("deg") {
|
||||||
@Override
|
@Override
|
||||||
public double func(int doc, FunctionValues vals) {
|
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") {
|
addParser(new DoubleParser("sqrt") {
|
||||||
|
|
|
@ -44,6 +44,9 @@ import java.util.Map;
|
||||||
* Haversine function with one point constant
|
* Haversine function with one point constant
|
||||||
*/
|
*/
|
||||||
public class HaversineConstFunction extends ValueSource {
|
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() {
|
public static ValueSourceParser parser = new ValueSourceParser() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -190,7 +193,7 @@ public class HaversineConstFunction extends ValueSource {
|
||||||
this.p2 = vs;
|
this.p2 = vs;
|
||||||
this.latSource = p2.getSources().get(0);
|
this.latSource = p2.getSources().get(0);
|
||||||
this.lonSource = p2.getSources().get(1);
|
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() {
|
protected String name() {
|
||||||
|
@ -201,15 +204,15 @@ public class HaversineConstFunction extends ValueSource {
|
||||||
public FunctionValues getValues(Map context, AtomicReaderContext readerContext) throws IOException {
|
public FunctionValues getValues(Map context, AtomicReaderContext readerContext) throws IOException {
|
||||||
final FunctionValues latVals = latSource.getValues(context, readerContext);
|
final FunctionValues latVals = latSource.getValues(context, readerContext);
|
||||||
final FunctionValues lonVals = lonSource.getValues(context, readerContext);
|
final FunctionValues lonVals = lonSource.getValues(context, readerContext);
|
||||||
final double latCenterRad = Math.toRadians(this.latCenter);
|
final double latCenterRad = this.latCenter * DEGREES_TO_RADIANS;
|
||||||
final double lonCenterRad = Math.toRadians(this.lonCenter);
|
final double lonCenterRad = this.lonCenter * DEGREES_TO_RADIANS;
|
||||||
final double latCenterRad_cos = this.latCenterRad_cos;
|
final double latCenterRad_cos = this.latCenterRad_cos;
|
||||||
|
|
||||||
return new DoubleDocValues(this) {
|
return new DoubleDocValues(this) {
|
||||||
@Override
|
@Override
|
||||||
public double doubleVal(int doc) {
|
public double doubleVal(int doc) {
|
||||||
double latRad = Math.toRadians(latVals.doubleVal(doc));
|
double latRad = latVals.doubleVal(doc) * DEGREES_TO_RADIANS;
|
||||||
double lonRad = Math.toRadians(lonVals.doubleVal(doc));
|
double lonRad = lonVals.doubleVal(doc) * DEGREES_TO_RADIANS;
|
||||||
double diffX = latCenterRad - latRad;
|
double diffX = latCenterRad - latRad;
|
||||||
double diffY = lonCenterRad - lonRad;
|
double diffY = lonCenterRad - lonRad;
|
||||||
double hsinX = Math.sin(diffX * 0.5);
|
double hsinX = Math.sin(diffX * 0.5);
|
||||||
|
|
|
@ -81,10 +81,10 @@ public class HaversineFunction extends ValueSource {
|
||||||
double y2;
|
double y2;
|
||||||
double x2;
|
double x2;
|
||||||
if (convertToRadians) {
|
if (convertToRadians) {
|
||||||
y1 = Math.toRadians(p1D[0]);
|
y1 = p1D[0] * HaversineConstFunction.DEGREES_TO_RADIANS;
|
||||||
x1 = Math.toRadians(p1D[1]);
|
x1 = p1D[1] * HaversineConstFunction.DEGREES_TO_RADIANS;
|
||||||
y2 = Math.toRadians(p2D[0]);
|
y2 = p2D[0] * HaversineConstFunction.DEGREES_TO_RADIANS;
|
||||||
x2 = Math.toRadians(p2D[1]);
|
x2 = p2D[1] * HaversineConstFunction.DEGREES_TO_RADIANS;
|
||||||
} else {
|
} else {
|
||||||
y1 = p1D[0];
|
y1 = p1D[0];
|
||||||
x1 = p1D[1];
|
x1 = p1D[1];
|
||||||
|
|
|
@ -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" + "}",
|
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)),
|
"pt", pt, "d", String.valueOf(distance)),
|
||||||
tests);
|
tests);
|
||||||
assertEquals(postFilterCount + 1, DelegatingCollector.setLastDelegateCount); // post filtering shouldn't be used
|
assertEquals(postFilterCount + 1, DelegatingCollector.setLastDelegateCount); // post filtering *should* have been used
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue