8
8
package org .elasticsearch .xpack .esql .expression .function .scalar .spatial ;
9
9
10
10
import org .apache .lucene .util .BytesRef ;
11
+ import org .elasticsearch .common .io .stream .NamedWriteableRegistry ;
12
+ import org .elasticsearch .common .io .stream .StreamInput ;
11
13
import org .elasticsearch .common .io .stream .StreamOutput ;
12
14
import org .elasticsearch .compute .data .Block ;
13
15
import org .elasticsearch .compute .data .BytesRefVectorBlock ;
16
+ import org .elasticsearch .compute .data .DoubleVector ;
14
17
import org .elasticsearch .compute .data .Page ;
15
18
import org .elasticsearch .compute .operator .EvalOperator ;
16
19
import org .elasticsearch .geometry .Geometry ;
17
20
import org .elasticsearch .geometry .utils .StandardValidator ;
18
21
import org .elasticsearch .geometry .utils .WellKnownBinary ;
19
22
import org .elasticsearch .geometry .utils .WellKnownText ;
20
23
import org .elasticsearch .xpack .esql .core .expression .Expression ;
21
- import org .elasticsearch .xpack .esql .core .expression .function .scalar .ScalarFunction ;
22
24
import org .elasticsearch .xpack .esql .core .tree .NodeInfo ;
23
25
import org .elasticsearch .xpack .esql .core .tree .Source ;
24
26
import org .elasticsearch .xpack .esql .core .type .DataType ;
25
- import org .elasticsearch .xpack .esql .evaluator .mapper .EvaluatorMapper ;
26
27
import org .elasticsearch .xpack .esql .expression .function .Example ;
27
28
import org .elasticsearch .xpack .esql .expression .function .FunctionInfo ;
28
29
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 ;
29
32
import org .locationtech .jts .io .WKTReader ;
30
33
import org .locationtech .jts .io .WKTWriter ;
31
34
import org .locationtech .jts .simplify .DouglasPeuckerSimplifier ;
37
40
import static org .elasticsearch .xpack .esql .core .type .DataType .GEO_SHAPE ;
38
41
import static org .elasticsearch .xpack .esql .expression .function .scalar .spatial .SpatialRelatesUtils .makeGeometryFromLiteral ;
39
42
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
+ );
41
49
Expression geometry ;
42
50
Expression tolerance ;
43
51
@@ -61,6 +69,14 @@ public StSimplify(
61
69
this .tolerance = tolerance ;
62
70
}
63
71
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
+
64
80
@ Override
65
81
public DataType dataType () {
66
82
return GEO_SHAPE ;
@@ -78,12 +94,14 @@ protected NodeInfo<? extends Expression> info() {
78
94
79
95
@ Override
80
96
public String getWriteableName () {
81
- return "StSimplify" ;
97
+ return ENTRY . name ;
82
98
}
83
99
84
100
@ Override
85
101
public void writeTo (StreamOutput out ) throws IOException {
86
-
102
+ source ().writeTo (out );
103
+ out .writeNamedWriteable (geometry );
104
+ out .writeNamedWriteable (tolerance );
87
105
}
88
106
89
107
@ Override
@@ -101,11 +119,11 @@ public void close() {
101
119
@ Override
102
120
public Block eval (Page page ) {
103
121
var isGeometryFoldable = geometry .foldable ();
104
- var isToleranceFoldable = tolerance .foldable ();
105
122
var positionCount = page .getPositionCount ();
106
123
var validator = StandardValidator .instance (true );
107
124
WKTReader reader = new WKTReader ();
108
125
WKTWriter writer = new WKTWriter ();
126
+ DoubleVector tolerances = (DoubleVector ) toleranceEvaluator .eval (page ).asVector ();
109
127
110
128
// TODO We are not extracting non foldable geometries
111
129
// TODO We are not using the tolerance
@@ -116,11 +134,13 @@ public Block eval(Page page) {
116
134
117
135
try {
118
136
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 );
122
137
123
138
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
+
124
144
result .appendBytesRef (new BytesRef (WellKnownBinary .toWKB (esGeometryResult , ByteOrder .LITTLE_ENDIAN )));
125
145
}
126
146
} catch (Exception e ) {
@@ -133,19 +153,24 @@ public Block eval(Page page) {
133
153
134
154
try {
135
155
for (int p = 0 ; p < positionCount ; p ++) {
156
+ double distanceTolerance = tolerances .getDouble (p );
136
157
var destRef = bytesRefVector .getBytesRef (p , new BytesRef ());
137
158
var wkt = WellKnownText .fromWKB (destRef .bytes , destRef .offset , destRef .length );
138
159
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
+ );
141
164
String simplifiedWkt = writer .write (simplifiedGeometry );
142
165
Geometry esGeometryResult = WellKnownText .fromWKT (validator , false , simplifiedWkt );
143
166
result .appendBytesRef (new BytesRef (WellKnownBinary .toWKB (esGeometryResult , ByteOrder .LITTLE_ENDIAN )));
144
167
}
145
168
} catch (Exception e ) {
146
169
throw new RuntimeException (e );
147
170
}
171
+ block .close ();
148
172
}
173
+ tolerances .close ();
149
174
150
175
return result .build ().asBlock ();
151
176
}
0 commit comments