Skip to content

Commit ed96b60

Browse files
committed
Adds tests
1 parent 805ab89 commit ed96b60

File tree

4 files changed

+116
-12
lines changed

4 files changed

+116
-12
lines changed

x-pack/plugin/esql/qa/testFixtures/src/main/resources/spatial.csv-spec

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3024,3 +3024,75 @@ wkt:keyword |pt:cartesian_point
30243024
"POINT(111)" |null
30253025
// end::to_cartesianpoint-str-parse-error-result[]
30263026
;
3027+
3028+
stSimplifyMultiRow
3029+
required_capability: st_simplify
3030+
3031+
FROM airports
3032+
| SORT name
3033+
| LIMIT 5
3034+
| EVAL result = st_simplify(TO_GEOSHAPE("POLYGON((-10 -60, 120 -60, 120 60, -10 60, -10 -60))"), 1.0)
3035+
| KEEP name, result
3036+
;
3037+
3038+
name:text | result:geo_shape
3039+
Aba Tenna D. Yilma Int'l | POLYGON ((-10.0 -60.0, -10.0 60.0, 120.0 60.0, 120.0 -60.0, -10.0 -60.0))
3040+
Abdul Rachman Saleh | POLYGON ((-10.0 -60.0, -10.0 60.0, 120.0 60.0, 120.0 -60.0, -10.0 -60.0))
3041+
Abidjan Port Bouet | POLYGON ((-10.0 -60.0, -10.0 60.0, 120.0 60.0, 120.0 -60.0, -10.0 -60.0))
3042+
Abu Dhabi Int'l | POLYGON ((-10.0 -60.0, -10.0 60.0, 120.0 60.0, 120.0 -60.0, -10.0 -60.0))
3043+
Abuja Int'l | POLYGON ((-10.0 -60.0, -10.0 60.0, 120.0 60.0, 120.0 -60.0, -10.0 -60.0))
3044+
;
3045+
3046+
stSimplifyMultiRowWithPoints
3047+
required_capability: st_simplify
3048+
3049+
FROM airports
3050+
| SORT name
3051+
| LIMIT 5
3052+
| EVAL result = st_simplify(location, 0.0)
3053+
| KEEP location, result
3054+
;
3055+
3056+
location:geo_point | result:geo_shape
3057+
POINT (41.857756722253 9.61267784753569) | POINT (41.857756722253 9.61267784753569)
3058+
POINT (112.711418617258 -7.92998002840567) | POINT (112.711418617258 -7.92998002840567)
3059+
POINT (-3.93221929167636 5.2543984451492) | POINT (-3.93221929167636 5.2543984451492)
3060+
POINT (54.6463293225558 24.4272271529764) | POINT (54.6463293225558 24.4272271529764)
3061+
POINT (7.27025993974356 9.00437659781094) | POINT (7.27025993974356 9.00437659781094)
3062+
;
3063+
3064+
stSimplifyNoSimplification
3065+
required_capability: st_simplify
3066+
3067+
ROW geo_shape = TO_GEOSHAPE("POLYGON((0 0, 1 0.1, 2 0, 2 2, 1 1.9, 0 2, 0 0))")
3068+
| EVAL result = st_simplify(geo_shape, 0.01)
3069+
| KEEP result
3070+
;
3071+
3072+
result:geo_shape
3073+
POLYGON ((0.0 0.0, 0.0 2.0, 1.0 1.9, 2.0 2.0, 2.0 0.0, 1.0 0.1, 0.0 0.0))
3074+
;
3075+
3076+
stSimplifyWithSimplification
3077+
required_capability: st_simplify
3078+
3079+
ROW geo_shape = TO_GEOSHAPE("POLYGON((0 0, 1 0.1, 2 0, 2 2, 1 1.9, 0 2, 0 0))")
3080+
| EVAL result = st_simplify(geo_shape, 0.2)
3081+
| KEEP result
3082+
;
3083+
3084+
result:geo_shape
3085+
POLYGON ((0.0 0.0, 0.0 2.0, 2.0 2.0, 2.0 0.0, 0.0 0.0))
3086+
;
3087+
3088+
stSimplifyEmptySimplification
3089+
required_capability: st_simplify
3090+
3091+
ROW geo_shape = TO_GEOSHAPE("POLYGON((0 0, 1 0.1, 2 0, 2 2, 1 1.9, 0 2, 0 0))")
3092+
| EVAL result = st_simplify(geo_shape, 2.0)
3093+
| KEEP result
3094+
;
3095+
3096+
result:geo_shape
3097+
POLYGON EMPTY
3098+
;

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ public enum Cap {
7878
*/
7979
ST_DISJOINT,
8080

81+
/**
82+
* Support for spatial simplification {@code ST_SIMPLIFY}
83+
*/
84+
ST_SIMPLIFY,
85+
8186
/**
8287
* The introduction of the {@code VALUES} agg.
8388
*/

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/ExpressionWritables.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeohash;
7272
import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeohex;
7373
import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StGeotile;
74+
import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StSimplify;
7475
import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StX;
7576
import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StXMax;
7677
import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.StXMin;
@@ -253,7 +254,8 @@ private static List<NamedWriteableRegistry.Entry> spatials() {
253254
StDistance.ENTRY,
254255
StGeohash.ENTRY,
255256
StGeotile.ENTRY,
256-
StGeohex.ENTRY
257+
StGeohex.ENTRY,
258+
StSimplify.ENTRY
257259
);
258260
}
259261

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/spatial/StSimplify.java

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,27 @@
88
package org.elasticsearch.xpack.esql.expression.function.scalar.spatial;
99

1010
import org.apache.lucene.util.BytesRef;
11+
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
12+
import org.elasticsearch.common.io.stream.StreamInput;
1113
import org.elasticsearch.common.io.stream.StreamOutput;
1214
import org.elasticsearch.compute.data.Block;
1315
import org.elasticsearch.compute.data.BytesRefVectorBlock;
16+
import org.elasticsearch.compute.data.DoubleVector;
1417
import org.elasticsearch.compute.data.Page;
1518
import org.elasticsearch.compute.operator.EvalOperator;
1619
import org.elasticsearch.geometry.Geometry;
1720
import org.elasticsearch.geometry.utils.StandardValidator;
1821
import org.elasticsearch.geometry.utils.WellKnownBinary;
1922
import org.elasticsearch.geometry.utils.WellKnownText;
2023
import org.elasticsearch.xpack.esql.core.expression.Expression;
21-
import org.elasticsearch.xpack.esql.core.expression.function.scalar.ScalarFunction;
2224
import org.elasticsearch.xpack.esql.core.tree.NodeInfo;
2325
import org.elasticsearch.xpack.esql.core.tree.Source;
2426
import org.elasticsearch.xpack.esql.core.type.DataType;
25-
import org.elasticsearch.xpack.esql.evaluator.mapper.EvaluatorMapper;
2627
import org.elasticsearch.xpack.esql.expression.function.Example;
2728
import org.elasticsearch.xpack.esql.expression.function.FunctionInfo;
2829
import org.elasticsearch.xpack.esql.expression.function.Param;
30+
import org.elasticsearch.xpack.esql.expression.function.scalar.EsqlScalarFunction;
31+
import org.elasticsearch.xpack.esql.io.stream.PlanStreamInput;
2932
import org.locationtech.jts.io.WKTReader;
3033
import org.locationtech.jts.io.WKTWriter;
3134
import org.locationtech.jts.simplify.DouglasPeuckerSimplifier;
@@ -37,7 +40,12 @@
3740
import static org.elasticsearch.xpack.esql.core.type.DataType.GEO_SHAPE;
3841
import static org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils.makeGeometryFromLiteral;
3942

40-
public class StSimplify extends ScalarFunction implements EvaluatorMapper {
43+
public class StSimplify extends EsqlScalarFunction {
44+
public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(
45+
Expression.class,
46+
"StSimplify",
47+
StSimplify::new
48+
);
4149
Expression geometry;
4250
Expression tolerance;
4351

@@ -61,6 +69,14 @@ public StSimplify(
6169
this.tolerance = tolerance;
6270
}
6371

72+
private StSimplify(StreamInput in) throws IOException {
73+
this(
74+
Source.readFrom((PlanStreamInput) in),
75+
in.readNamedWriteable(Expression.class),
76+
in.readNamedWriteable(Expression.class)
77+
);
78+
}
79+
6480
@Override
6581
public DataType dataType() {
6682
return GEO_SHAPE;
@@ -78,12 +94,14 @@ protected NodeInfo<? extends Expression> info() {
7894

7995
@Override
8096
public String getWriteableName() {
81-
return "StSimplify";
97+
return ENTRY.name;
8298
}
8399

84100
@Override
85101
public void writeTo(StreamOutput out) throws IOException {
86-
102+
source().writeTo(out);
103+
out.writeNamedWriteable(geometry);
104+
out.writeNamedWriteable(tolerance);
87105
}
88106

89107
@Override
@@ -101,11 +119,11 @@ public void close() {
101119
@Override
102120
public Block eval(Page page) {
103121
var isGeometryFoldable = geometry.foldable();
104-
var isToleranceFoldable = tolerance.foldable();
105122
var positionCount = page.getPositionCount();
106123
var validator = StandardValidator.instance(true);
107124
WKTReader reader = new WKTReader();
108125
WKTWriter writer = new WKTWriter();
126+
DoubleVector tolerances = (DoubleVector) toleranceEvaluator.eval(page).asVector();
109127

110128
// TODO We are not extracting non foldable geometries
111129
// TODO We are not using the tolerance
@@ -116,11 +134,13 @@ public Block eval(Page page) {
116134

117135
try {
118136
org.locationtech.jts.geom.Geometry jtsGeometry = reader.read(wkt);
119-
org.locationtech.jts.geom.Geometry simplifiedGeometry = DouglasPeuckerSimplifier.simplify(jtsGeometry, 0);
120-
String simplifiedWkt = writer.write(simplifiedGeometry);
121-
Geometry esGeometryResult = WellKnownText.fromWKT(validator, false, simplifiedWkt);
122137

123138
for (int p = 0; p < positionCount; p++) {
139+
double distanceTolerance = tolerances.getDouble(p);
140+
org.locationtech.jts.geom.Geometry simplifiedGeometry = DouglasPeuckerSimplifier.simplify(jtsGeometry, distanceTolerance);
141+
String simplifiedWkt = writer.write(simplifiedGeometry);
142+
Geometry esGeometryResult = WellKnownText.fromWKT(validator, false, simplifiedWkt);
143+
124144
result.appendBytesRef(new BytesRef(WellKnownBinary.toWKB(esGeometryResult, ByteOrder.LITTLE_ENDIAN)));
125145
}
126146
} catch (Exception e) {
@@ -133,19 +153,24 @@ public Block eval(Page page) {
133153

134154
try {
135155
for (int p = 0; p < positionCount; p++) {
156+
double distanceTolerance = tolerances.getDouble(p);
136157
var destRef = bytesRefVector.getBytesRef(p, new BytesRef());
137158
var wkt = WellKnownText.fromWKB(destRef.bytes, destRef.offset, destRef.length);
138159
org.locationtech.jts.geom.Geometry jtsGeometry = reader.read(wkt);
139-
org.locationtech.jts.geom.Geometry simplifiedGeometry =
140-
DouglasPeuckerSimplifier.simplify(jtsGeometry, 0);
160+
org.locationtech.jts.geom.Geometry simplifiedGeometry = DouglasPeuckerSimplifier.simplify(
161+
jtsGeometry,
162+
distanceTolerance
163+
);
141164
String simplifiedWkt = writer.write(simplifiedGeometry);
142165
Geometry esGeometryResult = WellKnownText.fromWKT(validator, false, simplifiedWkt);
143166
result.appendBytesRef(new BytesRef(WellKnownBinary.toWKB(esGeometryResult, ByteOrder.LITTLE_ENDIAN)));
144167
}
145168
} catch (Exception e) {
146169
throw new RuntimeException(e);
147170
}
171+
block.close();
148172
}
173+
tolerances.close();
149174

150175
return result.build().asBlock();
151176
}

0 commit comments

Comments
 (0)