Skip to content

Commit d50fa6f

Browse files
committed
In CartesianPoint, store coordinates as doubles.
This gives more predictable values when parsing and formatting a point. It matches the behavior for GeoPoint and the Point geometry.
1 parent 156d741 commit d50fa6f

File tree

3 files changed

+37
-37
lines changed

3 files changed

+37
-37
lines changed

x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/common/CartesianPoint.java

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,18 @@ public class CartesianPoint implements ToXContentFragment {
3737
private static final ParseField Y_FIELD = new ParseField("y");
3838
private static final ParseField Z_FIELD = new ParseField("z");
3939

40-
protected float x;
41-
protected float y;
40+
protected double x;
41+
protected double y;
4242

4343
public CartesianPoint() {
4444
}
4545

46-
public CartesianPoint(float x, float y) {
46+
public CartesianPoint(double x, double y) {
4747
this.x = x;
4848
this.y = y;
4949
}
5050

51-
public CartesianPoint reset(float x, float y) {
51+
public CartesianPoint reset(double x, double y) {
5252
this.x = x;
5353
this.y = y;
5454
return this;
@@ -69,11 +69,11 @@ public CartesianPoint resetFromCoordinates(String value, final boolean ignoreZVa
6969
throw new ElasticsearchParseException("failed to parse [{}], expected 2 or 3 coordinates "
7070
+ "but found: [{}]", vals, vals.length);
7171
}
72-
final float x;
73-
final float y;
72+
final double x;
73+
final double y;
7474
try {
75-
x = Float.parseFloat(vals[0].trim());
76-
if (Float.isFinite(x) == false) {
75+
x = Double.parseDouble(vals[0].trim());
76+
if (Double.isFinite(x) == false) {
7777
throw new ElasticsearchParseException("invalid [{}] value [{}]; " +
7878
"must be between -3.4028234663852886E38 and 3.4028234663852886E38",
7979
X_FIELD.getPreferredName(),
@@ -83,8 +83,8 @@ public CartesianPoint resetFromCoordinates(String value, final boolean ignoreZVa
8383
throw new ElasticsearchParseException("[{}]] must be a number", X_FIELD.getPreferredName());
8484
}
8585
try {
86-
y = Float.parseFloat(vals[1].trim());
87-
if (Float.isFinite(y) == false) {
86+
y = Double.parseDouble(vals[1].trim());
87+
if (Double.isFinite(y) == false) {
8888
throw new ElasticsearchParseException("invalid [{}] value [{}]; " +
8989
"must be between -3.4028234663852886E38 and 3.4028234663852886E38",
9090
Y_FIELD.getPreferredName(),
@@ -95,7 +95,7 @@ public CartesianPoint resetFromCoordinates(String value, final boolean ignoreZVa
9595
}
9696
if (vals.length > 2) {
9797
try {
98-
CartesianPoint.assertZValue(ignoreZValue, Float.parseFloat(vals[2].trim()));
98+
CartesianPoint.assertZValue(ignoreZValue, Double.parseDouble(vals[2].trim()));
9999
} catch (NumberFormatException ex) {
100100
throw new ElasticsearchParseException("[{}]] must be a number", Y_FIELD.getPreferredName());
101101
}
@@ -116,14 +116,14 @@ private CartesianPoint resetFromWKT(String value, boolean ignoreZValue) {
116116
"but found {}", PointFieldMapper.CONTENT_TYPE, geometry.type());
117117
}
118118
org.elasticsearch.geometry.Point point = (org.elasticsearch.geometry.Point) geometry;
119-
return reset((float) point.getX(), (float) point.getY());
119+
return reset(point.getX(), point.getY());
120120
}
121121

122-
public float getX() {
122+
public double getX() {
123123
return this.x;
124124
}
125125

126-
public float getY() {
126+
public double getY() {
127127
return this.y;
128128
}
129129

@@ -134,8 +134,8 @@ public boolean equals(Object o) {
134134

135135
CartesianPoint point = (CartesianPoint) o;
136136

137-
if (Float.compare(point.x, x) != 0) return false;
138-
if (Float.compare(point.y, y) != 0) return false;
137+
if (Double.compare(point.x, x) != 0) return false;
138+
if (Double.compare(point.y, y) != 0) return false;
139139

140140
return true;
141141
}
@@ -157,8 +157,8 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
157157

158158
public static CartesianPoint parsePoint(XContentParser parser, CartesianPoint point, boolean ignoreZvalue)
159159
throws IOException, ElasticsearchParseException {
160-
float x = Float.NaN;
161-
float y = Float.NaN;
160+
double x = Double.NaN;
161+
double y = Double.NaN;
162162
NumberFormatException numberFormatException = null;
163163

164164
if(parser.currentToken() == XContentParser.Token.START_OBJECT) {
@@ -172,7 +172,7 @@ public static CartesianPoint parsePoint(XContentParser parser, CartesianPoint po
172172
case VALUE_NUMBER:
173173
case VALUE_STRING:
174174
try {
175-
x = subParser.floatValue(true);
175+
x = subParser.doubleValue(true);
176176
} catch (NumberFormatException e) {
177177
numberFormatException = e;
178178
}
@@ -187,7 +187,7 @@ public static CartesianPoint parsePoint(XContentParser parser, CartesianPoint po
187187
case VALUE_NUMBER:
188188
case VALUE_STRING:
189189
try {
190-
y = subParser.floatValue(true);
190+
y = subParser.doubleValue(true);
191191
} catch (NumberFormatException e) {
192192
numberFormatException = e;
193193
}
@@ -202,7 +202,7 @@ public static CartesianPoint parsePoint(XContentParser parser, CartesianPoint po
202202
case VALUE_NUMBER:
203203
case VALUE_STRING:
204204
try {
205-
CartesianPoint.assertZValue(ignoreZvalue, subParser.floatValue(true));
205+
CartesianPoint.assertZValue(ignoreZvalue, subParser.doubleValue(true));
206206
} catch (NumberFormatException e) {
207207
numberFormatException = e;
208208
}
@@ -222,12 +222,12 @@ public static CartesianPoint parsePoint(XContentParser parser, CartesianPoint po
222222
}
223223
}
224224
if (numberFormatException != null) {
225-
throw new ElasticsearchParseException("[{}] and [{}] must be valid float values", numberFormatException,
225+
throw new ElasticsearchParseException("[{}] and [{}] must be valid double values", numberFormatException,
226226
X_FIELD.getPreferredName(),
227227
Y_FIELD.getPreferredName());
228-
} else if (Float.isNaN(x)) {
228+
} else if (Double.isNaN(x)) {
229229
throw new ElasticsearchParseException("field [{}] missing", X_FIELD.getPreferredName());
230-
} else if (Float.isNaN(y)) {
230+
} else if (Double.isNaN(y)) {
231231
throw new ElasticsearchParseException("field [{}] missing", Y_FIELD.getPreferredName());
232232
} else {
233233
return point.reset(x, y);
@@ -240,9 +240,9 @@ public static CartesianPoint parsePoint(XContentParser parser, CartesianPoint po
240240
if (subParser.currentToken() == XContentParser.Token.VALUE_NUMBER) {
241241
element++;
242242
if (element == 1) {
243-
x = subParser.floatValue();
243+
x = subParser.doubleValue();
244244
} else if (element == 2) {
245-
y = subParser.floatValue();
245+
y = subParser.doubleValue();
246246
} else {
247247
throw new ElasticsearchParseException("[{}}] field type does not accept > 2 dimensions",
248248
PointFieldMapper.CONTENT_TYPE);
@@ -277,12 +277,12 @@ public static CartesianPoint parsePoint(Object value, CartesianPoint point, bool
277277
}
278278
}
279279

280-
public static double assertZValue(final boolean ignoreZValue, float zValue) {
280+
public static double assertZValue(final boolean ignoreZValue, double zValue) {
281281
if (ignoreZValue == false) {
282282
throw new ElasticsearchParseException("Exception parsing coordinates: found Z value [{}] but [{}] "
283283
+ "parameter is [{}]", zValue, IGNORE_Z_VALUE, ignoreZValue);
284284
}
285-
if (Float.isFinite(zValue) == false) {
285+
if (Double.isFinite(zValue) == false) {
286286
throw new ElasticsearchParseException("invalid [{}] value [{}]; " +
287287
"must be between -3.4028234663852886E38 and 3.4028234663852886E38",
288288
Z_FIELD.getPreferredName(),

x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/index/mapper/PointFieldMapper.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@ protected ParsedPoint parseNullValue(Object nullValue, boolean ignoreZValue, boo
7171
ParsedCartesianPoint point = new ParsedCartesianPoint();
7272
CartesianPoint.parsePoint(nullValue, point, ignoreZValue);
7373
if (ignoreMalformed == false) {
74-
if (Float.isFinite(point.getX()) == false) {
74+
if (Double.isFinite(point.getX()) == false) {
7575
throw new IllegalArgumentException("illegal x value [" + point.getX() + "]");
7676
}
77-
if (Float.isFinite(point.getY()) == false) {
77+
if (Double.isFinite(point.getY()) == false) {
7878
throw new IllegalArgumentException("illegal y value [" + point.getY() + "]");
7979
}
8080
}
@@ -108,7 +108,7 @@ protected void addStoredFields(ParseContext context, List<? extends CartesianPoi
108108
protected void addDocValuesFields(String name, List<? extends CartesianPoint> points, List<IndexableField> fields,
109109
ParseContext context) {
110110
for (CartesianPoint point : points) {
111-
context.doc().add(new XYDocValuesField(fieldType().name(), point.getX(), point.getY()));
111+
context.doc().add(new XYDocValuesField(fieldType().name(), (float) point.getX(), (float) point.getY()));
112112
}
113113
}
114114

@@ -143,10 +143,10 @@ public String typeName() {
143143
protected static class ParsedCartesianPoint extends CartesianPoint implements AbstractPointGeometryFieldMapper.ParsedPoint {
144144
@Override
145145
public void validate(String fieldName) {
146-
if (Float.isFinite(getX()) == false) {
146+
if (Double.isFinite(getX()) == false) {
147147
throw new IllegalArgumentException("illegal x value [" + getX() + "] for " + fieldName);
148148
}
149-
if (Float.isFinite(getY()) == false) {
149+
if (Double.isFinite(getY()) == false) {
150150
throw new IllegalArgumentException("illegal y value [" + getY() + "] for " + fieldName);
151151
}
152152
}
@@ -163,7 +163,7 @@ public boolean isNormalizable(double coord) {
163163

164164
@Override
165165
public void resetCoords(double x, double y) {
166-
this.reset((float)x, (float)y);
166+
this.reset(x, y);
167167
}
168168

169169
@Override
@@ -223,7 +223,7 @@ public Class<List<? extends CartesianPoint>> processedClass() {
223223
public List<IndexableField> indexShape(ParseContext context, List<? extends CartesianPoint> points) {
224224
ArrayList<IndexableField> fields = new ArrayList<>(1);
225225
for (CartesianPoint point : points) {
226-
fields.add(new XYPointField(fieldType.name(), point.getX(), point.getY()));
226+
fields.add(new XYPointField(fieldType.name(), (float) point.getX(), (float) point.getY()));
227227
}
228228
return fields;
229229
}

x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/index/mapper/PointFieldMapperTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,8 +312,8 @@ public void testParseSourceValue() {
312312
AbstractGeometryFieldMapper<?, ?> mapper = new PointFieldMapper.Builder("field").build(context);
313313
SourceLookup sourceLookup = new SourceLookup();
314314

315-
Map<String, Object> jsonPoint = Map.of("type", "Point", "coordinates", List.of(42.0, 27.100000381469727));
316-
String wktPoint = "POINT (42.0 27.100000381469727)";
315+
Map<String, Object> jsonPoint = Map.of("type", "Point", "coordinates", List.of(42.0, 27.1));
316+
String wktPoint = "POINT (42.0 27.1)";
317317
Map<String, Object> otherJsonPoint = Map.of("type", "Point", "coordinates", List.of(30.0, 50.0));
318318
String otherWktPoint = "POINT (30.0 50.0)";
319319

0 commit comments

Comments
 (0)