Skip to content

Commit 6466ce7

Browse files
authored
Separate parsing geo format from fields API geo formats (#73806)
This change removes the current GeometryFormat interface and replace then with a GeometryParser that deals with Parsing formats and a GeometryFormatFactory that deals with fields API formats.
1 parent f725f99 commit 6466ce7

File tree

18 files changed

+272
-289
lines changed

18 files changed

+272
-289
lines changed

modules/lang-painless/src/main/java/org/elasticsearch/painless/action/PainlessExecuteAction.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,8 @@
3636
import org.elasticsearch.common.CheckedBiFunction;
3737
import org.elasticsearch.common.xcontent.ParseField;
3838
import org.elasticsearch.common.bytes.BytesReference;
39-
import org.elasticsearch.common.geo.GeoJsonGeometryFormat;
39+
import org.elasticsearch.common.geo.GeoFormatterFactory;
4040
import org.elasticsearch.common.geo.GeoPoint;
41-
import org.elasticsearch.common.geo.GeometryFormat;
42-
import org.elasticsearch.common.geo.GeometryParser;
4341
import org.elasticsearch.common.inject.Inject;
4442
import org.elasticsearch.common.io.stream.StreamInput;
4543
import org.elasticsearch.common.io.stream.StreamOutput;
@@ -94,6 +92,7 @@
9492
import java.util.List;
9593
import java.util.Map;
9694
import java.util.Objects;
95+
import java.util.function.Function;
9796

9897
import static java.util.Collections.emptyMap;
9998
import static org.elasticsearch.action.ValidateActions.addValidationError;
@@ -589,10 +588,10 @@ static Response innerShardOperation(Request request, ScriptService scriptService
589588
List<GeoPoint> points = new ArrayList<>();
590589
geoPointFieldScript.runGeoPointForDoc(0, gp -> points.add(new GeoPoint(gp)));
591590
// convert geo points to the standard format of the fields api
592-
GeometryFormat<Geometry> gf = new GeometryParser(true, true, true).geometryFormat(GeoJsonGeometryFormat.NAME);
591+
Function<Geometry, Object> format = GeoFormatterFactory.getFormatter(GeoFormatterFactory.GEOJSON);
593592
List<Object> objects = new ArrayList<>();
594593
for (GeoPoint gp : points) {
595-
objects.add(gf.toXContentAsObject(new Point(gp.getLon(), gp.getLat())));
594+
objects.add(format.apply(new Point(gp.getLon(), gp.getLat())));
596595
}
597596
return new Response(objects);
598597
}, indexService);
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
package org.elasticsearch.common.geo;
10+
11+
import org.elasticsearch.geometry.Geometry;
12+
import org.elasticsearch.geometry.utils.WellKnownText;
13+
14+
import java.util.HashMap;
15+
import java.util.Map;
16+
import java.util.function.Function;
17+
18+
/**
19+
* Output formatters supported by geo fields.
20+
*/
21+
public class GeoFormatterFactory {
22+
23+
public static final String GEOJSON = "geojson";
24+
public static final String WKT = "wkt";
25+
26+
private static final Map<String, Function<Geometry, Object>> FORMATTERS = new HashMap<>();
27+
static {
28+
FORMATTERS.put(GEOJSON, GeoJson::toMap);
29+
FORMATTERS.put(WKT, WellKnownText::toWKT);
30+
}
31+
32+
/**
33+
* Returns a formatter by name
34+
*/
35+
public static Function<Geometry, Object> getFormatter(String name) {
36+
Function<Geometry, Object> format = FORMATTERS.get(name);
37+
if (format == null) {
38+
throw new IllegalArgumentException("Unrecognized geometry format [" + format + "].");
39+
}
40+
return format;
41+
}
42+
}

server/src/main/java/org/elasticsearch/common/geo/GeoJsonGeometryFormat.java

Lines changed: 0 additions & 58 deletions
This file was deleted.

server/src/main/java/org/elasticsearch/common/geo/GeometryFormat.java

Lines changed: 0 additions & 44 deletions
This file was deleted.

server/src/main/java/org/elasticsearch/common/geo/GeometryParser.java

Lines changed: 7 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -27,56 +27,25 @@
2727
import java.util.Map;
2828

2929
/**
30-
* An utility class with a geometry parser methods supporting different shape representation formats
30+
* An utility class with to read geometries from a XContentParser or generic object.
3131
*/
3232
public final class GeometryParser {
3333

34-
private final GeoJsonGeometryFormat jsonGeometryFormat;
35-
private final WKTGeometryFormat wktGeometryFormat;
36-
private final boolean ignoreZValue;
34+
private final boolean rightOrientation, coerce, ignoreZValue;
35+
private final GeometryValidator validator;
3736

3837
public GeometryParser(boolean rightOrientation, boolean coerce, boolean ignoreZValue) {
39-
final GeometryValidator validator = StandardValidator.instance(ignoreZValue);
40-
jsonGeometryFormat = new GeoJsonGeometryFormat(validator, coerce, rightOrientation);
41-
wktGeometryFormat = new WKTGeometryFormat(validator, coerce);
38+
this.rightOrientation = rightOrientation;
39+
this.coerce = coerce;
4240
this.ignoreZValue = ignoreZValue;
41+
this.validator = StandardValidator.instance(ignoreZValue);
4342
}
4443

4544
/**
4645
* Parses supplied XContent into Geometry
4746
*/
4847
public Geometry parse(XContentParser parser) throws IOException, ParseException {
49-
return geometryFormat(parser).fromXContent(parser);
50-
}
51-
52-
/**
53-
* Returns a geometry format object that can parse and then serialize the object back to the same format.
54-
*/
55-
public GeometryFormat<Geometry> geometryFormat(String format) {
56-
if (format.equals(GeoJsonGeometryFormat.NAME)) {
57-
return jsonGeometryFormat;
58-
} else if (format.equals(WKTGeometryFormat.NAME)) {
59-
return wktGeometryFormat;
60-
} else {
61-
throw new IllegalArgumentException("Unrecognized geometry format [" + format + "].");
62-
}
63-
}
64-
65-
/**
66-
* Returns a geometry format object that can parse and then serialize the object back to the same format.
67-
* This method automatically recognizes the format by examining the provided {@link XContentParser}.
68-
*/
69-
public GeometryFormat<Geometry> geometryFormat(XContentParser parser) {
70-
if (parser.currentToken() == XContentParser.Token.START_OBJECT) {
71-
return jsonGeometryFormat;
72-
} else if (parser.currentToken() == XContentParser.Token.VALUE_STRING) {
73-
return wktGeometryFormat;
74-
} else if (parser.currentToken() == XContentParser.Token.VALUE_NULL) {
75-
// We don't know the format of the original geometry - so going with default
76-
return jsonGeometryFormat;
77-
} else {
78-
throw new ElasticsearchParseException("shape must be an object consisting of type and coordinates");
79-
}
48+
return GeometryParserFormat.geometryFormat(parser).fromXContent(validator, coerce, rightOrientation, parser);
8049
}
8150

8251
/**
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
package org.elasticsearch.common.geo;
10+
11+
import org.elasticsearch.ElasticsearchParseException;
12+
import org.elasticsearch.common.xcontent.ToXContent;
13+
import org.elasticsearch.common.xcontent.XContentBuilder;
14+
import org.elasticsearch.common.xcontent.XContentParser;
15+
import org.elasticsearch.geometry.Geometry;
16+
import org.elasticsearch.geometry.utils.GeometryValidator;
17+
import org.elasticsearch.geometry.utils.WellKnownText;
18+
19+
import java.io.IOException;
20+
import java.text.ParseException;
21+
22+
/**
23+
* Supported formats to read/write JSON geometries.
24+
*/
25+
public enum GeometryParserFormat {
26+
27+
WKT {
28+
@Override
29+
public XContentBuilder toXContent(Geometry geometry, XContentBuilder builder, ToXContent.Params params) throws IOException {
30+
if (geometry != null) {
31+
return builder.value(WellKnownText.toWKT(geometry));
32+
} else {
33+
return builder.nullValue();
34+
}
35+
}
36+
37+
@Override
38+
public Geometry fromXContent(GeometryValidator validator, boolean coerce, boolean rightOrientation, XContentParser parser)
39+
throws IOException, ParseException {
40+
if (parser.currentToken() == XContentParser.Token.VALUE_NULL) {
41+
return null;
42+
}
43+
return WellKnownText.fromWKT(validator, coerce, parser.text());
44+
}
45+
46+
},
47+
GEOJSON {
48+
@Override
49+
public XContentBuilder toXContent(Geometry geometry, XContentBuilder builder, ToXContent.Params params) throws IOException {
50+
if (geometry != null) {
51+
return GeoJson.toXContent(geometry, builder, params);
52+
} else {
53+
return builder.nullValue();
54+
}
55+
}
56+
57+
@Override
58+
public Geometry fromXContent(GeometryValidator validator, boolean coerce, boolean rightOrientation, XContentParser parser)
59+
throws IOException, ParseException {
60+
if (parser.currentToken() == XContentParser.Token.VALUE_NULL) {
61+
return null;
62+
}
63+
return GeoJson.fromXContent(validator, coerce, rightOrientation, parser);
64+
}
65+
};
66+
67+
/**
68+
* Serializes the geometry into its JSON representation
69+
*/
70+
public abstract XContentBuilder toXContent(Geometry geometry, XContentBuilder builder, ToXContent.Params params) throws IOException;
71+
72+
/**
73+
* Parser JSON representation of a geometry
74+
*/
75+
public abstract Geometry fromXContent(GeometryValidator validator, boolean coerce, boolean rightOrientation, XContentParser parser)
76+
throws IOException, ParseException;
77+
78+
/**
79+
* Returns a geometry parser format object that can parse and then serialize the object back to the same format.
80+
* This method automatically recognizes the format by examining the provided {@link XContentParser}.
81+
*/
82+
public static GeometryParserFormat geometryFormat(XContentParser parser) {
83+
switch (parser.currentToken()) {
84+
case START_OBJECT:
85+
case VALUE_NULL: // We don't know the format of the original geometry - so going with default
86+
return GEOJSON;
87+
case VALUE_STRING: return WKT;
88+
default: throw new ElasticsearchParseException("shape must be an object consisting of type and coordinates");
89+
}
90+
}
91+
}

server/src/main/java/org/elasticsearch/common/geo/WKTGeometryFormat.java

Lines changed: 0 additions & 58 deletions
This file was deleted.

0 commit comments

Comments
 (0)