Skip to content

Commit 8fb1aa9

Browse files
committed
Refactors GeoDistanceQueryBuilder/-Parser
Splits parsing and Lucene query generation. Switches from storing lat/lon separately to using GeoPoint instead. Relates to #10217
1 parent 65139ee commit 8fb1aa9

File tree

15 files changed

+659
-145
lines changed

15 files changed

+659
-145
lines changed

core/src/main/java/org/elasticsearch/common/Numbers.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,4 +171,12 @@ public static byte[] doubleToBytes(double val) {
171171
return longToBytes(Double.doubleToRawLongBits(val));
172172
}
173173

174+
/** Returns true if value is neither NaN nor infinite. */
175+
public static boolean isValidDouble(double value) {
176+
if (Double.isNaN(value) || Double.isInfinite(value)) {
177+
return false;
178+
}
179+
return true;
180+
}
181+
174182
}

core/src/main/java/org/elasticsearch/common/geo/GeoDistance.java

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,27 @@
2121

2222
import org.apache.lucene.util.Bits;
2323
import org.apache.lucene.util.SloppyMath;
24+
import org.elasticsearch.common.io.stream.StreamInput;
25+
import org.elasticsearch.common.io.stream.StreamOutput;
26+
import org.elasticsearch.common.io.stream.Writeable;
2427
import org.elasticsearch.common.unit.DistanceUnit;
2528
import org.elasticsearch.index.fielddata.FieldData;
2629
import org.elasticsearch.index.fielddata.GeoPointValues;
2730
import org.elasticsearch.index.fielddata.MultiGeoPointValues;
2831
import org.elasticsearch.index.fielddata.NumericDoubleValues;
2932
import org.elasticsearch.index.fielddata.SortedNumericDoubleValues;
3033
import org.elasticsearch.index.fielddata.SortingNumericDoubleValues;
31-
34+
import java.io.IOException;
3235
import java.util.Locale;
3336

3437
/**
3538
* Geo distance calculation.
3639
*/
37-
public enum GeoDistance {
40+
public enum GeoDistance implements Writeable<GeoDistance> {
3841
/**
3942
* Calculates distance as points on a plane. Faster, but less accurate than {@link #ARC}.
4043
*/
41-
PLANE() {
44+
PLANE {
4245
@Override
4346
public double calculate(double sourceLatitude, double sourceLongitude, double targetLatitude, double targetLongitude, DistanceUnit unit) {
4447
double px = targetLongitude - sourceLongitude;
@@ -60,7 +63,7 @@ public FixedSourceDistance fixedSourceDistance(double sourceLatitude, double sou
6063
/**
6164
* Calculates distance factor.
6265
*/
63-
FACTOR() {
66+
FACTOR {
6467
@Override
6568
public double calculate(double sourceLatitude, double sourceLongitude, double targetLatitude, double targetLongitude, DistanceUnit unit) {
6669
double longitudeDifference = targetLongitude - sourceLongitude;
@@ -82,7 +85,7 @@ public FixedSourceDistance fixedSourceDistance(double sourceLatitude, double sou
8285
/**
8386
* Calculates distance as points on a globe.
8487
*/
85-
ARC() {
88+
ARC {
8689
@Override
8790
public double calculate(double sourceLatitude, double sourceLongitude, double targetLatitude, double targetLongitude, DistanceUnit unit) {
8891
double x1 = sourceLatitude * Math.PI / 180D;
@@ -109,7 +112,7 @@ public FixedSourceDistance fixedSourceDistance(double sourceLatitude, double sou
109112
* Calculates distance as points on a globe in a sloppy way. Close to the pole areas the accuracy
110113
* of this function decreases.
111114
*/
112-
SLOPPY_ARC() {
115+
SLOPPY_ARC {
113116

114117
@Override
115118
public double normalize(double distance, DistanceUnit unit) {
@@ -127,12 +130,31 @@ public FixedSourceDistance fixedSourceDistance(double sourceLatitude, double sou
127130
}
128131
};
129132

133+
/** Returns a GeoDistance object as read from the StreamInput. */
134+
@Override
135+
public GeoDistance readFrom(StreamInput in) throws IOException {
136+
int ord = in.readVInt();
137+
if (ord < 0 || ord >= values().length) {
138+
throw new IOException("Unknown GeoDistance ordinal [" + ord + "]");
139+
}
140+
return GeoDistance.values()[ord];
141+
}
142+
143+
public static GeoDistance readGeoDistanceFrom(StreamInput in) throws IOException {
144+
return DEFAULT.readFrom(in);
145+
}
146+
147+
@Override
148+
public void writeTo(StreamOutput out) throws IOException {
149+
out.writeVInt(this.ordinal());
150+
}
151+
130152
/**
131153
* Default {@link GeoDistance} function. This method should be used, If no specific function has been selected.
132154
* This is an alias for <code>SLOPPY_ARC</code>
133155
*/
134-
public static final GeoDistance DEFAULT = SLOPPY_ARC;
135-
156+
public static final GeoDistance DEFAULT = SLOPPY_ARC;
157+
136158
public abstract double normalize(double distance, DistanceUnit unit);
137159

138160
public abstract double calculate(double sourceLatitude, double sourceLongitude, double targetLatitude, double targetLongitude, DistanceUnit unit);
@@ -180,14 +202,14 @@ public static DistanceBoundingCheck distanceBoundingCheck(double sourceLatitude,
180202

181203
/**
182204
* Get a {@link GeoDistance} according to a given name. Valid values are
183-
*
205+
*
184206
* <ul>
185207
* <li><b>plane</b> for <code>GeoDistance.PLANE</code></li>
186208
* <li><b>sloppy_arc</b> for <code>GeoDistance.SLOPPY_ARC</code></li>
187209
* <li><b>factor</b> for <code>GeoDistance.FACTOR</code></li>
188210
* <li><b>arc</b> for <code>GeoDistance.ARC</code></li>
189211
* </ul>
190-
*
212+
*
191213
* @param name name of the {@link GeoDistance}
192214
* @return a {@link GeoDistance}
193215
*/
@@ -336,7 +358,7 @@ public double calculate(double targetLatitude, double targetLongitude) {
336358

337359
/**
338360
* Basic implementation of {@link FixedSourceDistance}. This class keeps the basic parameters for a distance
339-
* functions based on a fixed source. Namely latitude, longitude and unit.
361+
* functions based on a fixed source. Namely latitude, longitude and unit.
340362
*/
341363
public static abstract class FixedSourceDistanceBase implements FixedSourceDistance {
342364
protected final double sourceLatitude;
@@ -349,7 +371,7 @@ public FixedSourceDistanceBase(double sourceLatitude, double sourceLongitude, Di
349371
this.unit = unit;
350372
}
351373
}
352-
374+
353375
public static class ArcFixedSourceDistance extends FixedSourceDistanceBase {
354376

355377
public ArcFixedSourceDistance(double sourceLatitude, double sourceLongitude, DistanceUnit unit) {

core/src/main/java/org/elasticsearch/common/geo/GeoPoint.java

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@
1919

2020
package org.elasticsearch.common.geo;
2121

22+
import org.elasticsearch.common.io.stream.StreamInput;
23+
import org.elasticsearch.common.io.stream.StreamOutput;
24+
import org.elasticsearch.common.io.stream.Writeable;
25+
import java.io.IOException;
26+
2227

2328
import org.apache.lucene.util.BitUtil;
2429
import org.apache.lucene.util.XGeoHashUtils;
@@ -27,11 +32,14 @@
2732
/**
2833
*
2934
*/
30-
public final class GeoPoint {
35+
public final class GeoPoint implements Writeable<GeoPoint> {
3136

3237
private double lat;
3338
private double lon;
3439
private final static double TOLERANCE = XGeoUtils.TOLERANCE;
40+
41+
// for serialization purposes
42+
private static final GeoPoint PROTOTYPE = new GeoPoint(Double.NaN, Double.NaN);
3543

3644
public GeoPoint() {
3745
}
@@ -152,8 +160,7 @@ public String toString() {
152160
}
153161

154162
public static GeoPoint parseFromLatLon(String latLon) {
155-
GeoPoint point = new GeoPoint();
156-
point.resetFromString(latLon);
163+
GeoPoint point = new GeoPoint(latLon);
157164
return point;
158165
}
159166

@@ -168,4 +175,21 @@ public static GeoPoint fromGeohash(long geohashLong) {
168175
public static GeoPoint fromIndexLong(long indexLong) {
169176
return new GeoPoint().resetFromIndexHash(indexLong);
170177
}
171-
}
178+
179+
@Override
180+
public GeoPoint readFrom(StreamInput in) throws IOException {
181+
double lat = in.readDouble();
182+
double lon = in.readDouble();
183+
return new GeoPoint(lat, lon);
184+
}
185+
186+
public static GeoPoint readGeoPointFrom(StreamInput in) throws IOException {
187+
return PROTOTYPE.readFrom(in);
188+
}
189+
190+
@Override
191+
public void writeTo(StreamOutput out) throws IOException {
192+
out.writeDouble(lat);
193+
out.writeDouble(lon);
194+
}
195+
}

core/src/main/java/org/elasticsearch/common/geo/GeoUtils.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,19 @@
3434
*/
3535
public class GeoUtils {
3636

37+
/** Maximum valid latitude in degrees. */
38+
public static final double MAX_LAT = 90.0;
39+
/** Minimum valid latitude in degrees. */
40+
public static final double MIN_LAT = -90.0;
41+
/** Maximum valid longitude in degrees. */
42+
public static final double MAX_LON = 180.0;
43+
/** Minimum valid longitude in degrees. */
44+
public static final double MIN_LON = -180.0;
45+
3746
public static final String LATITUDE = GeoPointFieldMapper.Names.LAT;
3847
public static final String LONGITUDE = GeoPointFieldMapper.Names.LON;
3948
public static final String GEOHASH = GeoPointFieldMapper.Names.GEOHASH;
40-
49+
4150
/** Earth ellipsoid major axis defined by WGS 84 in meters */
4251
public static final double EARTH_SEMI_MAJOR_AXIS = 6378137.0; // meters (WGS 84)
4352

@@ -56,6 +65,22 @@ public class GeoUtils {
5665
/** Earth ellipsoid polar distance in meters */
5766
public static final double EARTH_POLAR_DISTANCE = Math.PI * EARTH_SEMI_MINOR_AXIS;
5867

68+
/** Returns true if latitude is actually a valid latitude value.*/
69+
public static boolean isValidLatitude(double latitude) {
70+
if (Double.isNaN(latitude) || Double.isInfinite(latitude) || latitude < GeoUtils.MIN_LAT || latitude > GeoUtils.MAX_LAT) {
71+
return false;
72+
}
73+
return true;
74+
}
75+
76+
/** Returns true if longitude is actually a valid longitude value. */
77+
public static boolean isValidLongitude(double longitude) {
78+
if (Double.isNaN(longitude) || Double.isNaN(longitude) || longitude < GeoUtils.MIN_LON || longitude > GeoUtils.MAX_LON) {
79+
return false;
80+
}
81+
return true;
82+
}
83+
5984
/**
6085
* Return an approximate value of the diameter of the earth (in meters) at the given latitude (in radians).
6186
*/

0 commit comments

Comments
 (0)